diff --git a/.agents/skills/.gitignore b/.agents/skills/.gitignore new file mode 100644 index 000000000..d8ccabddf --- /dev/null +++ b/.agents/skills/.gitignore @@ -0,0 +1,5 @@ +* +!.gitignore +!/xcodegen/ +!/shadowsocksx-ng2-local-validation/ + diff --git a/.agents/skills/shadowsocksx-ng2-local-validation/SKILL.md b/.agents/skills/shadowsocksx-ng2-local-validation/SKILL.md new file mode 100644 index 000000000..28a8b0bf5 --- /dev/null +++ b/.agents/skills/shadowsocksx-ng2-local-validation/SKILL.md @@ -0,0 +1,43 @@ +--- +name: shadowsocksx-ng2-local-validation +description: Validate ShadowsocksX-NG2 changes and diagnose retained local validation results. +--- + +# ShadowsocksX-NG2 local validation + +This repository copy is the maintained skill. Copies under `~/.codex/memories/skills/` are historical snapshots. Paths below are relative to the repository root unless stated otherwise. + +## Select the evidence + +1. Inspect the request, staged and unstaged diffs, `ShadowsocksX-NG2/AGENTS.md`, and relevant ADRs. Read `ShadowsocksX-NG2/README.md` for build/signing conventions and `ShadowsocksX-NG2/Taskfile.dist.yml` for current gate definitions. +2. Identify the requested level: focused tests, full hostless suite, real-process smoke, Debug/Release build, native/manual UI, or real system-proxy behavior. Retain that scope; documentation-only changes do not require repeating full suites. +3. For structural/resource changes, update authoritative `project.yml` and run `task gen:prj` from `ShadowsocksX-NG2/`; never hand-edit the generated project. + +## Run the selected checks + +- Work from `ShadowsocksX-NG2/`. For combined validation use `task --exit-code validate`. From another directory use `task --exit-code --taskfile /absolute/path/to/ShadowsocksX-NG2/Taskfile.dist.yml validate`. +- Default gates are `lint test test:smoke build`, executed in order with fail-fast behavior. To select a non-duplicated subset, append e.g. `-- lint test`. Diagnose the first failure; later selected gates are `not_run`, not skipped tests. +- `test` runs offline binary/rule checks before the hostless arm64 Xcode suite. Its Xcode test counts do not count those earlier checks. `test:smoke` uses the separate `ShadowsocksX-NG2Smoke` scheme and real processes. `build` is Debug; Release is a separate `task build:release` and is outside `validate`. +- Run focused tests when appropriate using the existing Xcode scheme and test selection; a focused Xcode run does not cover the preceding Taskfile checks. Use isolated derived data when needed. Follow the repository Debug ad-hoc signing baseline; Release requires Developer ID signing and has no unsigned fallback. +- `task format` and `task lint:fix` mutate source; use when requested or needed for the change, then inspect the diff. Current commands and options belong in Taskfile, not this skill. + +## Read retained evidence + +`validate` prints its run directory, `ShadowsocksX-NG2/.build/validation/-/`. Gate directories use the gate name with `:` replaced by `-` (`test:smoke` → `test-smoke/`). `task clean` removes these artifacts; copy them elsewhere if long-term retention is needed. + +1. Read the run's `summary.txt` first. It records the overall exit code, selected gates, gate status/exit codes, test counts and evidence warnings. Per-gate `status.txt` supplies the same gate summary. +2. For failed Xcode tests, read that gate's `test-summary.json`, especially `testFailures`. Report each failing case using `testIdentifierString` (or `testName`) and its `failureText`. For example, `plutil -extract testFailures json -o - /test-summary.json` reads the retained failures without reopening the result bundle. +3. If the summary is absent, unreadable, or insufficient, read the relevant diagnostics: `test-summary.stderr.log` for extraction failure, `count-reader.log` for invalid counts, and `raw.log` for gate output, pre-Xcode failures, build/lint errors, or missing context. Query `result.xcresult` only for unresolved detail. When retained summaries answer the question, do not repeat `xcresulttool` extraction. +4. Keep command outcome and evidence completeness separate. `validate:result` writes the original gate exit code; summary extraction does not replace it. A missing result bundle or unreadable/invalid test summary means `evidence incomplete` and unknown counts, never zero counts or an inferred pass. `validate:summary` preserves the overall exit code and marks unexecuted selected gates `not_run`. Build has no test-count summary; lint has no xcresult requirement. + +## Diagnose within the evidence boundary + +- If XcodeGen reports `No project spec found`, check cwd. Permission failures in Xcode, macros, signing or Git may be environment boundaries: retry the unchanged command through authorized macOS execution before changing source. Distinguish missing Release signing configuration from source failure. +- Preserve assertions and default parallel execution when investigating flakes. Prefer deterministic readiness and explicit fixture release, cancellation and drainage over extra sleeps or increased timeouts. For parallelism claims, inspect runner evidence; configuration alone does not prove concurrent execution. +- For connectivity/latency smoke, verify listener ownership by the spawned process (`RuntimeSocketOwnershipProbe` or its current equivalent), response-header deadlines, and process-group/temp-environment cleanup. Use local DNS/loopback fixtures and proxy-egress observations where routing assertions require them. +- Keep inherited XCTest `test*` methods out of shared fixture bases to avoid duplicate execution. Measure slow rule/runtime segments before adding delay injection. +- Hostless tests, real-process smoke, native/manual UI, and real system-proxy acceptance are separate evidence levels. Hostless/smoke success does not establish SystemConfiguration writes, helper approval, notification behavior, or visual acceptance. + +## Finish + +Inspect staged and unstaged diffs and run `git diff --check`. Report the actual commands, run directory, exit codes, counts in Xcode's summary convention (parameterized executions may differ), warnings, evidence gaps, and omitted acceptance levels. Commit locally only when requested; push only with explicit authorization. diff --git a/.agents/skills/shadowsocksx-ng2-local-validation/agents/openai.yaml b/.agents/skills/shadowsocksx-ng2-local-validation/agents/openai.yaml new file mode 100644 index 000000000..5b1f887a9 --- /dev/null +++ b/.agents/skills/shadowsocksx-ng2-local-validation/agents/openai.yaml @@ -0,0 +1,2 @@ +policy: + allow_implicit_invocation: false diff --git a/.agents/skills/xcodegen/SKILL.md b/.agents/skills/xcodegen/SKILL.md new file mode 100644 index 000000000..382e18633 --- /dev/null +++ b/.agents/skills/xcodegen/SKILL.md @@ -0,0 +1,76 @@ +--- +name: xcodegen +description: Generate and manage Xcode projects with XcodeGen — write project.yml as the source of truth and produce .xcodeproj from it instead of hand-editing pbxproj files. Use this skill whenever creating or modifying an Xcode project's structure (targets, schemes, build settings, Info.plist, entitlements, dependencies like SPM packages or frameworks), when the user mentions xcodegen / project.yml / regenerating or fixing a .xcodeproj, or when asked to add files or targets to an Xcode project — even if they don't name XcodeGen explicitly. Also applies to CI project generation and migrating a repo to a generated-project workflow. +--- + +# XcodeGen + +XcodeGen generates `.xcodeproj` files from a declarative `project.yml` spec. + +**Core mental model: `project.yml` is the source of truth; `.xcodeproj` is a disposable build artifact.** Never hand-edit the `.xcodeproj` and never tell the user to add files through Xcode's UI — every structural change (new target, new source directory, new dependency) goes through `project.yml` + regeneration. That is the entire point of the tool: no pbxproj merge conflicts, and the project structure becomes reviewable YAML in git. + +## The workflow + +1. Check the tool exists: `which xcodegen` (install with `brew install xcodegen`). If the spec uses newer features, note them in `options.minimumXcodeGenVersion`. +2. Write or edit `project.yml` at the repo/project root. +3. Generate: `xcodegen generate` (add `--use-cache` in scripts/CI so unchanged specs skip regeneration). +4. Verify the result — a generated project that doesn't build is not done: + - `xcodebuild -list -project .xcodeproj` — schemes and configurations are as expected. + - `xcodebuild -project .xcodeproj -scheme build` — the real gate. + - `xcodegen dump --spec project.yml` prints the fully-resolved spec; use it to debug `include:` merges or surprising settings presets. + +## Minimal working example + +macOS app + unit tests + scheme — the shape most projects need; adapt platform, paths, and deployment target: + +```yaml +name: MyApp +options: + bundleIdPrefix: com.example # targets without PRODUCT_BUNDLE_IDENTIFIER get com.example. + deploymentTarget: + macOS: "13.0" + createIntermediateGroups: true +targets: + MyApp: + type: application + platform: macOS + sources: + - path: MyApp # a directory: everything under it is picked up + info: + path: MyApp/Info.plist # generated and written to disk; CFBundle* keys auto-filled + properties: + LSMinimumSystemVersion: "13.0" + scheme: + testTargets: + - MyAppTests # scheme "MyApp" builds app + runs tests + MyAppTests: + type: bundle.unit-test + platform: macOS + sources: + - path: MyAppTests + dependencies: + - target: MyApp # TEST_HOST is set automatically for unit tests +``` + +```bash +xcodegen generate +xcodebuild -project MyApp.xcodeproj -scheme MyApp build +``` + +## Rules that prevent most mistakes + +- **Regenerate after adding/removing source files.** Source globs are resolved when `xcodegen generate` runs, not live by Xcode — a new `.swift` file on disk is invisible to the project until then. "My file isn't in the target" almost always means: run `xcodegen generate`. (Xcode auto-reloads a regenerated project that's already open.) +- **Never mix settings styles.** In a `settings:` block, if you use `base:`, `configs:`, or `groups:`, a sibling plain map (e.g. `MARKETING_VERSION: 1.0` at the same level) is *silently ignored*. Pick one style per block; the plain-map style only works alone. +- **Quote deployment targets**: `deploymentTarget: "14.0"`, not `14.0` (YAML parses the latter as a float and trailing zeros vanish). +- **Prefer `info:` / `entitlements:` blocks** over committing static plists: XcodeGen writes the files and sets `INFOPLIST_FILE` / `CODE_SIGN_ENTITLEMENTS` for you, and fills `CFBundleIdentifier`, `CFBundleExecutable`, `CFBundleShortVersionString` etc. automatically. Anything you put in `properties:` wins. Info.plist files found in sources are never added to build phases. +- **Mark generated/optional paths** with `optional: true` on a source, or generation fails when the directory doesn't exist yet. +- **Test targets**: declare the app as a `dependencies: - target:` of the test target — that alone wires up `TEST_HOST` (unit tests) or `TEST_TARGET_NAME` (UI tests, type `bundle.ui-testing`). +- **Extensions embed themselves**: a dependency of an `application` target defaults to `embed: true`, so `- target: MyExtension` is usually all an app needs — no copy-files phase to write. +- **Extension bundle IDs must live under the app's bundle ID.** macOS/iOS validate that an embedded extension's bundle ID starts with the parent app's — `com.example.MyProxy.Tunnel`, not `com.example.Tunnel`. Since `bundleIdPrefix` auto-derivation gives every target `prefix.TargetName`, extensions fail a *build-validation* step (not compilation) with "Embedded binary's bundle identifier is not prefixed with the parent app's bundle identifier". Always set `PRODUCT_BUNDLE_IDENTIFIER` explicitly on extension targets (see recipes.md #2). +- **`.gitignore` the generated project** (`*.xcodeproj`) so no one edits it by accident. If the repo currently tracks one, flag the migration step (remove from index, regenerate locally) rather than doing it silently. +- **`xcodegen generate` is idempotent.** When in doubt, re-run it; there is no state to corrupt. + +## Choosing between the reference files + +- `references/project-spec.md` — syntax cheat sheet: every section of `project.yml` with exact key names. Read when you need a field you don't remember precisely (source exclude patterns, dependency options, scheme fields, SPM version constraints). +- `references/recipes.md` — complete copy-pasteable `project.yml` examples: app + unit/UI tests, app extension (e.g. network extension) with entitlements, SPM remote/local packages, per-config xcconfig, vendored pre-built binaries/frameworks, build-script phases, splitting a spec with `include:`. Read before writing any non-trivial spec — reuse a recipe rather than assembling from memory. diff --git a/.agents/skills/xcodegen/references/project-spec.md b/.agents/skills/xcodegen/references/project-spec.md new file mode 100644 index 000000000..24510b48e --- /dev/null +++ b/.agents/skills/xcodegen/references/project-spec.md @@ -0,0 +1,261 @@ +# project.yml Syntax Cheat Sheet + +Condensed from the official ProjectSpec docs (XcodeGen 2.4x). When this file and the official docs disagree, trust the docs: https://github.com/yonaskolb/XcodeGen/blob/master/Docs/ProjectSpec.md + +## Top level + +```yaml +name: MyProject # required +include: [base.yml] # merge other specs (see bottom of this file) +options: {...} # project-wide behavior (below) +attributes: {...} # raw PBXProject attributes (rarely needed) +configs: {...} # build configurations (default: Debug/Release) +configFiles: {Debug: path.xcconfig} +settingGroups: {name: {settings}} # reusable settings, referenced via settings.groups +settings: {...} # project-level build settings +targets: {TargetName: {...}} # the targets +fileGroups: [dir-or-file] # shown in project navigator, not in any target +schemes: {SchemeName: {...}} +schemeTemplates: {...} +targetTemplates: {...} +packages: {PackageName: {...}} # Swift packages +projectReferences: {Name: {path: Other.xcodeproj}} +``` + +## Options (commonly used) + +```yaml +options: + bundleIdPrefix: com.example # auto bundle IDs: prefix + target name + deploymentTarget: # project-wide defaults + macOS: "13.0" + iOS: "16.0" + createIntermediateGroups: true # groups for intermediate path components + minimumXcodeGenVersion: "2.38.0" + developmentLanguage: zh-Hans # default "en" + transitivelyLinkDependencies: false # link deps-of-deps (default false) + generateEmptyDirectories: false + groupSortPosition: bottom # top | bottom | none + groupOrdering: # custom group order in navigator + - order: [Sources, Resources, Tests] + preGenCommand: make resources # bash, skipped when cache skips generation + postGenCommand: pod install + defaultConfig: Debug + defaultSourceDirectoryType: group # group | folder | syncedFolder (xcode16_0+) +``` + +Environment variable expansion works in any string: `${SOME_VAR}` (disable with `xcodegen generate -n`). + +## Configs + +Each config maps to a build type; anything other than `debug`/`release` gets no default settings: + +```yaml +configs: + Debug: debug + Beta: release + AppStore: release +``` + +## Settings + +Two forms — **never mix them in one block** (plain keys are silently dropped if `base`/`configs`/`groups` is present): + +```yaml +settings: + SWIFT_VERSION: "5.9" # form 1: simple map + +settings: # form 2: structured + base: + MARKETING_VERSION: "1.0" + configs: # key matched case-insensitively/partially to config names + debug: + CODE_SIGN_IDENTITY: Apple Development + release: + CODE_SIGN_IDENTITY: Apple Distribution + groups: [shared-settings] # references to settingGroups +``` + +## Target + +```yaml +targets: + MyTarget: + type: application # required, see list below + platform: macOS # required: macOS | iOS | tvOS | watchOS | visionOS | auto + supportedDestinations: [macOS, macCatalyst] # alternative to platform (Xcode 14+) + deploymentTarget: "13.0" # or per-platform map for multi-platform targets + sources: [...] + dependencies: [...] + settings: {...} + configFiles: {Debug: path.xcconfig} + info: {...} # generates Info.plist + entitlements: {...} # generates .entitlements + templates: [Name] # from targetTemplates; ${target_name} substitution + templateAttributes: {attr: value} + preBuildScripts: [...] # also postCompileScripts, postBuildScripts + buildRules: [...] + buildToolPlugins: [{plugin: P, package: PKG}] + scheme: {...} # per-target convenience scheme + attributes: {...} + transitivelyLinkDependencies: true + requiresObjCLinking: true # default true only for library.static +``` + +Product types (attribute to `type:`): `application`, `app-extension`, `extensionkit-extension`, `framework`, `framework.static`, `library.static`, `library.dynamic`, `bundle`, `bundle.unit-test`, `bundle.ui-testing`, `tool`, `xpc-service`, `system-extension`, `watchkit2-extension`, `application.messages`, `application.watchapp2`, and friends. + +Settings set automatically for you (don't set by hand): `INFOPLIST_FILE` (if an Info.plist is found in sources or defined via `info:`), `TEST_HOST` (unit tests depending on an app), `TEST_TARGET_NAME` (UI tests depending on an app), `FRAMEWORK_SEARCH_PATHS` (Carthage), `OTHER_LDFLAGS` (ObjC linking). + +Multi-platform: `platform: [iOS, tvOS]` generates one target per platform named `Name_iOS`, `Name_tvOS`; `${platform}` interpolates inside the target spec. + +## Sources + +A source is a path string or an object. Directories are expanded at **generation time** — new files require regeneration. + +```yaml +sources: + - Sources # whole directory + - path: Sources + excludes: # bash-4 globstar patterns, relative to `path` + - "**/*.md" + - "ios/*.[mh]" + - "*-Private.h" + includes: ["**/*.swift"] # whitelist; excludes win on conflict + compilerFlags: ["-Werror"] + createIntermediateGroups: true + optional: true # don't fail if the path doesn't exist + headerVisibility: public # public | private | project + type: group # group (default for dirs) | file | folder | syncedFolder + buildPhase: sources # sources | resources | headers | none, or copyFiles: {destination: …, subpath: …} + - path: Vendor/Binaries + buildPhase: none # show in navigator only + - path: MyFile.swift # single file + buildPhase: + copyFiles: + destination: wrapper # absolutePath | productsDirectory | wrapper | executables | + subpath: Contents/Tools # resources | javaResources | frameworks | sharedFrameworks | + # sharedSupport | plugins +``` + +## Dependencies + +```yaml +dependencies: + - target: OtherTarget # links; embeds if this is an application (embed default true) + - target: OtherProject/OtherTarget # via projectReferences + - package: SomePackage # name from top-level packages + product: LibraryName # only if product ≠ package name + products: [A, B] # multiple products + - framework: Vendor/Foo.xcframework + embed: true # default true for apps + codeSign: true + weak: false + - sdk: libc++.tbd # or Contacts.framework, libz.dylib + - carthage: Alamofire # linkType: static|dynamic, findFrameworks: bool + - bundle: Prebuilt.bundle # adds to Copy Resources +``` + +## Info.plist and entitlements (`info:` / `entitlements:`) + +Files are written to disk on every generation. `info` auto-fills CFBundleIdentifier, CFBundleInfoDictionaryVersion, CFBundleExecutable, CFBundleName, CFBundleDevelopmentRegion, CFBundleShortVersionString, CFBundleVersion, CFBundlePackageType where appropriate; `entitlements` requires all properties explicitly. + +```yaml +info: + path: App/Info.plist + properties: + LSMinimumSystemVersion: "13.0" +entitlements: + path: App/App.entitlements + properties: + com.apple.security.application-groups: [group.com.example.app] +``` + +## Build scripts + +```yaml +preBuildScripts: # also postCompileScripts, postBuildScripts + - name: SwiftLint + script: swiftlint # or path: scripts/lint.sh + inputFiles: ["$(SRCROOT)/file1"] + outputFileLists: ["$(SRCROOT)/outputs.xcfilelist"] + showEnvVars: false + basedOnDependencyAnalysis: true # skip when inputs/outputs unchanged + runOnlyWhenInstalling: false +``` + +## Schemes + +Per-target convenience (preferred when one scheme ≈ one target): + +```yaml +targets: + App: + scheme: + testTargets: [AppTests] + configVariants: [Staging, Production] # generates one scheme per variant + gatherCoverageData: true + commandLineArguments: {"-MyArg": true} + environmentVariables: {KEY: VALUE} +``` + +Top-level (full control; `build.targets` is required): + +```yaml +schemes: + MyApp: + build: + targets: + MyApp: all # all | none | [run, test, profile, analyze, archive] + MyAppTests: [test] + run: + config: Debug + commandLineArguments: {"-InMemory": true} + environmentVariables: + - variable: API_ENV + value: staging + isEnabled: true + test: + gatherCoverageData: true + targets: + - AppTests + - name: UITests + parallelizable: true + randomExecutionOrder: true + skippedTests: [UITests/testFlaky()] + archive: + config: Release + customArchiveName: MyApp +``` + +## Swift packages + +```yaml +packages: + Yams: + url: https://github.com/jpsim/Yams + from: 2.0.0 # or majorVersion / minorVersion / exactVersion / version, + # minVersion+maxVersion, branch, revision + Alamofire: + github: Alamofire/Alamofire # shorthand for github URLs + exactVersion: 5.8.0 + LocalLib: + path: Packages/LocalLib # directory containing Package.swift + group: LocalPackages # navigator group, default "Packages" +``` + +Link into targets with `dependencies: - package: Yams`. + +## Splitting the spec (`include`) + +Included files merge additively (dicts merge, arrays append); suffix a key with `:REPLACE` to override instead of append. Paths inside included files are relative to that file unless `relativePaths: false`. + +```yaml +include: + - base.yml + - path: extra.yml + relativePaths: false + enable: ${INCLUDE_EXTRA} +targets: + App: # target defined in base.yml + sources:REPLACE: [NewSources] +``` diff --git a/.agents/skills/xcodegen/references/recipes.md b/.agents/skills/xcodegen/references/recipes.md new file mode 100644 index 000000000..f16859089 --- /dev/null +++ b/.agents/skills/xcodegen/references/recipes.md @@ -0,0 +1,252 @@ +# project.yml Recipes + +Complete, copy-pasteable specs. Combine the parts you need; trim what you don't. Each recipe is self-contained except where noted. + +## 1. iOS app + unit tests + UI tests + +```yaml +name: MyApp +options: + bundleIdPrefix: com.example + deploymentTarget: + iOS: "16.0" +targets: + MyApp: + type: application + platform: iOS + sources: [MyApp] + info: + path: MyApp/Info.plist + properties: + UILaunchScreen: {} # modern no-storyboard launch + UISupportedInterfaceOrientations: [UIInterfaceOrientationPortrait] + scheme: + testTargets: [MyAppTests, MyAppUITests] + MyAppTests: + type: bundle.unit-test + platform: iOS + sources: [MyAppTests] + dependencies: + - target: MyApp # TEST_HOST set automatically + MyAppUITests: + type: bundle.ui-testing + platform: iOS + sources: [MyAppUITests] + dependencies: + - target: MyApp # TEST_TARGET_NAME set automatically +``` + +## 2. macOS app with an embedded extension (network extension, share extension, …) + +Extensions need three things: the right `type`, an `NSExtension` (or `NSSystemExtension`) dict in Info.plist properties, and usually entitlements. The app embeds them automatically — no copy phase needed. + +```yaml +name: MyProxy +options: + bundleIdPrefix: com.example + deploymentTarget: + macOS: "13.0" +targets: + MyProxy: + type: application + platform: macOS + sources: + - path: MyProxy + info: + path: MyProxy/Info.plist + properties: + LSMinimumSystemVersion: "13.0" + entitlements: + path: MyProxy/MyProxy.entitlements + properties: + com.apple.security.app-sandbox: true + com.apple.security.network.client: true + com.apple.security.network.server: true + dependencies: + - target: Tunnel # embedded into Contents/PlugIns automatically + scheme: + testTargets: [MyProxyTests] + Tunnel: + type: app-extension # Network Extension packet-tunnel providers use this type; + # use system-extension for DriverKit/transparent-proxy style + platform: macOS + sources: [Tunnel] + settings: + base: + PRODUCT_BUNDLE_IDENTIFIER: com.example.MyProxy.Tunnel # must be prefixed by the app's + # bundle ID; bundleIdPrefix auto-derivation (com.example.Tunnel) + # fails at build validation, not compile + info: + path: Tunnel/Info.plist + properties: + CFBundleDisplayName: Tunnel + NSExtension: + NSExtensionPointIdentifier: com.apple.networkextension.packet-tunnel + entitlements: + path: Tunnel/Tunnel.entitlements + properties: + com.apple.security.app-sandbox: true + com.apple.security.network.client: true + MyProxyTests: + type: bundle.unit-test + platform: macOS + sources: [MyProxyTests] + dependencies: + - target: MyProxy +``` + +Note: Network Extension entitlements (`com.apple.developer.networking.networkextension`) require a provisioning profile from Apple; generation and local builds succeed without it, distribution signing does not. Don't "fix" a signing failure by inventing entitlement values. + +## 3. SPM dependencies (remote and local) + +```yaml +name: MyApp +options: + bundleIdPrefix: com.example +packages: + SnapshotTesting: + url: https://github.com/pointfreeco/swift-snapshot-testing + from: 1.17.0 + Alamofire: + github: Alamofire/Alamofire # shorthand + exactVersion: 5.8.0 + FeatureKit: + path: Packages/FeatureKit # local package (dir with Package.swift) +targets: + MyApp: + type: application + platform: iOS + sources: [MyApp] + dependencies: + - package: Alamofire + - package: FeatureKit + product: FeatureKitDomain # only when product ≠ package name + MyAppTests: + type: bundle.unit-test + platform: iOS + sources: [MyAppTests] + dependencies: + - target: MyApp + - package: SnapshotTesting + products: [SnapshotTesting] # or use `product:` for one +``` + +## 4. Custom configs + xcconfig files + +```yaml +name: MyApp +options: + bundleIdPrefix: com.example +configs: + Debug: debug + Beta: release # maps to release-type defaults + AppStore: release +configFiles: # project level + Debug: Configs/project-debug.xcconfig +targets: + MyApp: + type: application + platform: iOS + sources: [MyApp] + configFiles: # target level overrides + Debug: Configs/app-debug.xcconfig + Beta: Configs/app-beta.xcconfig + AppStore: Configs/app-appstore.xcconfig + settings: + base: + XCConfigOnlyWhenNotInFile: value # xcconfig wins for keys it defines +schemes: + MyApp-Beta: + build: + targets: {MyApp: all} + run: + config: Beta + archive: + config: AppStore +``` + +## 5. Vendored pre-built binaries and frameworks + +Pre-built CLI tools and xcframeworks checked into the repo (not built from source): + +```yaml +targets: + MyApp: + type: application + platform: macOS + sources: + - path: MyApp + - path: Vendor/Tools/ss-local # a single pre-built executable + buildPhase: + copyFiles: + destination: wrapper + subpath: Contents/Tools # ends up at MyApp.app/Contents/Tools/ss-local + - path: Vendor/Tools/privoxy + buildPhase: + copyFiles: + destination: wrapper + subpath: Contents/Tools + dependencies: + - framework: Vendor/Frameworks/SwiftZip.xcframework +``` + +Keep vendored binaries out of any target's plain `sources:` glob (or exclude them), otherwise XcodeGen guesses a build phase from the extension. Executables without extension are left alone, but being explicit with `buildPhase: copyFiles` documents intent. + +## 6. Build script phases with proper inputs/outputs + +Scripts without declared inputs/outputs re-run every build and break incremental builds — declare them: + +```yaml +targets: + MyApp: + type: application + platform: iOS + sources: [MyApp] + preBuildScripts: + - name: Generate Protos + script: | + ./scripts/generate-protos.sh + inputFiles: + - $(SRCROOT)/Protos/messages.proto + outputFiles: + - $(DERIVED_FILE_DIR)/Messages.pb.swift + basedOnDependencyAnalysis: true + postBuildScripts: + - name: SwiftLint + script: swiftlint + showEnvVars: false + - name: Crash Reporter Upload + script: ./scripts/upload-dsyms.sh + runOnlyWhenInstalling: true +``` + +## 7. Splitting a big spec across files + +`include` merges additively (dicts merge, arrays append); add `:REPLACE` to overwrite a list instead of appending to it. + +```yaml +# project.yml +name: MyApp +include: + - project/targets.yml + - project/schemes.yml +options: + bundleIdPrefix: com.example +``` + +```yaml +# project/targets.yml +targets: + MyApp: + type: application + platform: iOS + sources: [MyApp] + MyAppTests: + type: bundle.unit-test + platform: iOS + sources: [MyAppTests] + dependencies: + - target: MyApp +``` + +Use `xcodegen dump --spec project.yml` to inspect the merged result when an override doesn't behave. diff --git a/.codegraph/.gitignore b/.codegraph/.gitignore new file mode 100644 index 000000000..d20c0fe4b --- /dev/null +++ b/.codegraph/.gitignore @@ -0,0 +1,5 @@ +# CodeGraph data files — local to each machine, not for committing. +# Ignore everything in .codegraph/ except this file itself, so transient +# files (the database, daemon.pid, sockets, logs) never show up in git. +* +!.gitignore diff --git a/.codex/.gitignore b/.codex/.gitignore new file mode 100644 index 000000000..30e723611 --- /dev/null +++ b/.codex/.gitignore @@ -0,0 +1,2 @@ +config.toml +hooks.json diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md deleted file mode 100644 index 0d5b07841..000000000 --- a/.github/ISSUE_TEMPLATE/Bug_report.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**System and Shadowsocksx-NG version: (please complete the following information):** - - OS Version: [e.g. 10.13.1] - - Version [e.g. 22] - -**Diagnoisis file:** - -Please first upgrade to the latest version. -Then export the diagnosis file and upload it to here. - -**ss-local.log** - -Please upload the ss-local.log file here the file is in `~/Library/Logs` -1) Open 'Advanced Settings -> enable Verbose Mode' -2) Continue run `Shadowsocksx-NG` for 5 minutes -3) Upload the `~/Library/Logs/ss-local.log` here (with or without compress) - -**Application log** - -Open the `Console.app` and search `Shadowsocksx-NG` -Copy paste the log here - -**Crash Log** - -If the app crashes and pop up a crash log, please copy and paste here - -**Additional context** -Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/Feature_request.md b/.github/ISSUE_TEMPLATE/Feature_request.md deleted file mode 100644 index 538429512..000000000 --- a/.github/ISSUE_TEMPLATE/Feature_request.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/actions/setup-ng2/action.yml b/.github/actions/setup-ng2/action.yml new file mode 100644 index 000000000..1e41f3aa8 --- /dev/null +++ b/.github/actions/setup-ng2/action.yml @@ -0,0 +1,88 @@ +name: Set up NG2 dependencies +description: Install Homebrew tools and optionally fetch verified external binaries. +inputs: + packages: + description: Space-separated Homebrew formulae to install. + default: age go-task xcodegen swiftlint + external-binaries: + description: Whether to fetch and verify external binaries. + default: 'true' +runs: + using: composite + steps: + - name: Prepare Homebrew download cache + shell: bash + env: + HOMEBREW_PACKAGES: ${{ inputs.packages }} + id: homebrew-cache-key + run: | + read -r -a packages <<< "$HOMEBREW_PACKAGES" + brew info --json=v2 "${packages[@]}" > "$RUNNER_TEMP/homebrew-formulae.json" + formula_hash=$(python3 - "$RUNNER_TEMP/homebrew-formulae.json" <<'PY' + import hashlib + import json + import sys + + with open(sys.argv[1]) as source: + formulae = json.load(source)["formulae"] + versions = sorted( + (f["full_name"], f["versions"]["stable"], f["revision"], f["bottle"]) + for f in formulae + ) + print(hashlib.sha256(json.dumps(versions, sort_keys=True).encode()).hexdigest()) + PY + ) + echo "path=$(brew --cache)/downloads" >> "$GITHUB_OUTPUT" + echo "key=ng2-homebrew-downloads-v1-macos-$(sw_vers -productVersion)-$(uname -m)-$formula_hash" >> "$GITHUB_OUTPUT" + + - name: Restore Homebrew download cache + id: homebrew-cache + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ${{ steps.homebrew-cache-key.outputs.path }} + key: ${{ steps.homebrew-cache-key.outputs.key }} + + - name: Install build tools and test dependencies + id: install-build-tools + shell: bash + env: + HOMEBREW_PACKAGES: ${{ inputs.packages }} + HOMEBREW_NO_AUTO_UPDATE: '1' + HOMEBREW_NO_INSTALL_CLEANUP: '1' + run: | + read -r -a packages <<< "$HOMEBREW_PACKAGES" + brew install "${packages[@]}" + + - name: Save Homebrew download cache + if: steps.install-build-tools.outcome == 'success' && steps.homebrew-cache.outputs.cache-hit != 'true' + uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ${{ steps.homebrew-cache-key.outputs.path }} + key: ${{ steps.homebrew-cache.outputs.cache-primary-key }} + + - name: Restore external binary archive cache + if: inputs.external-binaries == 'true' + id: external-binary-cache + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ShadowsocksX-NG2/.build/external-binary-archives + key: ng2-external-binaries-macos-arm64-${{ hashFiles('ShadowsocksX-NG2/Vendor/*/manifest.json') }} + restore-keys: | + ng2-external-binaries-macos-arm64- + + - name: Fetch and verify external binaries + if: inputs.external-binaries == 'true' + shell: bash + id: fetch-external-binaries + working-directory: ShadowsocksX-NG2 + env: + EXTERNAL_BINARY_CACHE_DIR: ${{ github.workspace }}/ShadowsocksX-NG2/.build/external-binary-archives + run: Scripts/fetch-external-binaries.sh + + - name: Save external binary archive cache + if: inputs.external-binaries == 'true' && steps.fetch-external-binaries.outcome == 'success' && steps.external-binary-cache.outputs.cache-hit != 'true' + uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ShadowsocksX-NG2/.build/external-binary-archives + key: ${{ steps.external-binary-cache.outputs.cache-primary-key }} + diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..ca79ca5b4 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 1c223c1f1..000000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: CI - -on: [push,pull_request] - -jobs: - build: - - runs-on: macos-10.15 - - steps: - - uses: actions/checkout@v1 - - name: Run unit test - run: | - set -o pipefail && xcodebuild test -workspace ShadowsocksX-NG.xcworkspace -scheme ShadowsocksX-NG|xcpretty diff --git a/.github/workflows/shadowsocksx-ng2-ci.yml b/.github/workflows/shadowsocksx-ng2-ci.yml new file mode 100644 index 000000000..2eb1a411a --- /dev/null +++ b/.github/workflows/shadowsocksx-ng2-ci.yml @@ -0,0 +1,113 @@ +name: ShadowsocksX-NG2 CI + +on: + pull_request: + branches: [develop, master] + paths: + - "ShadowsocksX-NG2/**" + push: + branches: [develop, master] + paths: + - "ShadowsocksX-NG2/**" + workflow_dispatch: + paths: + - "ShadowsocksX-NG2/**" + +permissions: + contents: read + +concurrency: + group: ng2-ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +defaults: + run: + working-directory: ShadowsocksX-NG2 + +jobs: + style: + name: Style (Xcode 27 arm64) + runs-on: xcode-27 + timeout-minutes: 60 + steps: + - name: Check out source + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Set up dependencies + uses: ./.github/actions/setup-ng2 + with: + packages: go-task swiftlint + external-binaries: 'false' + + - name: Check Swift formatting + run: task --exit-code validate -- format:check + + - name: Lint + run: task --exit-code validate -- lint + + - name: Upload failed validation evidence + if: failure() + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 + with: + name: validation-${{ github.job }} + path: ShadowsocksX-NG2/.build/validation/ + include-hidden-files: true + retention-days: 7 + if-no-files-found: warn + + build-test: + name: Build and test (Xcode 27 arm64) + runs-on: xcode-27 + timeout-minutes: 60 + steps: + - name: Check out source + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Set up dependencies + uses: ./.github/actions/setup-ng2 + + - name: Build + run: task --exit-code validate -- build + + - name: Test + run: task --exit-code validate -- test + + - name: Upload failed validation evidence + if: failure() + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 + with: + name: validation-${{ github.job }} + path: ShadowsocksX-NG2/.build/validation/ + include-hidden-files: true + retention-days: 7 + if-no-files-found: warn + + smoke: + name: Smoke tests (Xcode 27 arm64) + runs-on: xcode-27 + timeout-minutes: 60 + steps: + - name: Check out source + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Set up dependencies + uses: ./.github/actions/setup-ng2 + + - name: Smoke tests + run: task --exit-code validate -- test:smoke + + - name: Upload failed validation evidence + if: failure() + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 + with: + name: validation-${{ github.job }} + path: ShadowsocksX-NG2/.build/validation/ + include-hidden-files: true + retention-days: 7 + if-no-files-found: warn diff --git a/.github/workflows/shadowsocksx-ng2-codeql.yml b/.github/workflows/shadowsocksx-ng2-codeql.yml new file mode 100644 index 000000000..c156da5b1 --- /dev/null +++ b/.github/workflows/shadowsocksx-ng2-codeql.yml @@ -0,0 +1,82 @@ +name: ShadowsocksX-NG2 CodeQL + +on: + push: + branches: [develop, master] + paths: + - "ShadowsocksX-NG2/**" + pull_request: + branches: [develop, master] + paths: + - "ShadowsocksX-NG2/**" + schedule: + - cron: '30 2 * * 1' + workflow_dispatch: + paths: + - "ShadowsocksX-NG2/**" + +permissions: + contents: read + security-events: write + +jobs: + analyze-interpreted: + name: Analyze ${{ matrix.language }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + language: [actions, python] + steps: + - name: Check out source + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Initialize CodeQL + uses: github/codeql-action/init@5895b2c9be147bc7f1c75ce72c5cb577febb1907 # v4 + with: + languages: ${{ matrix.language }} + build-mode: none + + - name: Analyze + uses: github/codeql-action/analyze@5895b2c9be147bc7f1c75ce72c5cb577febb1907 # v4 + with: + category: /language:${{ matrix.language }} + + analyze: + name: Analyze Swift + # CodeQL build tracing does not support macOS 27 or Xcode 27. + runs-on: macos-26 + env: + DEVELOPER_DIR: /Applications/Xcode_26.4.1.app/Contents/Developer + timeout-minutes: 60 + steps: + - name: Check out source + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Set up dependencies + uses: ./.github/actions/setup-ng2 + with: + packages: age go-task xcodegen + + - name: Initialize CodeQL + uses: github/codeql-action/init@5895b2c9be147bc7f1c75ce72c5cb577febb1907 # v4 + with: + languages: swift + build-mode: manual + + - name: Build + working-directory: ShadowsocksX-NG2 + run: >- + task build + BUILD_DESTINATION=generic/platform=macOS + BUILD_ALLOW_DEPRECATED=1 + DERIVED_DATA_DIR="$(mktemp -d "${RUNNER_TEMP}/codeql-derived-data.XXXXXX")" + + - name: Analyze + uses: github/codeql-action/analyze@5895b2c9be147bc7f1c75ce72c5cb577febb1907 # v4 + with: + category: /language:swift diff --git a/.gitignore b/.gitignore index 46e0a406b..c28d8eafc 100644 --- a/.gitignore +++ b/.gitignore @@ -69,3 +69,42 @@ profile Carthage/Build IDEWorkspaceChecks.plist + +#### +# Local agent scratch space (local-markdown issue tracker; see docs/agents/issue-tracker.md) +.scratch/ + +#### +# New project build artifacts +ShadowsocksX-NG2/.build/ +ShadowsocksX-NG2/dist/ +ShadowsocksX-NG2/DerivedData/ + +#### +# NG2 generated build files (project.yml is the source of truth; run `xcodegen generate`) +ShadowsocksX-NG2/*.xcodeproj +# 本机签名身份(DEVELOPMENT_TEAM),构建期由 Configs/Signing.xcconfig 可选包含 +ShadowsocksX-NG2/Configs/Signing.local.xcconfig +ShadowsocksX-NG2/App/Resources/Info.plist +ShadowsocksX-NG2/App/Resources/ShadowsocksX-NG2.entitlements +ShadowsocksX-NG2/Tests/Info.plist +ShadowsocksX-NG2/Tests/Smoke/Info.plist + +#### +# NG2 external binary cache (fetched & hash-verified by +# ShadowsocksX-NG2/Scripts/fetch-external-binaries.sh; manifests are committed) +ShadowsocksX-NG2/Vendor/sslocal/sslocal +ShadowsocksX-NG2/Vendor/sslocal/.fetched.sha256 +ShadowsocksX-NG2/Vendor/v2ray-plugin/v2ray-plugin +ShadowsocksX-NG2/Vendor/v2ray-plugin/.fetched.sha256 +ShadowsocksX-NG2/Vendor/ck-client/ck-client +ShadowsocksX-NG2/Vendor/ck-client/.fetched.sha256 + +### +# dotenv file +.env + +### +# cmux omx +.omx + diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..052f46683 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,27 @@ +minimum_pre_commit_version: "3.2.0" + +repos: + - repo: local + hooks: + - id: ng2-swift-format + name: Format staged NG2 Swift files + entry: swift format format --in-place --configuration ShadowsocksX-NG2/.swift-format + language: system + files: ^ShadowsocksX-NG2/.*\.swift$ + stages: [pre-commit] + + - id: ng2-swift-format-check + name: Check NG2 Swift formatting and style + entry: task --dir ShadowsocksX-NG2 format:check + language: system + files: ^ShadowsocksX-NG2/.*\.swift$ + pass_filenames: false + stages: [pre-commit] + + - id: ng2-swiftlint + name: Lint staged NG2 Swift files + entry: swiftlint lint --config ShadowsocksX-NG2/.swiftlint.yml --no-cache --quiet + language: system + files: ^ShadowsocksX-NG2/.*\.swift$ + stages: [pre-commit] + verbose: true diff --git a/.zcodeignore b/.zcodeignore new file mode 100644 index 000000000..2ce6b572e --- /dev/null +++ b/.zcodeignore @@ -0,0 +1,112 @@ +##### +# OS X temporary files that should never be committed +.DS_Store +*.swp +*.lock +profile + +#### +# Xcode temporary files that should never be committed +*~.nib + +#### +# Objective-C/Swift specific +*.hmap +*.ipa + +#### +# Xcode build files +DerivedData/ +build/ +Builds/ + +##### +# Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups) +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + +#### +# Xcode 4 +xcuserdata +!xcschemes +# Xcode 4 +*.moved-aside + +#### +# XCode 4 workspaces - more detailed +!xcshareddata +!default.xcworkspace +*.xcworkspacedata + + +#### +# Xcode 5 +*.xccheckout +*.xcuserstate + +#### +# Xcode 7 +*.xcscmblueprint + +#### +# AppCode +.idea/ + +#### +# Other Xcode files +profile +*.hmap +*.ipa + +#### +# Carthage +Carthage/Build + +IDEWorkspaceChecks.plist + +#### +# Local agent scratch space (local-markdown issue tracker; see docs/agents/issue-tracker.md) +.scratch/ + +#### +# New project build artifacts +ShadowsocksX-NG2/.build/ +ShadowsocksX-NG2/DerivedData/ + +# ===== ↑ 以上同步自 .gitignore(「从 .gitignore 同步」只重写以上部分)===== +.git/ +.hg/ +.svn/ +node_modules/ +bower_components/ +jspm_packages/ +__pycache__/ +site-packages/ +venv/ +coverage/ +htmlcov/ +lcov-report/ +cmakefiles/ +cmake-build-*/ +bazel-*/ +pods/ +deriveddata/ +storybook-static/ +playwright-report/ +test-results/ +allure-results/ +allure-report/ +cdk.out/ +*.egg-info/ +*.dist-info/ +eggs/ +pip-wheel-metadata/ +wheels/ +# ----- ↑ 以上为 ZCode 默认排除规则(自定义规则请写在本行下方,不会被同步/恢复改动)----- +# 自定义规则写在下方(本行提示可删除) diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..a45d93bce --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,55 @@ +# ShadowsocksX-NG + +A macOS Shadowsocks client. The legacy implementation has been removed from this repository and archived on the [`legacy-v1`](https://github.com/shadowsocks/ShadowsocksX-NG/tree/legacy-v1) branch of [shadowsocks/ShadowsocksX-NG](https://github.com/shadowsocks/ShadowsocksX-NG) for read-only reference. The new implementation lives in `ShadowsocksX-NG2/`. Links to legacy source code in documentation and comments must point to that branch. + +## Agent skills + +### Local validation + +When validating ShadowsocksX-NG2 changes or diagnosing local validation artifacts, read the [local validation skill](.agents/skills/shadowsocksx-ng2-local-validation/SKILL.md). The repository copy is maintained; copies with the same name in memory are historical snapshots. + +### Git commits + +Write commit messages in English using Conventional Commits. + +### Issue tracker + +Issue tracker configuration is contributor-local. + +Before using an issue-tracking skill: + +1. Resolve the Git common directory: + + `git rev-parse --path-format=absolute --git-common-dir` + +2. Read `/agent/issue-tracker.md`. + +3. Follow the tracker configuration found there. + +If the file does not exist, ask the contributor to +configure their preferred tracker. + +Never assume GitHub Issues is the default. +Never commit personal tracker configuration. +Never reference personal tracker issues or tasks in code, commit messages, pull requests, or GitHub comments. + +### Triage labels + +Use the five default role names as triage label strings: `needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, and `wontfix`. See `docs/agents/triage-labels.md`. + +### Domain docs + +Use a single context: one root `GLOSSARY.md` plus `docs/adr/`, created on demand. See `docs/agents/domain.md`. + +Write the body of `GLOSSARY.md` and new ADRs in Simplified Chinese, retaining code identifiers and necessary English terms. Existing ADRs retain their original language. + +Current code, `GLOSSARY.md`, and `docs/adr/` define the current state and accepted designs. Only `GLOSSARY.md` and `docs/adr/` are continuously maintained as current documentation; use current code as the source of truth for implementation behavior. Before using a design document or research report as an implementation basis, verify the relevant descriptions against the code. + +`docs/design/` records requirements, designs, and specifications at the time of each task. It is historical reference and does not represent the latest implementation. + +`docs/research/` contains research reports. Each report records upstream capabilities, candidate solutions, and conclusions at the time of writing. It does not describe the project's current state or establish that a design has been adopted. + +## Contribution Guidelines + +Follow the project's CONTRIBUTING.md for all contributions, including AI-assisted development. + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..22eeb7d79 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,96 @@ +# Contributing to ShadowsocksX-NG + +Thanks for your interest in contributing to ShadowsocksX-NG. + +ShadowsocksX-NG2 is a new native macOS client, developed separately from the legacy 1.x application. Work on NG2 takes place in `ShadowsocksX-NG2/` on the `develop` branch. The legacy 1.x source is available on the [`legacy-v1` branch](https://github.com/shadowsocks/ShadowsocksX-NG/tree/legacy-v1). + +## Current contribution status + +NG2 is still under development. New GitHub Issues and pull requests are temporarily restricted until the v2 code is stable and officially released, as noted in the [project README](README.md). Until then, use [GitHub Discussions](https://github.com/shadowsocks/ShadowsocksX-NG/discussions) for bug reports, questions, feedback, and feature suggestions. Keep NG2 reports out of unrelated legacy 1.x issues. + +The guidelines below describe the contribution process once Issues and pull requests are open. The current restrictions still apply. + +## Before proposing a change + +Check existing Discussions, Issues, and documentation for related work. Small fixes and documentation improvements usually need less coordination. Discuss substantial features, protocol or configuration changes, system-proxy behavior, security-sensitive changes, and architectural refactoring before starting implementation. + +Explain the problem and the behavior you want to change. Maintainers may suggest another approach or decline changes outside the project's scope. + +## Development setup + +NG2 targets macOS 15 or later on Apple Silicon (arm64). Build and test with the Xcode/Swift toolchain, [Task](https://taskfile.dev/), XcodeGen, and SwiftLint. The [Development, Build, and Testing guide](docs/development.md) lists exact tool versions, prerequisites, and troubleshooting. + +From the repository root: + +```sh +cd ShadowsocksX-NG2 +Scripts/fetch-external-binaries.sh +task gen:prj +task build +``` + +Fetch and verify external binaries before generating the Xcode project. `project.yml` defines Xcode project configuration and is the source of truth for the generated `.xcodeproj`. Debug builds use ad-hoc signing by default. Ordinary development and unit tests do not require a Developer ID certificate. + +## Quality and testing + +Keep changes focused and easy to review. Preserve existing behavior unless an intentional change has been agreed upon. Add or update tests when behavior changes, especially for regressions, configuration persistence, networking, process lifecycle, encryption, and system-proxy control. + +From the repository root, run: + +```sh +task --exit-code --taskfile ShadowsocksX-NG2/Taskfile.dist.yml validate +task --exit-code --taskfile ShadowsocksX-NG2/Taskfile.dist.yml format:check +``` + +The default validation sequence runs lint, unit tests, and a Debug build. Run real-process smoke tests separately with `task test:smoke` from `ShadowsocksX-NG2/`. Run the checks relevant to your changes, and explain any checks you skip. CI also runs formatting checks and separate test and smoke-test jobs. + +Follow the repository's Swift formatting and SwiftLint configuration. Prefer Swift Testing for new unit tests. Use XCTest when you need its UI-testing or performance APIs. Keep tests deterministic and isolated from real user configurations, credentials, and shared fixed ports. See [the development guide](docs/development.md) for test conventions and validation evidence. + +## Architecture and dependencies + +Before changing component boundaries or established behavior, read the [project structure guide](docs/project-structure.md), [glossary](GLOSSARY.md), and relevant [architecture decision records](docs/adr/). Check historical design and research documents against the current source code. + +Keep the boundaries clear between the SwiftUI app, domain code, background Agent, privileged helper, and bundled external executables. For changes to shared contracts, configuration formats, IPC, credentials, proxy routing, or packaging, describe compatibility and migration implications. Check licenses and provenance for new or updated third-party dependencies and binaries. Follow the [distribution and supply-chain guide](docs/distribution.md) when adding them. + +## Pull requests + +When pull requests are enabled: + +- Target `develop` for NG2 changes unless a maintainer requests another branch. +- Keep each pull request focused on one coherent change, with unrelated refactoring separated where practical. +- Describe the motivation, user-visible impact, implementation, and any compatibility or security considerations. +- Summarize the tests you ran and their results. Explain checks you could not run. +- Include screenshots or recordings for visible UI changes when helpful. +- Link relevant **public GitHub Issues** when applicable; an Issue is not required for every small fix. +- Address review feedback constructively. Maintainers decide whether and when a change is merged. + +Use English [Conventional Commits](https://www.conventionalcommits.org/) for commit messages, consistent with [`AGENTS.md`](AGENTS.md). + +## Public issue tracking and personal workflows + +GitHub Issues is the project's official tracker for public bug reports, feature requests, and contributor coordination when enabled. While Issues are restricted, use GitHub Discussions as described above. + +Use any tools you prefer for private planning and task management, including Beads, local Markdown files, or other trackers. The project does not require a particular issue tracker, AI agent, IDE, or worktree workflow. Internal tasks are not public project Issues, do not set project priorities, and do not establish maintainer commitments. + +Keep contributor-specific tracker configuration and internal task data out of tracked repository files. Never reference personal tracker issues, task IDs, or internal task links in source-code comments, commit messages, public GitHub Issues, pull requests, or GitHub comments. Use a relevant public GitHub Issue or Discussion as the shared reference. Write a clear, self-contained change description that reviewers can understand without internal task history. + +AI-assisted contributions follow the same standards as other contributions. Contributors are responsible for understanding, reviewing, and testing all code and content they propose, and for having the right to submit it. Keep secrets, user data, and confidential information out of external tools and submitted artifacts. + +## Security reports + +Do not report suspected security vulnerabilities in public Issues or Discussions. If GitHub's private vulnerability reporting mechanism is enabled for this repository, use it. Otherwise, contact the maintainers privately before sharing exploit details. Keep real server credentials, subscription URLs, private keys, and unredacted diagnostic logs out of public reports. + +## License and conduct + +Contributions must be compatible with the repository's [GNU GPL version 3 license](LICENSE). Submit only code, assets, and dependencies you have the right to contribute. Retain applicable copyright and third-party notices. + +Be respectful and constructive. Assume good intent, focus reviews on technical merits, and keep discussions useful to contributors with different levels of experience. + +## Further reading + +- [Project README](README.md) +- [NG2 developer overview](ShadowsocksX-NG2/README.md) +- [Development and validation](docs/development.md) +- [Project structure](docs/project-structure.md) +- [Architecture decisions](docs/adr/) +- [Signing and distribution](docs/distribution.md) diff --git a/GLOSSARY.md b/GLOSSARY.md new file mode 100644 index 000000000..340f0f980 --- /dev/null +++ b/GLOSSARY.md @@ -0,0 +1,318 @@ +# ShadowsocksX-NG + +本领域涵盖 macOS Shadowsocks 客户端的服务器配置、订阅、代理规则与代理控制,以及用户管理这些内容的工作区。术语用于统一产品讨论与代码中的概念,英文名称保留为检索对应。 + +## 领域术语 + +### 配置与订阅 + +**服务器库(Server library)**: +用户持久保存的完整配置目录、订阅关联、收藏与所需凭据的集合。它不同于为后台代理服务生成的运行配置,也不同于单个配置组的导出快照。 + +**配置目录(Configuration catalog)**: +服务器配置与配置组组成的有序树的根,根本身不作为用户可见的配置组。 + +**服务器配置(Server configuration)**: +一个 Shadowsocks 服务器的连接资料,包含用户可见名称、来源归属和持久身份,是配置目录中的叶节点。 + +**配置组(Configuration group)**: +具有名称和子节点顺序的容器,可包含服务器配置和嵌套配置组;每个节点最多属于一个父节点,组之间不形成环。 + +**收藏(Favorite)**: +用户对一个服务器配置或配置组的独立标记,不改变节点的来源或目录位置,也不包含对其后代的标记。 + +**收藏列表(Favorites list)**: +用户排列的收藏节点序列,每个节点最多出现一次,配置组与服务器配置均作为单独一项,不展开后代。 + +**节点时间戳(Node timestamps)**: +配置目录中每个节点(服务器配置或配置组)的创建时间与修改时间事实。创建时间是节点进入目录的时刻;修改时间是节点自身资料、或分组的直接子节点集合与顺序最后一次变化的时刻,移动节点本身不算修改。历史文档未记录的时间是未知事实,不做回填。 + +**配置组导出(Configuration group export)**: +用户请求生成的可分享文件快照,包含一个配置组及其全部后代的连接资料和所需凭据。它可以包含不具备激活条件的服务器配置。 + +**配置组分享(Configuration group share)**: +通过 SIP-008 JSON 文件或逐行 `ss://` URI 列表(文本文件或剪贴板)传递一个配置组及其全部后代服务器的连接资料和所需凭据,供其他客户端使用。URI 列表不保留分组结构。 + +**服务器分享(Server share)**: +通过二维码(屏幕显示、复制图片或保存图片文件)或剪贴板传递单个服务器配置的 `ss://` URI,供其他设备使用。 +_避免用词_:导出(导出指配置组或诊断报告等文件快照)。 + +**服务器导入(Server import)**: +把剪贴板文本或文件中的服务器配置引入配置目录、形成独立手动子树的操作。来源资料中的标识只用于装配其内部结构,导入产生的每个节点都获得全新的本地持久身份;同一资料重复导入产生相互独立的服务器配置,不与既有节点合并或去重。 + +**节点复制(Node duplication)**: +在原节点之后的同级位置创建独立手动副本。组复制包含整棵子树,保留层级、顺序、连接字段、所需凭据和空组;所有节点获得全新身份,副本与原节点的凭据修改互不影响。支持手动服务器、手动组和根层订阅组,不支持订阅服务器或嵌套订阅子组。订阅副本不携带订阅来源资料;顶层副本名称加本地化后缀并在同级重名时追加序号;名称末尾已有“副本”或“Copy”(含编号)时沿用该后缀,以同级未占用的编号命名,避免重复追加后缀。目录和凭据作为一次逻辑变更提交,失败不发布部分子树或凭据变更。复制不切换活动目标;在活动组内新增的副本按普通目录变更进入运行时收敛。 + +**导入来源(Import source)**: +一次服务器导入中可独立处理的一份资料,例如剪贴板文本或单个文件。每个来源独立解码、独立提交,是成功、部分成功与失败报告的粒度单位;一个来源失败不影响其他来源。 + +**服务器表单草稿(Server form draft)**: +用户创建或编辑一个服务器配置时,尚未保存的连接字段集合。 + +**插件参数草稿(Plugin parameter draft)**: +服务器表单中尚未保存的有序插件参数集合,每项包含参数名及可选值。无等号的标志与等号后的空值是不同的参数形式。 + +**手动组(Manual group)**: +用户拥有的配置组,其后代也由用户拥有。 + +**订阅(Subscription)**: +具有持久身份的远程配置来源,对应一个固定的订阅组;订阅 URL 是可修改的访问地址,而非来源身份。 + +**订阅资料(Subscription information)**: +供应商随订阅提供的已用流量、剩余流量、服务到期时间与流量重置时间等事实。它不包含服务器连接资料、凭据或完整订阅响应。 + +**订阅自动更新(Subscription automatic update)**: +GUI 应用运行期间,按订阅的生效设置定期获取远程配置的行为。仅保留菜单栏也属于应用运行。 + +**供应商自动更新策略(Provider automatic update policy)**: +订阅供应商提供的自动更新设置(关闭、每天或每周)及是否允许用户覆盖的约束。允许覆盖时用户可选择本地设置或跟随供应商;禁止覆盖时供应商设置生效。 + +**下次计划更新时间(Next scheduled update time)**: +订阅下一次自动更新到期的时刻,与最后成功更新时间不同。自动更新关闭时没有该计划。 + +**订阅组(Subscription group)**: +一个订阅拥有的配置子树,内容和结构以远程资料为准,用户不能在本地覆盖其成员、名称或连接字段。 + +**可删除节点(Deletable node)**: +用户拥有且可从配置目录删除的服务器配置或手动组。移除订阅属于订阅管理,与删除节点是不同的操作。 +_避免用词_:可移除节点(Removable node)。 + +**活动目标(Active target)**: +用户选定并保存的代理目标,可以是服务器配置或配置组;选择配置组时,目标仍是该组,而非实际被选用的后代服务器。列表呈现上,活动目标自身标记实心闪电;子树内含活动目标的配置组标记空心闪电。 + +**激活候选(Activation candidate)**: +没有已知本地阻断问题、可用于生成代理配置的服务器配置。它不保证远程可达,也不表示插件参数已经验证有效。 + +**服务器连通性测试(Server connectivity test)**: +用户手动请求,经指定服务器配置向测试 URL 发起应用 TCP 请求并检查响应的操作。测试经过该配置的实际传输路径,包括使用 UDP 传输的插件隧道;它不验证应用 UDP 中继。 + +**测试 URL(Connectivity test URL)**: +服务器连通性测试请求访问的目标地址,是用户可修改的非敏感偏好信息,在展示、日志与诊断中无需脱敏。 + +**代理响应延迟(Proxy response latency)**: +完成目标地址选择与预热后,经指定服务器配置访问测试 URL 的 HTTP 响应头耗时,以成功样本的中位数表示。结果保留测试时间,不按固定时长或网络变化自动判为过期,用户结合测试时间自行判断参考价值。它与测试目标及测试条件有关,不表示服务器 IP 的纯网络往返时间或下载速度。 + +**配置组最快响应延迟(Fastest group response latency)**: +配置组全部后代服务器最近一次测试结果中的成功项,其最小代理响应延迟。最近一次结果失败的服务器不贡献更早的成功结果;汇总不按测试时间排除结果。它不表示活动配置组实际选用的服务器或负载均衡后的响应耗时。 + +**托管插件(Managed plugin)**: +由产品随应用发布的 SIP003 插件,其发布版本与来源事实属于随应用提供的程序,不代表用户自备的同名程序。 + +**插件记录(Plugin record)**: +一份可由多个名称引用的本机插件资料,包含可执行程序的选择、共享的本地启动参数与插件传输模式;用户记录具有独立于名称的持久身份。 + +**插件传输模式(Plugin transport mode)**: +一条插件记录承载的传输协议范围:`tcp_only` 表示插件仅承载 TCP,`tcp_and_udp` 表示插件承载 TCP 与 UDP。它不表示插件已经具备 SIP003u 支持,也不同于本地 SOCKS5 端点的 UDP 中继能力。 + +**插件别名(Plugin alias)**: +引用同一插件记录的名称之一。同一记录的名称共享程序、本地启动参数与插件传输模式,服务器资料保留自己使用的名称。 + +**本地插件启动参数(Local plugin arguments)**: +当前 macOS 用户为一条插件记录设置的有序命令行参数,由所有引用该记录的服务器共享。它与服务器连接资料中的插件选项不同,不随服务器资料分享。 + +**用户插件映射(User plugin mapping)**: +当前 macOS 用户维护的插件名称与本机插件记录之间的对应关系。同名映射覆盖托管插件的默认选择,但不改写服务器配置中的插件引用。 + +**有效插件目录(Effective plugin catalog)**: +由当前应用提供的托管插件与用户插件映射共同确定的插件名称、实际来源与可用性事实集合。失效的用户映射仍保留其覆盖关系,不自动退回同名托管插件。 + +**旧版配置(Legacy configuration)**: +冻结的旧版客户端保存的服务器列表与偏好设置。 + +**旧版导入(Legacy import)**: +经用户确认,将旧版服务器资料转换为新客户端独立手动组的操作。它只迁移服务器资料,保留旧版来源和新客户端现有偏好设置。 + +### 代理规则 + +**代理模式(Proxy mode)**: +用户选择的流量路由方式,包括规则模式、全局模式和直连模式。全局模式下公共目标默认经 Shadowsocks 转发,固定本地目标仍直连。 + +**规则模式(Rule mode)**: +由内置规则和自定义规则决定各目标代理或直连的路由模式;未匹配目标的处理方式由规则默认动作决定。 + +**规则默认动作(Rule default action)**: +规则模式下,没有规则匹配目标时采用的代理或直连动作。 +_避免用词_:回退(Fallback,含义不明确)。 + +**规则方案(Rule preset)**: +规则模式内,具有固定匹配后行动和未匹配行动的规则组合,也是自定义规则、规则停用、浏览与离线规则测试的归属范围,包括仅GFW列表内目标代理、中国大陆目标直连和中国大陆目标代理三项方案。内置规则与自定义规则的匹配后行动由所属方案统一决定,固定本地目标始终直连。 +_避免用词_:规则预设(产品名称统一使用规则方案)。 + +**内置规则快照(Built-in rule snapshot)**: +随应用发布的固定规则集,包含来源、归属与转换报告等资料。它只保留转换后可决定路由的规则,不保留被吸收或遮蔽而省略的上游条目。 + +**自定义规则(Custom rule)**: +用户拥有的、具有持久身份的规则,以精确域名、域名后缀或 IPv4/IPv6 地址范围作为匹配条件,匹配后行动由所属规则方案决定。列表顺序不代表路由优先级。 +_避免用词_:用户规则(User rule)。 + +**自定义规则集合(Custom rule collection)**: +一项规则方案独立拥有的自定义规则集合,仅在该方案下参与规则模式路由。切换方案保留各集合,修改一个集合不影响其他方案。 + +**规则身份(Rule identity)**: +规范化匹配条件与路由动作的组合,用于识别不同来源中的等价规则。它与可编辑自定义条目的持久身份不同,单个 IP 地址与其完整前缀长度的 CIDR 等价。 + +**规则来源归属(Rule source membership)**: +一个规则身份所属的全部来源;等价条目合并展示时仍保留各来源归属。 + +**规则停用(Rule disablement)**: +用户为一项规则方案保存的、跨该方案全部来源排除某个规则身份的选择,不影响其他方案;来源条目仍保留,覆盖同一目标的更宽规则也不因此被停用。固定本地绕过策略不能停用。 + +**规则吸收(Rule absorption)**: +同动作规则之间的覆盖关系,其中较宽规则使较窄规则在路由判定中冗余。它与反动作遮蔽不同,也不删除已保存的自定义规则。 + +**规则遮蔽(Rule shadowing)**: +动作相反的规则之间的覆盖关系,可以是全部或部分覆盖,也可以涉及固定本地绕过策略。它与同动作吸收不同,也不表示规则已在运行中生效。 + +**快照转换报告(Snapshot conversion report)**: +生成内置规则快照时记录的转换、吸收、跳过与拒绝数量。它描述快照生成时的结果,而非当前规则集合的覆盖关系或运行状态。 + +**离线规则测试(Offline rule test)**: +针对域名、IP 地址或 URL 主机,依据指定规则方案的规则和默认动作,解释代理或直连结论及其原因的操作。各方案的测试状态相互独立,结果不受浏览筛选、实际代理模式或运行状态影响;测试不解析 DNS,也不测试连通性。 + +### 代理控制与网络 + +**代理模式选择器(Proxy mode selector)**: +用户选择规则、全局或直连模式的统一入口,与代理服务开关、系统代理开关和自定义规则管理分别对应不同意图。 + +**代理服务开关(Agent switch)**: +用户保存的后台代理服务开启或关闭意图,与服务当前是否健康不同。 +_避免用词_:代理开关(Proxy switch,与系统代理开关混淆)。 + +**系统代理开关(System proxy switch)**: +用户保存的、通过 macOS 系统代理设置使用本地代理入口的意图,与设置当前是否已应用或暂停不同。 +_避免用词_:代理开关(Proxy switch,与代理服务开关混淆)。 + +**系统代理配置(System proxy configuration)**: +macOS 网络服务上的设备级代理设置,由不同应用与用户账户共享。 +_避免用词_:全局代理配置(Global proxy configuration,与全局代理模式混淆)。 + +**网络服务(Network service)**: +macOS 中具有独立代理设置的命名网络配置项,包括当前未连接的项。它与物理接口及终端命令地址候选不同。 + +**期望系统代理配置(Desired system proxy configuration)**: +新客户端已保存设置所要求的代理值,与各网络服务上实际存在的值不同。 + +**受管系统代理配置(Typed system proxy configuration)**: +新客户端负责管理的 SOCKS、HTTP、HTTPS、PAC、自动发现、简单主机名排除和例外值的完整集合。 +_避免用词_:完整代理字典(Complete proxy dictionary,可能包含产品管理范围外的值)。 + +**系统代理配置差异(System proxy configuration difference)**: +网络服务上的受管代理值与期望系统代理配置之间当前存在的语义差异。它不表示历史变更,也不能证明由哪个应用造成。 + +**系统代理修复(System proxy repair)**: +用户明确请求将存在差异的网络服务对齐到期望系统代理配置的操作。 +_避免用词_:恢复(Restore,可能暗示恢复其他应用的旧值)。 + +**系统代理暂停(System proxy suspension)**: +后台代理服务或当前模式的出口不可用时,系统代理设置已清除、但系统代理意图仍开启的临时状态。清除失败属于清理失败,不属于成功暂停。 + +**附加系统代理例外(Additional system-proxy exception)**: +用户添加的主机名、域名、IP 地址或 CIDR,用于让 macOS 将对应流量排除在系统代理之外。它不改变固定本地绕过策略或代理规则。 +_避免用词_:绕过列表(Bypass list,混淆用户附加项与产品固定策略)。 + +**固定本地绕过策略(Fixed local bypass policy)**: +产品规定始终直连的本地 IP 范围与主机名,适用于系统代理和本地代理入口。用户可查看该策略,但不能通过附加系统代理例外修改它。 + +**HTTP 代理入口(HTTP proxy inbound)**: +后台代理服务提供的本地 HTTP/HTTPS 请求入口,与代理模式和旧版 Privoxy 适配器不同。 +_避免用词_:HTTP 代理模式(HTTP proxy mode)。 + +**SOCKS5 UDP 中继(SOCKS5 UDP relay)**: +SOCKS5 入口接受 UDP ASSOCIATE 流量并通过代理服务中继的能力。它不表示系统全部 UDP 流量都会被代理。 +_避免用词_:系统级 UDP 代理、自动 UDP 代理。 + +**旧版 Privoxy 适配器(Legacy Privoxy adapter)**: +冻结旧版中,将 HTTP(S) 请求桥接到本地 SOCKS5 的组件,仅属于旧版实现。 + +**本地监听(Local listening)**: +仅供本机使用的 SOCKS 与 HTTP 代理入口,始终随后台代理客户端提供服务。 + +**局域网监听(LAN listening)**: +供网络设备访问的附加 SOCKS 与 HTTP 代理入口,与本地监听共存并使用不同端口;它可以独立关闭。 + +**代理监听配置(Proxy listening configuration)**: +用户保存的本地与局域网代理入口配置,包含端口、局域网启用状态、监听模式、UDP 中继和身份验证资料。它不包含代理模式、代理服务开关、系统代理开关或附加系统代理例外,也不同于派生的运行配置文件。 + +**局域网身份验证(LAN authentication)**: +局域网 SOCKS 与 HTTP 入口共用的用户名和密码验证,不表示 UDP 中继具备同等保护。身份验证启用时,保存要求用户名和密码符合形状。身份验证关闭时凭据是保留值,不拦其他局域网设置的保存。 + +**监听模式(Listener mode)**: +局域网监听启用时采用的地址族选项,包括所有 IPv4 接口、所有 IPv4 与 IPv6 接口、所有 IPv6 接口;与是否启用局域网监听独立。 +_避免用词_:监听范围(Listen scope)。 + +**HTTP 代理环境命令(HTTP proxy environment command)**: +仅设置本机 HTTP/HTTPS 代理环境变量的终端命令,目标为本地监听入口。 + +**终端代理环境命令(Terminal proxy environment commands)**: +按目标 shell 语法设置 HTTP 与 SOCKS 代理环境变量及本地主机例外的命令。它只影响遵循这些环境变量的子进程。 + +**终端命令地址(Terminal command address)**: +复制的终端代理环境命令中,HTTP 与 SOCKS 入口共同使用的 IP 地址。它是当前应用会话内的选择,与监听设置和系统代理设置独立。 + +**代理运行服务(Proxy runtime)**: +为当前用户提供代理入口与外部隧道服务的后台服务,其生命周期独立于图形界面。 + +**运行配置文件(Runtime configuration file)**: +供外部隧道服务使用、由活动目标派生的连接配置,包含端点、凭据、加密、插件、监听与规则信息。它与用户管理的服务器配置和订阅文档不同。 + +**运行状态收敛(Runtime convergence)**: +将已部署的代理服务对齐到期望运行配置的过程,与保存用户配置意图是不同的概念。 + +### 设置与工作区 + +**第三方组件与许可证窗口(Third-party components and licenses window)**: +从关于对话框打开的独立资料窗口,展示当前安装应用随包提供的第三方组件、来源、版本、许可证与附加声明。 + +**登录项(Login item)**: +图形界面应用在用户登录项中的系统注册,是独立的偏好设置。 + +**独立保存设置项(Independently saved setting item)**: +用户作为一个整体明确保存的设置或一组关联值,其保存边界不包含其他未保存设置。 +_避免用词_:即时编辑(Immediate edit,可能暗示每次按键都应用)。 + +**系统级快捷键(System-level shortcut)**: +用户可配置的键盘操作,即使应用未获得焦点也能触发应用动作。 +_避免用词_:全局热键(Global hotkey)、全局快捷键(Global shortcut)。 + +**窗口内默认动作快捷键(Window-local default action shortcut)**: +绑定到当前聚焦窗口或表单的键盘操作,例如确认对话框;它与系统级快捷键不同。 + +**工作区页面(Workspace destination)**: +单一工作区中的顶层位置,例如首页、服务器、代理规则或设置。它只表示导航位置,不包含节点选择或功能草稿。 + +**工作区路由(Workspace route)**: +从工作区或其他应用入口切换工作区页面的导航选择与意图,与用户配置和功能局部状态不同。 + +**工作区窗口(Workspace window)**: +承载工作区的唯一主窗口;关闭后可从状态菜单重新打开。 + +**诊断窗口(Diagnostics window)**: +由状态菜单或应用菜单“诊断…”入口显式打开的唯一独立窗口(两入口同开一窗),承载状态摘要、日志查看与复制、脱敏报告导出。关闭后停止诊断轮询,不影响代理运行和日志记录;日志过滤选择在本次应用运行内保留。 + +**自适应应用形态(Adaptive app form)**: +随工作区、独立规则报告窗口、诊断窗口、关于对话框和第三方组件与许可证窗口的开启状态变化的应用呈现方式:有窗口时显示 Dock 图标并参与应用切换,最后一个窗口关闭后仅保留菜单栏状态菜单。 +_避免用词_:菜单栏形态(Menu bar form,应用形态并非恒定)。 + +**静默启动(Silent launch)**: +启动时不显示工作区窗口、从菜单栏形态开始的用户偏好。它只影响窗口呈现,与代理服务恢复和登录项分别对应不同设置。 + +### 凭据与诊断 + +**敏感信息(Sensitive information)**: +服务器密码、完整插件选项,以及用户提供的非空远程 URL,包括订阅 URL,但不包括测试 URL。 + +**凭据暴露边界(Credential exposure boundary)**: +产品降低意外泄露及向其他用户账户暴露凭据的保护范围。该范围不包含同一用户进程被攻破、root 访问或快照与备份,也不承诺安全擦除。 + +**诊断报告(Diagnostic report)**: +用户请求生成的脱敏文档,包含允许披露的运行状态、端点元数据、配置汇总及安全事件资料。它排除敏感信息、服务器地址、备注和原始日志。 + +**诊断日志视图(Diagnostic log view)**: +用户明确查看或复制界面事件与后台服务日志行的入口;行正文为脱敏后的原始文本,所展示的日志行不属于诊断报告。 + +**系统日志(System log)**: +本应用图形界面、后台服务与特权系统代理 helper 写入 macOS 统一日志系统、供用户在 Console.app 中按来源与类别过滤查看的本地事件流。它面向本地排错,不是诊断报告的内容来源,也不替代诊断日志视图的显式查看与复制;特权系统代理 helper 的事件只有这一个查看面,不进诊断日志视图。 +_避免用词_:os_log 输出(实现机制名,不是领域概念)。 + +**诊断事实(Diagnostic facts)**: +可供诊断报告使用的配置目录与代理服务汇总事实,已经脱敏,且不暴露配置条目或敏感信息。 diff --git a/LaunchHelper/LaunchHelper.xcodeproj/project.pbxproj b/LaunchHelper/LaunchHelper.xcodeproj/project.pbxproj deleted file mode 100644 index 868f153d7..000000000 --- a/LaunchHelper/LaunchHelper.xcodeproj/project.pbxproj +++ /dev/null @@ -1,331 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 9B9F13921E8A282C00DE4794 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9F13911E8A282C00DE4794 /* AppDelegate.m */; }; - 9B9F13951E8A282C00DE4794 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B9F13941E8A282C00DE4794 /* main.m */; }; - 9B9F13971E8A282C00DE4794 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9B9F13961E8A282C00DE4794 /* Assets.xcassets */; }; - 9B9F139A1E8A282C00DE4794 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B9F13981E8A282C00DE4794 /* MainMenu.xib */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 9B9F138D1E8A282C00DE4794 /* LaunchHelper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LaunchHelper.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 9B9F13901E8A282C00DE4794 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 9B9F13911E8A282C00DE4794 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 9B9F13941E8A282C00DE4794 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 9B9F13961E8A282C00DE4794 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 9B9F13991E8A282C00DE4794 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; - 9B9F139B1E8A282C00DE4794 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 9B9F138A1E8A282C00DE4794 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 9B9F13841E8A282C00DE4794 = { - isa = PBXGroup; - children = ( - 9B9F138F1E8A282C00DE4794 /* LaunchHelper */, - 9B9F138E1E8A282C00DE4794 /* Products */, - ); - sourceTree = ""; - }; - 9B9F138E1E8A282C00DE4794 /* Products */ = { - isa = PBXGroup; - children = ( - 9B9F138D1E8A282C00DE4794 /* LaunchHelper.app */, - ); - name = Products; - sourceTree = ""; - }; - 9B9F138F1E8A282C00DE4794 /* LaunchHelper */ = { - isa = PBXGroup; - children = ( - 9B9F13901E8A282C00DE4794 /* AppDelegate.h */, - 9B9F13911E8A282C00DE4794 /* AppDelegate.m */, - 9B9F13961E8A282C00DE4794 /* Assets.xcassets */, - 9B9F13981E8A282C00DE4794 /* MainMenu.xib */, - 9B9F139B1E8A282C00DE4794 /* Info.plist */, - 9B9F13931E8A282C00DE4794 /* Supporting Files */, - ); - path = LaunchHelper; - sourceTree = ""; - }; - 9B9F13931E8A282C00DE4794 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 9B9F13941E8A282C00DE4794 /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 9B9F138C1E8A282C00DE4794 /* LaunchHelper */ = { - isa = PBXNativeTarget; - buildConfigurationList = 9B9F139E1E8A282C00DE4794 /* Build configuration list for PBXNativeTarget "LaunchHelper" */; - buildPhases = ( - 9B9F13891E8A282C00DE4794 /* Sources */, - 9B9F138A1E8A282C00DE4794 /* Frameworks */, - 9B9F138B1E8A282C00DE4794 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = LaunchHelper; - productName = LaunchHelper; - productReference = 9B9F138D1E8A282C00DE4794 /* LaunchHelper.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 9B9F13851E8A282C00DE4794 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1250; - ORGANIZATIONNAME = qiuyuzhou; - TargetAttributes = { - 9B9F138C1E8A282C00DE4794 = { - CreatedOnToolsVersion = 8.2.1; - ProvisioningStyle = Manual; - }; - }; - }; - buildConfigurationList = 9B9F13881E8A282C00DE4794 /* Build configuration list for PBXProject "LaunchHelper" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - English, - en, - Base, - ); - mainGroup = 9B9F13841E8A282C00DE4794; - productRefGroup = 9B9F138E1E8A282C00DE4794 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 9B9F138C1E8A282C00DE4794 /* LaunchHelper */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 9B9F138B1E8A282C00DE4794 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 9B9F13971E8A282C00DE4794 /* Assets.xcassets in Resources */, - 9B9F139A1E8A282C00DE4794 /* MainMenu.xib in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 9B9F13891E8A282C00DE4794 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 9B9F13951E8A282C00DE4794 /* main.m in Sources */, - 9B9F13921E8A282C00DE4794 /* AppDelegate.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 9B9F13981E8A282C00DE4794 /* MainMenu.xib */ = { - isa = PBXVariantGroup; - children = ( - 9B9F13991E8A282C00DE4794 /* Base */, - ); - name = MainMenu.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 9B9F139C1E8A282C00DE4794 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - }; - name = Debug; - }; - 9B9F139D1E8A282C00DE4794 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; - }; - name = Release; - }; - 9B9F139F1E8A282C00DE4794 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "-"; - CODE_SIGN_STYLE = Manual; - COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = LaunchHelper/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.11; - PRODUCT_BUNDLE_IDENTIFIER = "com.qiuyuzhou.ShadowsocksX-NG.LaunchHelper"; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - 9B9F13A01E8A282C00DE4794 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "-"; - CODE_SIGN_STYLE = Manual; - COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = LaunchHelper/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.11; - PRODUCT_BUNDLE_IDENTIFIER = "com.qiuyuzhou.ShadowsocksX-NG.LaunchHelper"; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SKIP_INSTALL = YES; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 9B9F13881E8A282C00DE4794 /* Build configuration list for PBXProject "LaunchHelper" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 9B9F139C1E8A282C00DE4794 /* Debug */, - 9B9F139D1E8A282C00DE4794 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 9B9F139E1E8A282C00DE4794 /* Build configuration list for PBXNativeTarget "LaunchHelper" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 9B9F139F1E8A282C00DE4794 /* Debug */, - 9B9F13A01E8A282C00DE4794 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 9B9F13851E8A282C00DE4794 /* Project object */; -} diff --git a/LaunchHelper/LaunchHelper/AppDelegate.h b/LaunchHelper/LaunchHelper/AppDelegate.h deleted file mode 100644 index 20bacd10b..000000000 --- a/LaunchHelper/LaunchHelper/AppDelegate.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// AppDelegate.h -// LaunchHelper -// -// Created by 邱宇舟 on 2017/3/28. -// Copyright © 2017年 qiuyuzhou. All rights reserved. -// - -#import - -@interface AppDelegate : NSObject - - -@end - diff --git a/LaunchHelper/LaunchHelper/AppDelegate.m b/LaunchHelper/LaunchHelper/AppDelegate.m deleted file mode 100644 index 9fc364665..000000000 --- a/LaunchHelper/LaunchHelper/AppDelegate.m +++ /dev/null @@ -1,43 +0,0 @@ -// -// AppDelegate.m -// LaunchHelper -// -// Created by 邱宇舟 on 2017/3/28. -// Copyright © 2017年 qiuyuzhou. All rights reserved. -// - -#import "AppDelegate.h" - -@interface AppDelegate () - -@property (weak) IBOutlet NSWindow *window; -@end - -@implementation AppDelegate - -- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { - // Insert code here to initialize your application - NSLog(@"ShadowsocksX-NG LaunchHelper"); - - NSWorkspace* ws = [NSWorkspace sharedWorkspace]; - BOOL bLaunched = NO; - bLaunched = [ws launchApplication: @"/Applications/ShadowsocksX-NG.app"]; - if (!bLaunched) { - bLaunched = [ws launchApplication: @"ShadowsocksX-NG.app"]; - } - if (!bLaunched) { - NSArray *pathComponents = [[[NSBundle mainBundle] bundlePath] pathComponents]; - pathComponents = [pathComponents subarrayWithRange:NSMakeRange(0, [pathComponents count] - 4)]; - NSString *path = [NSString pathWithComponents:pathComponents]; - [[NSWorkspace sharedWorkspace] launchApplication:path]; - } - [NSApp terminate:nil]; -} - - -- (void)applicationWillTerminate:(NSNotification *)aNotification { - // Insert code here to tear down your application -} - - -@end diff --git a/LaunchHelper/LaunchHelper/Assets.xcassets/AppIcon.appiconset/Contents.json b/LaunchHelper/LaunchHelper/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 2db2b1c7c..000000000 --- a/LaunchHelper/LaunchHelper/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "images" : [ - { - "idiom" : "mac", - "size" : "16x16", - "scale" : "1x" - }, - { - "idiom" : "mac", - "size" : "16x16", - "scale" : "2x" - }, - { - "idiom" : "mac", - "size" : "32x32", - "scale" : "1x" - }, - { - "idiom" : "mac", - "size" : "32x32", - "scale" : "2x" - }, - { - "idiom" : "mac", - "size" : "128x128", - "scale" : "1x" - }, - { - "idiom" : "mac", - "size" : "128x128", - "scale" : "2x" - }, - { - "idiom" : "mac", - "size" : "256x256", - "scale" : "1x" - }, - { - "idiom" : "mac", - "size" : "256x256", - "scale" : "2x" - }, - { - "idiom" : "mac", - "size" : "512x512", - "scale" : "1x" - }, - { - "idiom" : "mac", - "size" : "512x512", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/LaunchHelper/LaunchHelper/Base.lproj/MainMenu.xib b/LaunchHelper/LaunchHelper/Base.lproj/MainMenu.xib deleted file mode 100644 index 0edb2c8bd..000000000 --- a/LaunchHelper/LaunchHelper/Base.lproj/MainMenu.xib +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/LaunchHelper/LaunchHelper/Info.plist b/LaunchHelper/LaunchHelper/Info.plist deleted file mode 100644 index 58edf891c..000000000 --- a/LaunchHelper/LaunchHelper/Info.plist +++ /dev/null @@ -1,34 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIconFile - - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleVersion - 2 - LSBackgroundOnly - - LSMinimumSystemVersion - $(MACOSX_DEPLOYMENT_TARGET) - NSHumanReadableCopyright - Copyright © 2017年 qiuyuzhou. All rights reserved. - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - - diff --git a/LaunchHelper/LaunchHelper/main.m b/LaunchHelper/LaunchHelper/main.m deleted file mode 100644 index c6f32860e..000000000 --- a/LaunchHelper/LaunchHelper/main.m +++ /dev/null @@ -1,13 +0,0 @@ -// -// main.m -// LaunchHelper -// -// Created by 邱宇舟 on 2017/3/28. -// Copyright © 2017年 qiuyuzhou. All rights reserved. -// - -#import - -int main(int argc, const char * argv[]) { - return NSApplicationMain(argc, argv); -} diff --git a/Podfile b/Podfile deleted file mode 100644 index 2cce1c50a..000000000 --- a/Podfile +++ /dev/null @@ -1,27 +0,0 @@ -# Uncomment this line to define a global platform for your project -# platform :ios, '9.0' -platform :macos, '10.12' - -target 'ShadowsocksX-NG' do - # Comment this line if you're not using Swift and don't want to use dynamic frameworks - use_frameworks! - - # Pods for ShadowsocksX-NG - pod 'Alamofire', '~> 5.4.3' - pod "GCDWebServer", "~> 3.0" - pod 'MASShortcut', '~> 2' - - # https://github.com/ReactiveX/RxSwift/blob/master/Documentation/GettingStarted.md - pod 'RxSwift', '~> 6.2.0' - pod 'RxCocoa', '~> 6.2.0' - - target 'ShadowsocksX-NGTests' do - inherit! :search_paths - # Pods for testing - end - -end - -target 'proxy_conf_helper' do - pod 'BRLOptionParser', '~> 0.3.1' -end diff --git a/Podfile.lock b/Podfile.lock deleted file mode 100644 index ba9ec4fe5..000000000 --- a/Podfile.lock +++ /dev/null @@ -1,44 +0,0 @@ -PODS: - - Alamofire (5.4.3) - - BRLOptionParser (0.3.1) - - GCDWebServer (3.5.4): - - GCDWebServer/Core (= 3.5.4) - - GCDWebServer/Core (3.5.4) - - MASShortcut (2.4.0) - - RxCocoa (6.2.0): - - RxRelay (= 6.2.0) - - RxSwift (= 6.2.0) - - RxRelay (6.2.0): - - RxSwift (= 6.2.0) - - RxSwift (6.2.0) - -DEPENDENCIES: - - Alamofire (~> 5.4.3) - - BRLOptionParser (~> 0.3.1) - - GCDWebServer (~> 3.0) - - MASShortcut (~> 2) - - RxCocoa (~> 6.2.0) - - RxSwift (~> 6.2.0) - -SPEC REPOS: - trunk: - - Alamofire - - BRLOptionParser - - GCDWebServer - - MASShortcut - - RxCocoa - - RxRelay - - RxSwift - -SPEC CHECKSUMS: - Alamofire: e447a2774a40c996748296fa2c55112fdbbc42f9 - BRLOptionParser: a03256a8ff003ca1f5376c55f55f210e085a3958 - GCDWebServer: 2c156a56c8226e2d5c0c3f208a3621ccffbe3ce4 - MASShortcut: d9e4909e878661cc42877cc9d6efbe638273ab57 - RxCocoa: 4baf94bb35f2c0ab31bc0cb9f1900155f646ba42 - RxRelay: e72dbfd157807478401ef1982e1c61c945c94b2f - RxSwift: d356ab7bee873611322f134c5f9ef379fa183d8f - -PODFILE CHECKSUM: 5e6ee339e4466d456309238c104e8625cd1e3e41 - -COCOAPODS: 1.10.1 diff --git a/Pods/Alamofire/LICENSE b/Pods/Alamofire/LICENSE deleted file mode 100644 index 6b4d719a7..000000000 --- a/Pods/Alamofire/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2014-2021 Alamofire Software Foundation (http://alamofire.org/) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/Pods/Alamofire/README.md b/Pods/Alamofire/README.md deleted file mode 100644 index 9a5a80631..000000000 --- a/Pods/Alamofire/README.md +++ /dev/null @@ -1,206 +0,0 @@ -![Alamofire: Elegant Networking in Swift](https://raw.githubusercontent.com/Alamofire/Alamofire/master/alamofire.png) - -[![Build Status](https://github.com/Alamofire/Alamofire/workflows/Alamofire%20CI/badge.svg?branch=master)](https://github.com/Alamofire/Alamofire/actions) -[![CocoaPods Compatible](https://img.shields.io/cocoapods/v/Alamofire.svg)](https://img.shields.io/cocoapods/v/Alamofire.svg) -[![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) -[![Platform](https://img.shields.io/cocoapods/p/Alamofire.svg?style=flat)](https://alamofire.github.io/Alamofire) -[![Twitter](https://img.shields.io/badge/twitter-@AlamofireSF-blue.svg?style=flat)](https://twitter.com/AlamofireSF) -[![Gitter](https://badges.gitter.im/Alamofire/Alamofire.svg)](https://gitter.im/Alamofire/Alamofire?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) -[![Open Source Helpers](https://www.codetriage.com/alamofire/alamofire/badges/users.svg)](https://www.codetriage.com/alamofire/alamofire) - -Alamofire is an HTTP networking library written in Swift. - -- [Features](#features) -- [Component Libraries](#component-libraries) -- [Requirements](#requirements) -- [Migration Guides](#migration-guides) -- [Communication](#communication) -- [Installation](#installation) -- [Usage](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#using-alamofire) - - [**Introduction -**](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#introduction) [Making Requests](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#making-requests), [Response Handling](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#response-handling), [Response Validation](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#response-validation), [Response Caching](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#response-caching) - - **HTTP -** [HTTP Methods](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#http-methods), [Parameters and Parameter Encoder](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md##request-parameters-and-parameter-encoders), [HTTP Headers](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#http-headers), [Authentication](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#authentication) - - **Large Data -** [Downloading Data to a File](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#downloading-data-to-a-file), [Uploading Data to a Server](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#uploading-data-to-a-server) - - **Tools -** [Statistical Metrics](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#statistical-metrics), [cURL Command Output](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#curl-command-output) -- [Advanced Usage](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md) - - **URL Session -** [Session Manager](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#session), [Session Delegate](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#sessiondelegate), [Request](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#request) - - **Routing -** [Routing Requests](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#routing-requests), [Adapting and Retrying Requests](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#adapting-and-retrying-requests-with-requestinterceptor) - - **Model Objects -** [Custom Response Handlers](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#customizing-response-handlers) - - **Connection -** [Security](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#security), [Network Reachability](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#network-reachability) -- [Open Radars](#open-radars) -- [FAQ](#faq) -- [Credits](#credits) -- [Donations](#donations) -- [License](#license) - -## Features - -- [x] Chainable Request / Response Methods -- [x] Combine Support -- [x] URL / JSON Parameter Encoding -- [x] Upload File / Data / Stream / MultipartFormData -- [x] Download File using Request or Resume Data -- [x] Authentication with `URLCredential` -- [x] HTTP Response Validation -- [x] Upload and Download Progress Closures with Progress -- [x] cURL Command Output -- [x] Dynamically Adapt and Retry Requests -- [x] TLS Certificate and Public Key Pinning -- [x] Network Reachability -- [x] Comprehensive Unit and Integration Test Coverage -- [x] [Complete Documentation](https://alamofire.github.io/Alamofire) - -## Component Libraries - -In order to keep Alamofire focused specifically on core networking implementations, additional component libraries have been created by the [Alamofire Software Foundation](https://github.com/Alamofire/Foundation) to bring additional functionality to the Alamofire ecosystem. - -- [AlamofireImage](https://github.com/Alamofire/AlamofireImage) - An image library including image response serializers, `UIImage` and `UIImageView` extensions, custom image filters, an auto-purging in-memory cache, and a priority-based image downloading system. -- [AlamofireNetworkActivityIndicator](https://github.com/Alamofire/AlamofireNetworkActivityIndicator) - Controls the visibility of the network activity indicator on iOS using Alamofire. It contains configurable delay timers to help mitigate flicker and can support `URLSession` instances not managed by Alamofire. - -## Requirements - -- iOS 10.0+ / macOS 10.12+ / tvOS 10.0+ / watchOS 3.0+ -- Xcode 11+ -- Swift 5.1+ - -## Migration Guides - -- [Alamofire 5.0 Migration Guide](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%205.0%20Migration%20Guide.md) -- [Alamofire 4.0 Migration Guide](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%204.0%20Migration%20Guide.md) -- [Alamofire 3.0 Migration Guide](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%203.0%20Migration%20Guide.md) -- [Alamofire 2.0 Migration Guide](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%202.0%20Migration%20Guide.md) - -## Communication -- If you **need help with making network requests** using Alamofire, use [Stack Overflow](https://stackoverflow.com/questions/tagged/alamofire) and tag `alamofire`. -- If you need to **find or understand an API**, check [our documentation](http://alamofire.github.io/Alamofire/) or [Apple's documentation for `URLSession`](https://developer.apple.com/documentation/foundation/url_loading_system), on top of which Alamofire is built. -- If you need **help with an Alamofire feature**, use [our forum on swift.org](https://forums.swift.org/c/related-projects/alamofire). -- If you'd like to **discuss Alamofire best practices**, use [our forum on swift.org](https://forums.swift.org/c/related-projects/alamofire). -- If you'd like to **discuss a feature request**, use [our forum on swift.org](https://forums.swift.org/c/related-projects/alamofire). -- If you **found a bug**, open an issue here on GitHub and follow the guide. The more detail the better! -- If you **want to contribute**, submit a pull request! - -## Installation - -### CocoaPods - -[CocoaPods](https://cocoapods.org) is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate Alamofire into your Xcode project using CocoaPods, specify it in your `Podfile`: - -```ruby -pod 'Alamofire', '~> 5.2' -``` - -### Carthage - -[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. To integrate Alamofire into your Xcode project using Carthage, specify it in your `Cartfile`: - -```ogdl -github "Alamofire/Alamofire" ~> 5.2 -``` - -### Swift Package Manager - -The [Swift Package Manager](https://swift.org/package-manager/) is a tool for automating the distribution of Swift code and is integrated into the `swift` compiler. It is in early development, but Alamofire does support its use on supported platforms. - -Once you have your Swift package set up, adding Alamofire as a dependency is as easy as adding it to the `dependencies` value of your `Package.swift`. - -```swift -dependencies: [ - .package(url: "https://github.com/Alamofire/Alamofire.git", .upToNextMajor(from: "5.2.0")) -] -``` - -### Manually - -If you prefer not to use any of the aforementioned dependency managers, you can integrate Alamofire into your project manually. - -#### Embedded Framework - -- Open up Terminal, `cd` into your top-level project directory, and run the following command "if" your project is not initialized as a git repository: - - ```bash - $ git init - ``` - -- Add Alamofire as a git [submodule](https://git-scm.com/docs/git-submodule) by running the following command: - - ```bash - $ git submodule add https://github.com/Alamofire/Alamofire.git - ``` - -- Open the new `Alamofire` folder, and drag the `Alamofire.xcodeproj` into the Project Navigator of your application's Xcode project. - - > It should appear nested underneath your application's blue project icon. Whether it is above or below all the other Xcode groups does not matter. - -- Select the `Alamofire.xcodeproj` in the Project Navigator and verify the deployment target matches that of your application target. -- Next, select your application project in the Project Navigator (blue project icon) to navigate to the target configuration window and select the application target under the "Targets" heading in the sidebar. -- In the tab bar at the top of that window, open the "General" panel. -- Click on the `+` button under the "Embedded Binaries" section. -- You will see two different `Alamofire.xcodeproj` folders each with two different versions of the `Alamofire.framework` nested inside a `Products` folder. - - > It does not matter which `Products` folder you choose from, but it does matter whether you choose the top or bottom `Alamofire.framework`. - -- Select the top `Alamofire.framework` for iOS and the bottom one for macOS. - - > You can verify which one you selected by inspecting the build log for your project. The build target for `Alamofire` will be listed as `Alamofire iOS`, `Alamofire macOS`, `Alamofire tvOS`, or `Alamofire watchOS`. - -- And that's it! - - > The `Alamofire.framework` is automagically added as a target dependency, linked framework and embedded framework in a copy files build phase which is all you need to build on the simulator and a device. - -## Open Radars - -The following radars have some effect on the current implementation of Alamofire. - -- [`rdar://21349340`](http://www.openradar.me/radar?id=5517037090635776) - Compiler throwing warning due to toll-free bridging issue in the test case -- `rdar://26870455` - Background URL Session Configurations do not work in the simulator -- `rdar://26849668` - Some URLProtocol APIs do not properly handle `URLRequest` -- `FB7624529` - `urlSession(_:task:didFinishCollecting:)` never called on watchOS - -## Resolved Radars - -The following radars have been resolved over time after being filed against the Alamofire project. - -- [`rdar://26761490`](http://www.openradar.me/radar?id=5010235949318144) - Swift string interpolation causing memory leak with common usage. - - (Resolved): 9/1/17 in Xcode 9 beta 6. -- [`rdar://36082113`](http://openradar.appspot.com/radar?id=4942308441063424) - `URLSessionTaskMetrics` failing to link on watchOS 3.0+ - - (Resolved): Just add `CFNetwork` to your linked frameworks. - -## Workarounds - -- Collection of `URLSessionTaskMetrics` is currently disabled on watchOS due to `FB7624529`. - -## FAQ - -### What's the origin of the name Alamofire? - -Alamofire is named after the [Alamo Fire flower](https://aggie-horticulture.tamu.edu/wildseed/alamofire.html), a hybrid variant of the Bluebonnet, the official state flower of Texas. - -## Credits - -Alamofire is owned and maintained by the [Alamofire Software Foundation](http://alamofire.org). You can follow them on Twitter at [@AlamofireSF](https://twitter.com/AlamofireSF) for project updates and releases. - -### Security Disclosure - -If you believe you have identified a security vulnerability with Alamofire, you should report it as soon as possible via email to security@alamofire.org. Please do not post it to a public issue tracker. - -## Donations - -The [ASF](https://github.com/Alamofire/Foundation#members) is looking to raise money to officially stay registered as a federal non-profit organization. -Registering will allow Foundation members to gain some legal protections and also allow us to put donations to use, tax-free. -Donating to the ASF will enable us to: - -- Pay our yearly legal fees to keep the non-profit in good status -- Pay for our mail servers to help us stay on top of all questions and security issues -- Potentially fund test servers to make it easier for us to test the edge cases -- Potentially fund developers to work on one of our projects full-time - -The community adoption of the ASF libraries has been amazing. -We are greatly humbled by your enthusiasm around the projects and want to continue to do everything we can to move the needle forward. -With your continued support, the ASF will be able to improve its reach and also provide better legal safety for the core members. -If you use any of our libraries for work, see if your employers would be interested in donating. -Any amount you can donate today to help us reach our goal would be greatly appreciated. - -[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=W34WPEE74APJQ) - -## License - -Alamofire is released under the MIT license. [See LICENSE](https://github.com/Alamofire/Alamofire/blob/master/LICENSE) for details. diff --git a/Pods/Alamofire/Source/AFError.swift b/Pods/Alamofire/Source/AFError.swift deleted file mode 100644 index e8e4fe832..000000000 --- a/Pods/Alamofire/Source/AFError.swift +++ /dev/null @@ -1,854 +0,0 @@ -// -// AFError.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -/// `AFError` is the error type returned by Alamofire. It encompasses a few different types of errors, each with -/// their own associated reasons. -public enum AFError: Error { - /// The underlying reason the `.multipartEncodingFailed` error occurred. - public enum MultipartEncodingFailureReason { - /// The `fileURL` provided for reading an encodable body part isn't a file `URL`. - case bodyPartURLInvalid(url: URL) - /// The filename of the `fileURL` provided has either an empty `lastPathComponent` or `pathExtension. - case bodyPartFilenameInvalid(in: URL) - /// The file at the `fileURL` provided was not reachable. - case bodyPartFileNotReachable(at: URL) - /// Attempting to check the reachability of the `fileURL` provided threw an error. - case bodyPartFileNotReachableWithError(atURL: URL, error: Error) - /// The file at the `fileURL` provided is actually a directory. - case bodyPartFileIsDirectory(at: URL) - /// The size of the file at the `fileURL` provided was not returned by the system. - case bodyPartFileSizeNotAvailable(at: URL) - /// The attempt to find the size of the file at the `fileURL` provided threw an error. - case bodyPartFileSizeQueryFailedWithError(forURL: URL, error: Error) - /// An `InputStream` could not be created for the provided `fileURL`. - case bodyPartInputStreamCreationFailed(for: URL) - /// An `OutputStream` could not be created when attempting to write the encoded data to disk. - case outputStreamCreationFailed(for: URL) - /// The encoded body data could not be written to disk because a file already exists at the provided `fileURL`. - case outputStreamFileAlreadyExists(at: URL) - /// The `fileURL` provided for writing the encoded body data to disk is not a file `URL`. - case outputStreamURLInvalid(url: URL) - /// The attempt to write the encoded body data to disk failed with an underlying error. - case outputStreamWriteFailed(error: Error) - /// The attempt to read an encoded body part `InputStream` failed with underlying system error. - case inputStreamReadFailed(error: Error) - } - - /// Represents unexpected input stream length that occur when encoding the `MultipartFormData`. Instances will be - /// embedded within an `AFError.multipartEncodingFailed` `.inputStreamReadFailed` case. - public struct UnexpectedInputStreamLength: Error { - /// The expected byte count to read. - public var bytesExpected: UInt64 - /// The actual byte count read. - public var bytesRead: UInt64 - } - - /// The underlying reason the `.parameterEncodingFailed` error occurred. - public enum ParameterEncodingFailureReason { - /// The `URLRequest` did not have a `URL` to encode. - case missingURL - /// JSON serialization failed with an underlying system error during the encoding process. - case jsonEncodingFailed(error: Error) - /// Custom parameter encoding failed due to the associated `Error`. - case customEncodingFailed(error: Error) - } - - /// The underlying reason the `.parameterEncoderFailed` error occurred. - public enum ParameterEncoderFailureReason { - /// Possible missing components. - public enum RequiredComponent { - /// The `URL` was missing or unable to be extracted from the passed `URLRequest` or during encoding. - case url - /// The `HTTPMethod` could not be extracted from the passed `URLRequest`. - case httpMethod(rawValue: String) - } - - /// A `RequiredComponent` was missing during encoding. - case missingRequiredComponent(RequiredComponent) - /// The underlying encoder failed with the associated error. - case encoderFailed(error: Error) - } - - /// The underlying reason the `.responseValidationFailed` error occurred. - public enum ResponseValidationFailureReason { - /// The data file containing the server response did not exist. - case dataFileNil - /// The data file containing the server response at the associated `URL` could not be read. - case dataFileReadFailed(at: URL) - /// The response did not contain a `Content-Type` and the `acceptableContentTypes` provided did not contain a - /// wildcard type. - case missingContentType(acceptableContentTypes: [String]) - /// The response `Content-Type` did not match any type in the provided `acceptableContentTypes`. - case unacceptableContentType(acceptableContentTypes: [String], responseContentType: String) - /// The response status code was not acceptable. - case unacceptableStatusCode(code: Int) - /// Custom response validation failed due to the associated `Error`. - case customValidationFailed(error: Error) - } - - /// The underlying reason the response serialization error occurred. - public enum ResponseSerializationFailureReason { - /// The server response contained no data or the data was zero length. - case inputDataNilOrZeroLength - /// The file containing the server response did not exist. - case inputFileNil - /// The file containing the server response could not be read from the associated `URL`. - case inputFileReadFailed(at: URL) - /// String serialization failed using the provided `String.Encoding`. - case stringSerializationFailed(encoding: String.Encoding) - /// JSON serialization failed with an underlying system error. - case jsonSerializationFailed(error: Error) - /// A `DataDecoder` failed to decode the response due to the associated `Error`. - case decodingFailed(error: Error) - /// A custom response serializer failed due to the associated `Error`. - case customSerializationFailed(error: Error) - /// Generic serialization failed for an empty response that wasn't type `Empty` but instead the associated type. - case invalidEmptyResponse(type: String) - } - - /// Underlying reason a server trust evaluation error occurred. - public enum ServerTrustFailureReason { - /// The output of a server trust evaluation. - public struct Output { - /// The host for which the evaluation was performed. - public let host: String - /// The `SecTrust` value which was evaluated. - public let trust: SecTrust - /// The `OSStatus` of evaluation operation. - public let status: OSStatus - /// The result of the evaluation operation. - public let result: SecTrustResultType - - /// Creates an `Output` value from the provided values. - init(_ host: String, _ trust: SecTrust, _ status: OSStatus, _ result: SecTrustResultType) { - self.host = host - self.trust = trust - self.status = status - self.result = result - } - } - - /// No `ServerTrustEvaluator` was found for the associated host. - case noRequiredEvaluator(host: String) - /// No certificates were found with which to perform the trust evaluation. - case noCertificatesFound - /// No public keys were found with which to perform the trust evaluation. - case noPublicKeysFound - /// During evaluation, application of the associated `SecPolicy` failed. - case policyApplicationFailed(trust: SecTrust, policy: SecPolicy, status: OSStatus) - /// During evaluation, setting the associated anchor certificates failed. - case settingAnchorCertificatesFailed(status: OSStatus, certificates: [SecCertificate]) - /// During evaluation, creation of the revocation policy failed. - case revocationPolicyCreationFailed - /// `SecTrust` evaluation failed with the associated `Error`, if one was produced. - case trustEvaluationFailed(error: Error?) - /// Default evaluation failed with the associated `Output`. - case defaultEvaluationFailed(output: Output) - /// Host validation failed with the associated `Output`. - case hostValidationFailed(output: Output) - /// Revocation check failed with the associated `Output` and options. - case revocationCheckFailed(output: Output, options: RevocationTrustEvaluator.Options) - /// Certificate pinning failed. - case certificatePinningFailed(host: String, trust: SecTrust, pinnedCertificates: [SecCertificate], serverCertificates: [SecCertificate]) - /// Public key pinning failed. - case publicKeyPinningFailed(host: String, trust: SecTrust, pinnedKeys: [SecKey], serverKeys: [SecKey]) - /// Custom server trust evaluation failed due to the associated `Error`. - case customEvaluationFailed(error: Error) - } - - /// The underlying reason the `.urlRequestValidationFailed` - public enum URLRequestValidationFailureReason { - /// URLRequest with GET method had body data. - case bodyDataInGETRequest(Data) - } - - /// `UploadableConvertible` threw an error in `createUploadable()`. - case createUploadableFailed(error: Error) - /// `URLRequestConvertible` threw an error in `asURLRequest()`. - case createURLRequestFailed(error: Error) - /// `SessionDelegate` threw an error while attempting to move downloaded file to destination URL. - case downloadedFileMoveFailed(error: Error, source: URL, destination: URL) - /// `Request` was explicitly cancelled. - case explicitlyCancelled - /// `URLConvertible` type failed to create a valid `URL`. - case invalidURL(url: URLConvertible) - /// Multipart form encoding failed. - case multipartEncodingFailed(reason: MultipartEncodingFailureReason) - /// `ParameterEncoding` threw an error during the encoding process. - case parameterEncodingFailed(reason: ParameterEncodingFailureReason) - /// `ParameterEncoder` threw an error while running the encoder. - case parameterEncoderFailed(reason: ParameterEncoderFailureReason) - /// `RequestAdapter` threw an error during adaptation. - case requestAdaptationFailed(error: Error) - /// `RequestRetrier` threw an error during the request retry process. - case requestRetryFailed(retryError: Error, originalError: Error) - /// Response validation failed. - case responseValidationFailed(reason: ResponseValidationFailureReason) - /// Response serialization failed. - case responseSerializationFailed(reason: ResponseSerializationFailureReason) - /// `ServerTrustEvaluating` instance threw an error during trust evaluation. - case serverTrustEvaluationFailed(reason: ServerTrustFailureReason) - /// `Session` which issued the `Request` was deinitialized, most likely because its reference went out of scope. - case sessionDeinitialized - /// `Session` was explicitly invalidated, possibly with the `Error` produced by the underlying `URLSession`. - case sessionInvalidated(error: Error?) - /// `URLSessionTask` completed with error. - case sessionTaskFailed(error: Error) - /// `URLRequest` failed validation. - case urlRequestValidationFailed(reason: URLRequestValidationFailureReason) -} - -extension Error { - /// Returns the instance cast as an `AFError`. - public var asAFError: AFError? { - self as? AFError - } - - /// Returns the instance cast as an `AFError`. If casting fails, a `fatalError` with the specified `message` is thrown. - public func asAFError(orFailWith message: @autoclosure () -> String, file: StaticString = #file, line: UInt = #line) -> AFError { - guard let afError = self as? AFError else { - fatalError(message(), file: file, line: line) - } - return afError - } - - /// Casts the instance as `AFError` or returns `defaultAFError` - func asAFError(or defaultAFError: @autoclosure () -> AFError) -> AFError { - self as? AFError ?? defaultAFError() - } -} - -// MARK: - Error Booleans - -extension AFError { - /// Returns whether the instance is `.sessionDeinitialized`. - public var isSessionDeinitializedError: Bool { - if case .sessionDeinitialized = self { return true } - return false - } - - /// Returns whether the instance is `.sessionInvalidated`. - public var isSessionInvalidatedError: Bool { - if case .sessionInvalidated = self { return true } - return false - } - - /// Returns whether the instance is `.explicitlyCancelled`. - public var isExplicitlyCancelledError: Bool { - if case .explicitlyCancelled = self { return true } - return false - } - - /// Returns whether the instance is `.invalidURL`. - public var isInvalidURLError: Bool { - if case .invalidURL = self { return true } - return false - } - - /// Returns whether the instance is `.parameterEncodingFailed`. When `true`, the `underlyingError` property will - /// contain the associated value. - public var isParameterEncodingError: Bool { - if case .parameterEncodingFailed = self { return true } - return false - } - - /// Returns whether the instance is `.parameterEncoderFailed`. When `true`, the `underlyingError` property will - /// contain the associated value. - public var isParameterEncoderError: Bool { - if case .parameterEncoderFailed = self { return true } - return false - } - - /// Returns whether the instance is `.multipartEncodingFailed`. When `true`, the `url` and `underlyingError` - /// properties will contain the associated values. - public var isMultipartEncodingError: Bool { - if case .multipartEncodingFailed = self { return true } - return false - } - - /// Returns whether the instance is `.requestAdaptationFailed`. When `true`, the `underlyingError` property will - /// contain the associated value. - public var isRequestAdaptationError: Bool { - if case .requestAdaptationFailed = self { return true } - return false - } - - /// Returns whether the instance is `.responseValidationFailed`. When `true`, the `acceptableContentTypes`, - /// `responseContentType`, `responseCode`, and `underlyingError` properties will contain the associated values. - public var isResponseValidationError: Bool { - if case .responseValidationFailed = self { return true } - return false - } - - /// Returns whether the instance is `.responseSerializationFailed`. When `true`, the `failedStringEncoding` and - /// `underlyingError` properties will contain the associated values. - public var isResponseSerializationError: Bool { - if case .responseSerializationFailed = self { return true } - return false - } - - /// Returns whether the instance is `.serverTrustEvaluationFailed`. When `true`, the `underlyingError` property will - /// contain the associated value. - public var isServerTrustEvaluationError: Bool { - if case .serverTrustEvaluationFailed = self { return true } - return false - } - - /// Returns whether the instance is `requestRetryFailed`. When `true`, the `underlyingError` property will - /// contain the associated value. - public var isRequestRetryError: Bool { - if case .requestRetryFailed = self { return true } - return false - } - - /// Returns whether the instance is `createUploadableFailed`. When `true`, the `underlyingError` property will - /// contain the associated value. - public var isCreateUploadableError: Bool { - if case .createUploadableFailed = self { return true } - return false - } - - /// Returns whether the instance is `createURLRequestFailed`. When `true`, the `underlyingError` property will - /// contain the associated value. - public var isCreateURLRequestError: Bool { - if case .createURLRequestFailed = self { return true } - return false - } - - /// Returns whether the instance is `downloadedFileMoveFailed`. When `true`, the `destination` and `underlyingError` properties will - /// contain the associated values. - public var isDownloadedFileMoveError: Bool { - if case .downloadedFileMoveFailed = self { return true } - return false - } - - /// Returns whether the instance is `createURLRequestFailed`. When `true`, the `underlyingError` property will - /// contain the associated value. - public var isSessionTaskError: Bool { - if case .sessionTaskFailed = self { return true } - return false - } -} - -// MARK: - Convenience Properties - -extension AFError { - /// The `URLConvertible` associated with the error. - public var urlConvertible: URLConvertible? { - guard case let .invalidURL(url) = self else { return nil } - return url - } - - /// The `URL` associated with the error. - public var url: URL? { - guard case let .multipartEncodingFailed(reason) = self else { return nil } - return reason.url - } - - /// The underlying `Error` responsible for generating the failure associated with `.sessionInvalidated`, - /// `.parameterEncodingFailed`, `.parameterEncoderFailed`, `.multipartEncodingFailed`, `.requestAdaptationFailed`, - /// `.responseSerializationFailed`, `.requestRetryFailed` errors. - public var underlyingError: Error? { - switch self { - case let .multipartEncodingFailed(reason): - return reason.underlyingError - case let .parameterEncodingFailed(reason): - return reason.underlyingError - case let .parameterEncoderFailed(reason): - return reason.underlyingError - case let .requestAdaptationFailed(error): - return error - case let .requestRetryFailed(retryError, _): - return retryError - case let .responseValidationFailed(reason): - return reason.underlyingError - case let .responseSerializationFailed(reason): - return reason.underlyingError - case let .serverTrustEvaluationFailed(reason): - return reason.underlyingError - case let .sessionInvalidated(error): - return error - case let .createUploadableFailed(error): - return error - case let .createURLRequestFailed(error): - return error - case let .downloadedFileMoveFailed(error, _, _): - return error - case let .sessionTaskFailed(error): - return error - case .explicitlyCancelled, - .invalidURL, - .sessionDeinitialized, - .urlRequestValidationFailed: - return nil - } - } - - /// The acceptable `Content-Type`s of a `.responseValidationFailed` error. - public var acceptableContentTypes: [String]? { - guard case let .responseValidationFailed(reason) = self else { return nil } - return reason.acceptableContentTypes - } - - /// The response `Content-Type` of a `.responseValidationFailed` error. - public var responseContentType: String? { - guard case let .responseValidationFailed(reason) = self else { return nil } - return reason.responseContentType - } - - /// The response code of a `.responseValidationFailed` error. - public var responseCode: Int? { - guard case let .responseValidationFailed(reason) = self else { return nil } - return reason.responseCode - } - - /// The `String.Encoding` associated with a failed `.stringResponse()` call. - public var failedStringEncoding: String.Encoding? { - guard case let .responseSerializationFailed(reason) = self else { return nil } - return reason.failedStringEncoding - } - - /// The `source` URL of a `.downloadedFileMoveFailed` error. - public var sourceURL: URL? { - guard case let .downloadedFileMoveFailed(_, source, _) = self else { return nil } - return source - } - - /// The `destination` URL of a `.downloadedFileMoveFailed` error. - public var destinationURL: URL? { - guard case let .downloadedFileMoveFailed(_, _, destination) = self else { return nil } - return destination - } - - /// The download resume data of any underlying network error. Only produced by `DownloadRequest`s. - public var downloadResumeData: Data? { - (underlyingError as? URLError)?.userInfo[NSURLSessionDownloadTaskResumeData] as? Data - } -} - -extension AFError.ParameterEncodingFailureReason { - var underlyingError: Error? { - switch self { - case let .jsonEncodingFailed(error), - let .customEncodingFailed(error): - return error - case .missingURL: - return nil - } - } -} - -extension AFError.ParameterEncoderFailureReason { - var underlyingError: Error? { - switch self { - case let .encoderFailed(error): - return error - case .missingRequiredComponent: - return nil - } - } -} - -extension AFError.MultipartEncodingFailureReason { - var url: URL? { - switch self { - case let .bodyPartURLInvalid(url), - let .bodyPartFilenameInvalid(url), - let .bodyPartFileNotReachable(url), - let .bodyPartFileIsDirectory(url), - let .bodyPartFileSizeNotAvailable(url), - let .bodyPartInputStreamCreationFailed(url), - let .outputStreamCreationFailed(url), - let .outputStreamFileAlreadyExists(url), - let .outputStreamURLInvalid(url), - let .bodyPartFileNotReachableWithError(url, _), - let .bodyPartFileSizeQueryFailedWithError(url, _): - return url - case .outputStreamWriteFailed, - .inputStreamReadFailed: - return nil - } - } - - var underlyingError: Error? { - switch self { - case let .bodyPartFileNotReachableWithError(_, error), - let .bodyPartFileSizeQueryFailedWithError(_, error), - let .outputStreamWriteFailed(error), - let .inputStreamReadFailed(error): - return error - case .bodyPartURLInvalid, - .bodyPartFilenameInvalid, - .bodyPartFileNotReachable, - .bodyPartFileIsDirectory, - .bodyPartFileSizeNotAvailable, - .bodyPartInputStreamCreationFailed, - .outputStreamCreationFailed, - .outputStreamFileAlreadyExists, - .outputStreamURLInvalid: - return nil - } - } -} - -extension AFError.ResponseValidationFailureReason { - var acceptableContentTypes: [String]? { - switch self { - case let .missingContentType(types), - let .unacceptableContentType(types, _): - return types - case .dataFileNil, - .dataFileReadFailed, - .unacceptableStatusCode, - .customValidationFailed: - return nil - } - } - - var responseContentType: String? { - switch self { - case let .unacceptableContentType(_, responseType): - return responseType - case .dataFileNil, - .dataFileReadFailed, - .missingContentType, - .unacceptableStatusCode, - .customValidationFailed: - return nil - } - } - - var responseCode: Int? { - switch self { - case let .unacceptableStatusCode(code): - return code - case .dataFileNil, - .dataFileReadFailed, - .missingContentType, - .unacceptableContentType, - .customValidationFailed: - return nil - } - } - - var underlyingError: Error? { - switch self { - case let .customValidationFailed(error): - return error - case .dataFileNil, - .dataFileReadFailed, - .missingContentType, - .unacceptableContentType, - .unacceptableStatusCode: - return nil - } - } -} - -extension AFError.ResponseSerializationFailureReason { - var failedStringEncoding: String.Encoding? { - switch self { - case let .stringSerializationFailed(encoding): - return encoding - case .inputDataNilOrZeroLength, - .inputFileNil, - .inputFileReadFailed(_), - .jsonSerializationFailed(_), - .decodingFailed(_), - .customSerializationFailed(_), - .invalidEmptyResponse: - return nil - } - } - - var underlyingError: Error? { - switch self { - case let .jsonSerializationFailed(error), - let .decodingFailed(error), - let .customSerializationFailed(error): - return error - case .inputDataNilOrZeroLength, - .inputFileNil, - .inputFileReadFailed, - .stringSerializationFailed, - .invalidEmptyResponse: - return nil - } - } -} - -extension AFError.ServerTrustFailureReason { - var output: AFError.ServerTrustFailureReason.Output? { - switch self { - case let .defaultEvaluationFailed(output), - let .hostValidationFailed(output), - let .revocationCheckFailed(output, _): - return output - case .noRequiredEvaluator, - .noCertificatesFound, - .noPublicKeysFound, - .policyApplicationFailed, - .settingAnchorCertificatesFailed, - .revocationPolicyCreationFailed, - .trustEvaluationFailed, - .certificatePinningFailed, - .publicKeyPinningFailed, - .customEvaluationFailed: - return nil - } - } - - var underlyingError: Error? { - switch self { - case let .customEvaluationFailed(error): - return error - case let .trustEvaluationFailed(error): - return error - case .noRequiredEvaluator, - .noCertificatesFound, - .noPublicKeysFound, - .policyApplicationFailed, - .settingAnchorCertificatesFailed, - .revocationPolicyCreationFailed, - .defaultEvaluationFailed, - .hostValidationFailed, - .revocationCheckFailed, - .certificatePinningFailed, - .publicKeyPinningFailed: - return nil - } - } -} - -// MARK: - Error Descriptions - -extension AFError: LocalizedError { - public var errorDescription: String? { - switch self { - case .explicitlyCancelled: - return "Request explicitly cancelled." - case let .invalidURL(url): - return "URL is not valid: \(url)" - case let .parameterEncodingFailed(reason): - return reason.localizedDescription - case let .parameterEncoderFailed(reason): - return reason.localizedDescription - case let .multipartEncodingFailed(reason): - return reason.localizedDescription - case let .requestAdaptationFailed(error): - return "Request adaption failed with error: \(error.localizedDescription)" - case let .responseValidationFailed(reason): - return reason.localizedDescription - case let .responseSerializationFailed(reason): - return reason.localizedDescription - case let .requestRetryFailed(retryError, originalError): - return """ - Request retry failed with retry error: \(retryError.localizedDescription), \ - original error: \(originalError.localizedDescription) - """ - case .sessionDeinitialized: - return """ - Session was invalidated without error, so it was likely deinitialized unexpectedly. \ - Be sure to retain a reference to your Session for the duration of your requests. - """ - case let .sessionInvalidated(error): - return "Session was invalidated with error: \(error?.localizedDescription ?? "No description.")" - case let .serverTrustEvaluationFailed(reason): - return "Server trust evaluation failed due to reason: \(reason.localizedDescription)" - case let .urlRequestValidationFailed(reason): - return "URLRequest validation failed due to reason: \(reason.localizedDescription)" - case let .createUploadableFailed(error): - return "Uploadable creation failed with error: \(error.localizedDescription)" - case let .createURLRequestFailed(error): - return "URLRequest creation failed with error: \(error.localizedDescription)" - case let .downloadedFileMoveFailed(error, source, destination): - return "Moving downloaded file from: \(source) to: \(destination) failed with error: \(error.localizedDescription)" - case let .sessionTaskFailed(error): - return "URLSessionTask failed with error: \(error.localizedDescription)" - } - } -} - -extension AFError.ParameterEncodingFailureReason { - var localizedDescription: String { - switch self { - case .missingURL: - return "URL request to encode was missing a URL" - case let .jsonEncodingFailed(error): - return "JSON could not be encoded because of error:\n\(error.localizedDescription)" - case let .customEncodingFailed(error): - return "Custom parameter encoder failed with error: \(error.localizedDescription)" - } - } -} - -extension AFError.ParameterEncoderFailureReason { - var localizedDescription: String { - switch self { - case let .missingRequiredComponent(component): - return "Encoding failed due to a missing request component: \(component)" - case let .encoderFailed(error): - return "The underlying encoder failed with the error: \(error)" - } - } -} - -extension AFError.MultipartEncodingFailureReason { - var localizedDescription: String { - switch self { - case let .bodyPartURLInvalid(url): - return "The URL provided is not a file URL: \(url)" - case let .bodyPartFilenameInvalid(url): - return "The URL provided does not have a valid filename: \(url)" - case let .bodyPartFileNotReachable(url): - return "The URL provided is not reachable: \(url)" - case let .bodyPartFileNotReachableWithError(url, error): - return """ - The system returned an error while checking the provided URL for reachability. - URL: \(url) - Error: \(error) - """ - case let .bodyPartFileIsDirectory(url): - return "The URL provided is a directory: \(url)" - case let .bodyPartFileSizeNotAvailable(url): - return "Could not fetch the file size from the provided URL: \(url)" - case let .bodyPartFileSizeQueryFailedWithError(url, error): - return """ - The system returned an error while attempting to fetch the file size from the provided URL. - URL: \(url) - Error: \(error) - """ - case let .bodyPartInputStreamCreationFailed(url): - return "Failed to create an InputStream for the provided URL: \(url)" - case let .outputStreamCreationFailed(url): - return "Failed to create an OutputStream for URL: \(url)" - case let .outputStreamFileAlreadyExists(url): - return "A file already exists at the provided URL: \(url)" - case let .outputStreamURLInvalid(url): - return "The provided OutputStream URL is invalid: \(url)" - case let .outputStreamWriteFailed(error): - return "OutputStream write failed with error: \(error)" - case let .inputStreamReadFailed(error): - return "InputStream read failed with error: \(error)" - } - } -} - -extension AFError.ResponseSerializationFailureReason { - var localizedDescription: String { - switch self { - case .inputDataNilOrZeroLength: - return "Response could not be serialized, input data was nil or zero length." - case .inputFileNil: - return "Response could not be serialized, input file was nil." - case let .inputFileReadFailed(url): - return "Response could not be serialized, input file could not be read: \(url)." - case let .stringSerializationFailed(encoding): - return "String could not be serialized with encoding: \(encoding)." - case let .jsonSerializationFailed(error): - return "JSON could not be serialized because of error:\n\(error.localizedDescription)" - case let .invalidEmptyResponse(type): - return """ - Empty response could not be serialized to type: \(type). \ - Use Empty as the expected type for such responses. - """ - case let .decodingFailed(error): - return "Response could not be decoded because of error:\n\(error.localizedDescription)" - case let .customSerializationFailed(error): - return "Custom response serializer failed with error:\n\(error.localizedDescription)" - } - } -} - -extension AFError.ResponseValidationFailureReason { - var localizedDescription: String { - switch self { - case .dataFileNil: - return "Response could not be validated, data file was nil." - case let .dataFileReadFailed(url): - return "Response could not be validated, data file could not be read: \(url)." - case let .missingContentType(types): - return """ - Response Content-Type was missing and acceptable content types \ - (\(types.joined(separator: ","))) do not match "*/*". - """ - case let .unacceptableContentType(acceptableTypes, responseType): - return """ - Response Content-Type "\(responseType)" does not match any acceptable types: \ - \(acceptableTypes.joined(separator: ",")). - """ - case let .unacceptableStatusCode(code): - return "Response status code was unacceptable: \(code)." - case let .customValidationFailed(error): - return "Custom response validation failed with error: \(error.localizedDescription)" - } - } -} - -extension AFError.ServerTrustFailureReason { - var localizedDescription: String { - switch self { - case let .noRequiredEvaluator(host): - return "A ServerTrustEvaluating value is required for host \(host) but none was found." - case .noCertificatesFound: - return "No certificates were found or provided for evaluation." - case .noPublicKeysFound: - return "No public keys were found or provided for evaluation." - case .policyApplicationFailed: - return "Attempting to set a SecPolicy failed." - case .settingAnchorCertificatesFailed: - return "Attempting to set the provided certificates as anchor certificates failed." - case .revocationPolicyCreationFailed: - return "Attempting to create a revocation policy failed." - case let .trustEvaluationFailed(error): - return "SecTrust evaluation failed with error: \(error?.localizedDescription ?? "None")" - case let .defaultEvaluationFailed(output): - return "Default evaluation failed for host \(output.host)." - case let .hostValidationFailed(output): - return "Host validation failed for host \(output.host)." - case let .revocationCheckFailed(output, _): - return "Revocation check failed for host \(output.host)." - case let .certificatePinningFailed(host, _, _, _): - return "Certificate pinning failed for host \(host)." - case let .publicKeyPinningFailed(host, _, _, _): - return "Public key pinning failed for host \(host)." - case let .customEvaluationFailed(error): - return "Custom trust evaluation failed with error: \(error.localizedDescription)" - } - } -} - -extension AFError.URLRequestValidationFailureReason { - var localizedDescription: String { - switch self { - case let .bodyDataInGETRequest(data): - return """ - Invalid URLRequest: Requests with GET method cannot have body data: - \(String(decoding: data, as: UTF8.self)) - """ - } - } -} diff --git a/Pods/Alamofire/Source/Alamofire.swift b/Pods/Alamofire/Source/Alamofire.swift deleted file mode 100644 index bcf43d02e..000000000 --- a/Pods/Alamofire/Source/Alamofire.swift +++ /dev/null @@ -1,29 +0,0 @@ -// -// Alamofire.swift -// -// Copyright (c) 2014-2021 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -/// Reference to `Session.default` for quick bootstrapping and examples. -public let AF = Session.default - -/// Current Alamofire version. Necessary since SPM doesn't use dynamic libraries. Plus this will be more accurate. -let version = "5.4.3" diff --git a/Pods/Alamofire/Source/AlamofireExtended.swift b/Pods/Alamofire/Source/AlamofireExtended.swift deleted file mode 100644 index 280c6de99..000000000 --- a/Pods/Alamofire/Source/AlamofireExtended.swift +++ /dev/null @@ -1,61 +0,0 @@ -// -// AlamofireExtended.swift -// -// Copyright (c) 2019 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -/// Type that acts as a generic extension point for all `AlamofireExtended` types. -public struct AlamofireExtension { - /// Stores the type or meta-type of any extended type. - public private(set) var type: ExtendedType - - /// Create an instance from the provided value. - /// - /// - Parameter type: Instance being extended. - public init(_ type: ExtendedType) { - self.type = type - } -} - -/// Protocol describing the `af` extension points for Alamofire extended types. -public protocol AlamofireExtended { - /// Type being extended. - associatedtype ExtendedType - - /// Static Alamofire extension point. - static var af: AlamofireExtension.Type { get set } - /// Instance Alamofire extension point. - var af: AlamofireExtension { get set } -} - -extension AlamofireExtended { - /// Static Alamofire extension point. - public static var af: AlamofireExtension.Type { - get { AlamofireExtension.self } - set {} - } - - /// Instance Alamofire extension point. - public var af: AlamofireExtension { - get { AlamofireExtension(self) } - set {} - } -} diff --git a/Pods/Alamofire/Source/AuthenticationInterceptor.swift b/Pods/Alamofire/Source/AuthenticationInterceptor.swift deleted file mode 100644 index 9d7f8360d..000000000 --- a/Pods/Alamofire/Source/AuthenticationInterceptor.swift +++ /dev/null @@ -1,404 +0,0 @@ -// -// AuthenticationInterceptor.swift -// -// Copyright (c) 2020 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -/// Types adopting the `AuthenticationCredential` protocol can be used to authenticate `URLRequest`s. -/// -/// One common example of an `AuthenticationCredential` is an OAuth2 credential containing an access token used to -/// authenticate all requests on behalf of a user. The access token generally has an expiration window of 60 minutes -/// which will then require a refresh of the credential using the refresh token to generate a new access token. -public protocol AuthenticationCredential { - /// Whether the credential requires a refresh. This property should always return `true` when the credential is - /// expired. It is also wise to consider returning `true` when the credential will expire in several seconds or - /// minutes depending on the expiration window of the credential. - /// - /// For example, if the credential is valid for 60 minutes, then it would be wise to return `true` when the - /// credential is only valid for 5 minutes or less. That ensures the credential will not expire as it is passed - /// around backend services. - var requiresRefresh: Bool { get } -} - -// MARK: - - -/// Types adopting the `Authenticator` protocol can be used to authenticate `URLRequest`s with an -/// `AuthenticationCredential` as well as refresh the `AuthenticationCredential` when required. -public protocol Authenticator: AnyObject { - /// The type of credential associated with the `Authenticator` instance. - associatedtype Credential: AuthenticationCredential - - /// Applies the `Credential` to the `URLRequest`. - /// - /// In the case of OAuth2, the access token of the `Credential` would be added to the `URLRequest` as a Bearer - /// token to the `Authorization` header. - /// - /// - Parameters: - /// - credential: The `Credential`. - /// - urlRequest: The `URLRequest`. - func apply(_ credential: Credential, to urlRequest: inout URLRequest) - - /// Refreshes the `Credential` and executes the `completion` closure with the `Result` once complete. - /// - /// Refresh can be called in one of two ways. It can be called before the `Request` is actually executed due to - /// a `requiresRefresh` returning `true` during the adapt portion of the `Request` creation process. It can also - /// be triggered by a failed `Request` where the authentication server denied access due to an expired or - /// invalidated access token. - /// - /// In the case of OAuth2, this method would use the refresh token of the `Credential` to generate a new - /// `Credential` using the authentication service. Once complete, the `completion` closure should be called with - /// the new `Credential`, or the error that occurred. - /// - /// In general, if the refresh call fails with certain status codes from the authentication server (commonly a 401), - /// the refresh token in the `Credential` can no longer be used to generate a valid `Credential`. In these cases, - /// you will need to reauthenticate the user with their username / password. - /// - /// Please note, these are just general examples of common use cases. They are not meant to solve your specific - /// authentication server challenges. Please work with your authentication server team to ensure your - /// `Authenticator` logic matches their expectations. - /// - /// - Parameters: - /// - credential: The `Credential` to refresh. - /// - session: The `Session` requiring the refresh. - /// - completion: The closure to be executed once the refresh is complete. - func refresh(_ credential: Credential, for session: Session, completion: @escaping (Result) -> Void) - - /// Determines whether the `URLRequest` failed due to an authentication error based on the `HTTPURLResponse`. - /// - /// If the authentication server **CANNOT** invalidate credentials after they are issued, then simply return `false` - /// for this method. If the authentication server **CAN** invalidate credentials due to security breaches, then you - /// will need to work with your authentication server team to understand how to identify when this occurs. - /// - /// In the case of OAuth2, where an authentication server can invalidate credentials, you will need to inspect the - /// `HTTPURLResponse` or possibly the `Error` for when this occurs. This is commonly handled by the authentication - /// server returning a 401 status code and some additional header to indicate an OAuth2 failure occurred. - /// - /// It is very important to understand how your authentication server works to be able to implement this correctly. - /// For example, if your authentication server returns a 401 when an OAuth2 error occurs, and your downstream - /// service also returns a 401 when you are not authorized to perform that operation, how do you know which layer - /// of the backend returned you a 401? You do not want to trigger a refresh unless you know your authentication - /// server is actually the layer rejecting the request. Again, work with your authentication server team to understand - /// how to identify an OAuth2 401 error vs. a downstream 401 error to avoid endless refresh loops. - /// - /// - Parameters: - /// - urlRequest: The `URLRequest`. - /// - response: The `HTTPURLResponse`. - /// - error: The `Error`. - /// - /// - Returns: `true` if the `URLRequest` failed due to an authentication error, `false` otherwise. - func didRequest(_ urlRequest: URLRequest, with response: HTTPURLResponse, failDueToAuthenticationError error: Error) -> Bool - - /// Determines whether the `URLRequest` is authenticated with the `Credential`. - /// - /// If the authentication server **CANNOT** invalidate credentials after they are issued, then simply return `true` - /// for this method. If the authentication server **CAN** invalidate credentials due to security breaches, then - /// read on. - /// - /// When an authentication server can invalidate credentials, it means that you may have a non-expired credential - /// that appears to be valid, but will be rejected by the authentication server when used. Generally when this - /// happens, a number of requests are all sent when the application is foregrounded, and all of them will be - /// rejected by the authentication server in the order they are received. The first failed request will trigger a - /// refresh internally, which will update the credential, and then retry all the queued requests with the new - /// credential. However, it is possible that some of the original requests will not return from the authentication - /// server until the refresh has completed. This is where this method comes in. - /// - /// When the authentication server rejects a credential, we need to check to make sure we haven't refreshed the - /// credential while the request was in flight. If it has already refreshed, then we don't need to trigger an - /// additional refresh. If it hasn't refreshed, then we need to refresh. - /// - /// Now that it is understood how the result of this method is used in the refresh lifecyle, let's walk through how - /// to implement it. You should return `true` in this method if the `URLRequest` is authenticated in a way that - /// matches the values in the `Credential`. In the case of OAuth2, this would mean that the Bearer token in the - /// `Authorization` header of the `URLRequest` matches the access token in the `Credential`. If it matches, then we - /// know the `Credential` was used to authenticate the `URLRequest` and should return `true`. If the Bearer token - /// did not match the access token, then you should return `false`. - /// - /// - Parameters: - /// - urlRequest: The `URLRequest`. - /// - credential: The `Credential`. - /// - /// - Returns: `true` if the `URLRequest` is authenticated with the `Credential`, `false` otherwise. - func isRequest(_ urlRequest: URLRequest, authenticatedWith credential: Credential) -> Bool -} - -// MARK: - - -/// Represents various authentication failures that occur when using the `AuthenticationInterceptor`. All errors are -/// still vended from Alamofire as `AFError` types. The `AuthenticationError` instances will be embedded within -/// `AFError` `.requestAdaptationFailed` or `.requestRetryFailed` cases. -public enum AuthenticationError: Error { - /// The credential was missing so the request could not be authenticated. - case missingCredential - /// The credential was refreshed too many times within the `RefreshWindow`. - case excessiveRefresh -} - -// MARK: - - -/// The `AuthenticationInterceptor` class manages the queuing and threading complexity of authenticating requests. -/// It relies on an `Authenticator` type to handle the actual `URLRequest` authentication and `Credential` refresh. -public class AuthenticationInterceptor: RequestInterceptor where AuthenticatorType: Authenticator { - // MARK: Typealiases - - /// Type of credential used to authenticate requests. - public typealias Credential = AuthenticatorType.Credential - - // MARK: Helper Types - - /// Type that defines a time window used to identify excessive refresh calls. When enabled, prior to executing a - /// refresh, the `AuthenticationInterceptor` compares the timestamp history of previous refresh calls against the - /// `RefreshWindow`. If more refreshes have occurred within the refresh window than allowed, the refresh is - /// cancelled and an `AuthorizationError.excessiveRefresh` error is thrown. - public struct RefreshWindow { - /// `TimeInterval` defining the duration of the time window before the current time in which the number of - /// refresh attempts is compared against `maximumAttempts`. For example, if `interval` is 30 seconds, then the - /// `RefreshWindow` represents the past 30 seconds. If more attempts occurred in the past 30 seconds than - /// `maximumAttempts`, an `.excessiveRefresh` error will be thrown. - public let interval: TimeInterval - - /// Total refresh attempts allowed within `interval` before throwing an `.excessiveRefresh` error. - public let maximumAttempts: Int - - /// Creates a `RefreshWindow` instance from the specified `interval` and `maximumAttempts`. - /// - /// - Parameters: - /// - interval: `TimeInterval` defining the duration of the time window before the current time. - /// - maximumAttempts: The maximum attempts allowed within the `TimeInterval`. - public init(interval: TimeInterval = 30.0, maximumAttempts: Int = 5) { - self.interval = interval - self.maximumAttempts = maximumAttempts - } - } - - private struct AdaptOperation { - let urlRequest: URLRequest - let session: Session - let completion: (Result) -> Void - } - - private enum AdaptResult { - case adapt(Credential) - case doNotAdapt(AuthenticationError) - case adaptDeferred - } - - private struct MutableState { - var credential: Credential? - - var isRefreshing = false - var refreshTimestamps: [TimeInterval] = [] - var refreshWindow: RefreshWindow? - - var adaptOperations: [AdaptOperation] = [] - var requestsToRetry: [(RetryResult) -> Void] = [] - } - - // MARK: Properties - - /// The `Credential` used to authenticate requests. - public var credential: Credential? { - get { mutableState.credential } - set { mutableState.credential = newValue } - } - - let authenticator: AuthenticatorType - let queue = DispatchQueue(label: "org.alamofire.authentication.inspector") - - @Protected - private var mutableState = MutableState() - - // MARK: Initialization - - /// Creates an `AuthenticationInterceptor` instance from the specified parameters. - /// - /// A `nil` `RefreshWindow` will result in the `AuthenticationInterceptor` not checking for excessive refresh calls. - /// It is recommended to always use a `RefreshWindow` to avoid endless refresh cycles. - /// - /// - Parameters: - /// - authenticator: The `Authenticator` type. - /// - credential: The `Credential` if it exists. `nil` by default. - /// - refreshWindow: The `RefreshWindow` used to identify excessive refresh calls. `RefreshWindow()` by default. - public init(authenticator: AuthenticatorType, - credential: Credential? = nil, - refreshWindow: RefreshWindow? = RefreshWindow()) { - self.authenticator = authenticator - mutableState.credential = credential - mutableState.refreshWindow = refreshWindow - } - - // MARK: Adapt - - public func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result) -> Void) { - let adaptResult: AdaptResult = $mutableState.write { mutableState in - // Queue the adapt operation if a refresh is already in place. - guard !mutableState.isRefreshing else { - let operation = AdaptOperation(urlRequest: urlRequest, session: session, completion: completion) - mutableState.adaptOperations.append(operation) - return .adaptDeferred - } - - // Throw missing credential error is the credential is missing. - guard let credential = mutableState.credential else { - let error = AuthenticationError.missingCredential - return .doNotAdapt(error) - } - - // Queue the adapt operation and trigger refresh operation if credential requires refresh. - guard !credential.requiresRefresh else { - let operation = AdaptOperation(urlRequest: urlRequest, session: session, completion: completion) - mutableState.adaptOperations.append(operation) - refresh(credential, for: session, insideLock: &mutableState) - return .adaptDeferred - } - - return .adapt(credential) - } - - switch adaptResult { - case let .adapt(credential): - var authenticatedRequest = urlRequest - authenticator.apply(credential, to: &authenticatedRequest) - completion(.success(authenticatedRequest)) - - case let .doNotAdapt(adaptError): - completion(.failure(adaptError)) - - case .adaptDeferred: - // No-op: adapt operation captured during refresh. - break - } - } - - // MARK: Retry - - public func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) { - // Do not attempt retry if there was not an original request and response from the server. - guard let urlRequest = request.request, let response = request.response else { - completion(.doNotRetry) - return - } - - // Do not attempt retry unless the `Authenticator` verifies failure was due to authentication error (i.e. 401 status code). - guard authenticator.didRequest(urlRequest, with: response, failDueToAuthenticationError: error) else { - completion(.doNotRetry) - return - } - - // Do not attempt retry if there is no credential. - guard let credential = credential else { - let error = AuthenticationError.missingCredential - completion(.doNotRetryWithError(error)) - return - } - - // Retry the request if the `Authenticator` verifies it was authenticated with a previous credential. - guard authenticator.isRequest(urlRequest, authenticatedWith: credential) else { - completion(.retry) - return - } - - $mutableState.write { mutableState in - mutableState.requestsToRetry.append(completion) - - guard !mutableState.isRefreshing else { return } - - refresh(credential, for: session, insideLock: &mutableState) - } - } - - // MARK: Refresh - - private func refresh(_ credential: Credential, for session: Session, insideLock mutableState: inout MutableState) { - guard !isRefreshExcessive(insideLock: &mutableState) else { - let error = AuthenticationError.excessiveRefresh - handleRefreshFailure(error, insideLock: &mutableState) - return - } - - mutableState.refreshTimestamps.append(ProcessInfo.processInfo.systemUptime) - mutableState.isRefreshing = true - - // Dispatch to queue to hop out of the lock in case authenticator.refresh is implemented synchronously. - queue.async { - self.authenticator.refresh(credential, for: session) { result in - self.$mutableState.write { mutableState in - switch result { - case let .success(credential): - self.handleRefreshSuccess(credential, insideLock: &mutableState) - case let .failure(error): - self.handleRefreshFailure(error, insideLock: &mutableState) - } - } - } - } - } - - private func isRefreshExcessive(insideLock mutableState: inout MutableState) -> Bool { - guard let refreshWindow = mutableState.refreshWindow else { return false } - - let refreshWindowMin = ProcessInfo.processInfo.systemUptime - refreshWindow.interval - - let refreshAttemptsWithinWindow = mutableState.refreshTimestamps.reduce(into: 0) { attempts, refreshTimestamp in - guard refreshWindowMin <= refreshTimestamp else { return } - attempts += 1 - } - - let isRefreshExcessive = refreshAttemptsWithinWindow >= refreshWindow.maximumAttempts - - return isRefreshExcessive - } - - private func handleRefreshSuccess(_ credential: Credential, insideLock mutableState: inout MutableState) { - mutableState.credential = credential - - let adaptOperations = mutableState.adaptOperations - let requestsToRetry = mutableState.requestsToRetry - - mutableState.adaptOperations.removeAll() - mutableState.requestsToRetry.removeAll() - - mutableState.isRefreshing = false - - // Dispatch to queue to hop out of the mutable state lock - queue.async { - adaptOperations.forEach { self.adapt($0.urlRequest, for: $0.session, completion: $0.completion) } - requestsToRetry.forEach { $0(.retry) } - } - } - - private func handleRefreshFailure(_ error: Error, insideLock mutableState: inout MutableState) { - let adaptOperations = mutableState.adaptOperations - let requestsToRetry = mutableState.requestsToRetry - - mutableState.adaptOperations.removeAll() - mutableState.requestsToRetry.removeAll() - - mutableState.isRefreshing = false - - // Dispatch to queue to hop out of the mutable state lock - queue.async { - adaptOperations.forEach { $0.completion(.failure(error)) } - requestsToRetry.forEach { $0(.doNotRetryWithError(error)) } - } - } -} diff --git a/Pods/Alamofire/Source/CachedResponseHandler.swift b/Pods/Alamofire/Source/CachedResponseHandler.swift deleted file mode 100644 index b6e0d4b2a..000000000 --- a/Pods/Alamofire/Source/CachedResponseHandler.swift +++ /dev/null @@ -1,91 +0,0 @@ -// -// CachedResponseHandler.swift -// -// Copyright (c) 2019 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -/// A type that handles whether the data task should store the HTTP response in the cache. -public protocol CachedResponseHandler { - /// Determines whether the HTTP response should be stored in the cache. - /// - /// The `completion` closure should be passed one of three possible options: - /// - /// 1. The cached response provided by the server (this is the most common use case). - /// 2. A modified version of the cached response (you may want to modify it in some way before caching). - /// 3. A `nil` value to prevent the cached response from being stored in the cache. - /// - /// - Parameters: - /// - task: The data task whose request resulted in the cached response. - /// - response: The cached response to potentially store in the cache. - /// - completion: The closure to execute containing cached response, a modified response, or `nil`. - func dataTask(_ task: URLSessionDataTask, - willCacheResponse response: CachedURLResponse, - completion: @escaping (CachedURLResponse?) -> Void) -} - -// MARK: - - -/// `ResponseCacher` is a convenience `CachedResponseHandler` making it easy to cache, not cache, or modify a cached -/// response. -public struct ResponseCacher { - /// Defines the behavior of the `ResponseCacher` type. - public enum Behavior { - /// Stores the cached response in the cache. - case cache - /// Prevents the cached response from being stored in the cache. - case doNotCache - /// Modifies the cached response before storing it in the cache. - case modify((URLSessionDataTask, CachedURLResponse) -> CachedURLResponse?) - } - - /// Returns a `ResponseCacher` with a follow `Behavior`. - public static let cache = ResponseCacher(behavior: .cache) - /// Returns a `ResponseCacher` with a do not follow `Behavior`. - public static let doNotCache = ResponseCacher(behavior: .doNotCache) - - /// The `Behavior` of the `ResponseCacher`. - public let behavior: Behavior - - /// Creates a `ResponseCacher` instance from the `Behavior`. - /// - /// - Parameter behavior: The `Behavior`. - public init(behavior: Behavior) { - self.behavior = behavior - } -} - -extension ResponseCacher: CachedResponseHandler { - public func dataTask(_ task: URLSessionDataTask, - willCacheResponse response: CachedURLResponse, - completion: @escaping (CachedURLResponse?) -> Void) { - switch behavior { - case .cache: - completion(response) - case .doNotCache: - completion(nil) - case let .modify(closure): - let response = closure(task, response) - completion(response) - } - } -} diff --git a/Pods/Alamofire/Source/Combine.swift b/Pods/Alamofire/Source/Combine.swift deleted file mode 100644 index a13824946..000000000 --- a/Pods/Alamofire/Source/Combine.swift +++ /dev/null @@ -1,622 +0,0 @@ -// -// Combine.swift -// -// Copyright (c) 2020 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -#if canImport(Combine) - -import Combine -import Dispatch -import Foundation - -// MARK: - DataRequest / UploadRequest - -/// A Combine `Publisher` that publishes the `DataResponse` of the provided `DataRequest`. -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) -public struct DataResponsePublisher: Publisher { - public typealias Output = DataResponse - public typealias Failure = Never - - private typealias Handler = (@escaping (_ response: DataResponse) -> Void) -> DataRequest - - private let request: DataRequest - private let responseHandler: Handler - - /// Creates an instance which will serialize responses using the provided `ResponseSerializer`. - /// - /// - Parameters: - /// - request: `DataRequest` for which to publish the response. - /// - queue: `DispatchQueue` on which the `DataResponse` value will be published. `.main` by default. - /// - serializer: `ResponseSerializer` used to produce the published `DataResponse`. - public init(_ request: DataRequest, queue: DispatchQueue, serializer: Serializer) - where Value == Serializer.SerializedObject { - self.request = request - responseHandler = { request.response(queue: queue, responseSerializer: serializer, completionHandler: $0) } - } - - /// Creates an instance which will serialize responses using the provided `DataResponseSerializerProtocol`. - /// - /// - Parameters: - /// - request: `DataRequest` for which to publish the response. - /// - queue: `DispatchQueue` on which the `DataResponse` value will be published. `.main` by default. - /// - serializer: `DataResponseSerializerProtocol` used to produce the published `DataResponse`. - public init(_ request: DataRequest, - queue: DispatchQueue, - serializer: Serializer) - where Value == Serializer.SerializedObject { - self.request = request - responseHandler = { request.response(queue: queue, responseSerializer: serializer, completionHandler: $0) } - } - - /// Publishes only the `Result` of the `DataResponse` value. - /// - /// - Returns: The `AnyPublisher` publishing the `Result` value. - public func result() -> AnyPublisher, Never> { - map { $0.result }.eraseToAnyPublisher() - } - - /// Publishes the `Result` of the `DataResponse` as a single `Value` or fail with the `AFError` instance. - /// - /// - Returns: The `AnyPublisher` publishing the stream. - public func value() -> AnyPublisher { - setFailureType(to: AFError.self).flatMap { $0.result.publisher }.eraseToAnyPublisher() - } - - public func receive(subscriber: S) where S: Subscriber, DataResponsePublisher.Failure == S.Failure, DataResponsePublisher.Output == S.Input { - subscriber.receive(subscription: Inner(request: request, - responseHandler: responseHandler, - downstream: subscriber)) - } - - private final class Inner: Subscription, Cancellable - where Downstream.Input == Output { - typealias Failure = Downstream.Failure - - @Protected - private var downstream: Downstream? - private let request: DataRequest - private let responseHandler: Handler - - init(request: DataRequest, responseHandler: @escaping Handler, downstream: Downstream) { - self.request = request - self.responseHandler = responseHandler - self.downstream = downstream - } - - func request(_ demand: Subscribers.Demand) { - assert(demand > 0) - - guard let downstream = downstream else { return } - - self.downstream = nil - responseHandler { response in - _ = downstream.receive(response) - downstream.receive(completion: .finished) - }.resume() - } - - func cancel() { - request.cancel() - downstream = nil - } - } -} - -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) -extension DataResponsePublisher where Value == Data? { - /// Creates an instance which publishes a `DataResponse` value without serialization. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) - public init(_ request: DataRequest, queue: DispatchQueue) { - self.request = request - responseHandler = { request.response(queue: queue, completionHandler: $0) } - } -} - -extension DataRequest { - /// Creates a `DataResponsePublisher` for this instance using the given `ResponseSerializer` and `DispatchQueue`. - /// - /// - Parameters: - /// - serializer: `ResponseSerializer` used to serialize response `Data`. - /// - queue: `DispatchQueue` on which the `DataResponse` will be published. `.main` by default. - /// - /// - Returns: The `DataResponsePublisher`. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) - public func publishResponse(using serializer: Serializer, on queue: DispatchQueue = .main) -> DataResponsePublisher - where Serializer.SerializedObject == T { - DataResponsePublisher(self, queue: queue, serializer: serializer) - } - - /// Creates a `DataResponsePublisher` for this instance and uses a `DataResponseSerializer` to serialize the - /// response. - /// - /// - Parameters: - /// - queue: `DispatchQueue` on which the `DataResponse` will be published. `.main` by default. - /// - preprocessor: `DataPreprocessor` which filters the `Data` before serialization. `PassthroughPreprocessor()` - /// by default. - /// - emptyResponseCodes: `Set` of HTTP status codes for which empty responses are allowed. `[204, 205]` by - /// default. - /// - emptyRequestMethods: `Set` of `HTTPMethod`s for which empty responses are allowed, regardless of - /// status code. `[.head]` by default. - /// - Returns: The `DataResponsePublisher`. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) - public func publishData(queue: DispatchQueue = .main, - preprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor, - emptyResponseCodes: Set = DataResponseSerializer.defaultEmptyResponseCodes, - emptyRequestMethods: Set = DataResponseSerializer.defaultEmptyRequestMethods) -> DataResponsePublisher { - publishResponse(using: DataResponseSerializer(dataPreprocessor: preprocessor, - emptyResponseCodes: emptyResponseCodes, - emptyRequestMethods: emptyRequestMethods), - on: queue) - } - - /// Creates a `DataResponsePublisher` for this instance and uses a `StringResponseSerializer` to serialize the - /// response. - /// - /// - Parameters: - /// - queue: `DispatchQueue` on which the `DataResponse` will be published. `.main` by default. - /// - preprocessor: `DataPreprocessor` which filters the `Data` before serialization. `PassthroughPreprocessor()` - /// by default. - /// - encoding: `String.Encoding` to parse the response. `nil` by default, in which case the encoding - /// will be determined by the server response, falling back to the default HTTP character - /// set, `ISO-8859-1`. - /// - emptyResponseCodes: `Set` of HTTP status codes for which empty responses are allowed. `[204, 205]` by - /// default. - /// - emptyRequestMethods: `Set` of `HTTPMethod`s for which empty responses are allowed, regardless of - /// status code. `[.head]` by default. - /// - /// - Returns: The `DataResponsePublisher`. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) - public func publishString(queue: DispatchQueue = .main, - preprocessor: DataPreprocessor = StringResponseSerializer.defaultDataPreprocessor, - encoding: String.Encoding? = nil, - emptyResponseCodes: Set = StringResponseSerializer.defaultEmptyResponseCodes, - emptyRequestMethods: Set = StringResponseSerializer.defaultEmptyRequestMethods) -> DataResponsePublisher { - publishResponse(using: StringResponseSerializer(dataPreprocessor: preprocessor, - encoding: encoding, - emptyResponseCodes: emptyResponseCodes, - emptyRequestMethods: emptyRequestMethods), - on: queue) - } - - /// Creates a `DataResponsePublisher` for this instance and uses a `DecodableResponseSerializer` to serialize the - /// response. - /// - /// - Parameters: - /// - type: `Decodable` type to which to decode response `Data`. Inferred from the context by default. - /// - queue: `DispatchQueue` on which the `DataResponse` will be published. `.main` by default. - /// - preprocessor: `DataPreprocessor` which filters the `Data` before serialization. `PassthroughPreprocessor()` - /// by default. - /// - decoder: `DataDecoder` instance used to decode response `Data`. `JSONDecoder()` by default. - /// - emptyResponseCodes: `Set` of HTTP status codes for which empty responses are allowed. `[204, 205]` by - /// default. - /// - emptyRequestMethods: `Set` of `HTTPMethod`s for which empty responses are allowed, regardless of - /// status code. `[.head]` by default. - /// - /// - Returns: The `DataResponsePublisher`. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) - public func publishDecodable(type: T.Type = T.self, - queue: DispatchQueue = .main, - preprocessor: DataPreprocessor = DecodableResponseSerializer.defaultDataPreprocessor, - decoder: DataDecoder = JSONDecoder(), - emptyResponseCodes: Set = DecodableResponseSerializer.defaultEmptyResponseCodes, - emptyResponseMethods: Set = DecodableResponseSerializer.defaultEmptyRequestMethods) -> DataResponsePublisher { - publishResponse(using: DecodableResponseSerializer(dataPreprocessor: preprocessor, - decoder: decoder, - emptyResponseCodes: emptyResponseCodes, - emptyRequestMethods: emptyResponseMethods), - on: queue) - } - - /// Creates a `DataResponsePublisher` for this instance which does not serialize the response before publishing. - /// - /// - queue: `DispatchQueue` on which the `DataResponse` will be published. `.main` by default. - /// - /// - Returns: The `DataResponsePublisher`. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) - public func publishUnserialized(queue: DispatchQueue = .main) -> DataResponsePublisher { - DataResponsePublisher(self, queue: queue) - } -} - -// A Combine `Publisher` that publishes a sequence of `Stream` values received by the provided `DataStreamRequest`. -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) -public struct DataStreamPublisher: Publisher { - public typealias Output = DataStreamRequest.Stream - public typealias Failure = Never - - private typealias Handler = (@escaping DataStreamRequest.Handler) -> DataStreamRequest - - private let request: DataStreamRequest - private let streamHandler: Handler - - /// Creates an instance which will serialize responses using the provided `DataStreamSerializer`. - /// - /// - Parameters: - /// - request: `DataStreamRequest` for which to publish the response. - /// - queue: `DispatchQueue` on which the `Stream` values will be published. `.main` by - /// default. - /// - serializer: `DataStreamSerializer` used to produce the published `Stream` values. - public init(_ request: DataStreamRequest, queue: DispatchQueue, serializer: Serializer) - where Value == Serializer.SerializedObject { - self.request = request - streamHandler = { request.responseStream(using: serializer, on: queue, stream: $0) } - } - - /// Publishes only the `Result` of the `DataStreamRequest.Stream`'s `Event`s. - /// - /// - Returns: The `AnyPublisher` publishing the `Result` value. - public func result() -> AnyPublisher, Never> { - compactMap { stream in - switch stream.event { - case let .stream(result): - return result - // If the stream has completed with an error, send the error value downstream as a `.failure`. - case let .complete(completion): - return completion.error.map(Result.failure) - } - } - .eraseToAnyPublisher() - } - - /// Publishes the streamed values of the `DataStreamRequest.Stream` as a sequence of `Value` or fail with the - /// `AFError` instance. - /// - /// - Returns: The `AnyPublisher` publishing the stream. - public func value() -> AnyPublisher { - result().setFailureType(to: AFError.self).flatMap { $0.publisher }.eraseToAnyPublisher() - } - - public func receive(subscriber: S) where S: Subscriber, DataStreamPublisher.Failure == S.Failure, DataStreamPublisher.Output == S.Input { - subscriber.receive(subscription: Inner(request: request, - streamHandler: streamHandler, - downstream: subscriber)) - } - - private final class Inner: Subscription, Cancellable - where Downstream.Input == Output { - typealias Failure = Downstream.Failure - - @Protected - private var downstream: Downstream? - private let request: DataStreamRequest - private let streamHandler: Handler - - init(request: DataStreamRequest, streamHandler: @escaping Handler, downstream: Downstream) { - self.request = request - self.streamHandler = streamHandler - self.downstream = downstream - } - - func request(_ demand: Subscribers.Demand) { - assert(demand > 0) - - guard let downstream = downstream else { return } - - self.downstream = nil - streamHandler { stream in - _ = downstream.receive(stream) - if case .complete = stream.event { - downstream.receive(completion: .finished) - } - }.resume() - } - - func cancel() { - request.cancel() - downstream = nil - } - } -} - -extension DataStreamRequest { - /// Creates a `DataStreamPublisher` for this instance using the given `DataStreamSerializer` and `DispatchQueue`. - /// - /// - Parameters: - /// - serializer: `DataStreamSerializer` used to serialize the streamed `Data`. - /// - queue: `DispatchQueue` on which the `DataRequest.Stream` values will be published. `.main` by default. - /// - Returns: The `DataStreamPublisher`. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) - public func publishStream(using serializer: Serializer, - on queue: DispatchQueue = .main) -> DataStreamPublisher { - DataStreamPublisher(self, queue: queue, serializer: serializer) - } - - /// Creates a `DataStreamPublisher` for this instance which uses a `PassthroughStreamSerializer` to stream `Data` - /// unserialized. - /// - /// - Parameters: - /// - queue: `DispatchQueue` on which the `DataRequest.Stream` values will be published. `.main` by default. - /// - Returns: The `DataStreamPublisher`. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) - public func publishData(queue: DispatchQueue = .main) -> DataStreamPublisher { - publishStream(using: PassthroughStreamSerializer(), on: queue) - } - - /// Creates a `DataStreamPublisher` for this instance which uses a `StringStreamSerializer` to serialize stream - /// `Data` values into `String` values. - /// - /// - Parameters: - /// - queue: `DispatchQueue` on which the `DataRequest.Stream` values will be published. `.main` by default. - /// - Returns: The `DataStreamPublisher`. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) - public func publishString(queue: DispatchQueue = .main) -> DataStreamPublisher { - publishStream(using: StringStreamSerializer(), on: queue) - } - - /// Creates a `DataStreamPublisher` for this instance which uses a `DecodableStreamSerializer` with the provided - /// parameters to serialize stream `Data` values into the provided type. - /// - /// - Parameters: - /// - type: `Decodable` type to which to decode stream `Data`. Inferred from the context by default. - /// - queue: `DispatchQueue` on which the `DataRequest.Stream` values will be published. `.main` by default. - /// - decoder: `DataDecoder` instance used to decode stream `Data`. `JSONDecoder()` by default. - /// - preprocessor: `DataPreprocessor` which filters incoming stream `Data` before serialization. - /// `PassthroughPreprocessor()` by default. - /// - Returns: The `DataStreamPublisher`. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) - public func publishDecodable(type: T.Type = T.self, - queue: DispatchQueue = .main, - decoder: DataDecoder = JSONDecoder(), - preprocessor: DataPreprocessor = PassthroughPreprocessor()) -> DataStreamPublisher { - publishStream(using: DecodableStreamSerializer(decoder: decoder, - dataPreprocessor: preprocessor), - on: queue) - } -} - -/// A Combine `Publisher` that publishes the `DownloadResponse` of the provided `DownloadRequest`. -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) -public struct DownloadResponsePublisher: Publisher { - public typealias Output = DownloadResponse - public typealias Failure = Never - - private typealias Handler = (@escaping (_ response: DownloadResponse) -> Void) -> DownloadRequest - - private let request: DownloadRequest - private let responseHandler: Handler - - /// Creates an instance which will serialize responses using the provided `ResponseSerializer`. - /// - /// - Parameters: - /// - request: `DownloadRequest` for which to publish the response. - /// - queue: `DispatchQueue` on which the `DownloadResponse` value will be published. `.main` by default. - /// - serializer: `ResponseSerializer` used to produce the published `DownloadResponse`. - public init(_ request: DownloadRequest, queue: DispatchQueue, serializer: Serializer) - where Value == Serializer.SerializedObject { - self.request = request - responseHandler = { request.response(queue: queue, responseSerializer: serializer, completionHandler: $0) } - } - - /// Creates an instance which will serialize responses using the provided `DownloadResponseSerializerProtocol` value. - /// - /// - Parameters: - /// - request: `DownloadRequest` for which to publish the response. - /// - queue: `DispatchQueue` on which the `DataResponse` value will be published. `.main` by default. - /// - serializer: `DownloadResponseSerializerProtocol` used to produce the published `DownloadResponse`. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) - public init(_ request: DownloadRequest, - queue: DispatchQueue, - serializer: Serializer) - where Value == Serializer.SerializedObject { - self.request = request - responseHandler = { request.response(queue: queue, responseSerializer: serializer, completionHandler: $0) } - } - - /// Publishes only the `Result` of the `DownloadResponse` value. - /// - /// - Returns: The `AnyPublisher` publishing the `Result` value. - public func result() -> AnyPublisher, Never> { - map { $0.result }.eraseToAnyPublisher() - } - - /// Publishes the `Result` of the `DownloadResponse` as a single `Value` or fail with the `AFError` instance. - /// - /// - Returns: The `AnyPublisher` publishing the stream. - public func value() -> AnyPublisher { - setFailureType(to: AFError.self).flatMap { $0.result.publisher }.eraseToAnyPublisher() - } - - public func receive(subscriber: S) where S: Subscriber, DownloadResponsePublisher.Failure == S.Failure, DownloadResponsePublisher.Output == S.Input { - subscriber.receive(subscription: Inner(request: request, - responseHandler: responseHandler, - downstream: subscriber)) - } - - private final class Inner: Subscription, Cancellable - where Downstream.Input == Output { - typealias Failure = Downstream.Failure - - @Protected - private var downstream: Downstream? - private let request: DownloadRequest - private let responseHandler: Handler - - init(request: DownloadRequest, responseHandler: @escaping Handler, downstream: Downstream) { - self.request = request - self.responseHandler = responseHandler - self.downstream = downstream - } - - func request(_ demand: Subscribers.Demand) { - assert(demand > 0) - - guard let downstream = downstream else { return } - - self.downstream = nil - responseHandler { response in - _ = downstream.receive(response) - downstream.receive(completion: .finished) - }.resume() - } - - func cancel() { - request.cancel() - downstream = nil - } - } -} - -extension DownloadRequest { - /// Creates a `DownloadResponsePublisher` for this instance using the given `ResponseSerializer` and `DispatchQueue`. - /// - /// - Parameters: - /// - serializer: `ResponseSerializer` used to serialize the response `Data` from disk. - /// - queue: `DispatchQueue` on which the `DownloadResponse` will be published.`.main` by default. - /// - /// - Returns: The `DownloadResponsePublisher`. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) - public func publishResponse(using serializer: Serializer, on queue: DispatchQueue = .main) -> DownloadResponsePublisher - where Serializer.SerializedObject == T { - DownloadResponsePublisher(self, queue: queue, serializer: serializer) - } - - /// Creates a `DownloadResponsePublisher` for this instance using the given `DownloadResponseSerializerProtocol` and - /// `DispatchQueue`. - /// - /// - Parameters: - /// - serializer: `DownloadResponseSerializer` used to serialize the response `Data` from disk. - /// - queue: `DispatchQueue` on which the `DownloadResponse` will be published.`.main` by default. - /// - /// - Returns: The `DownloadResponsePublisher`. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) - public func publishResponse(using serializer: Serializer, on queue: DispatchQueue = .main) -> DownloadResponsePublisher - where Serializer.SerializedObject == T { - DownloadResponsePublisher(self, queue: queue, serializer: serializer) - } - - /// Creates a `DownloadResponsePublisher` for this instance and uses a `URLResponseSerializer` to serialize the - /// response. - /// - /// - Parameter queue: `DispatchQueue` on which the `DownloadResponse` will be published. `.main` by default. - /// - /// - Returns: The `DownloadResponsePublisher`. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) - public func publishURL(queue: DispatchQueue = .main) -> DownloadResponsePublisher { - publishResponse(using: URLResponseSerializer(), on: queue) - } - - /// Creates a `DownloadResponsePublisher` for this instance and uses a `DataResponseSerializer` to serialize the - /// response. - /// - /// - Parameters: - /// - queue: `DispatchQueue` on which the `DownloadResponse` will be published. `.main` by default. - /// - preprocessor: `DataPreprocessor` which filters the `Data` before serialization. `PassthroughPreprocessor()` - /// by default. - /// - emptyResponseCodes: `Set` of HTTP status codes for which empty responses are allowed. `[204, 205]` by - /// default. - /// - emptyRequestMethods: `Set` of `HTTPMethod`s for which empty responses are allowed, regardless of - /// status code. `[.head]` by default. - /// - /// - Returns: The `DownloadResponsePublisher`. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) - public func publishData(queue: DispatchQueue = .main, - preprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor, - emptyResponseCodes: Set = DataResponseSerializer.defaultEmptyResponseCodes, - emptyRequestMethods: Set = DataResponseSerializer.defaultEmptyRequestMethods) -> DownloadResponsePublisher { - publishResponse(using: DataResponseSerializer(dataPreprocessor: preprocessor, - emptyResponseCodes: emptyResponseCodes, - emptyRequestMethods: emptyRequestMethods), - on: queue) - } - - /// Creates a `DataResponsePublisher` for this instance and uses a `StringResponseSerializer` to serialize the - /// response. - /// - /// - Parameters: - /// - queue: `DispatchQueue` on which the `DataResponse` will be published. `.main` by default. - /// - preprocessor: `DataPreprocessor` which filters the `Data` before serialization. `PassthroughPreprocessor()` - /// by default. - /// - encoding: `String.Encoding` to parse the response. `nil` by default, in which case the encoding - /// will be determined by the server response, falling back to the default HTTP character - /// set, `ISO-8859-1`. - /// - emptyResponseCodes: `Set` of HTTP status codes for which empty responses are allowed. `[204, 205]` by - /// default. - /// - emptyRequestMethods: `Set` of `HTTPMethod`s for which empty responses are allowed, regardless of - /// status code. `[.head]` by default. - /// - /// - Returns: The `DownloadResponsePublisher`. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) - public func publishString(queue: DispatchQueue = .main, - preprocessor: DataPreprocessor = StringResponseSerializer.defaultDataPreprocessor, - encoding: String.Encoding? = nil, - emptyResponseCodes: Set = StringResponseSerializer.defaultEmptyResponseCodes, - emptyRequestMethods: Set = StringResponseSerializer.defaultEmptyRequestMethods) -> DownloadResponsePublisher { - publishResponse(using: StringResponseSerializer(dataPreprocessor: preprocessor, - encoding: encoding, - emptyResponseCodes: emptyResponseCodes, - emptyRequestMethods: emptyRequestMethods), - on: queue) - } - - /// Creates a `DataResponsePublisher` for this instance and uses a `DecodableResponseSerializer` to serialize the - /// response. - /// - /// - Parameters: - /// - type: `Decodable` type to which to decode response `Data`. Inferred from the context by default. - /// - queue: `DispatchQueue` on which the `DataResponse` will be published. `.main` by default. - /// - preprocessor: `DataPreprocessor` which filters the `Data` before serialization. `PassthroughPreprocessor()` - /// by default. - /// - decoder: `DataDecoder` instance used to decode response `Data`. `JSONDecoder()` by default. - /// - emptyResponseCodes: `Set` of HTTP status codes for which empty responses are allowed. `[204, 205]` by - /// default. - /// - emptyRequestMethods: `Set` of `HTTPMethod`s for which empty responses are allowed, regardless of - /// status code. `[.head]` by default. - /// - /// - Returns: The `DownloadResponsePublisher`. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) - public func publishDecodable(type: T.Type = T.self, - queue: DispatchQueue = .main, - preprocessor: DataPreprocessor = DecodableResponseSerializer.defaultDataPreprocessor, - decoder: DataDecoder = JSONDecoder(), - emptyResponseCodes: Set = DecodableResponseSerializer.defaultEmptyResponseCodes, - emptyResponseMethods: Set = DecodableResponseSerializer.defaultEmptyRequestMethods) -> DownloadResponsePublisher { - publishResponse(using: DecodableResponseSerializer(dataPreprocessor: preprocessor, - decoder: decoder, - emptyResponseCodes: emptyResponseCodes, - emptyRequestMethods: emptyResponseMethods), - on: queue) - } -} - -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) -extension DownloadResponsePublisher where Value == URL? { - /// Creates an instance which publishes a `DownloadResponse` value without serialization. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) - public init(_ request: DownloadRequest, queue: DispatchQueue) { - self.request = request - responseHandler = { request.response(queue: queue, completionHandler: $0) } - } -} - -extension DownloadRequest { - /// Creates a `DownloadResponsePublisher` for this instance which does not serialize the response before publishing. - /// - /// - Parameter queue: `DispatchQueue` on which the `DownloadResponse` will be published. `.main` by default. - /// - /// - Returns: The `DownloadResponsePublisher`. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) - public func publishUnserialized(on queue: DispatchQueue = .main) -> DownloadResponsePublisher { - DownloadResponsePublisher(self, queue: queue) - } -} - -#endif diff --git a/Pods/Alamofire/Source/DispatchQueue+Alamofire.swift b/Pods/Alamofire/Source/DispatchQueue+Alamofire.swift deleted file mode 100644 index 10cd273ee..000000000 --- a/Pods/Alamofire/Source/DispatchQueue+Alamofire.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// DispatchQueue+Alamofire.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Dispatch -import Foundation - -extension DispatchQueue { - /// Execute the provided closure after a `TimeInterval`. - /// - /// - Parameters: - /// - delay: `TimeInterval` to delay execution. - /// - closure: Closure to execute. - func after(_ delay: TimeInterval, execute closure: @escaping () -> Void) { - asyncAfter(deadline: .now() + delay, execute: closure) - } -} diff --git a/Pods/Alamofire/Source/EventMonitor.swift b/Pods/Alamofire/Source/EventMonitor.swift deleted file mode 100644 index 3b096712f..000000000 --- a/Pods/Alamofire/Source/EventMonitor.swift +++ /dev/null @@ -1,892 +0,0 @@ -// -// EventMonitor.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -/// Protocol outlining the lifetime events inside Alamofire. It includes both events received from the various -/// `URLSession` delegate protocols as well as various events from the lifetime of `Request` and its subclasses. -public protocol EventMonitor { - /// The `DispatchQueue` onto which Alamofire's root `CompositeEventMonitor` will dispatch events. `.main` by default. - var queue: DispatchQueue { get } - - // MARK: - URLSession Events - - // MARK: URLSessionDelegate Events - - /// Event called during `URLSessionDelegate`'s `urlSession(_:didBecomeInvalidWithError:)` method. - func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) - - // MARK: URLSessionTaskDelegate Events - - /// Event called during `URLSessionTaskDelegate`'s `urlSession(_:task:didReceive:completionHandler:)` method. - func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge) - - /// Event called during `URLSessionTaskDelegate`'s `urlSession(_:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:)` method. - func urlSession(_ session: URLSession, - task: URLSessionTask, - didSendBodyData bytesSent: Int64, - totalBytesSent: Int64, - totalBytesExpectedToSend: Int64) - - /// Event called during `URLSessionTaskDelegate`'s `urlSession(_:task:needNewBodyStream:)` method. - func urlSession(_ session: URLSession, taskNeedsNewBodyStream task: URLSessionTask) - - /// Event called during `URLSessionTaskDelegate`'s `urlSession(_:task:willPerformHTTPRedirection:newRequest:completionHandler:)` method. - func urlSession(_ session: URLSession, - task: URLSessionTask, - willPerformHTTPRedirection response: HTTPURLResponse, - newRequest request: URLRequest) - - /// Event called during `URLSessionTaskDelegate`'s `urlSession(_:task:didFinishCollecting:)` method. - func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) - - /// Event called during `URLSessionTaskDelegate`'s `urlSession(_:task:didCompleteWithError:)` method. - func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) - - /// Event called during `URLSessionTaskDelegate`'s `urlSession(_:taskIsWaitingForConnectivity:)` method. - @available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) - func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) - - // MARK: URLSessionDataDelegate Events - - /// Event called during `URLSessionDataDelegate`'s `urlSession(_:dataTask:didReceive:)` method. - func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) - - /// Event called during `URLSessionDataDelegate`'s `urlSession(_:dataTask:willCacheResponse:completionHandler:)` method. - func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, willCacheResponse proposedResponse: CachedURLResponse) - - // MARK: URLSessionDownloadDelegate Events - - /// Event called during `URLSessionDownloadDelegate`'s `urlSession(_:downloadTask:didResumeAtOffset:expectedTotalBytes:)` method. - func urlSession(_ session: URLSession, - downloadTask: URLSessionDownloadTask, - didResumeAtOffset fileOffset: Int64, - expectedTotalBytes: Int64) - - /// Event called during `URLSessionDownloadDelegate`'s `urlSession(_:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:)` method. - func urlSession(_ session: URLSession, - downloadTask: URLSessionDownloadTask, - didWriteData bytesWritten: Int64, - totalBytesWritten: Int64, - totalBytesExpectedToWrite: Int64) - - /// Event called during `URLSessionDownloadDelegate`'s `urlSession(_:downloadTask:didFinishDownloadingTo:)` method. - func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) - - // MARK: - Request Events - - /// Event called when a `URLRequest` is first created for a `Request`. If a `RequestAdapter` is active, the - /// `URLRequest` will be adapted before being issued. - func request(_ request: Request, didCreateInitialURLRequest urlRequest: URLRequest) - - /// Event called when the attempt to create a `URLRequest` from a `Request`'s original `URLRequestConvertible` value fails. - func request(_ request: Request, didFailToCreateURLRequestWithError error: AFError) - - /// Event called when a `RequestAdapter` adapts the `Request`'s initial `URLRequest`. - func request(_ request: Request, didAdaptInitialRequest initialRequest: URLRequest, to adaptedRequest: URLRequest) - - /// Event called when a `RequestAdapter` fails to adapt the `Request`'s initial `URLRequest`. - func request(_ request: Request, didFailToAdaptURLRequest initialRequest: URLRequest, withError error: AFError) - - /// Event called when a final `URLRequest` is created for a `Request`. - func request(_ request: Request, didCreateURLRequest urlRequest: URLRequest) - - /// Event called when a `URLSessionTask` subclass instance is created for a `Request`. - func request(_ request: Request, didCreateTask task: URLSessionTask) - - /// Event called when a `Request` receives a `URLSessionTaskMetrics` value. - func request(_ request: Request, didGatherMetrics metrics: URLSessionTaskMetrics) - - /// Event called when a `Request` fails due to an error created by Alamofire. e.g. When certificate pinning fails. - func request(_ request: Request, didFailTask task: URLSessionTask, earlyWithError error: AFError) - - /// Event called when a `Request`'s task completes, possibly with an error. A `Request` may receive this event - /// multiple times if it is retried. - func request(_ request: Request, didCompleteTask task: URLSessionTask, with error: AFError?) - - /// Event called when a `Request` is about to be retried. - func requestIsRetrying(_ request: Request) - - /// Event called when a `Request` finishes and response serializers are being called. - func requestDidFinish(_ request: Request) - - /// Event called when a `Request` receives a `resume` call. - func requestDidResume(_ request: Request) - - /// Event called when a `Request`'s associated `URLSessionTask` is resumed. - func request(_ request: Request, didResumeTask task: URLSessionTask) - - /// Event called when a `Request` receives a `suspend` call. - func requestDidSuspend(_ request: Request) - - /// Event called when a `Request`'s associated `URLSessionTask` is suspended. - func request(_ request: Request, didSuspendTask task: URLSessionTask) - - /// Event called when a `Request` receives a `cancel` call. - func requestDidCancel(_ request: Request) - - /// Event called when a `Request`'s associated `URLSessionTask` is cancelled. - func request(_ request: Request, didCancelTask task: URLSessionTask) - - // MARK: DataRequest Events - - /// Event called when a `DataRequest` calls a `Validation`. - func request(_ request: DataRequest, - didValidateRequest urlRequest: URLRequest?, - response: HTTPURLResponse, - data: Data?, - withResult result: Request.ValidationResult) - - /// Event called when a `DataRequest` creates a `DataResponse` value without calling a `ResponseSerializer`. - func request(_ request: DataRequest, didParseResponse response: DataResponse) - - /// Event called when a `DataRequest` calls a `ResponseSerializer` and creates a generic `DataResponse`. - func request(_ request: DataRequest, didParseResponse response: DataResponse) - - // MARK: DataStreamRequest Events - - /// Event called when a `DataStreamRequest` calls a `Validation` closure. - /// - /// - Parameters: - /// - request: `DataStreamRequest` which is calling the `Validation`. - /// - urlRequest: `URLRequest` of the request being validated. - /// - response: `HTTPURLResponse` of the request being validated. - /// - result: Produced `ValidationResult`. - func request(_ request: DataStreamRequest, - didValidateRequest urlRequest: URLRequest?, - response: HTTPURLResponse, - withResult result: Request.ValidationResult) - - /// Event called when a `DataStreamSerializer` produces a value from streamed `Data`. - /// - /// - Parameters: - /// - request: `DataStreamRequest` for which the value was serialized. - /// - result: `Result` of the serialization attempt. - func request(_ request: DataStreamRequest, didParseStream result: Result) - - // MARK: UploadRequest Events - - /// Event called when an `UploadRequest` creates its `Uploadable` value, indicating the type of upload it represents. - func request(_ request: UploadRequest, didCreateUploadable uploadable: UploadRequest.Uploadable) - - /// Event called when an `UploadRequest` failed to create its `Uploadable` value due to an error. - func request(_ request: UploadRequest, didFailToCreateUploadableWithError error: AFError) - - /// Event called when an `UploadRequest` provides the `InputStream` from its `Uploadable` value. This only occurs if - /// the `InputStream` does not wrap a `Data` value or file `URL`. - func request(_ request: UploadRequest, didProvideInputStream stream: InputStream) - - // MARK: DownloadRequest Events - - /// Event called when a `DownloadRequest`'s `URLSessionDownloadTask` finishes and the temporary file has been moved. - func request(_ request: DownloadRequest, didFinishDownloadingUsing task: URLSessionTask, with result: Result) - - /// Event called when a `DownloadRequest`'s `Destination` closure is called and creates the destination URL the - /// downloaded file will be moved to. - func request(_ request: DownloadRequest, didCreateDestinationURL url: URL) - - /// Event called when a `DownloadRequest` calls a `Validation`. - func request(_ request: DownloadRequest, - didValidateRequest urlRequest: URLRequest?, - response: HTTPURLResponse, - fileURL: URL?, - withResult result: Request.ValidationResult) - - /// Event called when a `DownloadRequest` creates a `DownloadResponse` without calling a `ResponseSerializer`. - func request(_ request: DownloadRequest, didParseResponse response: DownloadResponse) - - /// Event called when a `DownloadRequest` calls a `DownloadResponseSerializer` and creates a generic `DownloadResponse` - func request(_ request: DownloadRequest, didParseResponse response: DownloadResponse) -} - -extension EventMonitor { - /// The default queue on which `CompositeEventMonitor`s will call the `EventMonitor` methods. `.main` by default. - public var queue: DispatchQueue { .main } - - // MARK: Default Implementations - - public func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) {} - public func urlSession(_ session: URLSession, - task: URLSessionTask, - didReceive challenge: URLAuthenticationChallenge) {} - public func urlSession(_ session: URLSession, - task: URLSessionTask, - didSendBodyData bytesSent: Int64, - totalBytesSent: Int64, - totalBytesExpectedToSend: Int64) {} - public func urlSession(_ session: URLSession, taskNeedsNewBodyStream task: URLSessionTask) {} - public func urlSession(_ session: URLSession, - task: URLSessionTask, - willPerformHTTPRedirection response: HTTPURLResponse, - newRequest request: URLRequest) {} - public func urlSession(_ session: URLSession, - task: URLSessionTask, - didFinishCollecting metrics: URLSessionTaskMetrics) {} - public func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {} - public func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) {} - public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {} - public func urlSession(_ session: URLSession, - dataTask: URLSessionDataTask, - willCacheResponse proposedResponse: CachedURLResponse) {} - public func urlSession(_ session: URLSession, - downloadTask: URLSessionDownloadTask, - didResumeAtOffset fileOffset: Int64, - expectedTotalBytes: Int64) {} - public func urlSession(_ session: URLSession, - downloadTask: URLSessionDownloadTask, - didWriteData bytesWritten: Int64, - totalBytesWritten: Int64, - totalBytesExpectedToWrite: Int64) {} - public func urlSession(_ session: URLSession, - downloadTask: URLSessionDownloadTask, - didFinishDownloadingTo location: URL) {} - public func request(_ request: Request, didCreateInitialURLRequest urlRequest: URLRequest) {} - public func request(_ request: Request, didFailToCreateURLRequestWithError error: AFError) {} - public func request(_ request: Request, - didAdaptInitialRequest initialRequest: URLRequest, - to adaptedRequest: URLRequest) {} - public func request(_ request: Request, - didFailToAdaptURLRequest initialRequest: URLRequest, - withError error: AFError) {} - public func request(_ request: Request, didCreateURLRequest urlRequest: URLRequest) {} - public func request(_ request: Request, didCreateTask task: URLSessionTask) {} - public func request(_ request: Request, didGatherMetrics metrics: URLSessionTaskMetrics) {} - public func request(_ request: Request, didFailTask task: URLSessionTask, earlyWithError error: AFError) {} - public func request(_ request: Request, didCompleteTask task: URLSessionTask, with error: AFError?) {} - public func requestIsRetrying(_ request: Request) {} - public func requestDidFinish(_ request: Request) {} - public func requestDidResume(_ request: Request) {} - public func request(_ request: Request, didResumeTask task: URLSessionTask) {} - public func requestDidSuspend(_ request: Request) {} - public func request(_ request: Request, didSuspendTask task: URLSessionTask) {} - public func requestDidCancel(_ request: Request) {} - public func request(_ request: Request, didCancelTask task: URLSessionTask) {} - public func request(_ request: DataRequest, - didValidateRequest urlRequest: URLRequest?, - response: HTTPURLResponse, - data: Data?, - withResult result: Request.ValidationResult) {} - public func request(_ request: DataRequest, didParseResponse response: DataResponse) {} - public func request(_ request: DataRequest, didParseResponse response: DataResponse) {} - public func request(_ request: DataStreamRequest, - didValidateRequest urlRequest: URLRequest?, - response: HTTPURLResponse, - withResult result: Request.ValidationResult) {} - public func request(_ request: DataStreamRequest, didParseStream result: Result) {} - public func request(_ request: UploadRequest, didCreateUploadable uploadable: UploadRequest.Uploadable) {} - public func request(_ request: UploadRequest, didFailToCreateUploadableWithError error: AFError) {} - public func request(_ request: UploadRequest, didProvideInputStream stream: InputStream) {} - public func request(_ request: DownloadRequest, didFinishDownloadingUsing task: URLSessionTask, with result: Result) {} - public func request(_ request: DownloadRequest, didCreateDestinationURL url: URL) {} - public func request(_ request: DownloadRequest, - didValidateRequest urlRequest: URLRequest?, - response: HTTPURLResponse, - fileURL: URL?, - withResult result: Request.ValidationResult) {} - public func request(_ request: DownloadRequest, didParseResponse response: DownloadResponse) {} - public func request(_ request: DownloadRequest, didParseResponse response: DownloadResponse) {} -} - -/// An `EventMonitor` which can contain multiple `EventMonitor`s and calls their methods on their queues. -public final class CompositeEventMonitor: EventMonitor { - public let queue = DispatchQueue(label: "org.alamofire.compositeEventMonitor", qos: .utility) - - let monitors: [EventMonitor] - - init(monitors: [EventMonitor]) { - self.monitors = monitors - } - - func performEvent(_ event: @escaping (EventMonitor) -> Void) { - queue.async { - for monitor in self.monitors { - monitor.queue.async { event(monitor) } - } - } - } - - public func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) { - performEvent { $0.urlSession(session, didBecomeInvalidWithError: error) } - } - - public func urlSession(_ session: URLSession, - task: URLSessionTask, - didReceive challenge: URLAuthenticationChallenge) { - performEvent { $0.urlSession(session, task: task, didReceive: challenge) } - } - - public func urlSession(_ session: URLSession, - task: URLSessionTask, - didSendBodyData bytesSent: Int64, - totalBytesSent: Int64, - totalBytesExpectedToSend: Int64) { - performEvent { - $0.urlSession(session, - task: task, - didSendBodyData: bytesSent, - totalBytesSent: totalBytesSent, - totalBytesExpectedToSend: totalBytesExpectedToSend) - } - } - - public func urlSession(_ session: URLSession, taskNeedsNewBodyStream task: URLSessionTask) { - performEvent { - $0.urlSession(session, taskNeedsNewBodyStream: task) - } - } - - public func urlSession(_ session: URLSession, - task: URLSessionTask, - willPerformHTTPRedirection response: HTTPURLResponse, - newRequest request: URLRequest) { - performEvent { - $0.urlSession(session, - task: task, - willPerformHTTPRedirection: response, - newRequest: request) - } - } - - public func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) { - performEvent { $0.urlSession(session, task: task, didFinishCollecting: metrics) } - } - - public func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { - performEvent { $0.urlSession(session, task: task, didCompleteWithError: error) } - } - - @available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) - public func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) { - performEvent { $0.urlSession(session, taskIsWaitingForConnectivity: task) } - } - - public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { - performEvent { $0.urlSession(session, dataTask: dataTask, didReceive: data) } - } - - public func urlSession(_ session: URLSession, - dataTask: URLSessionDataTask, - willCacheResponse proposedResponse: CachedURLResponse) { - performEvent { $0.urlSession(session, dataTask: dataTask, willCacheResponse: proposedResponse) } - } - - public func urlSession(_ session: URLSession, - downloadTask: URLSessionDownloadTask, - didResumeAtOffset fileOffset: Int64, - expectedTotalBytes: Int64) { - performEvent { - $0.urlSession(session, - downloadTask: downloadTask, - didResumeAtOffset: fileOffset, - expectedTotalBytes: expectedTotalBytes) - } - } - - public func urlSession(_ session: URLSession, - downloadTask: URLSessionDownloadTask, - didWriteData bytesWritten: Int64, - totalBytesWritten: Int64, - totalBytesExpectedToWrite: Int64) { - performEvent { - $0.urlSession(session, - downloadTask: downloadTask, - didWriteData: bytesWritten, - totalBytesWritten: totalBytesWritten, - totalBytesExpectedToWrite: totalBytesExpectedToWrite) - } - } - - public func urlSession(_ session: URLSession, - downloadTask: URLSessionDownloadTask, - didFinishDownloadingTo location: URL) { - performEvent { $0.urlSession(session, downloadTask: downloadTask, didFinishDownloadingTo: location) } - } - - public func request(_ request: Request, didCreateInitialURLRequest urlRequest: URLRequest) { - performEvent { $0.request(request, didCreateInitialURLRequest: urlRequest) } - } - - public func request(_ request: Request, didFailToCreateURLRequestWithError error: AFError) { - performEvent { $0.request(request, didFailToCreateURLRequestWithError: error) } - } - - public func request(_ request: Request, didAdaptInitialRequest initialRequest: URLRequest, to adaptedRequest: URLRequest) { - performEvent { $0.request(request, didAdaptInitialRequest: initialRequest, to: adaptedRequest) } - } - - public func request(_ request: Request, didFailToAdaptURLRequest initialRequest: URLRequest, withError error: AFError) { - performEvent { $0.request(request, didFailToAdaptURLRequest: initialRequest, withError: error) } - } - - public func request(_ request: Request, didCreateURLRequest urlRequest: URLRequest) { - performEvent { $0.request(request, didCreateURLRequest: urlRequest) } - } - - public func request(_ request: Request, didCreateTask task: URLSessionTask) { - performEvent { $0.request(request, didCreateTask: task) } - } - - public func request(_ request: Request, didGatherMetrics metrics: URLSessionTaskMetrics) { - performEvent { $0.request(request, didGatherMetrics: metrics) } - } - - public func request(_ request: Request, didFailTask task: URLSessionTask, earlyWithError error: AFError) { - performEvent { $0.request(request, didFailTask: task, earlyWithError: error) } - } - - public func request(_ request: Request, didCompleteTask task: URLSessionTask, with error: AFError?) { - performEvent { $0.request(request, didCompleteTask: task, with: error) } - } - - public func requestIsRetrying(_ request: Request) { - performEvent { $0.requestIsRetrying(request) } - } - - public func requestDidFinish(_ request: Request) { - performEvent { $0.requestDidFinish(request) } - } - - public func requestDidResume(_ request: Request) { - performEvent { $0.requestDidResume(request) } - } - - public func request(_ request: Request, didResumeTask task: URLSessionTask) { - performEvent { $0.request(request, didResumeTask: task) } - } - - public func requestDidSuspend(_ request: Request) { - performEvent { $0.requestDidSuspend(request) } - } - - public func request(_ request: Request, didSuspendTask task: URLSessionTask) { - performEvent { $0.request(request, didSuspendTask: task) } - } - - public func requestDidCancel(_ request: Request) { - performEvent { $0.requestDidCancel(request) } - } - - public func request(_ request: Request, didCancelTask task: URLSessionTask) { - performEvent { $0.request(request, didCancelTask: task) } - } - - public func request(_ request: DataRequest, - didValidateRequest urlRequest: URLRequest?, - response: HTTPURLResponse, - data: Data?, - withResult result: Request.ValidationResult) { - performEvent { $0.request(request, - didValidateRequest: urlRequest, - response: response, - data: data, - withResult: result) - } - } - - public func request(_ request: DataRequest, didParseResponse response: DataResponse) { - performEvent { $0.request(request, didParseResponse: response) } - } - - public func request(_ request: DataRequest, didParseResponse response: DataResponse) { - performEvent { $0.request(request, didParseResponse: response) } - } - - public func request(_ request: DataStreamRequest, - didValidateRequest urlRequest: URLRequest?, - response: HTTPURLResponse, - withResult result: Request.ValidationResult) { - performEvent { $0.request(request, - didValidateRequest: urlRequest, - response: response, - withResult: result) - } - } - - public func request(_ request: DataStreamRequest, didParseStream result: Result) { - performEvent { $0.request(request, didParseStream: result) } - } - - public func request(_ request: UploadRequest, didCreateUploadable uploadable: UploadRequest.Uploadable) { - performEvent { $0.request(request, didCreateUploadable: uploadable) } - } - - public func request(_ request: UploadRequest, didFailToCreateUploadableWithError error: AFError) { - performEvent { $0.request(request, didFailToCreateUploadableWithError: error) } - } - - public func request(_ request: UploadRequest, didProvideInputStream stream: InputStream) { - performEvent { $0.request(request, didProvideInputStream: stream) } - } - - public func request(_ request: DownloadRequest, didFinishDownloadingUsing task: URLSessionTask, with result: Result) { - performEvent { $0.request(request, didFinishDownloadingUsing: task, with: result) } - } - - public func request(_ request: DownloadRequest, didCreateDestinationURL url: URL) { - performEvent { $0.request(request, didCreateDestinationURL: url) } - } - - public func request(_ request: DownloadRequest, - didValidateRequest urlRequest: URLRequest?, - response: HTTPURLResponse, - fileURL: URL?, - withResult result: Request.ValidationResult) { - performEvent { $0.request(request, - didValidateRequest: urlRequest, - response: response, - fileURL: fileURL, - withResult: result) } - } - - public func request(_ request: DownloadRequest, didParseResponse response: DownloadResponse) { - performEvent { $0.request(request, didParseResponse: response) } - } - - public func request(_ request: DownloadRequest, didParseResponse response: DownloadResponse) { - performEvent { $0.request(request, didParseResponse: response) } - } -} - -/// `EventMonitor` that allows optional closures to be set to receive events. -open class ClosureEventMonitor: EventMonitor { - /// Closure called on the `urlSession(_:didBecomeInvalidWithError:)` event. - open var sessionDidBecomeInvalidWithError: ((URLSession, Error?) -> Void)? - - /// Closure called on the `urlSession(_:task:didReceive:completionHandler:)`. - open var taskDidReceiveChallenge: ((URLSession, URLSessionTask, URLAuthenticationChallenge) -> Void)? - - /// Closure that receives `urlSession(_:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:)` event. - open var taskDidSendBodyData: ((URLSession, URLSessionTask, Int64, Int64, Int64) -> Void)? - - /// Closure called on the `urlSession(_:task:needNewBodyStream:)` event. - open var taskNeedNewBodyStream: ((URLSession, URLSessionTask) -> Void)? - - /// Closure called on the `urlSession(_:task:willPerformHTTPRedirection:newRequest:completionHandler:)` event. - open var taskWillPerformHTTPRedirection: ((URLSession, URLSessionTask, HTTPURLResponse, URLRequest) -> Void)? - - /// Closure called on the `urlSession(_:task:didFinishCollecting:)` event. - open var taskDidFinishCollectingMetrics: ((URLSession, URLSessionTask, URLSessionTaskMetrics) -> Void)? - - /// Closure called on the `urlSession(_:task:didCompleteWithError:)` event. - open var taskDidComplete: ((URLSession, URLSessionTask, Error?) -> Void)? - - /// Closure called on the `urlSession(_:taskIsWaitingForConnectivity:)` event. - open var taskIsWaitingForConnectivity: ((URLSession, URLSessionTask) -> Void)? - - /// Closure that receives the `urlSession(_:dataTask:didReceive:)` event. - open var dataTaskDidReceiveData: ((URLSession, URLSessionDataTask, Data) -> Void)? - - /// Closure called on the `urlSession(_:dataTask:willCacheResponse:completionHandler:)` event. - open var dataTaskWillCacheResponse: ((URLSession, URLSessionDataTask, CachedURLResponse) -> Void)? - - /// Closure called on the `urlSession(_:downloadTask:didFinishDownloadingTo:)` event. - open var downloadTaskDidFinishDownloadingToURL: ((URLSession, URLSessionDownloadTask, URL) -> Void)? - - /// Closure called on the `urlSession(_:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:)` - /// event. - open var downloadTaskDidWriteData: ((URLSession, URLSessionDownloadTask, Int64, Int64, Int64) -> Void)? - - /// Closure called on the `urlSession(_:downloadTask:didResumeAtOffset:expectedTotalBytes:)` event. - open var downloadTaskDidResumeAtOffset: ((URLSession, URLSessionDownloadTask, Int64, Int64) -> Void)? - - // MARK: - Request Events - - /// Closure called on the `request(_:didCreateInitialURLRequest:)` event. - open var requestDidCreateInitialURLRequest: ((Request, URLRequest) -> Void)? - - /// Closure called on the `request(_:didFailToCreateURLRequestWithError:)` event. - open var requestDidFailToCreateURLRequestWithError: ((Request, AFError) -> Void)? - - /// Closure called on the `request(_:didAdaptInitialRequest:to:)` event. - open var requestDidAdaptInitialRequestToAdaptedRequest: ((Request, URLRequest, URLRequest) -> Void)? - - /// Closure called on the `request(_:didFailToAdaptURLRequest:withError:)` event. - open var requestDidFailToAdaptURLRequestWithError: ((Request, URLRequest, AFError) -> Void)? - - /// Closure called on the `request(_:didCreateURLRequest:)` event. - open var requestDidCreateURLRequest: ((Request, URLRequest) -> Void)? - - /// Closure called on the `request(_:didCreateTask:)` event. - open var requestDidCreateTask: ((Request, URLSessionTask) -> Void)? - - /// Closure called on the `request(_:didGatherMetrics:)` event. - open var requestDidGatherMetrics: ((Request, URLSessionTaskMetrics) -> Void)? - - /// Closure called on the `request(_:didFailTask:earlyWithError:)` event. - open var requestDidFailTaskEarlyWithError: ((Request, URLSessionTask, AFError) -> Void)? - - /// Closure called on the `request(_:didCompleteTask:with:)` event. - open var requestDidCompleteTaskWithError: ((Request, URLSessionTask, AFError?) -> Void)? - - /// Closure called on the `requestIsRetrying(_:)` event. - open var requestIsRetrying: ((Request) -> Void)? - - /// Closure called on the `requestDidFinish(_:)` event. - open var requestDidFinish: ((Request) -> Void)? - - /// Closure called on the `requestDidResume(_:)` event. - open var requestDidResume: ((Request) -> Void)? - - /// Closure called on the `request(_:didResumeTask:)` event. - open var requestDidResumeTask: ((Request, URLSessionTask) -> Void)? - - /// Closure called on the `requestDidSuspend(_:)` event. - open var requestDidSuspend: ((Request) -> Void)? - - /// Closure called on the `request(_:didSuspendTask:)` event. - open var requestDidSuspendTask: ((Request, URLSessionTask) -> Void)? - - /// Closure called on the `requestDidCancel(_:)` event. - open var requestDidCancel: ((Request) -> Void)? - - /// Closure called on the `request(_:didCancelTask:)` event. - open var requestDidCancelTask: ((Request, URLSessionTask) -> Void)? - - /// Closure called on the `request(_:didValidateRequest:response:data:withResult:)` event. - open var requestDidValidateRequestResponseDataWithResult: ((DataRequest, URLRequest?, HTTPURLResponse, Data?, Request.ValidationResult) -> Void)? - - /// Closure called on the `request(_:didParseResponse:)` event. - open var requestDidParseResponse: ((DataRequest, DataResponse) -> Void)? - - /// Closure called on the `request(_:didValidateRequest:response:withResult:)` event. - open var requestDidValidateRequestResponseWithResult: ((DataStreamRequest, URLRequest?, HTTPURLResponse, Request.ValidationResult) -> Void)? - - /// Closure called on the `request(_:didCreateUploadable:)` event. - open var requestDidCreateUploadable: ((UploadRequest, UploadRequest.Uploadable) -> Void)? - - /// Closure called on the `request(_:didFailToCreateUploadableWithError:)` event. - open var requestDidFailToCreateUploadableWithError: ((UploadRequest, AFError) -> Void)? - - /// Closure called on the `request(_:didProvideInputStream:)` event. - open var requestDidProvideInputStream: ((UploadRequest, InputStream) -> Void)? - - /// Closure called on the `request(_:didFinishDownloadingUsing:with:)` event. - open var requestDidFinishDownloadingUsingTaskWithResult: ((DownloadRequest, URLSessionTask, Result) -> Void)? - - /// Closure called on the `request(_:didCreateDestinationURL:)` event. - open var requestDidCreateDestinationURL: ((DownloadRequest, URL) -> Void)? - - /// Closure called on the `request(_:didValidateRequest:response:temporaryURL:destinationURL:withResult:)` event. - open var requestDidValidateRequestResponseFileURLWithResult: ((DownloadRequest, URLRequest?, HTTPURLResponse, URL?, Request.ValidationResult) -> Void)? - - /// Closure called on the `request(_:didParseResponse:)` event. - open var requestDidParseDownloadResponse: ((DownloadRequest, DownloadResponse) -> Void)? - - public let queue: DispatchQueue - - /// Creates an instance using the provided queue. - /// - /// - Parameter queue: `DispatchQueue` on which events will fired. `.main` by default. - public init(queue: DispatchQueue = .main) { - self.queue = queue - } - - open func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) { - sessionDidBecomeInvalidWithError?(session, error) - } - - open func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge) { - taskDidReceiveChallenge?(session, task, challenge) - } - - open func urlSession(_ session: URLSession, - task: URLSessionTask, - didSendBodyData bytesSent: Int64, - totalBytesSent: Int64, - totalBytesExpectedToSend: Int64) { - taskDidSendBodyData?(session, task, bytesSent, totalBytesSent, totalBytesExpectedToSend) - } - - open func urlSession(_ session: URLSession, taskNeedsNewBodyStream task: URLSessionTask) { - taskNeedNewBodyStream?(session, task) - } - - open func urlSession(_ session: URLSession, - task: URLSessionTask, - willPerformHTTPRedirection response: HTTPURLResponse, - newRequest request: URLRequest) { - taskWillPerformHTTPRedirection?(session, task, response, request) - } - - open func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) { - taskDidFinishCollectingMetrics?(session, task, metrics) - } - - open func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { - taskDidComplete?(session, task, error) - } - - open func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) { - taskIsWaitingForConnectivity?(session, task) - } - - open func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { - dataTaskDidReceiveData?(session, dataTask, data) - } - - open func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, willCacheResponse proposedResponse: CachedURLResponse) { - dataTaskWillCacheResponse?(session, dataTask, proposedResponse) - } - - open func urlSession(_ session: URLSession, - downloadTask: URLSessionDownloadTask, - didResumeAtOffset fileOffset: Int64, - expectedTotalBytes: Int64) { - downloadTaskDidResumeAtOffset?(session, downloadTask, fileOffset, expectedTotalBytes) - } - - open func urlSession(_ session: URLSession, - downloadTask: URLSessionDownloadTask, - didWriteData bytesWritten: Int64, - totalBytesWritten: Int64, - totalBytesExpectedToWrite: Int64) { - downloadTaskDidWriteData?(session, downloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) - } - - open func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { - downloadTaskDidFinishDownloadingToURL?(session, downloadTask, location) - } - - // MARK: Request Events - - open func request(_ request: Request, didCreateInitialURLRequest urlRequest: URLRequest) { - requestDidCreateInitialURLRequest?(request, urlRequest) - } - - open func request(_ request: Request, didFailToCreateURLRequestWithError error: AFError) { - requestDidFailToCreateURLRequestWithError?(request, error) - } - - open func request(_ request: Request, didAdaptInitialRequest initialRequest: URLRequest, to adaptedRequest: URLRequest) { - requestDidAdaptInitialRequestToAdaptedRequest?(request, initialRequest, adaptedRequest) - } - - open func request(_ request: Request, didFailToAdaptURLRequest initialRequest: URLRequest, withError error: AFError) { - requestDidFailToAdaptURLRequestWithError?(request, initialRequest, error) - } - - open func request(_ request: Request, didCreateURLRequest urlRequest: URLRequest) { - requestDidCreateURLRequest?(request, urlRequest) - } - - open func request(_ request: Request, didCreateTask task: URLSessionTask) { - requestDidCreateTask?(request, task) - } - - open func request(_ request: Request, didGatherMetrics metrics: URLSessionTaskMetrics) { - requestDidGatherMetrics?(request, metrics) - } - - open func request(_ request: Request, didFailTask task: URLSessionTask, earlyWithError error: AFError) { - requestDidFailTaskEarlyWithError?(request, task, error) - } - - open func request(_ request: Request, didCompleteTask task: URLSessionTask, with error: AFError?) { - requestDidCompleteTaskWithError?(request, task, error) - } - - open func requestIsRetrying(_ request: Request) { - requestIsRetrying?(request) - } - - open func requestDidFinish(_ request: Request) { - requestDidFinish?(request) - } - - open func requestDidResume(_ request: Request) { - requestDidResume?(request) - } - - public func request(_ request: Request, didResumeTask task: URLSessionTask) { - requestDidResumeTask?(request, task) - } - - open func requestDidSuspend(_ request: Request) { - requestDidSuspend?(request) - } - - public func request(_ request: Request, didSuspendTask task: URLSessionTask) { - requestDidSuspendTask?(request, task) - } - - open func requestDidCancel(_ request: Request) { - requestDidCancel?(request) - } - - public func request(_ request: Request, didCancelTask task: URLSessionTask) { - requestDidCancelTask?(request, task) - } - - open func request(_ request: DataRequest, - didValidateRequest urlRequest: URLRequest?, - response: HTTPURLResponse, - data: Data?, - withResult result: Request.ValidationResult) { - requestDidValidateRequestResponseDataWithResult?(request, urlRequest, response, data, result) - } - - open func request(_ request: DataRequest, didParseResponse response: DataResponse) { - requestDidParseResponse?(request, response) - } - - public func request(_ request: DataStreamRequest, didValidateRequest urlRequest: URLRequest?, response: HTTPURLResponse, withResult result: Request.ValidationResult) { - requestDidValidateRequestResponseWithResult?(request, urlRequest, response, result) - } - - open func request(_ request: UploadRequest, didCreateUploadable uploadable: UploadRequest.Uploadable) { - requestDidCreateUploadable?(request, uploadable) - } - - open func request(_ request: UploadRequest, didFailToCreateUploadableWithError error: AFError) { - requestDidFailToCreateUploadableWithError?(request, error) - } - - open func request(_ request: UploadRequest, didProvideInputStream stream: InputStream) { - requestDidProvideInputStream?(request, stream) - } - - open func request(_ request: DownloadRequest, didFinishDownloadingUsing task: URLSessionTask, with result: Result) { - requestDidFinishDownloadingUsingTaskWithResult?(request, task, result) - } - - open func request(_ request: DownloadRequest, didCreateDestinationURL url: URL) { - requestDidCreateDestinationURL?(request, url) - } - - open func request(_ request: DownloadRequest, - didValidateRequest urlRequest: URLRequest?, - response: HTTPURLResponse, - fileURL: URL?, - withResult result: Request.ValidationResult) { - requestDidValidateRequestResponseFileURLWithResult?(request, - urlRequest, - response, - fileURL, - result) - } - - open func request(_ request: DownloadRequest, didParseResponse response: DownloadResponse) { - requestDidParseDownloadResponse?(request, response) - } -} diff --git a/Pods/Alamofire/Source/HTTPHeaders.swift b/Pods/Alamofire/Source/HTTPHeaders.swift deleted file mode 100644 index 7829fc69b..000000000 --- a/Pods/Alamofire/Source/HTTPHeaders.swift +++ /dev/null @@ -1,449 +0,0 @@ -// -// HTTPHeaders.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -/// An order-preserving and case-insensitive representation of HTTP headers. -public struct HTTPHeaders { - private var headers: [HTTPHeader] = [] - - /// Creates an empty instance. - public init() {} - - /// Creates an instance from an array of `HTTPHeader`s. Duplicate case-insensitive names are collapsed into the last - /// name and value encountered. - public init(_ headers: [HTTPHeader]) { - self.init() - - headers.forEach { update($0) } - } - - /// Creates an instance from a `[String: String]`. Duplicate case-insensitive names are collapsed into the last name - /// and value encountered. - public init(_ dictionary: [String: String]) { - self.init() - - dictionary.forEach { update(HTTPHeader(name: $0.key, value: $0.value)) } - } - - /// Case-insensitively updates or appends an `HTTPHeader` into the instance using the provided `name` and `value`. - /// - /// - Parameters: - /// - name: The `HTTPHeader` name. - /// - value: The `HTTPHeader value. - public mutating func add(name: String, value: String) { - update(HTTPHeader(name: name, value: value)) - } - - /// Case-insensitively updates or appends the provided `HTTPHeader` into the instance. - /// - /// - Parameter header: The `HTTPHeader` to update or append. - public mutating func add(_ header: HTTPHeader) { - update(header) - } - - /// Case-insensitively updates or appends an `HTTPHeader` into the instance using the provided `name` and `value`. - /// - /// - Parameters: - /// - name: The `HTTPHeader` name. - /// - value: The `HTTPHeader value. - public mutating func update(name: String, value: String) { - update(HTTPHeader(name: name, value: value)) - } - - /// Case-insensitively updates or appends the provided `HTTPHeader` into the instance. - /// - /// - Parameter header: The `HTTPHeader` to update or append. - public mutating func update(_ header: HTTPHeader) { - guard let index = headers.index(of: header.name) else { - headers.append(header) - return - } - - headers.replaceSubrange(index...index, with: [header]) - } - - /// Case-insensitively removes an `HTTPHeader`, if it exists, from the instance. - /// - /// - Parameter name: The name of the `HTTPHeader` to remove. - public mutating func remove(name: String) { - guard let index = headers.index(of: name) else { return } - - headers.remove(at: index) - } - - /// Sort the current instance by header name, case insensitively. - public mutating func sort() { - headers.sort { $0.name.lowercased() < $1.name.lowercased() } - } - - /// Returns an instance sorted by header name. - /// - /// - Returns: A copy of the current instance sorted by name. - public func sorted() -> HTTPHeaders { - var headers = self - headers.sort() - - return headers - } - - /// Case-insensitively find a header's value by name. - /// - /// - Parameter name: The name of the header to search for, case-insensitively. - /// - /// - Returns: The value of header, if it exists. - public func value(for name: String) -> String? { - guard let index = headers.index(of: name) else { return nil } - - return headers[index].value - } - - /// Case-insensitively access the header with the given name. - /// - /// - Parameter name: The name of the header. - public subscript(_ name: String) -> String? { - get { value(for: name) } - set { - if let value = newValue { - update(name: name, value: value) - } else { - remove(name: name) - } - } - } - - /// The dictionary representation of all headers. - /// - /// This representation does not preserve the current order of the instance. - public var dictionary: [String: String] { - let namesAndValues = headers.map { ($0.name, $0.value) } - - return Dictionary(namesAndValues, uniquingKeysWith: { _, last in last }) - } -} - -extension HTTPHeaders: ExpressibleByDictionaryLiteral { - public init(dictionaryLiteral elements: (String, String)...) { - self.init() - - elements.forEach { update(name: $0.0, value: $0.1) } - } -} - -extension HTTPHeaders: ExpressibleByArrayLiteral { - public init(arrayLiteral elements: HTTPHeader...) { - self.init(elements) - } -} - -extension HTTPHeaders: Sequence { - public func makeIterator() -> IndexingIterator<[HTTPHeader]> { - headers.makeIterator() - } -} - -extension HTTPHeaders: Collection { - public var startIndex: Int { - headers.startIndex - } - - public var endIndex: Int { - headers.endIndex - } - - public subscript(position: Int) -> HTTPHeader { - headers[position] - } - - public func index(after i: Int) -> Int { - headers.index(after: i) - } -} - -extension HTTPHeaders: CustomStringConvertible { - public var description: String { - headers.map { $0.description } - .joined(separator: "\n") - } -} - -// MARK: - HTTPHeader - -/// A representation of a single HTTP header's name / value pair. -public struct HTTPHeader: Hashable { - /// Name of the header. - public let name: String - - /// Value of the header. - public let value: String - - /// Creates an instance from the given `name` and `value`. - /// - /// - Parameters: - /// - name: The name of the header. - /// - value: The value of the header. - public init(name: String, value: String) { - self.name = name - self.value = value - } -} - -extension HTTPHeader: CustomStringConvertible { - public var description: String { - "\(name): \(value)" - } -} - -extension HTTPHeader { - /// Returns an `Accept` header. - /// - /// - Parameter value: The `Accept` value. - /// - Returns: The header. - public static func accept(_ value: String) -> HTTPHeader { - HTTPHeader(name: "Accept", value: value) - } - - /// Returns an `Accept-Charset` header. - /// - /// - Parameter value: The `Accept-Charset` value. - /// - Returns: The header. - public static func acceptCharset(_ value: String) -> HTTPHeader { - HTTPHeader(name: "Accept-Charset", value: value) - } - - /// Returns an `Accept-Language` header. - /// - /// Alamofire offers a default Accept-Language header that accumulates and encodes the system's preferred languages. - /// Use `HTTPHeader.defaultAcceptLanguage`. - /// - /// - Parameter value: The `Accept-Language` value. - /// - /// - Returns: The header. - public static func acceptLanguage(_ value: String) -> HTTPHeader { - HTTPHeader(name: "Accept-Language", value: value) - } - - /// Returns an `Accept-Encoding` header. - /// - /// Alamofire offers a default accept encoding value that provides the most common values. Use - /// `HTTPHeader.defaultAcceptEncoding`. - /// - /// - Parameter value: The `Accept-Encoding` value. - /// - /// - Returns: The header - public static func acceptEncoding(_ value: String) -> HTTPHeader { - HTTPHeader(name: "Accept-Encoding", value: value) - } - - /// Returns a `Basic` `Authorization` header using the `username` and `password` provided. - /// - /// - Parameters: - /// - username: The username of the header. - /// - password: The password of the header. - /// - /// - Returns: The header. - public static func authorization(username: String, password: String) -> HTTPHeader { - let credential = Data("\(username):\(password)".utf8).base64EncodedString() - - return authorization("Basic \(credential)") - } - - /// Returns a `Bearer` `Authorization` header using the `bearerToken` provided - /// - /// - Parameter bearerToken: The bearer token. - /// - /// - Returns: The header. - public static func authorization(bearerToken: String) -> HTTPHeader { - authorization("Bearer \(bearerToken)") - } - - /// Returns an `Authorization` header. - /// - /// Alamofire provides built-in methods to produce `Authorization` headers. For a Basic `Authorization` header use - /// `HTTPHeader.authorization(username:password:)`. For a Bearer `Authorization` header, use - /// `HTTPHeader.authorization(bearerToken:)`. - /// - /// - Parameter value: The `Authorization` value. - /// - /// - Returns: The header. - public static func authorization(_ value: String) -> HTTPHeader { - HTTPHeader(name: "Authorization", value: value) - } - - /// Returns a `Content-Disposition` header. - /// - /// - Parameter value: The `Content-Disposition` value. - /// - /// - Returns: The header. - public static func contentDisposition(_ value: String) -> HTTPHeader { - HTTPHeader(name: "Content-Disposition", value: value) - } - - /// Returns a `Content-Type` header. - /// - /// All Alamofire `ParameterEncoding`s and `ParameterEncoder`s set the `Content-Type` of the request, so it may not be necessary to manually - /// set this value. - /// - /// - Parameter value: The `Content-Type` value. - /// - /// - Returns: The header. - public static func contentType(_ value: String) -> HTTPHeader { - HTTPHeader(name: "Content-Type", value: value) - } - - /// Returns a `User-Agent` header. - /// - /// - Parameter value: The `User-Agent` value. - /// - /// - Returns: The header. - public static func userAgent(_ value: String) -> HTTPHeader { - HTTPHeader(name: "User-Agent", value: value) - } -} - -extension Array where Element == HTTPHeader { - /// Case-insensitively finds the index of an `HTTPHeader` with the provided name, if it exists. - func index(of name: String) -> Int? { - let lowercasedName = name.lowercased() - return firstIndex { $0.name.lowercased() == lowercasedName } - } -} - -// MARK: - Defaults - -extension HTTPHeaders { - /// The default set of `HTTPHeaders` used by Alamofire. Includes `Accept-Encoding`, `Accept-Language`, and - /// `User-Agent`. - public static let `default`: HTTPHeaders = [.defaultAcceptEncoding, - .defaultAcceptLanguage, - .defaultUserAgent] -} - -extension HTTPHeader { - /// Returns Alamofire's default `Accept-Encoding` header, appropriate for the encodings supported by particular OS - /// versions. - /// - /// See the [Accept-Encoding HTTP header documentation](https://tools.ietf.org/html/rfc7230#section-4.2.3) . - public static let defaultAcceptEncoding: HTTPHeader = { - let encodings: [String] - if #available(iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0, *) { - encodings = ["br", "gzip", "deflate"] - } else { - encodings = ["gzip", "deflate"] - } - - return .acceptEncoding(encodings.qualityEncoded()) - }() - - /// Returns Alamofire's default `Accept-Language` header, generated by querying `Locale` for the user's - /// `preferredLanguages`. - /// - /// See the [Accept-Language HTTP header documentation](https://tools.ietf.org/html/rfc7231#section-5.3.5). - public static let defaultAcceptLanguage: HTTPHeader = { - .acceptLanguage(Locale.preferredLanguages.prefix(6).qualityEncoded()) - }() - - /// Returns Alamofire's default `User-Agent` header. - /// - /// See the [User-Agent header documentation](https://tools.ietf.org/html/rfc7231#section-5.5.3). - /// - /// Example: `iOS Example/1.0 (org.alamofire.iOS-Example; build:1; iOS 13.0.0) Alamofire/5.0.0` - public static let defaultUserAgent: HTTPHeader = { - let info = Bundle.main.infoDictionary - let executable = (info?[kCFBundleExecutableKey as String] as? String) ?? - (ProcessInfo.processInfo.arguments.first?.split(separator: "/").last.map(String.init)) ?? - "Unknown" - let bundle = info?[kCFBundleIdentifierKey as String] as? String ?? "Unknown" - let appVersion = info?["CFBundleShortVersionString"] as? String ?? "Unknown" - let appBuild = info?[kCFBundleVersionKey as String] as? String ?? "Unknown" - - let osNameVersion: String = { - let version = ProcessInfo.processInfo.operatingSystemVersion - let versionString = "\(version.majorVersion).\(version.minorVersion).\(version.patchVersion)" - let osName: String = { - #if os(iOS) - #if targetEnvironment(macCatalyst) - return "macOS(Catalyst)" - #else - return "iOS" - #endif - #elseif os(watchOS) - return "watchOS" - #elseif os(tvOS) - return "tvOS" - #elseif os(macOS) - return "macOS" - #elseif os(Linux) - return "Linux" - #elseif os(Windows) - return "Windows" - #else - return "Unknown" - #endif - }() - - return "\(osName) \(versionString)" - }() - - let alamofireVersion = "Alamofire/\(version)" - - let userAgent = "\(executable)/\(appVersion) (\(bundle); build:\(appBuild); \(osNameVersion)) \(alamofireVersion)" - - return .userAgent(userAgent) - }() -} - -extension Collection where Element == String { - func qualityEncoded() -> String { - enumerated().map { index, encoding in - let quality = 1.0 - (Double(index) * 0.1) - return "\(encoding);q=\(quality)" - }.joined(separator: ", ") - } -} - -// MARK: - System Type Extensions - -extension URLRequest { - /// Returns `allHTTPHeaderFields` as `HTTPHeaders`. - public var headers: HTTPHeaders { - get { allHTTPHeaderFields.map(HTTPHeaders.init) ?? HTTPHeaders() } - set { allHTTPHeaderFields = newValue.dictionary } - } -} - -extension HTTPURLResponse { - /// Returns `allHeaderFields` as `HTTPHeaders`. - public var headers: HTTPHeaders { - (allHeaderFields as? [String: String]).map(HTTPHeaders.init) ?? HTTPHeaders() - } -} - -extension URLSessionConfiguration { - /// Returns `httpAdditionalHeaders` as `HTTPHeaders`. - public var headers: HTTPHeaders { - get { (httpAdditionalHeaders as? [String: String]).map(HTTPHeaders.init) ?? HTTPHeaders() } - set { httpAdditionalHeaders = newValue.dictionary } - } -} diff --git a/Pods/Alamofire/Source/HTTPMethod.swift b/Pods/Alamofire/Source/HTTPMethod.swift deleted file mode 100644 index 4867c1e9d..000000000 --- a/Pods/Alamofire/Source/HTTPMethod.swift +++ /dev/null @@ -1,54 +0,0 @@ -// -// HTTPMethod.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -/// Type representing HTTP methods. Raw `String` value is stored and compared case-sensitively, so -/// `HTTPMethod.get != HTTPMethod(rawValue: "get")`. -/// -/// See https://tools.ietf.org/html/rfc7231#section-4.3 -public struct HTTPMethod: RawRepresentable, Equatable, Hashable { - /// `CONNECT` method. - public static let connect = HTTPMethod(rawValue: "CONNECT") - /// `DELETE` method. - public static let delete = HTTPMethod(rawValue: "DELETE") - /// `GET` method. - public static let get = HTTPMethod(rawValue: "GET") - /// `HEAD` method. - public static let head = HTTPMethod(rawValue: "HEAD") - /// `OPTIONS` method. - public static let options = HTTPMethod(rawValue: "OPTIONS") - /// `PATCH` method. - public static let patch = HTTPMethod(rawValue: "PATCH") - /// `POST` method. - public static let post = HTTPMethod(rawValue: "POST") - /// `PUT` method. - public static let put = HTTPMethod(rawValue: "PUT") - /// `TRACE` method. - public static let trace = HTTPMethod(rawValue: "TRACE") - - public let rawValue: String - - public init(rawValue: String) { - self.rawValue = rawValue - } -} diff --git a/Pods/Alamofire/Source/MultipartFormData.swift b/Pods/Alamofire/Source/MultipartFormData.swift deleted file mode 100644 index d9cecef5e..000000000 --- a/Pods/Alamofire/Source/MultipartFormData.swift +++ /dev/null @@ -1,553 +0,0 @@ -// -// MultipartFormData.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -#if os(iOS) || os(watchOS) || os(tvOS) -import MobileCoreServices -#elseif os(macOS) -import CoreServices -#endif - -/// Constructs `multipart/form-data` for uploads within an HTTP or HTTPS body. There are currently two ways to encode -/// multipart form data. The first way is to encode the data directly in memory. This is very efficient, but can lead -/// to memory issues if the dataset is too large. The second way is designed for larger datasets and will write all the -/// data to a single file on disk with all the proper boundary segmentation. The second approach MUST be used for -/// larger datasets such as video content, otherwise your app may run out of memory when trying to encode the dataset. -/// -/// For more information on `multipart/form-data` in general, please refer to the RFC-2388 and RFC-2045 specs as well -/// and the w3 form documentation. -/// -/// - https://www.ietf.org/rfc/rfc2388.txt -/// - https://www.ietf.org/rfc/rfc2045.txt -/// - https://www.w3.org/TR/html401/interact/forms.html#h-17.13 -open class MultipartFormData { - // MARK: - Helper Types - - enum EncodingCharacters { - static let crlf = "\r\n" - } - - enum BoundaryGenerator { - enum BoundaryType { - case initial, encapsulated, final - } - - static func randomBoundary() -> String { - let first = UInt32.random(in: UInt32.min...UInt32.max) - let second = UInt32.random(in: UInt32.min...UInt32.max) - - return String(format: "alamofire.boundary.%08x%08x", first, second) - } - - static func boundaryData(forBoundaryType boundaryType: BoundaryType, boundary: String) -> Data { - let boundaryText: String - - switch boundaryType { - case .initial: - boundaryText = "--\(boundary)\(EncodingCharacters.crlf)" - case .encapsulated: - boundaryText = "\(EncodingCharacters.crlf)--\(boundary)\(EncodingCharacters.crlf)" - case .final: - boundaryText = "\(EncodingCharacters.crlf)--\(boundary)--\(EncodingCharacters.crlf)" - } - - return Data(boundaryText.utf8) - } - } - - class BodyPart { - let headers: HTTPHeaders - let bodyStream: InputStream - let bodyContentLength: UInt64 - var hasInitialBoundary = false - var hasFinalBoundary = false - - init(headers: HTTPHeaders, bodyStream: InputStream, bodyContentLength: UInt64) { - self.headers = headers - self.bodyStream = bodyStream - self.bodyContentLength = bodyContentLength - } - } - - // MARK: - Properties - - /// Default memory threshold used when encoding `MultipartFormData`, in bytes. - public static let encodingMemoryThreshold: UInt64 = 10_000_000 - - /// The `Content-Type` header value containing the boundary used to generate the `multipart/form-data`. - open lazy var contentType: String = "multipart/form-data; boundary=\(self.boundary)" - - /// The content length of all body parts used to generate the `multipart/form-data` not including the boundaries. - public var contentLength: UInt64 { bodyParts.reduce(0) { $0 + $1.bodyContentLength } } - - /// The boundary used to separate the body parts in the encoded form data. - public let boundary: String - - let fileManager: FileManager - - private var bodyParts: [BodyPart] - private var bodyPartError: AFError? - private let streamBufferSize: Int - - // MARK: - Lifecycle - - /// Creates an instance. - /// - /// - Parameters: - /// - fileManager: `FileManager` to use for file operations, if needed. - /// - boundary: Boundary `String` used to separate body parts. - public init(fileManager: FileManager = .default, boundary: String? = nil) { - self.fileManager = fileManager - self.boundary = boundary ?? BoundaryGenerator.randomBoundary() - bodyParts = [] - - // - // The optimal read/write buffer size in bytes for input and output streams is 1024 (1KB). For more - // information, please refer to the following article: - // - https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Streams/Articles/ReadingInputStreams.html - // - streamBufferSize = 1024 - } - - // MARK: - Body Parts - - /// Creates a body part from the data and appends it to the instance. - /// - /// The body part data will be encoded using the following format: - /// - /// - `Content-Disposition: form-data; name=#{name}; filename=#{filename}` (HTTP Header) - /// - `Content-Type: #{mimeType}` (HTTP Header) - /// - Encoded file data - /// - Multipart form boundary - /// - /// - Parameters: - /// - data: `Data` to encoding into the instance. - /// - name: Name to associate with the `Data` in the `Content-Disposition` HTTP header. - /// - fileName: Filename to associate with the `Data` in the `Content-Disposition` HTTP header. - /// - mimeType: MIME type to associate with the data in the `Content-Type` HTTP header. - public func append(_ data: Data, withName name: String, fileName: String? = nil, mimeType: String? = nil) { - let headers = contentHeaders(withName: name, fileName: fileName, mimeType: mimeType) - let stream = InputStream(data: data) - let length = UInt64(data.count) - - append(stream, withLength: length, headers: headers) - } - - /// Creates a body part from the file and appends it to the instance. - /// - /// The body part data will be encoded using the following format: - /// - /// - `Content-Disposition: form-data; name=#{name}; filename=#{generated filename}` (HTTP Header) - /// - `Content-Type: #{generated mimeType}` (HTTP Header) - /// - Encoded file data - /// - Multipart form boundary - /// - /// The filename in the `Content-Disposition` HTTP header is generated from the last path component of the - /// `fileURL`. The `Content-Type` HTTP header MIME type is generated by mapping the `fileURL` extension to the - /// system associated MIME type. - /// - /// - Parameters: - /// - fileURL: `URL` of the file whose content will be encoded into the instance. - /// - name: Name to associate with the file content in the `Content-Disposition` HTTP header. - public func append(_ fileURL: URL, withName name: String) { - let fileName = fileURL.lastPathComponent - let pathExtension = fileURL.pathExtension - - if !fileName.isEmpty && !pathExtension.isEmpty { - let mime = mimeType(forPathExtension: pathExtension) - append(fileURL, withName: name, fileName: fileName, mimeType: mime) - } else { - setBodyPartError(withReason: .bodyPartFilenameInvalid(in: fileURL)) - } - } - - /// Creates a body part from the file and appends it to the instance. - /// - /// The body part data will be encoded using the following format: - /// - /// - Content-Disposition: form-data; name=#{name}; filename=#{filename} (HTTP Header) - /// - Content-Type: #{mimeType} (HTTP Header) - /// - Encoded file data - /// - Multipart form boundary - /// - /// - Parameters: - /// - fileURL: `URL` of the file whose content will be encoded into the instance. - /// - name: Name to associate with the file content in the `Content-Disposition` HTTP header. - /// - fileName: Filename to associate with the file content in the `Content-Disposition` HTTP header. - /// - mimeType: MIME type to associate with the file content in the `Content-Type` HTTP header. - public func append(_ fileURL: URL, withName name: String, fileName: String, mimeType: String) { - let headers = contentHeaders(withName: name, fileName: fileName, mimeType: mimeType) - - //============================================================ - // Check 1 - is file URL? - //============================================================ - - guard fileURL.isFileURL else { - setBodyPartError(withReason: .bodyPartURLInvalid(url: fileURL)) - return - } - - //============================================================ - // Check 2 - is file URL reachable? - //============================================================ - - do { - let isReachable = try fileURL.checkPromisedItemIsReachable() - guard isReachable else { - setBodyPartError(withReason: .bodyPartFileNotReachable(at: fileURL)) - return - } - } catch { - setBodyPartError(withReason: .bodyPartFileNotReachableWithError(atURL: fileURL, error: error)) - return - } - - //============================================================ - // Check 3 - is file URL a directory? - //============================================================ - - var isDirectory: ObjCBool = false - let path = fileURL.path - - guard fileManager.fileExists(atPath: path, isDirectory: &isDirectory) && !isDirectory.boolValue else { - setBodyPartError(withReason: .bodyPartFileIsDirectory(at: fileURL)) - return - } - - //============================================================ - // Check 4 - can the file size be extracted? - //============================================================ - - let bodyContentLength: UInt64 - - do { - guard let fileSize = try fileManager.attributesOfItem(atPath: path)[.size] as? NSNumber else { - setBodyPartError(withReason: .bodyPartFileSizeNotAvailable(at: fileURL)) - return - } - - bodyContentLength = fileSize.uint64Value - } catch { - setBodyPartError(withReason: .bodyPartFileSizeQueryFailedWithError(forURL: fileURL, error: error)) - return - } - - //============================================================ - // Check 5 - can a stream be created from file URL? - //============================================================ - - guard let stream = InputStream(url: fileURL) else { - setBodyPartError(withReason: .bodyPartInputStreamCreationFailed(for: fileURL)) - return - } - - append(stream, withLength: bodyContentLength, headers: headers) - } - - /// Creates a body part from the stream and appends it to the instance. - /// - /// The body part data will be encoded using the following format: - /// - /// - `Content-Disposition: form-data; name=#{name}; filename=#{filename}` (HTTP Header) - /// - `Content-Type: #{mimeType}` (HTTP Header) - /// - Encoded stream data - /// - Multipart form boundary - /// - /// - Parameters: - /// - stream: `InputStream` to encode into the instance. - /// - length: Length, in bytes, of the stream. - /// - name: Name to associate with the stream content in the `Content-Disposition` HTTP header. - /// - fileName: Filename to associate with the stream content in the `Content-Disposition` HTTP header. - /// - mimeType: MIME type to associate with the stream content in the `Content-Type` HTTP header. - public func append(_ stream: InputStream, - withLength length: UInt64, - name: String, - fileName: String, - mimeType: String) { - let headers = contentHeaders(withName: name, fileName: fileName, mimeType: mimeType) - append(stream, withLength: length, headers: headers) - } - - /// Creates a body part with the stream, length, and headers and appends it to the instance. - /// - /// The body part data will be encoded using the following format: - /// - /// - HTTP headers - /// - Encoded stream data - /// - Multipart form boundary - /// - /// - Parameters: - /// - stream: `InputStream` to encode into the instance. - /// - length: Length, in bytes, of the stream. - /// - headers: `HTTPHeaders` for the body part. - public func append(_ stream: InputStream, withLength length: UInt64, headers: HTTPHeaders) { - let bodyPart = BodyPart(headers: headers, bodyStream: stream, bodyContentLength: length) - bodyParts.append(bodyPart) - } - - // MARK: - Data Encoding - - /// Encodes all appended body parts into a single `Data` value. - /// - /// - Note: This method will load all the appended body parts into memory all at the same time. This method should - /// only be used when the encoded data will have a small memory footprint. For large data cases, please use - /// the `writeEncodedData(to:))` method. - /// - /// - Returns: The encoded `Data`, if encoding is successful. - /// - Throws: An `AFError` if encoding encounters an error. - public func encode() throws -> Data { - if let bodyPartError = bodyPartError { - throw bodyPartError - } - - var encoded = Data() - - bodyParts.first?.hasInitialBoundary = true - bodyParts.last?.hasFinalBoundary = true - - for bodyPart in bodyParts { - let encodedData = try encode(bodyPart) - encoded.append(encodedData) - } - - return encoded - } - - /// Writes all appended body parts to the given file `URL`. - /// - /// This process is facilitated by reading and writing with input and output streams, respectively. Thus, - /// this approach is very memory efficient and should be used for large body part data. - /// - /// - Parameter fileURL: File `URL` to which to write the form data. - /// - Throws: An `AFError` if encoding encounters an error. - public func writeEncodedData(to fileURL: URL) throws { - if let bodyPartError = bodyPartError { - throw bodyPartError - } - - if fileManager.fileExists(atPath: fileURL.path) { - throw AFError.multipartEncodingFailed(reason: .outputStreamFileAlreadyExists(at: fileURL)) - } else if !fileURL.isFileURL { - throw AFError.multipartEncodingFailed(reason: .outputStreamURLInvalid(url: fileURL)) - } - - guard let outputStream = OutputStream(url: fileURL, append: false) else { - throw AFError.multipartEncodingFailed(reason: .outputStreamCreationFailed(for: fileURL)) - } - - outputStream.open() - defer { outputStream.close() } - - bodyParts.first?.hasInitialBoundary = true - bodyParts.last?.hasFinalBoundary = true - - for bodyPart in bodyParts { - try write(bodyPart, to: outputStream) - } - } - - // MARK: - Private - Body Part Encoding - - private func encode(_ bodyPart: BodyPart) throws -> Data { - var encoded = Data() - - let initialData = bodyPart.hasInitialBoundary ? initialBoundaryData() : encapsulatedBoundaryData() - encoded.append(initialData) - - let headerData = encodeHeaders(for: bodyPart) - encoded.append(headerData) - - let bodyStreamData = try encodeBodyStream(for: bodyPart) - encoded.append(bodyStreamData) - - if bodyPart.hasFinalBoundary { - encoded.append(finalBoundaryData()) - } - - return encoded - } - - private func encodeHeaders(for bodyPart: BodyPart) -> Data { - let headerText = bodyPart.headers.map { "\($0.name): \($0.value)\(EncodingCharacters.crlf)" } - .joined() - + EncodingCharacters.crlf - - return Data(headerText.utf8) - } - - private func encodeBodyStream(for bodyPart: BodyPart) throws -> Data { - let inputStream = bodyPart.bodyStream - inputStream.open() - defer { inputStream.close() } - - var encoded = Data() - - while inputStream.hasBytesAvailable { - var buffer = [UInt8](repeating: 0, count: streamBufferSize) - let bytesRead = inputStream.read(&buffer, maxLength: streamBufferSize) - - if let error = inputStream.streamError { - throw AFError.multipartEncodingFailed(reason: .inputStreamReadFailed(error: error)) - } - - if bytesRead > 0 { - encoded.append(buffer, count: bytesRead) - } else { - break - } - } - - guard UInt64(encoded.count) == bodyPart.bodyContentLength else { - let error = AFError.UnexpectedInputStreamLength(bytesExpected: bodyPart.bodyContentLength, - bytesRead: UInt64(encoded.count)) - throw AFError.multipartEncodingFailed(reason: .inputStreamReadFailed(error: error)) - } - - return encoded - } - - // MARK: - Private - Writing Body Part to Output Stream - - private func write(_ bodyPart: BodyPart, to outputStream: OutputStream) throws { - try writeInitialBoundaryData(for: bodyPart, to: outputStream) - try writeHeaderData(for: bodyPart, to: outputStream) - try writeBodyStream(for: bodyPart, to: outputStream) - try writeFinalBoundaryData(for: bodyPart, to: outputStream) - } - - private func writeInitialBoundaryData(for bodyPart: BodyPart, to outputStream: OutputStream) throws { - let initialData = bodyPart.hasInitialBoundary ? initialBoundaryData() : encapsulatedBoundaryData() - return try write(initialData, to: outputStream) - } - - private func writeHeaderData(for bodyPart: BodyPart, to outputStream: OutputStream) throws { - let headerData = encodeHeaders(for: bodyPart) - return try write(headerData, to: outputStream) - } - - private func writeBodyStream(for bodyPart: BodyPart, to outputStream: OutputStream) throws { - let inputStream = bodyPart.bodyStream - - inputStream.open() - defer { inputStream.close() } - - while inputStream.hasBytesAvailable { - var buffer = [UInt8](repeating: 0, count: streamBufferSize) - let bytesRead = inputStream.read(&buffer, maxLength: streamBufferSize) - - if let streamError = inputStream.streamError { - throw AFError.multipartEncodingFailed(reason: .inputStreamReadFailed(error: streamError)) - } - - if bytesRead > 0 { - if buffer.count != bytesRead { - buffer = Array(buffer[0.. 0, outputStream.hasSpaceAvailable { - let bytesWritten = outputStream.write(buffer, maxLength: bytesToWrite) - - if let error = outputStream.streamError { - throw AFError.multipartEncodingFailed(reason: .outputStreamWriteFailed(error: error)) - } - - bytesToWrite -= bytesWritten - - if bytesToWrite > 0 { - buffer = Array(buffer[bytesWritten.. String { - if - let id = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension as CFString, nil)?.takeRetainedValue(), - let contentType = UTTypeCopyPreferredTagWithClass(id, kUTTagClassMIMEType)?.takeRetainedValue() { - return contentType as String - } - - return "application/octet-stream" - } - - // MARK: - Private - Content Headers - - private func contentHeaders(withName name: String, fileName: String? = nil, mimeType: String? = nil) -> HTTPHeaders { - var disposition = "form-data; name=\"\(name)\"" - if let fileName = fileName { disposition += "; filename=\"\(fileName)\"" } - - var headers: HTTPHeaders = [.contentDisposition(disposition)] - if let mimeType = mimeType { headers.add(.contentType(mimeType)) } - - return headers - } - - // MARK: - Private - Boundary Encoding - - private func initialBoundaryData() -> Data { - BoundaryGenerator.boundaryData(forBoundaryType: .initial, boundary: boundary) - } - - private func encapsulatedBoundaryData() -> Data { - BoundaryGenerator.boundaryData(forBoundaryType: .encapsulated, boundary: boundary) - } - - private func finalBoundaryData() -> Data { - BoundaryGenerator.boundaryData(forBoundaryType: .final, boundary: boundary) - } - - // MARK: - Private - Errors - - private func setBodyPartError(withReason reason: AFError.MultipartEncodingFailureReason) { - guard bodyPartError == nil else { return } - bodyPartError = AFError.multipartEncodingFailed(reason: reason) - } -} diff --git a/Pods/Alamofire/Source/MultipartUpload.swift b/Pods/Alamofire/Source/MultipartUpload.swift deleted file mode 100644 index 606bd33ee..000000000 --- a/Pods/Alamofire/Source/MultipartUpload.swift +++ /dev/null @@ -1,89 +0,0 @@ -// -// MultipartUpload.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -/// Internal type which encapsulates a `MultipartFormData` upload. -final class MultipartUpload { - lazy var result = Result { try build() } - - @Protected - private(set) var multipartFormData: MultipartFormData - let encodingMemoryThreshold: UInt64 - let request: URLRequestConvertible - let fileManager: FileManager - - init(encodingMemoryThreshold: UInt64, - request: URLRequestConvertible, - multipartFormData: MultipartFormData) { - self.encodingMemoryThreshold = encodingMemoryThreshold - self.request = request - fileManager = multipartFormData.fileManager - self.multipartFormData = multipartFormData - } - - func build() throws -> UploadRequest.Uploadable { - let uploadable: UploadRequest.Uploadable - if multipartFormData.contentLength < encodingMemoryThreshold { - let data = try multipartFormData.encode() - - uploadable = .data(data) - } else { - let tempDirectoryURL = fileManager.temporaryDirectory - let directoryURL = tempDirectoryURL.appendingPathComponent("org.alamofire.manager/multipart.form.data") - let fileName = UUID().uuidString - let fileURL = directoryURL.appendingPathComponent(fileName) - - try fileManager.createDirectory(at: directoryURL, withIntermediateDirectories: true, attributes: nil) - - do { - try multipartFormData.writeEncodedData(to: fileURL) - } catch { - // Cleanup after attempted write if it fails. - try? fileManager.removeItem(at: fileURL) - throw error - } - - uploadable = .file(fileURL, shouldRemove: true) - } - - return uploadable - } -} - -extension MultipartUpload: UploadConvertible { - func asURLRequest() throws -> URLRequest { - var urlRequest = try request.asURLRequest() - - $multipartFormData.read { multipartFormData in - urlRequest.headers.add(.contentType(multipartFormData.contentType)) - } - - return urlRequest - } - - func createUploadable() throws -> UploadRequest.Uploadable { - try result.get() - } -} diff --git a/Pods/Alamofire/Source/NetworkReachabilityManager.swift b/Pods/Alamofire/Source/NetworkReachabilityManager.swift deleted file mode 100644 index b97b62fa4..000000000 --- a/Pods/Alamofire/Source/NetworkReachabilityManager.swift +++ /dev/null @@ -1,267 +0,0 @@ -// -// NetworkReachabilityManager.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -#if !(os(watchOS) || os(Linux)) - -import Foundation -import SystemConfiguration - -/// The `NetworkReachabilityManager` class listens for reachability changes of hosts and addresses for both cellular and -/// WiFi network interfaces. -/// -/// Reachability can be used to determine background information about why a network operation failed, or to retry -/// network requests when a connection is established. It should not be used to prevent a user from initiating a network -/// request, as it's possible that an initial request may be required to establish reachability. -open class NetworkReachabilityManager { - /// Defines the various states of network reachability. - public enum NetworkReachabilityStatus { - /// It is unknown whether the network is reachable. - case unknown - /// The network is not reachable. - case notReachable - /// The network is reachable on the associated `ConnectionType`. - case reachable(ConnectionType) - - init(_ flags: SCNetworkReachabilityFlags) { - guard flags.isActuallyReachable else { self = .notReachable; return } - - var networkStatus: NetworkReachabilityStatus = .reachable(.ethernetOrWiFi) - - if flags.isCellular { networkStatus = .reachable(.cellular) } - - self = networkStatus - } - - /// Defines the various connection types detected by reachability flags. - public enum ConnectionType { - /// The connection type is either over Ethernet or WiFi. - case ethernetOrWiFi - /// The connection type is a cellular connection. - case cellular - } - } - - /// A closure executed when the network reachability status changes. The closure takes a single argument: the - /// network reachability status. - public typealias Listener = (NetworkReachabilityStatus) -> Void - - /// Default `NetworkReachabilityManager` for the zero address and a `listenerQueue` of `.main`. - public static let `default` = NetworkReachabilityManager() - - // MARK: - Properties - - /// Whether the network is currently reachable. - open var isReachable: Bool { isReachableOnCellular || isReachableOnEthernetOrWiFi } - - /// Whether the network is currently reachable over the cellular interface. - /// - /// - Note: Using this property to decide whether to make a high or low bandwidth request is not recommended. - /// Instead, set the `allowsCellularAccess` on any `URLRequest`s being issued. - /// - open var isReachableOnCellular: Bool { status == .reachable(.cellular) } - - /// Whether the network is currently reachable over Ethernet or WiFi interface. - open var isReachableOnEthernetOrWiFi: Bool { status == .reachable(.ethernetOrWiFi) } - - /// `DispatchQueue` on which reachability will update. - public let reachabilityQueue = DispatchQueue(label: "org.alamofire.reachabilityQueue") - - /// Flags of the current reachability type, if any. - open var flags: SCNetworkReachabilityFlags? { - var flags = SCNetworkReachabilityFlags() - - return (SCNetworkReachabilityGetFlags(reachability, &flags)) ? flags : nil - } - - /// The current network reachability status. - open var status: NetworkReachabilityStatus { - flags.map(NetworkReachabilityStatus.init) ?? .unknown - } - - /// Mutable state storage. - struct MutableState { - /// A closure executed when the network reachability status changes. - var listener: Listener? - /// `DispatchQueue` on which listeners will be called. - var listenerQueue: DispatchQueue? - /// Previously calculated status. - var previousStatus: NetworkReachabilityStatus? - } - - /// `SCNetworkReachability` instance providing notifications. - private let reachability: SCNetworkReachability - - /// Protected storage for mutable state. - @Protected - private var mutableState = MutableState() - - // MARK: - Initialization - - /// Creates an instance with the specified host. - /// - /// - Note: The `host` value must *not* contain a scheme, just the hostname. - /// - /// - Parameters: - /// - host: Host used to evaluate network reachability. Must *not* include the scheme (e.g. `https`). - public convenience init?(host: String) { - guard let reachability = SCNetworkReachabilityCreateWithName(nil, host) else { return nil } - - self.init(reachability: reachability) - } - - /// Creates an instance that monitors the address 0.0.0.0. - /// - /// Reachability treats the 0.0.0.0 address as a special token that causes it to monitor the general routing - /// status of the device, both IPv4 and IPv6. - public convenience init?() { - var zero = sockaddr() - zero.sa_len = UInt8(MemoryLayout.size) - zero.sa_family = sa_family_t(AF_INET) - - guard let reachability = SCNetworkReachabilityCreateWithAddress(nil, &zero) else { return nil } - - self.init(reachability: reachability) - } - - private init(reachability: SCNetworkReachability) { - self.reachability = reachability - } - - deinit { - stopListening() - } - - // MARK: - Listening - - /// Starts listening for changes in network reachability status. - /// - /// - Note: Stops and removes any existing listener. - /// - /// - Parameters: - /// - queue: `DispatchQueue` on which to call the `listener` closure. `.main` by default. - /// - listener: `Listener` closure called when reachability changes. - /// - /// - Returns: `true` if listening was started successfully, `false` otherwise. - @discardableResult - open func startListening(onQueue queue: DispatchQueue = .main, - onUpdatePerforming listener: @escaping Listener) -> Bool { - stopListening() - - $mutableState.write { state in - state.listenerQueue = queue - state.listener = listener - } - - var context = SCNetworkReachabilityContext(version: 0, - info: Unmanaged.passUnretained(self).toOpaque(), - retain: nil, - release: nil, - copyDescription: nil) - let callback: SCNetworkReachabilityCallBack = { _, flags, info in - guard let info = info else { return } - - let instance = Unmanaged.fromOpaque(info).takeUnretainedValue() - instance.notifyListener(flags) - } - - let queueAdded = SCNetworkReachabilitySetDispatchQueue(reachability, reachabilityQueue) - let callbackAdded = SCNetworkReachabilitySetCallback(reachability, callback, &context) - - // Manually call listener to give initial state, since the framework may not. - if let currentFlags = flags { - reachabilityQueue.async { - self.notifyListener(currentFlags) - } - } - - return callbackAdded && queueAdded - } - - /// Stops listening for changes in network reachability status. - open func stopListening() { - SCNetworkReachabilitySetCallback(reachability, nil, nil) - SCNetworkReachabilitySetDispatchQueue(reachability, nil) - $mutableState.write { state in - state.listener = nil - state.listenerQueue = nil - state.previousStatus = nil - } - } - - // MARK: - Internal - Listener Notification - - /// Calls the `listener` closure of the `listenerQueue` if the computed status hasn't changed. - /// - /// - Note: Should only be called from the `reachabilityQueue`. - /// - /// - Parameter flags: `SCNetworkReachabilityFlags` to use to calculate the status. - func notifyListener(_ flags: SCNetworkReachabilityFlags) { - let newStatus = NetworkReachabilityStatus(flags) - - $mutableState.write { state in - guard state.previousStatus != newStatus else { return } - - state.previousStatus = newStatus - - let listener = state.listener - state.listenerQueue?.async { listener?(newStatus) } - } - } -} - -// MARK: - - -extension NetworkReachabilityManager.NetworkReachabilityStatus: Equatable {} - -extension SCNetworkReachabilityFlags { - var isReachable: Bool { contains(.reachable) } - var isConnectionRequired: Bool { contains(.connectionRequired) } - var canConnectAutomatically: Bool { contains(.connectionOnDemand) || contains(.connectionOnTraffic) } - var canConnectWithoutUserInteraction: Bool { canConnectAutomatically && !contains(.interventionRequired) } - var isActuallyReachable: Bool { isReachable && (!isConnectionRequired || canConnectWithoutUserInteraction) } - var isCellular: Bool { - #if os(iOS) || os(tvOS) - return contains(.isWWAN) - #else - return false - #endif - } - - /// Human readable `String` for all states, to help with debugging. - var readableDescription: String { - let W = isCellular ? "W" : "-" - let R = isReachable ? "R" : "-" - let c = isConnectionRequired ? "c" : "-" - let t = contains(.transientConnection) ? "t" : "-" - let i = contains(.interventionRequired) ? "i" : "-" - let C = contains(.connectionOnTraffic) ? "C" : "-" - let D = contains(.connectionOnDemand) ? "D" : "-" - let l = contains(.isLocalAddress) ? "l" : "-" - let d = contains(.isDirect) ? "d" : "-" - let a = contains(.connectionAutomatic) ? "a" : "-" - - return "\(W)\(R) \(c)\(t)\(i)\(C)\(D)\(l)\(d)\(a)" - } -} -#endif diff --git a/Pods/Alamofire/Source/Notifications.swift b/Pods/Alamofire/Source/Notifications.swift deleted file mode 100644 index 66434b6e7..000000000 --- a/Pods/Alamofire/Source/Notifications.swift +++ /dev/null @@ -1,115 +0,0 @@ -// -// Notifications.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -extension Request { - /// Posted when a `Request` is resumed. The `Notification` contains the resumed `Request`. - public static let didResumeNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didResume") - /// Posted when a `Request` is suspended. The `Notification` contains the suspended `Request`. - public static let didSuspendNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didSuspend") - /// Posted when a `Request` is cancelled. The `Notification` contains the cancelled `Request`. - public static let didCancelNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didCancel") - /// Posted when a `Request` is finished. The `Notification` contains the completed `Request`. - public static let didFinishNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didFinish") - - /// Posted when a `URLSessionTask` is resumed. The `Notification` contains the `Request` associated with the `URLSessionTask`. - public static let didResumeTaskNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didResumeTask") - /// Posted when a `URLSessionTask` is suspended. The `Notification` contains the `Request` associated with the `URLSessionTask`. - public static let didSuspendTaskNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didSuspendTask") - /// Posted when a `URLSessionTask` is cancelled. The `Notification` contains the `Request` associated with the `URLSessionTask`. - public static let didCancelTaskNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didCancelTask") - /// Posted when a `URLSessionTask` is completed. The `Notification` contains the `Request` associated with the `URLSessionTask`. - public static let didCompleteTaskNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didCompleteTask") -} - -// MARK: - - -extension Notification { - /// The `Request` contained by the instance's `userInfo`, `nil` otherwise. - public var request: Request? { - userInfo?[String.requestKey] as? Request - } - - /// Convenience initializer for a `Notification` containing a `Request` payload. - /// - /// - Parameters: - /// - name: The name of the notification. - /// - request: The `Request` payload. - init(name: Notification.Name, request: Request) { - self.init(name: name, object: nil, userInfo: [String.requestKey: request]) - } -} - -extension NotificationCenter { - /// Convenience function for posting notifications with `Request` payloads. - /// - /// - Parameters: - /// - name: The name of the notification. - /// - request: The `Request` payload. - func postNotification(named name: Notification.Name, with request: Request) { - let notification = Notification(name: name, request: request) - post(notification) - } -} - -extension String { - /// User info dictionary key representing the `Request` associated with the notification. - fileprivate static let requestKey = "org.alamofire.notification.key.request" -} - -/// `EventMonitor` that provides Alamofire's notifications. -public final class AlamofireNotifications: EventMonitor { - public func requestDidResume(_ request: Request) { - NotificationCenter.default.postNotification(named: Request.didResumeNotification, with: request) - } - - public func requestDidSuspend(_ request: Request) { - NotificationCenter.default.postNotification(named: Request.didSuspendNotification, with: request) - } - - public func requestDidCancel(_ request: Request) { - NotificationCenter.default.postNotification(named: Request.didCancelNotification, with: request) - } - - public func requestDidFinish(_ request: Request) { - NotificationCenter.default.postNotification(named: Request.didFinishNotification, with: request) - } - - public func request(_ request: Request, didResumeTask task: URLSessionTask) { - NotificationCenter.default.postNotification(named: Request.didResumeTaskNotification, with: request) - } - - public func request(_ request: Request, didSuspendTask task: URLSessionTask) { - NotificationCenter.default.postNotification(named: Request.didSuspendTaskNotification, with: request) - } - - public func request(_ request: Request, didCancelTask task: URLSessionTask) { - NotificationCenter.default.postNotification(named: Request.didCancelTaskNotification, with: request) - } - - public func request(_ request: Request, didCompleteTask task: URLSessionTask, with error: AFError?) { - NotificationCenter.default.postNotification(named: Request.didCompleteTaskNotification, with: request) - } -} diff --git a/Pods/Alamofire/Source/OperationQueue+Alamofire.swift b/Pods/Alamofire/Source/OperationQueue+Alamofire.swift deleted file mode 100644 index b06a0ccc3..000000000 --- a/Pods/Alamofire/Source/OperationQueue+Alamofire.swift +++ /dev/null @@ -1,49 +0,0 @@ -// -// OperationQueue+Alamofire.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -extension OperationQueue { - /// Creates an instance using the provided parameters. - /// - /// - Parameters: - /// - qualityOfService: `QualityOfService` to be applied to the queue. `.default` by default. - /// - maxConcurrentOperationCount: Maximum concurrent operations. - /// `OperationQueue.defaultMaxConcurrentOperationCount` by default. - /// - underlyingQueue: Underlying `DispatchQueue`. `nil` by default. - /// - name: Name for the queue. `nil` by default. - /// - startSuspended: Whether the queue starts suspended. `false` by default. - convenience init(qualityOfService: QualityOfService = .default, - maxConcurrentOperationCount: Int = OperationQueue.defaultMaxConcurrentOperationCount, - underlyingQueue: DispatchQueue? = nil, - name: String? = nil, - startSuspended: Bool = false) { - self.init() - self.qualityOfService = qualityOfService - self.maxConcurrentOperationCount = maxConcurrentOperationCount - self.underlyingQueue = underlyingQueue - self.name = name - isSuspended = startSuspended - } -} diff --git a/Pods/Alamofire/Source/ParameterEncoder.swift b/Pods/Alamofire/Source/ParameterEncoder.swift deleted file mode 100644 index f4facbee3..000000000 --- a/Pods/Alamofire/Source/ParameterEncoder.swift +++ /dev/null @@ -1,184 +0,0 @@ -// -// ParameterEncoder.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -/// A type that can encode any `Encodable` type into a `URLRequest`. -public protocol ParameterEncoder { - /// Encode the provided `Encodable` parameters into `request`. - /// - /// - Parameters: - /// - parameters: The `Encodable` parameter value. - /// - request: The `URLRequest` into which to encode the parameters. - /// - /// - Returns: A `URLRequest` with the result of the encoding. - /// - Throws: An `Error` when encoding fails. For Alamofire provided encoders, this will be an instance of - /// `AFError.parameterEncoderFailed` with an associated `ParameterEncoderFailureReason`. - func encode(_ parameters: Parameters?, into request: URLRequest) throws -> URLRequest -} - -/// A `ParameterEncoder` that encodes types as JSON body data. -/// -/// If no `Content-Type` header is already set on the provided `URLRequest`s, it's set to `application/json`. -open class JSONParameterEncoder: ParameterEncoder { - /// Returns an encoder with default parameters. - public static var `default`: JSONParameterEncoder { JSONParameterEncoder() } - - /// Returns an encoder with `JSONEncoder.outputFormatting` set to `.prettyPrinted`. - public static var prettyPrinted: JSONParameterEncoder { - let encoder = JSONEncoder() - encoder.outputFormatting = .prettyPrinted - - return JSONParameterEncoder(encoder: encoder) - } - - /// Returns an encoder with `JSONEncoder.outputFormatting` set to `.sortedKeys`. - @available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) - public static var sortedKeys: JSONParameterEncoder { - let encoder = JSONEncoder() - encoder.outputFormatting = .sortedKeys - - return JSONParameterEncoder(encoder: encoder) - } - - /// `JSONEncoder` used to encode parameters. - public let encoder: JSONEncoder - - /// Creates an instance with the provided `JSONEncoder`. - /// - /// - Parameter encoder: The `JSONEncoder`. `JSONEncoder()` by default. - public init(encoder: JSONEncoder = JSONEncoder()) { - self.encoder = encoder - } - - open func encode(_ parameters: Parameters?, - into request: URLRequest) throws -> URLRequest { - guard let parameters = parameters else { return request } - - var request = request - - do { - let data = try encoder.encode(parameters) - request.httpBody = data - if request.headers["Content-Type"] == nil { - request.headers.update(.contentType("application/json")) - } - } catch { - throw AFError.parameterEncodingFailed(reason: .jsonEncodingFailed(error: error)) - } - - return request - } -} - -/// A `ParameterEncoder` that encodes types as URL-encoded query strings to be set on the URL or as body data, depending -/// on the `Destination` set. -/// -/// If no `Content-Type` header is already set on the provided `URLRequest`s, it will be set to -/// `application/x-www-form-urlencoded; charset=utf-8`. -/// -/// Encoding behavior can be customized by passing an instance of `URLEncodedFormEncoder` to the initializer. -open class URLEncodedFormParameterEncoder: ParameterEncoder { - /// Defines where the URL-encoded string should be set for each `URLRequest`. - public enum Destination { - /// Applies the encoded query string to any existing query string for `.get`, `.head`, and `.delete` request. - /// Sets it to the `httpBody` for all other methods. - case methodDependent - /// Applies the encoded query string to any existing query string from the `URLRequest`. - case queryString - /// Applies the encoded query string to the `httpBody` of the `URLRequest`. - case httpBody - - /// Determines whether the URL-encoded string should be applied to the `URLRequest`'s `url`. - /// - /// - Parameter method: The `HTTPMethod`. - /// - /// - Returns: Whether the URL-encoded string should be applied to a `URL`. - func encodesParametersInURL(for method: HTTPMethod) -> Bool { - switch self { - case .methodDependent: return [.get, .head, .delete].contains(method) - case .queryString: return true - case .httpBody: return false - } - } - } - - /// Returns an encoder with default parameters. - public static var `default`: URLEncodedFormParameterEncoder { URLEncodedFormParameterEncoder() } - - /// The `URLEncodedFormEncoder` to use. - public let encoder: URLEncodedFormEncoder - - /// The `Destination` for the URL-encoded string. - public let destination: Destination - - /// Creates an instance with the provided `URLEncodedFormEncoder` instance and `Destination` value. - /// - /// - Parameters: - /// - encoder: The `URLEncodedFormEncoder`. `URLEncodedFormEncoder()` by default. - /// - destination: The `Destination`. `.methodDependent` by default. - public init(encoder: URLEncodedFormEncoder = URLEncodedFormEncoder(), destination: Destination = .methodDependent) { - self.encoder = encoder - self.destination = destination - } - - open func encode(_ parameters: Parameters?, - into request: URLRequest) throws -> URLRequest { - guard let parameters = parameters else { return request } - - var request = request - - guard let url = request.url else { - throw AFError.parameterEncoderFailed(reason: .missingRequiredComponent(.url)) - } - - guard let method = request.method else { - let rawValue = request.method?.rawValue ?? "nil" - throw AFError.parameterEncoderFailed(reason: .missingRequiredComponent(.httpMethod(rawValue: rawValue))) - } - - if destination.encodesParametersInURL(for: method), - var components = URLComponents(url: url, resolvingAgainstBaseURL: false) { - let query: String = try Result { try encoder.encode(parameters) } - .mapError { AFError.parameterEncoderFailed(reason: .encoderFailed(error: $0)) }.get() - let newQueryString = [components.percentEncodedQuery, query].compactMap { $0 }.joinedWithAmpersands() - components.percentEncodedQuery = newQueryString.isEmpty ? nil : newQueryString - - guard let newURL = components.url else { - throw AFError.parameterEncoderFailed(reason: .missingRequiredComponent(.url)) - } - - request.url = newURL - } else { - if request.headers["Content-Type"] == nil { - request.headers.update(.contentType("application/x-www-form-urlencoded; charset=utf-8")) - } - - request.httpBody = try Result { try encoder.encode(parameters) } - .mapError { AFError.parameterEncoderFailed(reason: .encoderFailed(error: $0)) }.get() - } - - return request - } -} diff --git a/Pods/Alamofire/Source/ParameterEncoding.swift b/Pods/Alamofire/Source/ParameterEncoding.swift deleted file mode 100644 index 6e72604c7..000000000 --- a/Pods/Alamofire/Source/ParameterEncoding.swift +++ /dev/null @@ -1,317 +0,0 @@ -// -// ParameterEncoding.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -/// A dictionary of parameters to apply to a `URLRequest`. -public typealias Parameters = [String: Any] - -/// A type used to define how a set of parameters are applied to a `URLRequest`. -public protocol ParameterEncoding { - /// Creates a `URLRequest` by encoding parameters and applying them on the passed request. - /// - /// - Parameters: - /// - urlRequest: `URLRequestConvertible` value onto which parameters will be encoded. - /// - parameters: `Parameters` to encode onto the request. - /// - /// - Returns: The encoded `URLRequest`. - /// - Throws: Any `Error` produced during parameter encoding. - func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest -} - -// MARK: - - -/// Creates a url-encoded query string to be set as or appended to any existing URL query string or set as the HTTP -/// body of the URL request. Whether the query string is set or appended to any existing URL query string or set as -/// the HTTP body depends on the destination of the encoding. -/// -/// The `Content-Type` HTTP header field of an encoded request with HTTP body is set to -/// `application/x-www-form-urlencoded; charset=utf-8`. -/// -/// There is no published specification for how to encode collection types. By default the convention of appending -/// `[]` to the key for array values (`foo[]=1&foo[]=2`), and appending the key surrounded by square brackets for -/// nested dictionary values (`foo[bar]=baz`) is used. Optionally, `ArrayEncoding` can be used to omit the -/// square brackets appended to array keys. -/// -/// `BoolEncoding` can be used to configure how boolean values are encoded. The default behavior is to encode -/// `true` as 1 and `false` as 0. -public struct URLEncoding: ParameterEncoding { - // MARK: Helper Types - - /// Defines whether the url-encoded query string is applied to the existing query string or HTTP body of the - /// resulting URL request. - public enum Destination { - /// Applies encoded query string result to existing query string for `GET`, `HEAD` and `DELETE` requests and - /// sets as the HTTP body for requests with any other HTTP method. - case methodDependent - /// Sets or appends encoded query string result to existing query string. - case queryString - /// Sets encoded query string result as the HTTP body of the URL request. - case httpBody - - func encodesParametersInURL(for method: HTTPMethod) -> Bool { - switch self { - case .methodDependent: return [.get, .head, .delete].contains(method) - case .queryString: return true - case .httpBody: return false - } - } - } - - /// Configures how `Array` parameters are encoded. - public enum ArrayEncoding { - /// An empty set of square brackets is appended to the key for every value. This is the default behavior. - case brackets - /// No brackets are appended. The key is encoded as is. - case noBrackets - - func encode(key: String) -> String { - switch self { - case .brackets: - return "\(key)[]" - case .noBrackets: - return key - } - } - } - - /// Configures how `Bool` parameters are encoded. - public enum BoolEncoding { - /// Encode `true` as `1` and `false` as `0`. This is the default behavior. - case numeric - /// Encode `true` and `false` as string literals. - case literal - - func encode(value: Bool) -> String { - switch self { - case .numeric: - return value ? "1" : "0" - case .literal: - return value ? "true" : "false" - } - } - } - - // MARK: Properties - - /// Returns a default `URLEncoding` instance with a `.methodDependent` destination. - public static var `default`: URLEncoding { URLEncoding() } - - /// Returns a `URLEncoding` instance with a `.queryString` destination. - public static var queryString: URLEncoding { URLEncoding(destination: .queryString) } - - /// Returns a `URLEncoding` instance with an `.httpBody` destination. - public static var httpBody: URLEncoding { URLEncoding(destination: .httpBody) } - - /// The destination defining where the encoded query string is to be applied to the URL request. - public let destination: Destination - - /// The encoding to use for `Array` parameters. - public let arrayEncoding: ArrayEncoding - - /// The encoding to use for `Bool` parameters. - public let boolEncoding: BoolEncoding - - // MARK: Initialization - - /// Creates an instance using the specified parameters. - /// - /// - Parameters: - /// - destination: `Destination` defining where the encoded query string will be applied. `.methodDependent` by - /// default. - /// - arrayEncoding: `ArrayEncoding` to use. `.brackets` by default. - /// - boolEncoding: `BoolEncoding` to use. `.numeric` by default. - public init(destination: Destination = .methodDependent, - arrayEncoding: ArrayEncoding = .brackets, - boolEncoding: BoolEncoding = .numeric) { - self.destination = destination - self.arrayEncoding = arrayEncoding - self.boolEncoding = boolEncoding - } - - // MARK: Encoding - - public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest { - var urlRequest = try urlRequest.asURLRequest() - - guard let parameters = parameters else { return urlRequest } - - if let method = urlRequest.method, destination.encodesParametersInURL(for: method) { - guard let url = urlRequest.url else { - throw AFError.parameterEncodingFailed(reason: .missingURL) - } - - if var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false), !parameters.isEmpty { - let percentEncodedQuery = (urlComponents.percentEncodedQuery.map { $0 + "&" } ?? "") + query(parameters) - urlComponents.percentEncodedQuery = percentEncodedQuery - urlRequest.url = urlComponents.url - } - } else { - if urlRequest.headers["Content-Type"] == nil { - urlRequest.headers.update(.contentType("application/x-www-form-urlencoded; charset=utf-8")) - } - - urlRequest.httpBody = Data(query(parameters).utf8) - } - - return urlRequest - } - - /// Creates a percent-escaped, URL encoded query string components from the given key-value pair recursively. - /// - /// - Parameters: - /// - key: Key of the query component. - /// - value: Value of the query component. - /// - /// - Returns: The percent-escaped, URL encoded query string components. - public func queryComponents(fromKey key: String, value: Any) -> [(String, String)] { - var components: [(String, String)] = [] - switch value { - case let dictionary as [String: Any]: - for (nestedKey, value) in dictionary { - components += queryComponents(fromKey: "\(key)[\(nestedKey)]", value: value) - } - case let array as [Any]: - for value in array { - components += queryComponents(fromKey: arrayEncoding.encode(key: key), value: value) - } - case let number as NSNumber: - if number.isBool { - components.append((escape(key), escape(boolEncoding.encode(value: number.boolValue)))) - } else { - components.append((escape(key), escape("\(number)"))) - } - case let bool as Bool: - components.append((escape(key), escape(boolEncoding.encode(value: bool)))) - default: - components.append((escape(key), escape("\(value)"))) - } - return components - } - - /// Creates a percent-escaped string following RFC 3986 for a query string key or value. - /// - /// - Parameter string: `String` to be percent-escaped. - /// - /// - Returns: The percent-escaped `String`. - public func escape(_ string: String) -> String { - string.addingPercentEncoding(withAllowedCharacters: .afURLQueryAllowed) ?? string - } - - private func query(_ parameters: [String: Any]) -> String { - var components: [(String, String)] = [] - - for key in parameters.keys.sorted(by: <) { - let value = parameters[key]! - components += queryComponents(fromKey: key, value: value) - } - return components.map { "\($0)=\($1)" }.joined(separator: "&") - } -} - -// MARK: - - -/// Uses `JSONSerialization` to create a JSON representation of the parameters object, which is set as the body of the -/// request. The `Content-Type` HTTP header field of an encoded request is set to `application/json`. -public struct JSONEncoding: ParameterEncoding { - // MARK: Properties - - /// Returns a `JSONEncoding` instance with default writing options. - public static var `default`: JSONEncoding { JSONEncoding() } - - /// Returns a `JSONEncoding` instance with `.prettyPrinted` writing options. - public static var prettyPrinted: JSONEncoding { JSONEncoding(options: .prettyPrinted) } - - /// The options for writing the parameters as JSON data. - public let options: JSONSerialization.WritingOptions - - // MARK: Initialization - - /// Creates an instance using the specified `WritingOptions`. - /// - /// - Parameter options: `JSONSerialization.WritingOptions` to use. - public init(options: JSONSerialization.WritingOptions = []) { - self.options = options - } - - // MARK: Encoding - - public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest { - var urlRequest = try urlRequest.asURLRequest() - - guard let parameters = parameters else { return urlRequest } - - do { - let data = try JSONSerialization.data(withJSONObject: parameters, options: options) - - if urlRequest.headers["Content-Type"] == nil { - urlRequest.headers.update(.contentType("application/json")) - } - - urlRequest.httpBody = data - } catch { - throw AFError.parameterEncodingFailed(reason: .jsonEncodingFailed(error: error)) - } - - return urlRequest - } - - /// Encodes any JSON compatible object into a `URLRequest`. - /// - /// - Parameters: - /// - urlRequest: `URLRequestConvertible` value into which the object will be encoded. - /// - jsonObject: `Any` value (must be JSON compatible` to be encoded into the `URLRequest`. `nil` by default. - /// - /// - Returns: The encoded `URLRequest`. - /// - Throws: Any `Error` produced during encoding. - public func encode(_ urlRequest: URLRequestConvertible, withJSONObject jsonObject: Any? = nil) throws -> URLRequest { - var urlRequest = try urlRequest.asURLRequest() - - guard let jsonObject = jsonObject else { return urlRequest } - - do { - let data = try JSONSerialization.data(withJSONObject: jsonObject, options: options) - - if urlRequest.headers["Content-Type"] == nil { - urlRequest.headers.update(.contentType("application/json")) - } - - urlRequest.httpBody = data - } catch { - throw AFError.parameterEncodingFailed(reason: .jsonEncodingFailed(error: error)) - } - - return urlRequest - } -} - -// MARK: - - -extension NSNumber { - fileprivate var isBool: Bool { - // Use Obj-C type encoding to check whether the underlying type is a `Bool`, as it's guaranteed as part of - // swift-corelibs-foundation, per [this discussion on the Swift forums](https://forums.swift.org/t/alamofire-on-linux-possible-but-not-release-ready/34553/22). - String(cString: objCType) == "c" - } -} diff --git a/Pods/Alamofire/Source/Protected.swift b/Pods/Alamofire/Source/Protected.swift deleted file mode 100644 index 6288205e6..000000000 --- a/Pods/Alamofire/Source/Protected.swift +++ /dev/null @@ -1,224 +0,0 @@ -// -// Protected.swift -// -// Copyright (c) 2014-2020 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -private protocol Lock { - func lock() - func unlock() -} - -extension Lock { - /// Executes a closure returning a value while acquiring the lock. - /// - /// - Parameter closure: The closure to run. - /// - /// - Returns: The value the closure generated. - func around(_ closure: () -> T) -> T { - lock(); defer { unlock() } - return closure() - } - - /// Execute a closure while acquiring the lock. - /// - /// - Parameter closure: The closure to run. - func around(_ closure: () -> Void) { - lock(); defer { unlock() } - closure() - } -} - -#if os(Linux) -/// A `pthread_mutex_t` wrapper. -final class MutexLock: Lock { - private var mutex: UnsafeMutablePointer - - init() { - mutex = .allocate(capacity: 1) - - var attr = pthread_mutexattr_t() - pthread_mutexattr_init(&attr) - pthread_mutexattr_settype(&attr, .init(PTHREAD_MUTEX_ERRORCHECK)) - - let error = pthread_mutex_init(mutex, &attr) - precondition(error == 0, "Failed to create pthread_mutex") - } - - deinit { - let error = pthread_mutex_destroy(mutex) - precondition(error == 0, "Failed to destroy pthread_mutex") - } - - fileprivate func lock() { - let error = pthread_mutex_lock(mutex) - precondition(error == 0, "Failed to lock pthread_mutex") - } - - fileprivate func unlock() { - let error = pthread_mutex_unlock(mutex) - precondition(error == 0, "Failed to unlock pthread_mutex") - } -} -#endif - -#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) -/// An `os_unfair_lock` wrapper. -final class UnfairLock: Lock { - private let unfairLock: os_unfair_lock_t - - init() { - unfairLock = .allocate(capacity: 1) - unfairLock.initialize(to: os_unfair_lock()) - } - - deinit { - unfairLock.deinitialize(count: 1) - unfairLock.deallocate() - } - - fileprivate func lock() { - os_unfair_lock_lock(unfairLock) - } - - fileprivate func unlock() { - os_unfair_lock_unlock(unfairLock) - } -} -#endif - -/// A thread-safe wrapper around a value. -@propertyWrapper -@dynamicMemberLookup -final class Protected { - #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) - private let lock = UnfairLock() - #elseif os(Linux) - private let lock = MutexLock() - #endif - private var value: T - - init(_ value: T) { - self.value = value - } - - /// The contained value. Unsafe for anything more than direct read or write. - var wrappedValue: T { - get { lock.around { value } } - set { lock.around { value = newValue } } - } - - var projectedValue: Protected { self } - - init(wrappedValue: T) { - value = wrappedValue - } - - /// Synchronously read or transform the contained value. - /// - /// - Parameter closure: The closure to execute. - /// - /// - Returns: The return value of the closure passed. - func read(_ closure: (T) -> U) -> U { - lock.around { closure(self.value) } - } - - /// Synchronously modify the protected value. - /// - /// - Parameter closure: The closure to execute. - /// - /// - Returns: The modified value. - @discardableResult - func write(_ closure: (inout T) -> U) -> U { - lock.around { closure(&self.value) } - } - - subscript(dynamicMember keyPath: WritableKeyPath) -> Property { - get { lock.around { value[keyPath: keyPath] } } - set { lock.around { value[keyPath: keyPath] = newValue } } - } -} - -extension Protected where T: RangeReplaceableCollection { - /// Adds a new element to the end of this protected collection. - /// - /// - Parameter newElement: The `Element` to append. - func append(_ newElement: T.Element) { - write { (ward: inout T) in - ward.append(newElement) - } - } - - /// Adds the elements of a sequence to the end of this protected collection. - /// - /// - Parameter newElements: The `Sequence` to append. - func append(contentsOf newElements: S) where S.Element == T.Element { - write { (ward: inout T) in - ward.append(contentsOf: newElements) - } - } - - /// Add the elements of a collection to the end of the protected collection. - /// - /// - Parameter newElements: The `Collection` to append. - func append(contentsOf newElements: C) where C.Element == T.Element { - write { (ward: inout T) in - ward.append(contentsOf: newElements) - } - } -} - -extension Protected where T == Data? { - /// Adds the contents of a `Data` value to the end of the protected `Data`. - /// - /// - Parameter data: The `Data` to be appended. - func append(_ data: Data) { - write { (ward: inout T) in - ward?.append(data) - } - } -} - -extension Protected where T == Request.MutableState { - /// Attempts to transition to the passed `State`. - /// - /// - Parameter state: The `State` to attempt transition to. - /// - /// - Returns: Whether the transition occurred. - func attemptToTransitionTo(_ state: Request.State) -> Bool { - lock.around { - guard value.state.canTransitionTo(state) else { return false } - - value.state = state - - return true - } - } - - /// Perform a closure while locked with the provided `Request.State`. - /// - /// - Parameter perform: The closure to perform while locked. - func withState(perform: (Request.State) -> Void) { - lock.around { perform(value.state) } - } -} diff --git a/Pods/Alamofire/Source/RedirectHandler.swift b/Pods/Alamofire/Source/RedirectHandler.swift deleted file mode 100644 index b6c069cad..000000000 --- a/Pods/Alamofire/Source/RedirectHandler.swift +++ /dev/null @@ -1,95 +0,0 @@ -// -// RedirectHandler.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -/// A type that handles how an HTTP redirect response from a remote server should be redirected to the new request. -public protocol RedirectHandler { - /// Determines how the HTTP redirect response should be redirected to the new request. - /// - /// The `completion` closure should be passed one of three possible options: - /// - /// 1. The new request specified by the redirect (this is the most common use case). - /// 2. A modified version of the new request (you may want to route it somewhere else). - /// 3. A `nil` value to deny the redirect request and return the body of the redirect response. - /// - /// - Parameters: - /// - task: The `URLSessionTask` whose request resulted in a redirect. - /// - request: The `URLRequest` to the new location specified by the redirect response. - /// - response: The `HTTPURLResponse` containing the server's response to the original request. - /// - completion: The closure to execute containing the new `URLRequest`, a modified `URLRequest`, or `nil`. - func task(_ task: URLSessionTask, - willBeRedirectedTo request: URLRequest, - for response: HTTPURLResponse, - completion: @escaping (URLRequest?) -> Void) -} - -// MARK: - - -/// `Redirector` is a convenience `RedirectHandler` making it easy to follow, not follow, or modify a redirect. -public struct Redirector { - /// Defines the behavior of the `Redirector` type. - public enum Behavior { - /// Follow the redirect as defined in the response. - case follow - /// Do not follow the redirect defined in the response. - case doNotFollow - /// Modify the redirect request defined in the response. - case modify((URLSessionTask, URLRequest, HTTPURLResponse) -> URLRequest?) - } - - /// Returns a `Redirector` with a `.follow` `Behavior`. - public static let follow = Redirector(behavior: .follow) - /// Returns a `Redirector` with a `.doNotFollow` `Behavior`. - public static let doNotFollow = Redirector(behavior: .doNotFollow) - - /// The `Behavior` of the `Redirector`. - public let behavior: Behavior - - /// Creates a `Redirector` instance from the `Behavior`. - /// - /// - Parameter behavior: The `Behavior`. - public init(behavior: Behavior) { - self.behavior = behavior - } -} - -// MARK: - - -extension Redirector: RedirectHandler { - public func task(_ task: URLSessionTask, - willBeRedirectedTo request: URLRequest, - for response: HTTPURLResponse, - completion: @escaping (URLRequest?) -> Void) { - switch behavior { - case .follow: - completion(request) - case .doNotFollow: - completion(nil) - case let .modify(closure): - let request = closure(task, request, response) - completion(request) - } - } -} diff --git a/Pods/Alamofire/Source/Request.swift b/Pods/Alamofire/Source/Request.swift deleted file mode 100644 index 849f87847..000000000 --- a/Pods/Alamofire/Source/Request.swift +++ /dev/null @@ -1,1882 +0,0 @@ -// -// Request.swift -// -// Copyright (c) 2014-2020 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -/// `Request` is the common superclass of all Alamofire request types and provides common state, delegate, and callback -/// handling. -public class Request { - /// State of the `Request`, with managed transitions between states set when calling `resume()`, `suspend()`, or - /// `cancel()` on the `Request`. - public enum State { - /// Initial state of the `Request`. - case initialized - /// `State` set when `resume()` is called. Any tasks created for the `Request` will have `resume()` called on - /// them in this state. - case resumed - /// `State` set when `suspend()` is called. Any tasks created for the `Request` will have `suspend()` called on - /// them in this state. - case suspended - /// `State` set when `cancel()` is called. Any tasks created for the `Request` will have `cancel()` called on - /// them. Unlike `resumed` or `suspended`, once in the `cancelled` state, the `Request` can no longer transition - /// to any other state. - case cancelled - /// `State` set when all response serialization completion closures have been cleared on the `Request` and - /// enqueued on their respective queues. - case finished - - /// Determines whether `self` can be transitioned to the provided `State`. - func canTransitionTo(_ state: State) -> Bool { - switch (self, state) { - case (.initialized, _): - return true - case (_, .initialized), (.cancelled, _), (.finished, _): - return false - case (.resumed, .cancelled), (.suspended, .cancelled), (.resumed, .suspended), (.suspended, .resumed): - return true - case (.suspended, .suspended), (.resumed, .resumed): - return false - case (_, .finished): - return true - } - } - } - - // MARK: - Initial State - - /// `UUID` providing a unique identifier for the `Request`, used in the `Hashable` and `Equatable` conformances. - public let id: UUID - /// The serial queue for all internal async actions. - public let underlyingQueue: DispatchQueue - /// The queue used for all serialization actions. By default it's a serial queue that targets `underlyingQueue`. - public let serializationQueue: DispatchQueue - /// `EventMonitor` used for event callbacks. - public let eventMonitor: EventMonitor? - /// The `Request`'s interceptor. - public let interceptor: RequestInterceptor? - /// The `Request`'s delegate. - public private(set) weak var delegate: RequestDelegate? - - // MARK: - Mutable State - - /// Type encapsulating all mutable state that may need to be accessed from anything other than the `underlyingQueue`. - struct MutableState { - /// State of the `Request`. - var state: State = .initialized - /// `ProgressHandler` and `DispatchQueue` provided for upload progress callbacks. - var uploadProgressHandler: (handler: ProgressHandler, queue: DispatchQueue)? - /// `ProgressHandler` and `DispatchQueue` provided for download progress callbacks. - var downloadProgressHandler: (handler: ProgressHandler, queue: DispatchQueue)? - /// `RedirectHandler` provided for to handle request redirection. - var redirectHandler: RedirectHandler? - /// `CachedResponseHandler` provided to handle response caching. - var cachedResponseHandler: CachedResponseHandler? - /// Queue and closure called when the `Request` is able to create a cURL description of itself. - var cURLHandler: (queue: DispatchQueue, handler: (String) -> Void)? - /// Queue and closure called when the `Request` creates a `URLRequest`. - var urlRequestHandler: (queue: DispatchQueue, handler: (URLRequest) -> Void)? - /// Queue and closure called when the `Request` creates a `URLSessionTask`. - var urlSessionTaskHandler: (queue: DispatchQueue, handler: (URLSessionTask) -> Void)? - /// Response serialization closures that handle response parsing. - var responseSerializers: [() -> Void] = [] - /// Response serialization completion closures executed once all response serializers are complete. - var responseSerializerCompletions: [() -> Void] = [] - /// Whether response serializer processing is finished. - var responseSerializerProcessingFinished = false - /// `URLCredential` used for authentication challenges. - var credential: URLCredential? - /// All `URLRequest`s created by Alamofire on behalf of the `Request`. - var requests: [URLRequest] = [] - /// All `URLSessionTask`s created by Alamofire on behalf of the `Request`. - var tasks: [URLSessionTask] = [] - /// All `URLSessionTaskMetrics` values gathered by Alamofire on behalf of the `Request`. Should correspond - /// exactly the the `tasks` created. - var metrics: [URLSessionTaskMetrics] = [] - /// Number of times any retriers provided retried the `Request`. - var retryCount = 0 - /// Final `AFError` for the `Request`, whether from various internal Alamofire calls or as a result of a `task`. - var error: AFError? - /// Whether the instance has had `finish()` called and is running the serializers. Should be replaced with a - /// representation in the state machine in the future. - var isFinishing = false - } - - /// Protected `MutableState` value that provides thread-safe access to state values. - @Protected - fileprivate var mutableState = MutableState() - - /// `State` of the `Request`. - public var state: State { mutableState.state } - /// Returns whether `state` is `.initialized`. - public var isInitialized: Bool { state == .initialized } - /// Returns whether `state is `.resumed`. - public var isResumed: Bool { state == .resumed } - /// Returns whether `state` is `.suspended`. - public var isSuspended: Bool { state == .suspended } - /// Returns whether `state` is `.cancelled`. - public var isCancelled: Bool { state == .cancelled } - /// Returns whether `state` is `.finished`. - public var isFinished: Bool { state == .finished } - - // MARK: Progress - - /// Closure type executed when monitoring the upload or download progress of a request. - public typealias ProgressHandler = (Progress) -> Void - - /// `Progress` of the upload of the body of the executed `URLRequest`. Reset to `0` if the `Request` is retried. - public let uploadProgress = Progress(totalUnitCount: 0) - /// `Progress` of the download of any response data. Reset to `0` if the `Request` is retried. - public let downloadProgress = Progress(totalUnitCount: 0) - /// `ProgressHandler` called when `uploadProgress` is updated, on the provided `DispatchQueue`. - private var uploadProgressHandler: (handler: ProgressHandler, queue: DispatchQueue)? { - get { mutableState.uploadProgressHandler } - set { mutableState.uploadProgressHandler = newValue } - } - - /// `ProgressHandler` called when `downloadProgress` is updated, on the provided `DispatchQueue`. - fileprivate var downloadProgressHandler: (handler: ProgressHandler, queue: DispatchQueue)? { - get { mutableState.downloadProgressHandler } - set { mutableState.downloadProgressHandler = newValue } - } - - // MARK: Redirect Handling - - /// `RedirectHandler` set on the instance. - public private(set) var redirectHandler: RedirectHandler? { - get { mutableState.redirectHandler } - set { mutableState.redirectHandler = newValue } - } - - // MARK: Cached Response Handling - - /// `CachedResponseHandler` set on the instance. - public private(set) var cachedResponseHandler: CachedResponseHandler? { - get { mutableState.cachedResponseHandler } - set { mutableState.cachedResponseHandler = newValue } - } - - // MARK: URLCredential - - /// `URLCredential` used for authentication challenges. Created by calling one of the `authenticate` methods. - public private(set) var credential: URLCredential? { - get { mutableState.credential } - set { mutableState.credential = newValue } - } - - // MARK: Validators - - /// `Validator` callback closures that store the validation calls enqueued. - @Protected - fileprivate var validators: [() -> Void] = [] - - // MARK: URLRequests - - /// All `URLRequests` created on behalf of the `Request`, including original and adapted requests. - public var requests: [URLRequest] { mutableState.requests } - /// First `URLRequest` created on behalf of the `Request`. May not be the first one actually executed. - public var firstRequest: URLRequest? { requests.first } - /// Last `URLRequest` created on behalf of the `Request`. - public var lastRequest: URLRequest? { requests.last } - /// Current `URLRequest` created on behalf of the `Request`. - public var request: URLRequest? { lastRequest } - - /// `URLRequest`s from all of the `URLSessionTask`s executed on behalf of the `Request`. May be different from - /// `requests` due to `URLSession` manipulation. - public var performedRequests: [URLRequest] { $mutableState.read { $0.tasks.compactMap { $0.currentRequest } } } - - // MARK: HTTPURLResponse - - /// `HTTPURLResponse` received from the server, if any. If the `Request` was retried, this is the response of the - /// last `URLSessionTask`. - public var response: HTTPURLResponse? { lastTask?.response as? HTTPURLResponse } - - // MARK: Tasks - - /// All `URLSessionTask`s created on behalf of the `Request`. - public var tasks: [URLSessionTask] { mutableState.tasks } - /// First `URLSessionTask` created on behalf of the `Request`. - public var firstTask: URLSessionTask? { tasks.first } - /// Last `URLSessionTask` crated on behalf of the `Request`. - public var lastTask: URLSessionTask? { tasks.last } - /// Current `URLSessionTask` created on behalf of the `Request`. - public var task: URLSessionTask? { lastTask } - - // MARK: Metrics - - /// All `URLSessionTaskMetrics` gathered on behalf of the `Request`. Should correspond to the `tasks` created. - public var allMetrics: [URLSessionTaskMetrics] { mutableState.metrics } - /// First `URLSessionTaskMetrics` gathered on behalf of the `Request`. - public var firstMetrics: URLSessionTaskMetrics? { allMetrics.first } - /// Last `URLSessionTaskMetrics` gathered on behalf of the `Request`. - public var lastMetrics: URLSessionTaskMetrics? { allMetrics.last } - /// Current `URLSessionTaskMetrics` gathered on behalf of the `Request`. - public var metrics: URLSessionTaskMetrics? { lastMetrics } - - // MARK: Retry Count - - /// Number of times the `Request` has been retried. - public var retryCount: Int { mutableState.retryCount } - - // MARK: Error - - /// `Error` returned from Alamofire internally, from the network request directly, or any validators executed. - public fileprivate(set) var error: AFError? { - get { mutableState.error } - set { mutableState.error = newValue } - } - - /// Default initializer for the `Request` superclass. - /// - /// - Parameters: - /// - id: `UUID` used for the `Hashable` and `Equatable` implementations. `UUID()` by default. - /// - underlyingQueue: `DispatchQueue` on which all internal `Request` work is performed. - /// - serializationQueue: `DispatchQueue` on which all serialization work is performed. By default targets - /// `underlyingQueue`, but can be passed another queue from a `Session`. - /// - eventMonitor: `EventMonitor` called for event callbacks from internal `Request` actions. - /// - interceptor: `RequestInterceptor` used throughout the request lifecycle. - /// - delegate: `RequestDelegate` that provides an interface to actions not performed by the `Request`. - init(id: UUID = UUID(), - underlyingQueue: DispatchQueue, - serializationQueue: DispatchQueue, - eventMonitor: EventMonitor?, - interceptor: RequestInterceptor?, - delegate: RequestDelegate) { - self.id = id - self.underlyingQueue = underlyingQueue - self.serializationQueue = serializationQueue - self.eventMonitor = eventMonitor - self.interceptor = interceptor - self.delegate = delegate - } - - // MARK: - Internal Event API - - // All API must be called from underlyingQueue. - - /// Called when an initial `URLRequest` has been created on behalf of the instance. If a `RequestAdapter` is active, - /// the `URLRequest` will be adapted before being issued. - /// - /// - Parameter request: The `URLRequest` created. - func didCreateInitialURLRequest(_ request: URLRequest) { - dispatchPrecondition(condition: .onQueue(underlyingQueue)) - - $mutableState.write { $0.requests.append(request) } - - eventMonitor?.request(self, didCreateInitialURLRequest: request) - } - - /// Called when initial `URLRequest` creation has failed, typically through a `URLRequestConvertible`. - /// - /// - Note: Triggers retry. - /// - /// - Parameter error: `AFError` thrown from the failed creation. - func didFailToCreateURLRequest(with error: AFError) { - dispatchPrecondition(condition: .onQueue(underlyingQueue)) - - self.error = error - - eventMonitor?.request(self, didFailToCreateURLRequestWithError: error) - - callCURLHandlerIfNecessary() - - retryOrFinish(error: error) - } - - /// Called when a `RequestAdapter` has successfully adapted a `URLRequest`. - /// - /// - Parameters: - /// - initialRequest: The `URLRequest` that was adapted. - /// - adaptedRequest: The `URLRequest` returned by the `RequestAdapter`. - func didAdaptInitialRequest(_ initialRequest: URLRequest, to adaptedRequest: URLRequest) { - dispatchPrecondition(condition: .onQueue(underlyingQueue)) - - $mutableState.write { $0.requests.append(adaptedRequest) } - - eventMonitor?.request(self, didAdaptInitialRequest: initialRequest, to: adaptedRequest) - } - - /// Called when a `RequestAdapter` fails to adapt a `URLRequest`. - /// - /// - Note: Triggers retry. - /// - /// - Parameters: - /// - request: The `URLRequest` the adapter was called with. - /// - error: The `AFError` returned by the `RequestAdapter`. - func didFailToAdaptURLRequest(_ request: URLRequest, withError error: AFError) { - dispatchPrecondition(condition: .onQueue(underlyingQueue)) - - self.error = error - - eventMonitor?.request(self, didFailToAdaptURLRequest: request, withError: error) - - callCURLHandlerIfNecessary() - - retryOrFinish(error: error) - } - - /// Final `URLRequest` has been created for the instance. - /// - /// - Parameter request: The `URLRequest` created. - func didCreateURLRequest(_ request: URLRequest) { - dispatchPrecondition(condition: .onQueue(underlyingQueue)) - - $mutableState.read { state in - state.urlRequestHandler?.queue.async { state.urlRequestHandler?.handler(request) } - } - - eventMonitor?.request(self, didCreateURLRequest: request) - - callCURLHandlerIfNecessary() - } - - /// Asynchronously calls any stored `cURLHandler` and then removes it from `mutableState`. - private func callCURLHandlerIfNecessary() { - $mutableState.write { mutableState in - guard let cURLHandler = mutableState.cURLHandler else { return } - - cURLHandler.queue.async { cURLHandler.handler(self.cURLDescription()) } - - mutableState.cURLHandler = nil - } - } - - /// Called when a `URLSessionTask` is created on behalf of the instance. - /// - /// - Parameter task: The `URLSessionTask` created. - func didCreateTask(_ task: URLSessionTask) { - dispatchPrecondition(condition: .onQueue(underlyingQueue)) - - $mutableState.write { state in - state.tasks.append(task) - - guard let urlSessionTaskHandler = state.urlSessionTaskHandler else { return } - - urlSessionTaskHandler.queue.async { urlSessionTaskHandler.handler(task) } - } - - eventMonitor?.request(self, didCreateTask: task) - } - - /// Called when resumption is completed. - func didResume() { - dispatchPrecondition(condition: .onQueue(underlyingQueue)) - - eventMonitor?.requestDidResume(self) - } - - /// Called when a `URLSessionTask` is resumed on behalf of the instance. - /// - /// - Parameter task: The `URLSessionTask` resumed. - func didResumeTask(_ task: URLSessionTask) { - dispatchPrecondition(condition: .onQueue(underlyingQueue)) - - eventMonitor?.request(self, didResumeTask: task) - } - - /// Called when suspension is completed. - func didSuspend() { - dispatchPrecondition(condition: .onQueue(underlyingQueue)) - - eventMonitor?.requestDidSuspend(self) - } - - /// Called when a `URLSessionTask` is suspended on behalf of the instance. - /// - /// - Parameter task: The `URLSessionTask` suspended. - func didSuspendTask(_ task: URLSessionTask) { - dispatchPrecondition(condition: .onQueue(underlyingQueue)) - - eventMonitor?.request(self, didSuspendTask: task) - } - - /// Called when cancellation is completed, sets `error` to `AFError.explicitlyCancelled`. - func didCancel() { - dispatchPrecondition(condition: .onQueue(underlyingQueue)) - - error = error ?? AFError.explicitlyCancelled - - eventMonitor?.requestDidCancel(self) - } - - /// Called when a `URLSessionTask` is cancelled on behalf of the instance. - /// - /// - Parameter task: The `URLSessionTask` cancelled. - func didCancelTask(_ task: URLSessionTask) { - dispatchPrecondition(condition: .onQueue(underlyingQueue)) - - eventMonitor?.request(self, didCancelTask: task) - } - - /// Called when a `URLSessionTaskMetrics` value is gathered on behalf of the instance. - /// - /// - Parameter metrics: The `URLSessionTaskMetrics` gathered. - func didGatherMetrics(_ metrics: URLSessionTaskMetrics) { - dispatchPrecondition(condition: .onQueue(underlyingQueue)) - - $mutableState.write { $0.metrics.append(metrics) } - - eventMonitor?.request(self, didGatherMetrics: metrics) - } - - /// Called when a `URLSessionTask` fails before it is finished, typically during certificate pinning. - /// - /// - Parameters: - /// - task: The `URLSessionTask` which failed. - /// - error: The early failure `AFError`. - func didFailTask(_ task: URLSessionTask, earlyWithError error: AFError) { - dispatchPrecondition(condition: .onQueue(underlyingQueue)) - - self.error = error - - // Task will still complete, so didCompleteTask(_:with:) will handle retry. - eventMonitor?.request(self, didFailTask: task, earlyWithError: error) - } - - /// Called when a `URLSessionTask` completes. All tasks will eventually call this method. - /// - /// - Note: Response validation is synchronously triggered in this step. - /// - /// - Parameters: - /// - task: The `URLSessionTask` which completed. - /// - error: The `AFError` `task` may have completed with. If `error` has already been set on the instance, this - /// value is ignored. - func didCompleteTask(_ task: URLSessionTask, with error: AFError?) { - dispatchPrecondition(condition: .onQueue(underlyingQueue)) - - self.error = self.error ?? error - - validators.forEach { $0() } - - eventMonitor?.request(self, didCompleteTask: task, with: error) - - retryOrFinish(error: self.error) - } - - /// Called when the `RequestDelegate` is going to retry this `Request`. Calls `reset()`. - func prepareForRetry() { - dispatchPrecondition(condition: .onQueue(underlyingQueue)) - - $mutableState.write { $0.retryCount += 1 } - - reset() - - eventMonitor?.requestIsRetrying(self) - } - - /// Called to determine whether retry will be triggered for the particular error, or whether the instance should - /// call `finish()`. - /// - /// - Parameter error: The possible `AFError` which may trigger retry. - func retryOrFinish(error: AFError?) { - dispatchPrecondition(condition: .onQueue(underlyingQueue)) - - guard let error = error, let delegate = delegate else { finish(); return } - - delegate.retryResult(for: self, dueTo: error) { retryResult in - switch retryResult { - case .doNotRetry: - self.finish() - case let .doNotRetryWithError(retryError): - self.finish(error: retryError.asAFError(orFailWith: "Received retryError was not already AFError")) - case .retry, .retryWithDelay: - delegate.retryRequest(self, withDelay: retryResult.delay) - } - } - } - - /// Finishes this `Request` and starts the response serializers. - /// - /// - Parameter error: The possible `Error` with which the instance will finish. - func finish(error: AFError? = nil) { - dispatchPrecondition(condition: .onQueue(underlyingQueue)) - - guard !mutableState.isFinishing else { return } - - mutableState.isFinishing = true - - if let error = error { self.error = error } - - // Start response handlers - processNextResponseSerializer() - - eventMonitor?.requestDidFinish(self) - } - - /// Appends the response serialization closure to the instance. - /// - /// - Note: This method will also `resume` the instance if `delegate.startImmediately` returns `true`. - /// - /// - Parameter closure: The closure containing the response serialization call. - func appendResponseSerializer(_ closure: @escaping () -> Void) { - $mutableState.write { mutableState in - mutableState.responseSerializers.append(closure) - - if mutableState.state == .finished { - mutableState.state = .resumed - } - - if mutableState.responseSerializerProcessingFinished { - underlyingQueue.async { self.processNextResponseSerializer() } - } - - if mutableState.state.canTransitionTo(.resumed) { - underlyingQueue.async { if self.delegate?.startImmediately == true { self.resume() } } - } - } - } - - /// Returns the next response serializer closure to execute if there's one left. - /// - /// - Returns: The next response serialization closure, if there is one. - func nextResponseSerializer() -> (() -> Void)? { - var responseSerializer: (() -> Void)? - - $mutableState.write { mutableState in - let responseSerializerIndex = mutableState.responseSerializerCompletions.count - - if responseSerializerIndex < mutableState.responseSerializers.count { - responseSerializer = mutableState.responseSerializers[responseSerializerIndex] - } - } - - return responseSerializer - } - - /// Processes the next response serializer and calls all completions if response serialization is complete. - func processNextResponseSerializer() { - guard let responseSerializer = nextResponseSerializer() else { - // Execute all response serializer completions and clear them - var completions: [() -> Void] = [] - - $mutableState.write { mutableState in - completions = mutableState.responseSerializerCompletions - - // Clear out all response serializers and response serializer completions in mutable state since the - // request is complete. It's important to do this prior to calling the completion closures in case - // the completions call back into the request triggering a re-processing of the response serializers. - // An example of how this can happen is by calling cancel inside a response completion closure. - mutableState.responseSerializers.removeAll() - mutableState.responseSerializerCompletions.removeAll() - - if mutableState.state.canTransitionTo(.finished) { - mutableState.state = .finished - } - - mutableState.responseSerializerProcessingFinished = true - mutableState.isFinishing = false - } - - completions.forEach { $0() } - - // Cleanup the request - cleanup() - - return - } - - serializationQueue.async { responseSerializer() } - } - - /// Notifies the `Request` that the response serializer is complete. - /// - /// - Parameter completion: The completion handler provided with the response serializer, called when all serializers - /// are complete. - func responseSerializerDidComplete(completion: @escaping () -> Void) { - $mutableState.write { $0.responseSerializerCompletions.append(completion) } - processNextResponseSerializer() - } - - /// Resets all task and response serializer related state for retry. - func reset() { - error = nil - - uploadProgress.totalUnitCount = 0 - uploadProgress.completedUnitCount = 0 - downloadProgress.totalUnitCount = 0 - downloadProgress.completedUnitCount = 0 - - $mutableState.write { state in - state.isFinishing = false - state.responseSerializerCompletions = [] - } - } - - /// Called when updating the upload progress. - /// - /// - Parameters: - /// - totalBytesSent: Total bytes sent so far. - /// - totalBytesExpectedToSend: Total bytes expected to send. - func updateUploadProgress(totalBytesSent: Int64, totalBytesExpectedToSend: Int64) { - uploadProgress.totalUnitCount = totalBytesExpectedToSend - uploadProgress.completedUnitCount = totalBytesSent - - uploadProgressHandler?.queue.async { self.uploadProgressHandler?.handler(self.uploadProgress) } - } - - /// Perform a closure on the current `state` while locked. - /// - /// - Parameter perform: The closure to perform. - func withState(perform: (State) -> Void) { - $mutableState.withState(perform: perform) - } - - // MARK: Task Creation - - /// Called when creating a `URLSessionTask` for this `Request`. Subclasses must override. - /// - /// - Parameters: - /// - request: `URLRequest` to use to create the `URLSessionTask`. - /// - session: `URLSession` which creates the `URLSessionTask`. - /// - /// - Returns: The `URLSessionTask` created. - func task(for request: URLRequest, using session: URLSession) -> URLSessionTask { - fatalError("Subclasses must override.") - } - - // MARK: - Public API - - // These APIs are callable from any queue. - - // MARK: State - - /// Cancels the instance. Once cancelled, a `Request` can no longer be resumed or suspended. - /// - /// - Returns: The instance. - @discardableResult - public func cancel() -> Self { - $mutableState.write { mutableState in - guard mutableState.state.canTransitionTo(.cancelled) else { return } - - mutableState.state = .cancelled - - underlyingQueue.async { self.didCancel() } - - guard let task = mutableState.tasks.last, task.state != .completed else { - underlyingQueue.async { self.finish() } - return - } - - // Resume to ensure metrics are gathered. - task.resume() - task.cancel() - underlyingQueue.async { self.didCancelTask(task) } - } - - return self - } - - /// Suspends the instance. - /// - /// - Returns: The instance. - @discardableResult - public func suspend() -> Self { - $mutableState.write { mutableState in - guard mutableState.state.canTransitionTo(.suspended) else { return } - - mutableState.state = .suspended - - underlyingQueue.async { self.didSuspend() } - - guard let task = mutableState.tasks.last, task.state != .completed else { return } - - task.suspend() - underlyingQueue.async { self.didSuspendTask(task) } - } - - return self - } - - /// Resumes the instance. - /// - /// - Returns: The instance. - @discardableResult - public func resume() -> Self { - $mutableState.write { mutableState in - guard mutableState.state.canTransitionTo(.resumed) else { return } - - mutableState.state = .resumed - - underlyingQueue.async { self.didResume() } - - guard let task = mutableState.tasks.last, task.state != .completed else { return } - - task.resume() - underlyingQueue.async { self.didResumeTask(task) } - } - - return self - } - - // MARK: - Closure API - - /// Associates a credential using the provided values with the instance. - /// - /// - Parameters: - /// - username: The username. - /// - password: The password. - /// - persistence: The `URLCredential.Persistence` for the created `URLCredential`. `.forSession` by default. - /// - /// - Returns: The instance. - @discardableResult - public func authenticate(username: String, password: String, persistence: URLCredential.Persistence = .forSession) -> Self { - let credential = URLCredential(user: username, password: password, persistence: persistence) - - return authenticate(with: credential) - } - - /// Associates the provided credential with the instance. - /// - /// - Parameter credential: The `URLCredential`. - /// - /// - Returns: The instance. - @discardableResult - public func authenticate(with credential: URLCredential) -> Self { - mutableState.credential = credential - - return self - } - - /// Sets a closure to be called periodically during the lifecycle of the instance as data is read from the server. - /// - /// - Note: Only the last closure provided is used. - /// - /// - Parameters: - /// - queue: The `DispatchQueue` to execute the closure on. `.main` by default. - /// - closure: The closure to be executed periodically as data is read from the server. - /// - /// - Returns: The instance. - @discardableResult - public func downloadProgress(queue: DispatchQueue = .main, closure: @escaping ProgressHandler) -> Self { - mutableState.downloadProgressHandler = (handler: closure, queue: queue) - - return self - } - - /// Sets a closure to be called periodically during the lifecycle of the instance as data is sent to the server. - /// - /// - Note: Only the last closure provided is used. - /// - /// - Parameters: - /// - queue: The `DispatchQueue` to execute the closure on. `.main` by default. - /// - closure: The closure to be executed periodically as data is sent to the server. - /// - /// - Returns: The instance. - @discardableResult - public func uploadProgress(queue: DispatchQueue = .main, closure: @escaping ProgressHandler) -> Self { - mutableState.uploadProgressHandler = (handler: closure, queue: queue) - - return self - } - - // MARK: Redirects - - /// Sets the redirect handler for the instance which will be used if a redirect response is encountered. - /// - /// - Note: Attempting to set the redirect handler more than once is a logic error and will crash. - /// - /// - Parameter handler: The `RedirectHandler`. - /// - /// - Returns: The instance. - @discardableResult - public func redirect(using handler: RedirectHandler) -> Self { - $mutableState.write { mutableState in - precondition(mutableState.redirectHandler == nil, "Redirect handler has already been set.") - mutableState.redirectHandler = handler - } - - return self - } - - // MARK: Cached Responses - - /// Sets the cached response handler for the `Request` which will be used when attempting to cache a response. - /// - /// - Note: Attempting to set the cache handler more than once is a logic error and will crash. - /// - /// - Parameter handler: The `CachedResponseHandler`. - /// - /// - Returns: The instance. - @discardableResult - public func cacheResponse(using handler: CachedResponseHandler) -> Self { - $mutableState.write { mutableState in - precondition(mutableState.cachedResponseHandler == nil, "Cached response handler has already been set.") - mutableState.cachedResponseHandler = handler - } - - return self - } - - // MARK: - Lifetime APIs - - /// Sets a handler to be called when the cURL description of the request is available. - /// - /// - Note: When waiting for a `Request`'s `URLRequest` to be created, only the last `handler` will be called. - /// - /// - Parameters: - /// - queue: `DispatchQueue` on which `handler` will be called. - /// - handler: Closure to be called when the cURL description is available. - /// - /// - Returns: The instance. - @discardableResult - public func cURLDescription(on queue: DispatchQueue, calling handler: @escaping (String) -> Void) -> Self { - $mutableState.write { mutableState in - if mutableState.requests.last != nil { - queue.async { handler(self.cURLDescription()) } - } else { - mutableState.cURLHandler = (queue, handler) - } - } - - return self - } - - /// Sets a handler to be called when the cURL description of the request is available. - /// - /// - Note: When waiting for a `Request`'s `URLRequest` to be created, only the last `handler` will be called. - /// - /// - Parameter handler: Closure to be called when the cURL description is available. Called on the instance's - /// `underlyingQueue` by default. - /// - /// - Returns: The instance. - @discardableResult - public func cURLDescription(calling handler: @escaping (String) -> Void) -> Self { - $mutableState.write { mutableState in - if mutableState.requests.last != nil { - underlyingQueue.async { handler(self.cURLDescription()) } - } else { - mutableState.cURLHandler = (underlyingQueue, handler) - } - } - - return self - } - - /// Sets a closure to called whenever Alamofire creates a `URLRequest` for this instance. - /// - /// - Note: This closure will be called multiple times if the instance adapts incoming `URLRequest`s or is retried. - /// - /// - Parameters: - /// - queue: `DispatchQueue` on which `handler` will be called. `.main` by default. - /// - handler: Closure to be called when a `URLRequest` is available. - /// - /// - Returns: The instance. - @discardableResult - public func onURLRequestCreation(on queue: DispatchQueue = .main, perform handler: @escaping (URLRequest) -> Void) -> Self { - $mutableState.write { state in - if let request = state.requests.last { - queue.async { handler(request) } - } - - state.urlRequestHandler = (queue, handler) - } - - return self - } - - /// Sets a closure to be called whenever the instance creates a `URLSessionTask`. - /// - /// - Note: This API should only be used to provide `URLSessionTask`s to existing API, like `NSFileProvider`. It - /// **SHOULD NOT** be used to interact with tasks directly, as that may be break Alamofire features. - /// Additionally, this closure may be called multiple times if the instance is retried. - /// - /// - Parameters: - /// - queue: `DispatchQueue` on which `handler` will be called. `.main` by default. - /// - handler: Closure to be called when the `URLSessionTask` is available. - /// - /// - Returns: The instance. - @discardableResult - public func onURLSessionTaskCreation(on queue: DispatchQueue = .main, perform handler: @escaping (URLSessionTask) -> Void) -> Self { - $mutableState.write { state in - if let task = state.tasks.last { - queue.async { handler(task) } - } - - state.urlSessionTaskHandler = (queue, handler) - } - - return self - } - - // MARK: Cleanup - - /// Final cleanup step executed when the instance finishes response serialization. - func cleanup() { - delegate?.cleanup(after: self) - // No-op: override in subclass - } -} - -// MARK: - Protocol Conformances - -extension Request: Equatable { - public static func ==(lhs: Request, rhs: Request) -> Bool { - lhs.id == rhs.id - } -} - -extension Request: Hashable { - public func hash(into hasher: inout Hasher) { - hasher.combine(id) - } -} - -extension Request: CustomStringConvertible { - /// A textual representation of this instance, including the `HTTPMethod` and `URL` if the `URLRequest` has been - /// created, as well as the response status code, if a response has been received. - public var description: String { - guard let request = performedRequests.last ?? lastRequest, - let url = request.url, - let method = request.httpMethod else { return "No request created yet." } - - let requestDescription = "\(method) \(url.absoluteString)" - - return response.map { "\(requestDescription) (\($0.statusCode))" } ?? requestDescription - } -} - -extension Request { - /// cURL representation of the instance. - /// - /// - Returns: The cURL equivalent of the instance. - public func cURLDescription() -> String { - guard - let request = lastRequest, - let url = request.url, - let host = url.host, - let method = request.httpMethod else { return "$ curl command could not be created" } - - var components = ["$ curl -v"] - - components.append("-X \(method)") - - if let credentialStorage = delegate?.sessionConfiguration.urlCredentialStorage { - let protectionSpace = URLProtectionSpace(host: host, - port: url.port ?? 0, - protocol: url.scheme, - realm: host, - authenticationMethod: NSURLAuthenticationMethodHTTPBasic) - - if let credentials = credentialStorage.credentials(for: protectionSpace)?.values { - for credential in credentials { - guard let user = credential.user, let password = credential.password else { continue } - components.append("-u \(user):\(password)") - } - } else { - if let credential = credential, let user = credential.user, let password = credential.password { - components.append("-u \(user):\(password)") - } - } - } - - if let configuration = delegate?.sessionConfiguration, configuration.httpShouldSetCookies { - if - let cookieStorage = configuration.httpCookieStorage, - let cookies = cookieStorage.cookies(for: url), !cookies.isEmpty { - let allCookies = cookies.map { "\($0.name)=\($0.value)" }.joined(separator: ";") - - components.append("-b \"\(allCookies)\"") - } - } - - var headers = HTTPHeaders() - - if let sessionHeaders = delegate?.sessionConfiguration.headers { - for header in sessionHeaders where header.name != "Cookie" { - headers[header.name] = header.value - } - } - - for header in request.headers where header.name != "Cookie" { - headers[header.name] = header.value - } - - for header in headers { - let escapedValue = header.value.replacingOccurrences(of: "\"", with: "\\\"") - components.append("-H \"\(header.name): \(escapedValue)\"") - } - - if let httpBodyData = request.httpBody { - let httpBody = String(decoding: httpBodyData, as: UTF8.self) - var escapedBody = httpBody.replacingOccurrences(of: "\\\"", with: "\\\\\"") - escapedBody = escapedBody.replacingOccurrences(of: "\"", with: "\\\"") - - components.append("-d \"\(escapedBody)\"") - } - - components.append("\"\(url.absoluteString)\"") - - return components.joined(separator: " \\\n\t") - } -} - -/// Protocol abstraction for `Request`'s communication back to the `SessionDelegate`. -public protocol RequestDelegate: AnyObject { - /// `URLSessionConfiguration` used to create the underlying `URLSessionTask`s. - var sessionConfiguration: URLSessionConfiguration { get } - - /// Determines whether the `Request` should automatically call `resume()` when adding the first response handler. - var startImmediately: Bool { get } - - /// Notifies the delegate the `Request` has reached a point where it needs cleanup. - /// - /// - Parameter request: The `Request` to cleanup after. - func cleanup(after request: Request) - - /// Asynchronously ask the delegate whether a `Request` will be retried. - /// - /// - Parameters: - /// - request: `Request` which failed. - /// - error: `Error` which produced the failure. - /// - completion: Closure taking the `RetryResult` for evaluation. - func retryResult(for request: Request, dueTo error: AFError, completion: @escaping (RetryResult) -> Void) - - /// Asynchronously retry the `Request`. - /// - /// - Parameters: - /// - request: `Request` which will be retried. - /// - timeDelay: `TimeInterval` after which the retry will be triggered. - func retryRequest(_ request: Request, withDelay timeDelay: TimeInterval?) -} - -// MARK: - Subclasses - -// MARK: - DataRequest - -/// `Request` subclass which handles in-memory `Data` download using `URLSessionDataTask`. -public class DataRequest: Request { - /// `URLRequestConvertible` value used to create `URLRequest`s for this instance. - public let convertible: URLRequestConvertible - /// `Data` read from the server so far. - public var data: Data? { mutableData } - - /// Protected storage for the `Data` read by the instance. - @Protected - private var mutableData: Data? = nil - - /// Creates a `DataRequest` using the provided parameters. - /// - /// - Parameters: - /// - id: `UUID` used for the `Hashable` and `Equatable` implementations. `UUID()` by default. - /// - convertible: `URLRequestConvertible` value used to create `URLRequest`s for this instance. - /// - underlyingQueue: `DispatchQueue` on which all internal `Request` work is performed. - /// - serializationQueue: `DispatchQueue` on which all serialization work is performed. By default targets - /// `underlyingQueue`, but can be passed another queue from a `Session`. - /// - eventMonitor: `EventMonitor` called for event callbacks from internal `Request` actions. - /// - interceptor: `RequestInterceptor` used throughout the request lifecycle. - /// - delegate: `RequestDelegate` that provides an interface to actions not performed by the `Request`. - init(id: UUID = UUID(), - convertible: URLRequestConvertible, - underlyingQueue: DispatchQueue, - serializationQueue: DispatchQueue, - eventMonitor: EventMonitor?, - interceptor: RequestInterceptor?, - delegate: RequestDelegate) { - self.convertible = convertible - - super.init(id: id, - underlyingQueue: underlyingQueue, - serializationQueue: serializationQueue, - eventMonitor: eventMonitor, - interceptor: interceptor, - delegate: delegate) - } - - override func reset() { - super.reset() - - mutableData = nil - } - - /// Called when `Data` is received by this instance. - /// - /// - Note: Also calls `updateDownloadProgress`. - /// - /// - Parameter data: The `Data` received. - func didReceive(data: Data) { - if self.data == nil { - mutableData = data - } else { - $mutableData.write { $0?.append(data) } - } - - updateDownloadProgress() - } - - override func task(for request: URLRequest, using session: URLSession) -> URLSessionTask { - let copiedRequest = request - return session.dataTask(with: copiedRequest) - } - - /// Called to updated the `downloadProgress` of the instance. - func updateDownloadProgress() { - let totalBytesReceived = Int64(data?.count ?? 0) - let totalBytesExpected = task?.response?.expectedContentLength ?? NSURLSessionTransferSizeUnknown - - downloadProgress.totalUnitCount = totalBytesExpected - downloadProgress.completedUnitCount = totalBytesReceived - - downloadProgressHandler?.queue.async { self.downloadProgressHandler?.handler(self.downloadProgress) } - } - - /// Validates the request, using the specified closure. - /// - /// - Note: If validation fails, subsequent calls to response handlers will have an associated error. - /// - /// - Parameter validation: `Validation` closure used to validate the response. - /// - /// - Returns: The instance. - @discardableResult - public func validate(_ validation: @escaping Validation) -> Self { - let validator: () -> Void = { [unowned self] in - guard self.error == nil, let response = self.response else { return } - - let result = validation(self.request, response, self.data) - - if case let .failure(error) = result { self.error = error.asAFError(or: .responseValidationFailed(reason: .customValidationFailed(error: error))) } - - self.eventMonitor?.request(self, - didValidateRequest: self.request, - response: response, - data: self.data, - withResult: result) - } - - $validators.write { $0.append(validator) } - - return self - } -} - -// MARK: - DataStreamRequest - -/// `Request` subclass which streams HTTP response `Data` through a `Handler` closure. -public final class DataStreamRequest: Request { - /// Closure type handling `DataStreamRequest.Stream` values. - public typealias Handler = (Stream) throws -> Void - - /// Type encapsulating an `Event` as it flows through the stream, as well as a `CancellationToken` which can be used - /// to stop the stream at any time. - public struct Stream { - /// Latest `Event` from the stream. - public let event: Event - /// Token used to cancel the stream. - public let token: CancellationToken - - /// Cancel the ongoing stream by canceling the underlying `DataStreamRequest`. - public func cancel() { - token.cancel() - } - } - - /// Type representing an event flowing through the stream. Contains either the `Result` of processing streamed - /// `Data` or the completion of the stream. - public enum Event { - /// Output produced every time the instance receives additional `Data`. The associated value contains the - /// `Result` of processing the incoming `Data`. - case stream(Result) - /// Output produced when the instance has completed, whether due to stream end, cancellation, or an error. - /// Associated `Completion` value contains the final state. - case complete(Completion) - } - - /// Value containing the state of a `DataStreamRequest` when the stream was completed. - public struct Completion { - /// Last `URLRequest` issued by the instance. - public let request: URLRequest? - /// Last `HTTPURLResponse` received by the instance. - public let response: HTTPURLResponse? - /// Last `URLSessionTaskMetrics` produced for the instance. - public let metrics: URLSessionTaskMetrics? - /// `AFError` produced for the instance, if any. - public let error: AFError? - } - - /// Type used to cancel an ongoing stream. - public struct CancellationToken { - weak var request: DataStreamRequest? - - init(_ request: DataStreamRequest) { - self.request = request - } - - /// Cancel the ongoing stream by canceling the underlying `DataStreamRequest`. - public func cancel() { - request?.cancel() - } - } - - /// `URLRequestConvertible` value used to create `URLRequest`s for this instance. - public let convertible: URLRequestConvertible - /// Whether or not the instance will be cancelled if stream parsing encounters an error. - public let automaticallyCancelOnStreamError: Bool - - /// Internal mutable state specific to this type. - struct StreamMutableState { - /// `OutputStream` bound to the `InputStream` produced by `asInputStream`, if it has been called. - var outputStream: OutputStream? - /// Stream closures called as `Data` is received. - var streams: [(_ data: Data) -> Void] = [] - /// Number of currently executing streams. Used to ensure completions are only fired after all streams are - /// enqueued. - var numberOfExecutingStreams = 0 - /// Completion calls enqueued while streams are still executing. - var enqueuedCompletionEvents: [() -> Void] = [] - } - - @Protected - var streamMutableState = StreamMutableState() - - /// Creates a `DataStreamRequest` using the provided parameters. - /// - /// - Parameters: - /// - id: `UUID` used for the `Hashable` and `Equatable` implementations. `UUID()` - /// by default. - /// - convertible: `URLRequestConvertible` value used to create `URLRequest`s for this - /// instance. - /// - automaticallyCancelOnStreamError: `Bool` indicating whether the instance will be cancelled when an `Error` - /// is thrown while serializing stream `Data`. - /// - underlyingQueue: `DispatchQueue` on which all internal `Request` work is performed. - /// - serializationQueue: `DispatchQueue` on which all serialization work is performed. By default - /// targets - /// `underlyingQueue`, but can be passed another queue from a `Session`. - /// - eventMonitor: `EventMonitor` called for event callbacks from internal `Request` actions. - /// - interceptor: `RequestInterceptor` used throughout the request lifecycle. - /// - delegate: `RequestDelegate` that provides an interface to actions not performed by - /// the `Request`. - init(id: UUID = UUID(), - convertible: URLRequestConvertible, - automaticallyCancelOnStreamError: Bool, - underlyingQueue: DispatchQueue, - serializationQueue: DispatchQueue, - eventMonitor: EventMonitor?, - interceptor: RequestInterceptor?, - delegate: RequestDelegate) { - self.convertible = convertible - self.automaticallyCancelOnStreamError = automaticallyCancelOnStreamError - - super.init(id: id, - underlyingQueue: underlyingQueue, - serializationQueue: serializationQueue, - eventMonitor: eventMonitor, - interceptor: interceptor, - delegate: delegate) - } - - override func task(for request: URLRequest, using session: URLSession) -> URLSessionTask { - let copiedRequest = request - return session.dataTask(with: copiedRequest) - } - - override func finish(error: AFError? = nil) { - $streamMutableState.write { state in - state.outputStream?.close() - } - - super.finish(error: error) - } - - func didReceive(data: Data) { - $streamMutableState.write { state in - if let stream = state.outputStream { - underlyingQueue.async { - var bytes = Array(data) - stream.write(&bytes, maxLength: bytes.count) - } - } - state.numberOfExecutingStreams += state.streams.count - let localState = state - underlyingQueue.async { localState.streams.forEach { $0(data) } } - } - } - - /// Validates the `URLRequest` and `HTTPURLResponse` received for the instance using the provided `Validation` closure. - /// - /// - Parameter validation: `Validation` closure used to validate the request and response. - /// - /// - Returns: The `DataStreamRequest`. - @discardableResult - public func validate(_ validation: @escaping Validation) -> Self { - let validator: () -> Void = { [unowned self] in - guard self.error == nil, let response = self.response else { return } - - let result = validation(self.request, response) - - if case let .failure(error) = result { - self.error = error.asAFError(or: .responseValidationFailed(reason: .customValidationFailed(error: error))) - } - - self.eventMonitor?.request(self, - didValidateRequest: self.request, - response: response, - withResult: result) - } - - $validators.write { $0.append(validator) } - - return self - } - - /// Produces an `InputStream` that receives the `Data` received by the instance. - /// - /// - Note: The `InputStream` produced by this method must have `open()` called before being able to read `Data`. - /// Additionally, this method will automatically call `resume()` on the instance, regardless of whether or - /// not the creating session has `startRequestsImmediately` set to `true`. - /// - /// - Parameter bufferSize: Size, in bytes, of the buffer between the `OutputStream` and `InputStream`. - /// - /// - Returns: The `InputStream` bound to the internal `OutboundStream`. - public func asInputStream(bufferSize: Int = 1024) -> InputStream? { - defer { resume() } - - var inputStream: InputStream? - $streamMutableState.write { state in - Foundation.Stream.getBoundStreams(withBufferSize: bufferSize, - inputStream: &inputStream, - outputStream: &state.outputStream) - state.outputStream?.open() - } - - return inputStream - } - - func capturingError(from closure: () throws -> Void) { - do { - try closure() - } catch { - self.error = error.asAFError(or: .responseSerializationFailed(reason: .customSerializationFailed(error: error))) - cancel() - } - } - - func appendStreamCompletion(on queue: DispatchQueue, - stream: @escaping Handler) { - appendResponseSerializer { - self.underlyingQueue.async { - self.responseSerializerDidComplete { - self.$streamMutableState.write { state in - guard state.numberOfExecutingStreams == 0 else { - state.enqueuedCompletionEvents.append { - self.enqueueCompletion(on: queue, stream: stream) - } - - return - } - - self.enqueueCompletion(on: queue, stream: stream) - } - } - } - } - } - - func enqueueCompletion(on queue: DispatchQueue, - stream: @escaping Handler) { - queue.async { - do { - let completion = Completion(request: self.request, - response: self.response, - metrics: self.metrics, - error: self.error) - try stream(.init(event: .complete(completion), token: .init(self))) - } catch { - // Ignore error, as errors on Completion can't be handled anyway. - } - } - } -} - -extension DataStreamRequest.Stream { - /// Incoming `Result` values from `Event.stream`. - public var result: Result? { - guard case let .stream(result) = event else { return nil } - - return result - } - - /// `Success` value of the instance, if any. - public var value: Success? { - guard case let .success(value) = result else { return nil } - - return value - } - - /// `Failure` value of the instance, if any. - public var error: Failure? { - guard case let .failure(error) = result else { return nil } - - return error - } - - /// `Completion` value of the instance, if any. - public var completion: DataStreamRequest.Completion? { - guard case let .complete(completion) = event else { return nil } - - return completion - } -} - -// MARK: - DownloadRequest - -/// `Request` subclass which downloads `Data` to a file on disk using `URLSessionDownloadTask`. -public class DownloadRequest: Request { - /// A set of options to be executed prior to moving a downloaded file from the temporary `URL` to the destination - /// `URL`. - public struct Options: OptionSet { - /// Specifies that intermediate directories for the destination URL should be created. - public static let createIntermediateDirectories = Options(rawValue: 1 << 0) - /// Specifies that any previous file at the destination `URL` should be removed. - public static let removePreviousFile = Options(rawValue: 1 << 1) - - public let rawValue: Int - - public init(rawValue: Int) { - self.rawValue = rawValue - } - } - - // MARK: Destination - - /// A closure executed once a `DownloadRequest` has successfully completed in order to determine where to move the - /// temporary file written to during the download process. The closure takes two arguments: the temporary file URL - /// and the `HTTPURLResponse`, and returns two values: the file URL where the temporary file should be moved and - /// the options defining how the file should be moved. - /// - /// - Note: Downloads from a local `file://` `URL`s do not use the `Destination` closure, as those downloads do not - /// return an `HTTPURLResponse`. Instead the file is merely moved within the temporary directory. - public typealias Destination = (_ temporaryURL: URL, - _ response: HTTPURLResponse) -> (destinationURL: URL, options: Options) - - /// Creates a download file destination closure which uses the default file manager to move the temporary file to a - /// file URL in the first available directory with the specified search path directory and search path domain mask. - /// - /// - Parameters: - /// - directory: The search path directory. `.documentDirectory` by default. - /// - domain: The search path domain mask. `.userDomainMask` by default. - /// - options: `DownloadRequest.Options` used when moving the downloaded file to its destination. None by - /// default. - /// - Returns: The `Destination` closure. - public class func suggestedDownloadDestination(for directory: FileManager.SearchPathDirectory = .documentDirectory, - in domain: FileManager.SearchPathDomainMask = .userDomainMask, - options: Options = []) -> Destination { - { temporaryURL, response in - let directoryURLs = FileManager.default.urls(for: directory, in: domain) - let url = directoryURLs.first?.appendingPathComponent(response.suggestedFilename!) ?? temporaryURL - - return (url, options) - } - } - - /// Default `Destination` used by Alamofire to ensure all downloads persist. This `Destination` prepends - /// `Alamofire_` to the automatically generated download name and moves it within the temporary directory. Files - /// with this destination must be additionally moved if they should survive the system reclamation of temporary - /// space. - static let defaultDestination: Destination = { url, _ in - (defaultDestinationURL(url), []) - } - - /// Default `URL` creation closure. Creates a `URL` in the temporary directory with `Alamofire_` prepended to the - /// provided file name. - static let defaultDestinationURL: (URL) -> URL = { url in - let filename = "Alamofire_\(url.lastPathComponent)" - let destination = url.deletingLastPathComponent().appendingPathComponent(filename) - - return destination - } - - // MARK: Downloadable - - /// Type describing the source used to create the underlying `URLSessionDownloadTask`. - public enum Downloadable { - /// Download should be started from the `URLRequest` produced by the associated `URLRequestConvertible` value. - case request(URLRequestConvertible) - /// Download should be started from the associated resume `Data` value. - case resumeData(Data) - } - - // MARK: Mutable State - - /// Type containing all mutable state for `DownloadRequest` instances. - private struct DownloadRequestMutableState { - /// Possible resume `Data` produced when cancelling the instance. - var resumeData: Data? - /// `URL` to which `Data` is being downloaded. - var fileURL: URL? - } - - /// Protected mutable state specific to `DownloadRequest`. - @Protected - private var mutableDownloadState = DownloadRequestMutableState() - - /// If the download is resumable and is eventually cancelled or fails, this value may be used to resume the download - /// using the `download(resumingWith data:)` API. - /// - /// - Note: For more information about `resumeData`, see [Apple's documentation](https://developer.apple.com/documentation/foundation/urlsessiondownloadtask/1411634-cancel). - public var resumeData: Data? { mutableDownloadState.resumeData ?? error?.downloadResumeData } - /// If the download is successful, the `URL` where the file was downloaded. - public var fileURL: URL? { mutableDownloadState.fileURL } - - // MARK: Initial State - - /// `Downloadable` value used for this instance. - public let downloadable: Downloadable - /// The `Destination` to which the downloaded file is moved. - let destination: Destination - - /// Creates a `DownloadRequest` using the provided parameters. - /// - /// - Parameters: - /// - id: `UUID` used for the `Hashable` and `Equatable` implementations. `UUID()` by default. - /// - downloadable: `Downloadable` value used to create `URLSessionDownloadTasks` for the instance. - /// - underlyingQueue: `DispatchQueue` on which all internal `Request` work is performed. - /// - serializationQueue: `DispatchQueue` on which all serialization work is performed. By default targets - /// `underlyingQueue`, but can be passed another queue from a `Session`. - /// - eventMonitor: `EventMonitor` called for event callbacks from internal `Request` actions. - /// - interceptor: `RequestInterceptor` used throughout the request lifecycle. - /// - delegate: `RequestDelegate` that provides an interface to actions not performed by the `Request` - /// - destination: `Destination` closure used to move the downloaded file to its final location. - init(id: UUID = UUID(), - downloadable: Downloadable, - underlyingQueue: DispatchQueue, - serializationQueue: DispatchQueue, - eventMonitor: EventMonitor?, - interceptor: RequestInterceptor?, - delegate: RequestDelegate, - destination: @escaping Destination) { - self.downloadable = downloadable - self.destination = destination - - super.init(id: id, - underlyingQueue: underlyingQueue, - serializationQueue: serializationQueue, - eventMonitor: eventMonitor, - interceptor: interceptor, - delegate: delegate) - } - - override func reset() { - super.reset() - - $mutableDownloadState.write { - $0.resumeData = nil - $0.fileURL = nil - } - } - - /// Called when a download has finished. - /// - /// - Parameters: - /// - task: `URLSessionTask` that finished the download. - /// - result: `Result` of the automatic move to `destination`. - func didFinishDownloading(using task: URLSessionTask, with result: Result) { - eventMonitor?.request(self, didFinishDownloadingUsing: task, with: result) - - switch result { - case let .success(url): mutableDownloadState.fileURL = url - case let .failure(error): self.error = error - } - } - - /// Updates the `downloadProgress` using the provided values. - /// - /// - Parameters: - /// - bytesWritten: Total bytes written so far. - /// - totalBytesExpectedToWrite: Total bytes expected to write. - func updateDownloadProgress(bytesWritten: Int64, totalBytesExpectedToWrite: Int64) { - downloadProgress.totalUnitCount = totalBytesExpectedToWrite - downloadProgress.completedUnitCount += bytesWritten - - downloadProgressHandler?.queue.async { self.downloadProgressHandler?.handler(self.downloadProgress) } - } - - override func task(for request: URLRequest, using session: URLSession) -> URLSessionTask { - session.downloadTask(with: request) - } - - /// Creates a `URLSessionTask` from the provided resume data. - /// - /// - Parameters: - /// - data: `Data` used to resume the download. - /// - session: `URLSession` used to create the `URLSessionTask`. - /// - /// - Returns: The `URLSessionTask` created. - public func task(forResumeData data: Data, using session: URLSession) -> URLSessionTask { - session.downloadTask(withResumeData: data) - } - - /// Cancels the instance. Once cancelled, a `DownloadRequest` can no longer be resumed or suspended. - /// - /// - Note: This method will NOT produce resume data. If you wish to cancel and produce resume data, use - /// `cancel(producingResumeData:)` or `cancel(byProducingResumeData:)`. - /// - /// - Returns: The instance. - @discardableResult - override public func cancel() -> Self { - cancel(producingResumeData: false) - } - - /// Cancels the instance, optionally producing resume data. Once cancelled, a `DownloadRequest` can no longer be - /// resumed or suspended. - /// - /// - Note: If `producingResumeData` is `true`, the `resumeData` property will be populated with any resume data, if - /// available. - /// - /// - Returns: The instance. - @discardableResult - public func cancel(producingResumeData shouldProduceResumeData: Bool) -> Self { - cancel(optionallyProducingResumeData: shouldProduceResumeData ? { _ in } : nil) - } - - /// Cancels the instance while producing resume data. Once cancelled, a `DownloadRequest` can no longer be resumed - /// or suspended. - /// - /// - Note: The resume data passed to the completion handler will also be available on the instance's `resumeData` - /// property. - /// - /// - Parameter completionHandler: The completion handler that is called when the download has been successfully - /// cancelled. It is not guaranteed to be called on a particular queue, so you may - /// want use an appropriate queue to perform your work. - /// - /// - Returns: The instance. - @discardableResult - public func cancel(byProducingResumeData completionHandler: @escaping (_ data: Data?) -> Void) -> Self { - cancel(optionallyProducingResumeData: completionHandler) - } - - /// Internal implementation of cancellation that optionally takes a resume data handler. If no handler is passed, - /// cancellation is performed without producing resume data. - /// - /// - Parameter completionHandler: Optional resume data handler. - /// - /// - Returns: The instance. - private func cancel(optionallyProducingResumeData completionHandler: ((_ resumeData: Data?) -> Void)?) -> Self { - $mutableState.write { mutableState in - guard mutableState.state.canTransitionTo(.cancelled) else { return } - - mutableState.state = .cancelled - - underlyingQueue.async { self.didCancel() } - - guard let task = mutableState.tasks.last as? URLSessionDownloadTask, task.state != .completed else { - underlyingQueue.async { self.finish() } - return - } - - if let completionHandler = completionHandler { - // Resume to ensure metrics are gathered. - task.resume() - task.cancel { resumeData in - self.mutableDownloadState.resumeData = resumeData - self.underlyingQueue.async { self.didCancelTask(task) } - completionHandler(resumeData) - } - } else { - // Resume to ensure metrics are gathered. - task.resume() - task.cancel(byProducingResumeData: { _ in }) - self.underlyingQueue.async { self.didCancelTask(task) } - } - } - - return self - } - - /// Validates the request, using the specified closure. - /// - /// - Note: If validation fails, subsequent calls to response handlers will have an associated error. - /// - /// - Parameter validation: `Validation` closure to validate the response. - /// - /// - Returns: The instance. - @discardableResult - public func validate(_ validation: @escaping Validation) -> Self { - let validator: () -> Void = { [unowned self] in - guard self.error == nil, let response = self.response else { return } - - let result = validation(self.request, response, self.fileURL) - - if case let .failure(error) = result { - self.error = error.asAFError(or: .responseValidationFailed(reason: .customValidationFailed(error: error))) - } - - self.eventMonitor?.request(self, - didValidateRequest: self.request, - response: response, - fileURL: self.fileURL, - withResult: result) - } - - $validators.write { $0.append(validator) } - - return self - } -} - -// MARK: - UploadRequest - -/// `DataRequest` subclass which handles `Data` upload from memory, file, or stream using `URLSessionUploadTask`. -public class UploadRequest: DataRequest { - /// Type describing the origin of the upload, whether `Data`, file, or stream. - public enum Uploadable { - /// Upload from the provided `Data` value. - case data(Data) - /// Upload from the provided file `URL`, as well as a `Bool` determining whether the source file should be - /// automatically removed once uploaded. - case file(URL, shouldRemove: Bool) - /// Upload from the provided `InputStream`. - case stream(InputStream) - } - - // MARK: Initial State - - /// The `UploadableConvertible` value used to produce the `Uploadable` value for this instance. - public let upload: UploadableConvertible - - /// `FileManager` used to perform cleanup tasks, including the removal of multipart form encoded payloads written - /// to disk. - public let fileManager: FileManager - - // MARK: Mutable State - - /// `Uploadable` value used by the instance. - public var uploadable: Uploadable? - - /// Creates an `UploadRequest` using the provided parameters. - /// - /// - Parameters: - /// - id: `UUID` used for the `Hashable` and `Equatable` implementations. `UUID()` by default. - /// - convertible: `UploadConvertible` value used to determine the type of upload to be performed. - /// - underlyingQueue: `DispatchQueue` on which all internal `Request` work is performed. - /// - serializationQueue: `DispatchQueue` on which all serialization work is performed. By default targets - /// `underlyingQueue`, but can be passed another queue from a `Session`. - /// - eventMonitor: `EventMonitor` called for event callbacks from internal `Request` actions. - /// - interceptor: `RequestInterceptor` used throughout the request lifecycle. - /// - delegate: `RequestDelegate` that provides an interface to actions not performed by the `Request`. - init(id: UUID = UUID(), - convertible: UploadConvertible, - underlyingQueue: DispatchQueue, - serializationQueue: DispatchQueue, - eventMonitor: EventMonitor?, - interceptor: RequestInterceptor?, - fileManager: FileManager, - delegate: RequestDelegate) { - upload = convertible - self.fileManager = fileManager - - super.init(id: id, - convertible: convertible, - underlyingQueue: underlyingQueue, - serializationQueue: serializationQueue, - eventMonitor: eventMonitor, - interceptor: interceptor, - delegate: delegate) - } - - /// Called when the `Uploadable` value has been created from the `UploadConvertible`. - /// - /// - Parameter uploadable: The `Uploadable` that was created. - func didCreateUploadable(_ uploadable: Uploadable) { - self.uploadable = uploadable - - eventMonitor?.request(self, didCreateUploadable: uploadable) - } - - /// Called when the `Uploadable` value could not be created. - /// - /// - Parameter error: `AFError` produced by the failure. - func didFailToCreateUploadable(with error: AFError) { - self.error = error - - eventMonitor?.request(self, didFailToCreateUploadableWithError: error) - - retryOrFinish(error: error) - } - - override func task(for request: URLRequest, using session: URLSession) -> URLSessionTask { - guard let uploadable = uploadable else { - fatalError("Attempting to create a URLSessionUploadTask when Uploadable value doesn't exist.") - } - - switch uploadable { - case let .data(data): return session.uploadTask(with: request, from: data) - case let .file(url, _): return session.uploadTask(with: request, fromFile: url) - case .stream: return session.uploadTask(withStreamedRequest: request) - } - } - - override func reset() { - // Uploadable must be recreated on every retry. - uploadable = nil - - super.reset() - } - - /// Produces the `InputStream` from `uploadable`, if it can. - /// - /// - Note: Calling this method with a non-`.stream` `Uploadable` is a logic error and will crash. - /// - /// - Returns: The `InputStream`. - func inputStream() -> InputStream { - guard let uploadable = uploadable else { - fatalError("Attempting to access the input stream but the uploadable doesn't exist.") - } - - guard case let .stream(stream) = uploadable else { - fatalError("Attempted to access the stream of an UploadRequest that wasn't created with one.") - } - - eventMonitor?.request(self, didProvideInputStream: stream) - - return stream - } - - override public func cleanup() { - defer { super.cleanup() } - - guard - let uploadable = self.uploadable, - case let .file(url, shouldRemove) = uploadable, - shouldRemove - else { return } - - try? fileManager.removeItem(at: url) - } -} - -/// A type that can produce an `UploadRequest.Uploadable` value. -public protocol UploadableConvertible { - /// Produces an `UploadRequest.Uploadable` value from the instance. - /// - /// - Returns: The `UploadRequest.Uploadable`. - /// - Throws: Any `Error` produced during creation. - func createUploadable() throws -> UploadRequest.Uploadable -} - -extension UploadRequest.Uploadable: UploadableConvertible { - public func createUploadable() throws -> UploadRequest.Uploadable { - self - } -} - -/// A type that can be converted to an upload, whether from an `UploadRequest.Uploadable` or `URLRequestConvertible`. -public protocol UploadConvertible: UploadableConvertible & URLRequestConvertible {} diff --git a/Pods/Alamofire/Source/RequestInterceptor.swift b/Pods/Alamofire/Source/RequestInterceptor.swift deleted file mode 100644 index 1912e9c16..000000000 --- a/Pods/Alamofire/Source/RequestInterceptor.swift +++ /dev/null @@ -1,244 +0,0 @@ -// -// RequestInterceptor.swift -// -// Copyright (c) 2019 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -/// A type that can inspect and optionally adapt a `URLRequest` in some manner if necessary. -public protocol RequestAdapter { - /// Inspects and adapts the specified `URLRequest` in some manner and calls the completion handler with the Result. - /// - /// - Parameters: - /// - urlRequest: The `URLRequest` to adapt. - /// - session: The `Session` that will execute the `URLRequest`. - /// - completion: The completion handler that must be called when adaptation is complete. - func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result) -> Void) -} - -// MARK: - - -/// Outcome of determination whether retry is necessary. -public enum RetryResult { - /// Retry should be attempted immediately. - case retry - /// Retry should be attempted after the associated `TimeInterval`. - case retryWithDelay(TimeInterval) - /// Do not retry. - case doNotRetry - /// Do not retry due to the associated `Error`. - case doNotRetryWithError(Error) -} - -extension RetryResult { - var retryRequired: Bool { - switch self { - case .retry, .retryWithDelay: return true - default: return false - } - } - - var delay: TimeInterval? { - switch self { - case let .retryWithDelay(delay): return delay - default: return nil - } - } - - var error: Error? { - guard case let .doNotRetryWithError(error) = self else { return nil } - return error - } -} - -/// A type that determines whether a request should be retried after being executed by the specified session manager -/// and encountering an error. -public protocol RequestRetrier { - /// Determines whether the `Request` should be retried by calling the `completion` closure. - /// - /// This operation is fully asynchronous. Any amount of time can be taken to determine whether the request needs - /// to be retried. The one requirement is that the completion closure is called to ensure the request is properly - /// cleaned up after. - /// - /// - Parameters: - /// - request: `Request` that failed due to the provided `Error`. - /// - session: `Session` that produced the `Request`. - /// - error: `Error` encountered while executing the `Request`. - /// - completion: Completion closure to be executed when a retry decision has been determined. - func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) -} - -// MARK: - - -/// Type that provides both `RequestAdapter` and `RequestRetrier` functionality. -public protocol RequestInterceptor: RequestAdapter, RequestRetrier {} - -extension RequestInterceptor { - public func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result) -> Void) { - completion(.success(urlRequest)) - } - - public func retry(_ request: Request, - for session: Session, - dueTo error: Error, - completion: @escaping (RetryResult) -> Void) { - completion(.doNotRetry) - } -} - -/// `RequestAdapter` closure definition. -public typealias AdaptHandler = (URLRequest, Session, _ completion: @escaping (Result) -> Void) -> Void -/// `RequestRetrier` closure definition. -public typealias RetryHandler = (Request, Session, Error, _ completion: @escaping (RetryResult) -> Void) -> Void - -// MARK: - - -/// Closure-based `RequestAdapter`. -open class Adapter: RequestInterceptor { - private let adaptHandler: AdaptHandler - - /// Creates an instance using the provided closure. - /// - /// - Parameter adaptHandler: `AdaptHandler` closure to be executed when handling request adaptation. - public init(_ adaptHandler: @escaping AdaptHandler) { - self.adaptHandler = adaptHandler - } - - open func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result) -> Void) { - adaptHandler(urlRequest, session, completion) - } -} - -// MARK: - - -/// Closure-based `RequestRetrier`. -open class Retrier: RequestInterceptor { - private let retryHandler: RetryHandler - - /// Creates an instance using the provided closure. - /// - /// - Parameter retryHandler: `RetryHandler` closure to be executed when handling request retry. - public init(_ retryHandler: @escaping RetryHandler) { - self.retryHandler = retryHandler - } - - open func retry(_ request: Request, - for session: Session, - dueTo error: Error, - completion: @escaping (RetryResult) -> Void) { - retryHandler(request, session, error, completion) - } -} - -// MARK: - - -/// `RequestInterceptor` which can use multiple `RequestAdapter` and `RequestRetrier` values. -open class Interceptor: RequestInterceptor { - /// All `RequestAdapter`s associated with the instance. These adapters will be run until one fails. - public let adapters: [RequestAdapter] - /// All `RequestRetrier`s associated with the instance. These retriers will be run one at a time until one triggers retry. - public let retriers: [RequestRetrier] - - /// Creates an instance from `AdaptHandler` and `RetryHandler` closures. - /// - /// - Parameters: - /// - adaptHandler: `AdaptHandler` closure to be used. - /// - retryHandler: `RetryHandler` closure to be used. - public init(adaptHandler: @escaping AdaptHandler, retryHandler: @escaping RetryHandler) { - adapters = [Adapter(adaptHandler)] - retriers = [Retrier(retryHandler)] - } - - /// Creates an instance from `RequestAdapter` and `RequestRetrier` values. - /// - /// - Parameters: - /// - adapter: `RequestAdapter` value to be used. - /// - retrier: `RequestRetrier` value to be used. - public init(adapter: RequestAdapter, retrier: RequestRetrier) { - adapters = [adapter] - retriers = [retrier] - } - - /// Creates an instance from the arrays of `RequestAdapter` and `RequestRetrier` values. - /// - /// - Parameters: - /// - adapters: `RequestAdapter` values to be used. - /// - retriers: `RequestRetrier` values to be used. - /// - interceptors: `RequestInterceptor`s to be used. - public init(adapters: [RequestAdapter] = [], retriers: [RequestRetrier] = [], interceptors: [RequestInterceptor] = []) { - self.adapters = adapters + interceptors - self.retriers = retriers + interceptors - } - - open func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result) -> Void) { - adapt(urlRequest, for: session, using: adapters, completion: completion) - } - - private func adapt(_ urlRequest: URLRequest, - for session: Session, - using adapters: [RequestAdapter], - completion: @escaping (Result) -> Void) { - var pendingAdapters = adapters - - guard !pendingAdapters.isEmpty else { completion(.success(urlRequest)); return } - - let adapter = pendingAdapters.removeFirst() - - adapter.adapt(urlRequest, for: session) { result in - switch result { - case let .success(urlRequest): - self.adapt(urlRequest, for: session, using: pendingAdapters, completion: completion) - case .failure: - completion(result) - } - } - } - - open func retry(_ request: Request, - for session: Session, - dueTo error: Error, - completion: @escaping (RetryResult) -> Void) { - retry(request, for: session, dueTo: error, using: retriers, completion: completion) - } - - private func retry(_ request: Request, - for session: Session, - dueTo error: Error, - using retriers: [RequestRetrier], - completion: @escaping (RetryResult) -> Void) { - var pendingRetriers = retriers - - guard !pendingRetriers.isEmpty else { completion(.doNotRetry); return } - - let retrier = pendingRetriers.removeFirst() - - retrier.retry(request, for: session, dueTo: error) { result in - switch result { - case .retry, .retryWithDelay, .doNotRetryWithError: - completion(result) - case .doNotRetry: - // Only continue to the next retrier if retry was not triggered and no error was encountered - self.retry(request, for: session, dueTo: error, using: pendingRetriers, completion: completion) - } - } - } -} diff --git a/Pods/Alamofire/Source/RequestTaskMap.swift b/Pods/Alamofire/Source/RequestTaskMap.swift deleted file mode 100644 index 85b58f377..000000000 --- a/Pods/Alamofire/Source/RequestTaskMap.swift +++ /dev/null @@ -1,149 +0,0 @@ -// -// RequestTaskMap.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -/// A type that maintains a two way, one to one map of `URLSessionTask`s to `Request`s. -struct RequestTaskMap { - private typealias Events = (completed: Bool, metricsGathered: Bool) - - private var tasksToRequests: [URLSessionTask: Request] - private var requestsToTasks: [Request: URLSessionTask] - private var taskEvents: [URLSessionTask: Events] - - var requests: [Request] { - Array(tasksToRequests.values) - } - - init(tasksToRequests: [URLSessionTask: Request] = [:], - requestsToTasks: [Request: URLSessionTask] = [:], - taskEvents: [URLSessionTask: (completed: Bool, metricsGathered: Bool)] = [:]) { - self.tasksToRequests = tasksToRequests - self.requestsToTasks = requestsToTasks - self.taskEvents = taskEvents - } - - subscript(_ request: Request) -> URLSessionTask? { - get { requestsToTasks[request] } - set { - guard let newValue = newValue else { - guard let task = requestsToTasks[request] else { - fatalError("RequestTaskMap consistency error: no task corresponding to request found.") - } - - requestsToTasks.removeValue(forKey: request) - tasksToRequests.removeValue(forKey: task) - taskEvents.removeValue(forKey: task) - - return - } - - requestsToTasks[request] = newValue - tasksToRequests[newValue] = request - taskEvents[newValue] = (completed: false, metricsGathered: false) - } - } - - subscript(_ task: URLSessionTask) -> Request? { - get { tasksToRequests[task] } - set { - guard let newValue = newValue else { - guard let request = tasksToRequests[task] else { - fatalError("RequestTaskMap consistency error: no request corresponding to task found.") - } - - tasksToRequests.removeValue(forKey: task) - requestsToTasks.removeValue(forKey: request) - taskEvents.removeValue(forKey: task) - - return - } - - tasksToRequests[task] = newValue - requestsToTasks[newValue] = task - taskEvents[task] = (completed: false, metricsGathered: false) - } - } - - var count: Int { - precondition(tasksToRequests.count == requestsToTasks.count, - "RequestTaskMap.count invalid, requests.count: \(tasksToRequests.count) != tasks.count: \(requestsToTasks.count)") - - return tasksToRequests.count - } - - var eventCount: Int { - precondition(taskEvents.count == count, "RequestTaskMap.eventCount invalid, count: \(count) != taskEvents.count: \(taskEvents.count)") - - return taskEvents.count - } - - var isEmpty: Bool { - precondition(tasksToRequests.isEmpty == requestsToTasks.isEmpty, - "RequestTaskMap.isEmpty invalid, requests.isEmpty: \(tasksToRequests.isEmpty) != tasks.isEmpty: \(requestsToTasks.isEmpty)") - - return tasksToRequests.isEmpty - } - - var isEventsEmpty: Bool { - precondition(taskEvents.isEmpty == isEmpty, "RequestTaskMap.isEventsEmpty invalid, isEmpty: \(isEmpty) != taskEvents.isEmpty: \(taskEvents.isEmpty)") - - return taskEvents.isEmpty - } - - mutating func disassociateIfNecessaryAfterGatheringMetricsForTask(_ task: URLSessionTask) -> Bool { - guard let events = taskEvents[task] else { - fatalError("RequestTaskMap consistency error: no events corresponding to task found.") - } - - switch (events.completed, events.metricsGathered) { - case (_, true): fatalError("RequestTaskMap consistency error: duplicate metricsGatheredForTask call.") - case (false, false): taskEvents[task] = (completed: false, metricsGathered: true); return false - case (true, false): self[task] = nil; return true - } - } - - mutating func disassociateIfNecessaryAfterCompletingTask(_ task: URLSessionTask) -> Bool { - guard let events = taskEvents[task] else { - fatalError("RequestTaskMap consistency error: no events corresponding to task found.") - } - - switch (events.completed, events.metricsGathered) { - case (true, _): fatalError("RequestTaskMap consistency error: duplicate completionReceivedForTask call.") - #if os(Linux) // Linux doesn't gather metrics, so unconditionally remove the reference and return true. - default: self[task] = nil; return true - #else - case (false, false): - if #available(macOS 10.12, iOS 10, watchOS 7, tvOS 10, *) { - taskEvents[task] = (completed: true, metricsGathered: false); return false - } else { - // watchOS < 7 doesn't gather metrics, so unconditionally remove the reference and return true. - self[task] = nil; return true - } - case (false, true): - self[task] = nil; return true - #endif - } - } -} diff --git a/Pods/Alamofire/Source/Response.swift b/Pods/Alamofire/Source/Response.swift deleted file mode 100644 index 92e9c44eb..000000000 --- a/Pods/Alamofire/Source/Response.swift +++ /dev/null @@ -1,454 +0,0 @@ -// -// Response.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -/// Default type of `DataResponse` returned by Alamofire, with an `AFError` `Failure` type. -public typealias AFDataResponse = DataResponse -/// Default type of `DownloadResponse` returned by Alamofire, with an `AFError` `Failure` type. -public typealias AFDownloadResponse = DownloadResponse - -/// Type used to store all values associated with a serialized response of a `DataRequest` or `UploadRequest`. -public struct DataResponse { - /// The URL request sent to the server. - public let request: URLRequest? - - /// The server's response to the URL request. - public let response: HTTPURLResponse? - - /// The data returned by the server. - public let data: Data? - - /// The final metrics of the response. - /// - /// - Note: Due to `FB7624529`, collection of `URLSessionTaskMetrics` on watchOS is currently disabled.` - /// - public let metrics: URLSessionTaskMetrics? - - /// The time taken to serialize the response. - public let serializationDuration: TimeInterval - - /// The result of response serialization. - public let result: Result - - /// Returns the associated value of the result if it is a success, `nil` otherwise. - public var value: Success? { result.success } - - /// Returns the associated error value if the result if it is a failure, `nil` otherwise. - public var error: Failure? { result.failure } - - /// Creates a `DataResponse` instance with the specified parameters derived from the response serialization. - /// - /// - Parameters: - /// - request: The `URLRequest` sent to the server. - /// - response: The `HTTPURLResponse` from the server. - /// - data: The `Data` returned by the server. - /// - metrics: The `URLSessionTaskMetrics` of the `DataRequest` or `UploadRequest`. - /// - serializationDuration: The duration taken by serialization. - /// - result: The `Result` of response serialization. - public init(request: URLRequest?, - response: HTTPURLResponse?, - data: Data?, - metrics: URLSessionTaskMetrics?, - serializationDuration: TimeInterval, - result: Result) { - self.request = request - self.response = response - self.data = data - self.metrics = metrics - self.serializationDuration = serializationDuration - self.result = result - } -} - -// MARK: - - -extension DataResponse: CustomStringConvertible, CustomDebugStringConvertible { - /// The textual representation used when written to an output stream, which includes whether the result was a - /// success or failure. - public var description: String { - "\(result)" - } - - /// The debug textual representation used when written to an output stream, which includes (if available) a summary - /// of the `URLRequest`, the request's headers and body (if decodable as a `String` below 100KB); the - /// `HTTPURLResponse`'s status code, headers, and body; the duration of the network and serialization actions; and - /// the `Result` of serialization. - public var debugDescription: String { - guard let urlRequest = request else { return "[Request]: None\n[Result]: \(result)" } - - let requestDescription = DebugDescription.description(of: urlRequest) - - let responseDescription = response.map { response in - let responseBodyDescription = DebugDescription.description(for: data, headers: response.headers) - - return """ - \(DebugDescription.description(of: response)) - \(responseBodyDescription.indentingNewlines()) - """ - } ?? "[Response]: None" - - let networkDuration = metrics.map { "\($0.taskInterval.duration)s" } ?? "None" - - return """ - \(requestDescription) - \(responseDescription) - [Network Duration]: \(networkDuration) - [Serialization Duration]: \(serializationDuration)s - [Result]: \(result) - """ - } -} - -// MARK: - - -extension DataResponse { - /// Evaluates the specified closure when the result of this `DataResponse` is a success, passing the unwrapped - /// result value as a parameter. - /// - /// Use the `map` method with a closure that does not throw. For example: - /// - /// let possibleData: DataResponse = ... - /// let possibleInt = possibleData.map { $0.count } - /// - /// - parameter transform: A closure that takes the success value of the instance's result. - /// - /// - returns: A `DataResponse` whose result wraps the value returned by the given closure. If this instance's - /// result is a failure, returns a response wrapping the same failure. - public func map(_ transform: (Success) -> NewSuccess) -> DataResponse { - DataResponse(request: request, - response: response, - data: data, - metrics: metrics, - serializationDuration: serializationDuration, - result: result.map(transform)) - } - - /// Evaluates the given closure when the result of this `DataResponse` is a success, passing the unwrapped result - /// value as a parameter. - /// - /// Use the `tryMap` method with a closure that may throw an error. For example: - /// - /// let possibleData: DataResponse = ... - /// let possibleObject = possibleData.tryMap { - /// try JSONSerialization.jsonObject(with: $0) - /// } - /// - /// - parameter transform: A closure that takes the success value of the instance's result. - /// - /// - returns: A success or failure `DataResponse` depending on the result of the given closure. If this instance's - /// result is a failure, returns the same failure. - public func tryMap(_ transform: (Success) throws -> NewSuccess) -> DataResponse { - DataResponse(request: request, - response: response, - data: data, - metrics: metrics, - serializationDuration: serializationDuration, - result: result.tryMap(transform)) - } - - /// Evaluates the specified closure when the `DataResponse` is a failure, passing the unwrapped error as a parameter. - /// - /// Use the `mapError` function with a closure that does not throw. For example: - /// - /// let possibleData: DataResponse = ... - /// let withMyError = possibleData.mapError { MyError.error($0) } - /// - /// - Parameter transform: A closure that takes the error of the instance. - /// - /// - Returns: A `DataResponse` instance containing the result of the transform. - public func mapError(_ transform: (Failure) -> NewFailure) -> DataResponse { - DataResponse(request: request, - response: response, - data: data, - metrics: metrics, - serializationDuration: serializationDuration, - result: result.mapError(transform)) - } - - /// Evaluates the specified closure when the `DataResponse` is a failure, passing the unwrapped error as a parameter. - /// - /// Use the `tryMapError` function with a closure that may throw an error. For example: - /// - /// let possibleData: DataResponse = ... - /// let possibleObject = possibleData.tryMapError { - /// try someFailableFunction(taking: $0) - /// } - /// - /// - Parameter transform: A throwing closure that takes the error of the instance. - /// - /// - Returns: A `DataResponse` instance containing the result of the transform. - public func tryMapError(_ transform: (Failure) throws -> NewFailure) -> DataResponse { - DataResponse(request: request, - response: response, - data: data, - metrics: metrics, - serializationDuration: serializationDuration, - result: result.tryMapError(transform)) - } -} - -// MARK: - - -/// Used to store all data associated with a serialized response of a download request. -public struct DownloadResponse { - /// The URL request sent to the server. - public let request: URLRequest? - - /// The server's response to the URL request. - public let response: HTTPURLResponse? - - /// The final destination URL of the data returned from the server after it is moved. - public let fileURL: URL? - - /// The resume data generated if the request was cancelled. - public let resumeData: Data? - - /// The final metrics of the response. - /// - /// - Note: Due to `FB7624529`, collection of `URLSessionTaskMetrics` on watchOS is currently disabled.` - /// - public let metrics: URLSessionTaskMetrics? - - /// The time taken to serialize the response. - public let serializationDuration: TimeInterval - - /// The result of response serialization. - public let result: Result - - /// Returns the associated value of the result if it is a success, `nil` otherwise. - public var value: Success? { result.success } - - /// Returns the associated error value if the result if it is a failure, `nil` otherwise. - public var error: Failure? { result.failure } - - /// Creates a `DownloadResponse` instance with the specified parameters derived from response serialization. - /// - /// - Parameters: - /// - request: The `URLRequest` sent to the server. - /// - response: The `HTTPURLResponse` from the server. - /// - temporaryURL: The temporary destination `URL` of the data returned from the server. - /// - destinationURL: The final destination `URL` of the data returned from the server, if it was moved. - /// - resumeData: The resume `Data` generated if the request was cancelled. - /// - metrics: The `URLSessionTaskMetrics` of the `DownloadRequest`. - /// - serializationDuration: The duration taken by serialization. - /// - result: The `Result` of response serialization. - public init(request: URLRequest?, - response: HTTPURLResponse?, - fileURL: URL?, - resumeData: Data?, - metrics: URLSessionTaskMetrics?, - serializationDuration: TimeInterval, - result: Result) { - self.request = request - self.response = response - self.fileURL = fileURL - self.resumeData = resumeData - self.metrics = metrics - self.serializationDuration = serializationDuration - self.result = result - } -} - -// MARK: - - -extension DownloadResponse: CustomStringConvertible, CustomDebugStringConvertible { - /// The textual representation used when written to an output stream, which includes whether the result was a - /// success or failure. - public var description: String { - "\(result)" - } - - /// The debug textual representation used when written to an output stream, which includes the URL request, the URL - /// response, the temporary and destination URLs, the resume data, the durations of the network and serialization - /// actions, and the response serialization result. - public var debugDescription: String { - guard let urlRequest = request else { return "[Request]: None\n[Result]: \(result)" } - - let requestDescription = DebugDescription.description(of: urlRequest) - let responseDescription = response.map(DebugDescription.description(of:)) ?? "[Response]: None" - let networkDuration = metrics.map { "\($0.taskInterval.duration)s" } ?? "None" - let resumeDataDescription = resumeData.map { "\($0)" } ?? "None" - - return """ - \(requestDescription) - \(responseDescription) - [File URL]: \(fileURL?.path ?? "None") - [Resume Data]: \(resumeDataDescription) - [Network Duration]: \(networkDuration) - [Serialization Duration]: \(serializationDuration)s - [Result]: \(result) - """ - } -} - -// MARK: - - -extension DownloadResponse { - /// Evaluates the given closure when the result of this `DownloadResponse` is a success, passing the unwrapped - /// result value as a parameter. - /// - /// Use the `map` method with a closure that does not throw. For example: - /// - /// let possibleData: DownloadResponse = ... - /// let possibleInt = possibleData.map { $0.count } - /// - /// - parameter transform: A closure that takes the success value of the instance's result. - /// - /// - returns: A `DownloadResponse` whose result wraps the value returned by the given closure. If this instance's - /// result is a failure, returns a response wrapping the same failure. - public func map(_ transform: (Success) -> NewSuccess) -> DownloadResponse { - DownloadResponse(request: request, - response: response, - fileURL: fileURL, - resumeData: resumeData, - metrics: metrics, - serializationDuration: serializationDuration, - result: result.map(transform)) - } - - /// Evaluates the given closure when the result of this `DownloadResponse` is a success, passing the unwrapped - /// result value as a parameter. - /// - /// Use the `tryMap` method with a closure that may throw an error. For example: - /// - /// let possibleData: DownloadResponse = ... - /// let possibleObject = possibleData.tryMap { - /// try JSONSerialization.jsonObject(with: $0) - /// } - /// - /// - parameter transform: A closure that takes the success value of the instance's result. - /// - /// - returns: A success or failure `DownloadResponse` depending on the result of the given closure. If this - /// instance's result is a failure, returns the same failure. - public func tryMap(_ transform: (Success) throws -> NewSuccess) -> DownloadResponse { - DownloadResponse(request: request, - response: response, - fileURL: fileURL, - resumeData: resumeData, - metrics: metrics, - serializationDuration: serializationDuration, - result: result.tryMap(transform)) - } - - /// Evaluates the specified closure when the `DownloadResponse` is a failure, passing the unwrapped error as a parameter. - /// - /// Use the `mapError` function with a closure that does not throw. For example: - /// - /// let possibleData: DownloadResponse = ... - /// let withMyError = possibleData.mapError { MyError.error($0) } - /// - /// - Parameter transform: A closure that takes the error of the instance. - /// - /// - Returns: A `DownloadResponse` instance containing the result of the transform. - public func mapError(_ transform: (Failure) -> NewFailure) -> DownloadResponse { - DownloadResponse(request: request, - response: response, - fileURL: fileURL, - resumeData: resumeData, - metrics: metrics, - serializationDuration: serializationDuration, - result: result.mapError(transform)) - } - - /// Evaluates the specified closure when the `DownloadResponse` is a failure, passing the unwrapped error as a parameter. - /// - /// Use the `tryMapError` function with a closure that may throw an error. For example: - /// - /// let possibleData: DownloadResponse = ... - /// let possibleObject = possibleData.tryMapError { - /// try someFailableFunction(taking: $0) - /// } - /// - /// - Parameter transform: A throwing closure that takes the error of the instance. - /// - /// - Returns: A `DownloadResponse` instance containing the result of the transform. - public func tryMapError(_ transform: (Failure) throws -> NewFailure) -> DownloadResponse { - DownloadResponse(request: request, - response: response, - fileURL: fileURL, - resumeData: resumeData, - metrics: metrics, - serializationDuration: serializationDuration, - result: result.tryMapError(transform)) - } -} - -private enum DebugDescription { - static func description(of request: URLRequest) -> String { - let requestSummary = "\(request.httpMethod!) \(request)" - let requestHeadersDescription = DebugDescription.description(for: request.headers) - let requestBodyDescription = DebugDescription.description(for: request.httpBody, headers: request.headers) - - return """ - [Request]: \(requestSummary) - \(requestHeadersDescription.indentingNewlines()) - \(requestBodyDescription.indentingNewlines()) - """ - } - - static func description(of response: HTTPURLResponse) -> String { - """ - [Response]: - [Status Code]: \(response.statusCode) - \(DebugDescription.description(for: response.headers).indentingNewlines()) - """ - } - - static func description(for headers: HTTPHeaders) -> String { - guard !headers.isEmpty else { return "[Headers]: None" } - - let headerDescription = "\(headers.sorted())".indentingNewlines() - return """ - [Headers]: - \(headerDescription) - """ - } - - static func description(for data: Data?, - headers: HTTPHeaders, - allowingPrintableTypes printableTypes: [String] = ["json", "xml", "text"], - maximumLength: Int = 100_000) -> String { - guard let data = data, !data.isEmpty else { return "[Body]: None" } - - guard - data.count <= maximumLength, - printableTypes.compactMap({ headers["Content-Type"]?.contains($0) }).contains(true) - else { return "[Body]: \(data.count) bytes" } - - return """ - [Body]: - \(String(decoding: data, as: UTF8.self) - .trimmingCharacters(in: .whitespacesAndNewlines) - .indentingNewlines()) - """ - } -} - -extension String { - fileprivate func indentingNewlines(by spaceCount: Int = 4) -> String { - let spaces = String(repeating: " ", count: spaceCount) - return replacingOccurrences(of: "\n", with: "\n\(spaces)") - } -} diff --git a/Pods/Alamofire/Source/ResponseSerialization.swift b/Pods/Alamofire/Source/ResponseSerialization.swift deleted file mode 100644 index 1b77016d5..000000000 --- a/Pods/Alamofire/Source/ResponseSerialization.swift +++ /dev/null @@ -1,1116 +0,0 @@ -// -// ResponseSerialization.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -// MARK: Protocols - -/// The type to which all data response serializers must conform in order to serialize a response. -public protocol DataResponseSerializerProtocol { - /// The type of serialized object to be created. - associatedtype SerializedObject - - /// Serialize the response `Data` into the provided type.. - /// - /// - Parameters: - /// - request: `URLRequest` which was used to perform the request, if any. - /// - response: `HTTPURLResponse` received from the server, if any. - /// - data: `Data` returned from the server, if any. - /// - error: `Error` produced by Alamofire or the underlying `URLSession` during the request. - /// - /// - Returns: The `SerializedObject`. - /// - Throws: Any `Error` produced during serialization. - func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> SerializedObject -} - -/// The type to which all download response serializers must conform in order to serialize a response. -public protocol DownloadResponseSerializerProtocol { - /// The type of serialized object to be created. - associatedtype SerializedObject - - /// Serialize the downloaded response `Data` from disk into the provided type.. - /// - /// - Parameters: - /// - request: `URLRequest` which was used to perform the request, if any. - /// - response: `HTTPURLResponse` received from the server, if any. - /// - fileURL: File `URL` to which the response data was downloaded. - /// - error: `Error` produced by Alamofire or the underlying `URLSession` during the request. - /// - /// - Returns: The `SerializedObject`. - /// - Throws: Any `Error` produced during serialization. - func serializeDownload(request: URLRequest?, response: HTTPURLResponse?, fileURL: URL?, error: Error?) throws -> SerializedObject -} - -/// A serializer that can handle both data and download responses. -public protocol ResponseSerializer: DataResponseSerializerProtocol & DownloadResponseSerializerProtocol { - /// `DataPreprocessor` used to prepare incoming `Data` for serialization. - var dataPreprocessor: DataPreprocessor { get } - /// `HTTPMethod`s for which empty response bodies are considered appropriate. - var emptyRequestMethods: Set { get } - /// HTTP response codes for which empty response bodies are considered appropriate. - var emptyResponseCodes: Set { get } -} - -/// Type used to preprocess `Data` before it handled by a serializer. -public protocol DataPreprocessor { - /// Process `Data` before it's handled by a serializer. - /// - Parameter data: The raw `Data` to process. - func preprocess(_ data: Data) throws -> Data -} - -/// `DataPreprocessor` that returns passed `Data` without any transform. -public struct PassthroughPreprocessor: DataPreprocessor { - public init() {} - - public func preprocess(_ data: Data) throws -> Data { data } -} - -/// `DataPreprocessor` that trims Google's typical `)]}',\n` XSSI JSON header. -public struct GoogleXSSIPreprocessor: DataPreprocessor { - public init() {} - - public func preprocess(_ data: Data) throws -> Data { - (data.prefix(6) == Data(")]}',\n".utf8)) ? data.dropFirst(6) : data - } -} - -extension ResponseSerializer { - /// Default `DataPreprocessor`. `PassthroughPreprocessor` by default. - public static var defaultDataPreprocessor: DataPreprocessor { PassthroughPreprocessor() } - /// Default `HTTPMethod`s for which empty response bodies are considered appropriate. `[.head]` by default. - public static var defaultEmptyRequestMethods: Set { [.head] } - /// HTTP response codes for which empty response bodies are considered appropriate. `[204, 205]` by default. - public static var defaultEmptyResponseCodes: Set { [204, 205] } - - public var dataPreprocessor: DataPreprocessor { Self.defaultDataPreprocessor } - public var emptyRequestMethods: Set { Self.defaultEmptyRequestMethods } - public var emptyResponseCodes: Set { Self.defaultEmptyResponseCodes } - - /// Determines whether the `request` allows empty response bodies, if `request` exists. - /// - /// - Parameter request: `URLRequest` to evaluate. - /// - /// - Returns: `Bool` representing the outcome of the evaluation, or `nil` if `request` was `nil`. - public func requestAllowsEmptyResponseData(_ request: URLRequest?) -> Bool? { - request.flatMap { $0.httpMethod } - .flatMap(HTTPMethod.init) - .map { emptyRequestMethods.contains($0) } - } - - /// Determines whether the `response` allows empty response bodies, if `response` exists`. - /// - /// - Parameter response: `HTTPURLResponse` to evaluate. - /// - /// - Returns: `Bool` representing the outcome of the evaluation, or `nil` if `response` was `nil`. - public func responseAllowsEmptyResponseData(_ response: HTTPURLResponse?) -> Bool? { - response.flatMap { $0.statusCode } - .map { emptyResponseCodes.contains($0) } - } - - /// Determines whether `request` and `response` allow empty response bodies. - /// - /// - Parameters: - /// - request: `URLRequest` to evaluate. - /// - response: `HTTPURLResponse` to evaluate. - /// - /// - Returns: `true` if `request` or `response` allow empty bodies, `false` otherwise. - public func emptyResponseAllowed(forRequest request: URLRequest?, response: HTTPURLResponse?) -> Bool { - (requestAllowsEmptyResponseData(request) == true) || (responseAllowsEmptyResponseData(response) == true) - } -} - -/// By default, any serializer declared to conform to both types will get file serialization for free, as it just feeds -/// the data read from disk into the data response serializer. -extension DownloadResponseSerializerProtocol where Self: DataResponseSerializerProtocol { - public func serializeDownload(request: URLRequest?, response: HTTPURLResponse?, fileURL: URL?, error: Error?) throws -> Self.SerializedObject { - guard error == nil else { throw error! } - - guard let fileURL = fileURL else { - throw AFError.responseSerializationFailed(reason: .inputFileNil) - } - - let data: Data - do { - data = try Data(contentsOf: fileURL) - } catch { - throw AFError.responseSerializationFailed(reason: .inputFileReadFailed(at: fileURL)) - } - - do { - return try serialize(request: request, response: response, data: data, error: error) - } catch { - throw error - } - } -} - -// MARK: - Default - -extension DataRequest { - /// Adds a handler to be called once the request has finished. - /// - /// - Parameters: - /// - queue: The queue on which the completion handler is dispatched. `.main` by default. - /// - completionHandler: The code to be executed once the request has finished. - /// - /// - Returns: The request. - @discardableResult - public func response(queue: DispatchQueue = .main, completionHandler: @escaping (AFDataResponse) -> Void) -> Self { - appendResponseSerializer { - // Start work that should be on the serialization queue. - let result = AFResult(value: self.data, error: self.error) - // End work that should be on the serialization queue. - - self.underlyingQueue.async { - let response = DataResponse(request: self.request, - response: self.response, - data: self.data, - metrics: self.metrics, - serializationDuration: 0, - result: result) - - self.eventMonitor?.request(self, didParseResponse: response) - - self.responseSerializerDidComplete { queue.async { completionHandler(response) } } - } - } - - return self - } - - /// Adds a handler to be called once the request has finished. - /// - /// - Parameters: - /// - queue: The queue on which the completion handler is dispatched. `.main` by default - /// - responseSerializer: The response serializer responsible for serializing the request, response, and data. - /// - completionHandler: The code to be executed once the request has finished. - /// - /// - Returns: The request. - @discardableResult - public func response(queue: DispatchQueue = .main, - responseSerializer: Serializer, - completionHandler: @escaping (AFDataResponse) -> Void) - -> Self { - appendResponseSerializer { - // Start work that should be on the serialization queue. - let start = ProcessInfo.processInfo.systemUptime - let result: AFResult = Result { - try responseSerializer.serialize(request: self.request, - response: self.response, - data: self.data, - error: self.error) - }.mapError { error in - error.asAFError(or: .responseSerializationFailed(reason: .customSerializationFailed(error: error))) - } - - let end = ProcessInfo.processInfo.systemUptime - // End work that should be on the serialization queue. - - self.underlyingQueue.async { - let response = DataResponse(request: self.request, - response: self.response, - data: self.data, - metrics: self.metrics, - serializationDuration: end - start, - result: result) - - self.eventMonitor?.request(self, didParseResponse: response) - - guard let serializerError = result.failure, let delegate = self.delegate else { - self.responseSerializerDidComplete { queue.async { completionHandler(response) } } - return - } - - delegate.retryResult(for: self, dueTo: serializerError) { retryResult in - var didComplete: (() -> Void)? - - defer { - if let didComplete = didComplete { - self.responseSerializerDidComplete { queue.async { didComplete() } } - } - } - - switch retryResult { - case .doNotRetry: - didComplete = { completionHandler(response) } - - case let .doNotRetryWithError(retryError): - let result: AFResult = .failure(retryError.asAFError(orFailWith: "Received retryError was not already AFError")) - - let response = DataResponse(request: self.request, - response: self.response, - data: self.data, - metrics: self.metrics, - serializationDuration: end - start, - result: result) - - didComplete = { completionHandler(response) } - - case .retry, .retryWithDelay: - delegate.retryRequest(self, withDelay: retryResult.delay) - } - } - } - } - - return self - } -} - -extension DownloadRequest { - /// Adds a handler to be called once the request has finished. - /// - /// - Parameters: - /// - queue: The queue on which the completion handler is dispatched. `.main` by default. - /// - completionHandler: The code to be executed once the request has finished. - /// - /// - Returns: The request. - @discardableResult - public func response(queue: DispatchQueue = .main, - completionHandler: @escaping (AFDownloadResponse) -> Void) - -> Self { - appendResponseSerializer { - // Start work that should be on the serialization queue. - let result = AFResult(value: self.fileURL, error: self.error) - // End work that should be on the serialization queue. - - self.underlyingQueue.async { - let response = DownloadResponse(request: self.request, - response: self.response, - fileURL: self.fileURL, - resumeData: self.resumeData, - metrics: self.metrics, - serializationDuration: 0, - result: result) - - self.eventMonitor?.request(self, didParseResponse: response) - - self.responseSerializerDidComplete { queue.async { completionHandler(response) } } - } - } - - return self - } - - /// Adds a handler to be called once the request has finished. - /// - /// - Parameters: - /// - queue: The queue on which the completion handler is dispatched. `.main` by default. - /// - responseSerializer: The response serializer responsible for serializing the request, response, and data - /// contained in the destination `URL`. - /// - completionHandler: The code to be executed once the request has finished. - /// - /// - Returns: The request. - @discardableResult - public func response(queue: DispatchQueue = .main, - responseSerializer: Serializer, - completionHandler: @escaping (AFDownloadResponse) -> Void) - -> Self { - appendResponseSerializer { - // Start work that should be on the serialization queue. - let start = ProcessInfo.processInfo.systemUptime - let result: AFResult = Result { - try responseSerializer.serializeDownload(request: self.request, - response: self.response, - fileURL: self.fileURL, - error: self.error) - }.mapError { error in - error.asAFError(or: .responseSerializationFailed(reason: .customSerializationFailed(error: error))) - } - let end = ProcessInfo.processInfo.systemUptime - // End work that should be on the serialization queue. - - self.underlyingQueue.async { - let response = DownloadResponse(request: self.request, - response: self.response, - fileURL: self.fileURL, - resumeData: self.resumeData, - metrics: self.metrics, - serializationDuration: end - start, - result: result) - - self.eventMonitor?.request(self, didParseResponse: response) - - guard let serializerError = result.failure, let delegate = self.delegate else { - self.responseSerializerDidComplete { queue.async { completionHandler(response) } } - return - } - - delegate.retryResult(for: self, dueTo: serializerError) { retryResult in - var didComplete: (() -> Void)? - - defer { - if let didComplete = didComplete { - self.responseSerializerDidComplete { queue.async { didComplete() } } - } - } - - switch retryResult { - case .doNotRetry: - didComplete = { completionHandler(response) } - - case let .doNotRetryWithError(retryError): - let result: AFResult = .failure(retryError.asAFError(orFailWith: "Received retryError was not already AFError")) - - let response = DownloadResponse(request: self.request, - response: self.response, - fileURL: self.fileURL, - resumeData: self.resumeData, - metrics: self.metrics, - serializationDuration: end - start, - result: result) - - didComplete = { completionHandler(response) } - - case .retry, .retryWithDelay: - delegate.retryRequest(self, withDelay: retryResult.delay) - } - } - } - } - - return self - } -} - -// MARK: - URL - -/// A `DownloadResponseSerializerProtocol` that performs only `Error` checking and ensures that a downloaded `fileURL` -/// is present. -public struct URLResponseSerializer: DownloadResponseSerializerProtocol { - /// Creates an instance. - public init() {} - - public func serializeDownload(request: URLRequest?, - response: HTTPURLResponse?, - fileURL: URL?, - error: Error?) throws -> URL { - guard error == nil else { throw error! } - - guard let url = fileURL else { - throw AFError.responseSerializationFailed(reason: .inputFileNil) - } - - return url - } -} - -extension DownloadRequest { - /// Adds a handler using a `URLResponseSerializer` to be called once the request is finished. - /// - /// - Parameters: - /// - queue: The queue on which the completion handler is called. `.main` by default. - /// - completionHandler: A closure to be executed once the request has finished. - /// - /// - Returns: The request. - @discardableResult - public func responseURL(queue: DispatchQueue = .main, - completionHandler: @escaping (AFDownloadResponse) -> Void) -> Self { - response(queue: queue, responseSerializer: URLResponseSerializer(), completionHandler: completionHandler) - } -} - -// MARK: - Data - -/// A `ResponseSerializer` that performs minimal response checking and returns any response `Data` as-is. By default, a -/// request returning `nil` or no data is considered an error. However, if the request has an `HTTPMethod` or the -/// response has an HTTP status code valid for empty responses, then an empty `Data` value is returned. -public final class DataResponseSerializer: ResponseSerializer { - public let dataPreprocessor: DataPreprocessor - public let emptyResponseCodes: Set - public let emptyRequestMethods: Set - - /// Creates an instance using the provided values. - /// - /// - Parameters: - /// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization. - /// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default. - /// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default. - public init(dataPreprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor, - emptyResponseCodes: Set = DataResponseSerializer.defaultEmptyResponseCodes, - emptyRequestMethods: Set = DataResponseSerializer.defaultEmptyRequestMethods) { - self.dataPreprocessor = dataPreprocessor - self.emptyResponseCodes = emptyResponseCodes - self.emptyRequestMethods = emptyRequestMethods - } - - public func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> Data { - guard error == nil else { throw error! } - - guard var data = data, !data.isEmpty else { - guard emptyResponseAllowed(forRequest: request, response: response) else { - throw AFError.responseSerializationFailed(reason: .inputDataNilOrZeroLength) - } - - return Data() - } - - data = try dataPreprocessor.preprocess(data) - - return data - } -} - -extension DataRequest { - /// Adds a handler using a `DataResponseSerializer` to be called once the request has finished. - /// - /// - Parameters: - /// - queue: The queue on which the completion handler is called. `.main` by default. - /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the - /// `completionHandler`. `PassthroughPreprocessor()` by default. - /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default. - /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. - /// - completionHandler: A closure to be executed once the request has finished. - /// - /// - Returns: The request. - @discardableResult - public func responseData(queue: DispatchQueue = .main, - dataPreprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor, - emptyResponseCodes: Set = DataResponseSerializer.defaultEmptyResponseCodes, - emptyRequestMethods: Set = DataResponseSerializer.defaultEmptyRequestMethods, - completionHandler: @escaping (AFDataResponse) -> Void) -> Self { - response(queue: queue, - responseSerializer: DataResponseSerializer(dataPreprocessor: dataPreprocessor, - emptyResponseCodes: emptyResponseCodes, - emptyRequestMethods: emptyRequestMethods), - completionHandler: completionHandler) - } -} - -extension DownloadRequest { - /// Adds a handler using a `DataResponseSerializer` to be called once the request has finished. - /// - /// - Parameters: - /// - queue: The queue on which the completion handler is called. `.main` by default. - /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the - /// `completionHandler`. `PassthroughPreprocessor()` by default. - /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default. - /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. - /// - completionHandler: A closure to be executed once the request has finished. - /// - /// - Returns: The request. - @discardableResult - public func responseData(queue: DispatchQueue = .main, - dataPreprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor, - emptyResponseCodes: Set = DataResponseSerializer.defaultEmptyResponseCodes, - emptyRequestMethods: Set = DataResponseSerializer.defaultEmptyRequestMethods, - completionHandler: @escaping (AFDownloadResponse) -> Void) -> Self { - response(queue: queue, - responseSerializer: DataResponseSerializer(dataPreprocessor: dataPreprocessor, - emptyResponseCodes: emptyResponseCodes, - emptyRequestMethods: emptyRequestMethods), - completionHandler: completionHandler) - } -} - -// MARK: - String - -/// A `ResponseSerializer` that decodes the response data as a `String`. By default, a request returning `nil` or no -/// data is considered an error. However, if the request has an `HTTPMethod` or the response has an HTTP status code -/// valid for empty responses, then an empty `String` is returned. -public final class StringResponseSerializer: ResponseSerializer { - public let dataPreprocessor: DataPreprocessor - /// Optional string encoding used to validate the response. - public let encoding: String.Encoding? - public let emptyResponseCodes: Set - public let emptyRequestMethods: Set - - /// Creates an instance with the provided values. - /// - /// - Parameters: - /// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization. - /// - encoding: A string encoding. Defaults to `nil`, in which case the encoding will be determined - /// from the server response, falling back to the default HTTP character set, `ISO-8859-1`. - /// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default. - /// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default. - public init(dataPreprocessor: DataPreprocessor = StringResponseSerializer.defaultDataPreprocessor, - encoding: String.Encoding? = nil, - emptyResponseCodes: Set = StringResponseSerializer.defaultEmptyResponseCodes, - emptyRequestMethods: Set = StringResponseSerializer.defaultEmptyRequestMethods) { - self.dataPreprocessor = dataPreprocessor - self.encoding = encoding - self.emptyResponseCodes = emptyResponseCodes - self.emptyRequestMethods = emptyRequestMethods - } - - public func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> String { - guard error == nil else { throw error! } - - guard var data = data, !data.isEmpty else { - guard emptyResponseAllowed(forRequest: request, response: response) else { - throw AFError.responseSerializationFailed(reason: .inputDataNilOrZeroLength) - } - - return "" - } - - data = try dataPreprocessor.preprocess(data) - - var convertedEncoding = encoding - - if let encodingName = response?.textEncodingName, convertedEncoding == nil { - convertedEncoding = String.Encoding(ianaCharsetName: encodingName) - } - - let actualEncoding = convertedEncoding ?? .isoLatin1 - - guard let string = String(data: data, encoding: actualEncoding) else { - throw AFError.responseSerializationFailed(reason: .stringSerializationFailed(encoding: actualEncoding)) - } - - return string - } -} - -extension DataRequest { - /// Adds a handler using a `StringResponseSerializer` to be called once the request has finished. - /// - /// - Parameters: - /// - queue: The queue on which the completion handler is dispatched. `.main` by default. - /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the - /// `completionHandler`. `PassthroughPreprocessor()` by default. - /// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined - /// from the server response, falling back to the default HTTP character set, `ISO-8859-1`. - /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default. - /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. - /// - completionHandler: A closure to be executed once the request has finished. - /// - /// - Returns: The request. - @discardableResult - public func responseString(queue: DispatchQueue = .main, - dataPreprocessor: DataPreprocessor = StringResponseSerializer.defaultDataPreprocessor, - encoding: String.Encoding? = nil, - emptyResponseCodes: Set = StringResponseSerializer.defaultEmptyResponseCodes, - emptyRequestMethods: Set = StringResponseSerializer.defaultEmptyRequestMethods, - completionHandler: @escaping (AFDataResponse) -> Void) -> Self { - response(queue: queue, - responseSerializer: StringResponseSerializer(dataPreprocessor: dataPreprocessor, - encoding: encoding, - emptyResponseCodes: emptyResponseCodes, - emptyRequestMethods: emptyRequestMethods), - completionHandler: completionHandler) - } -} - -extension DownloadRequest { - /// Adds a handler using a `StringResponseSerializer` to be called once the request has finished. - /// - /// - Parameters: - /// - queue: The queue on which the completion handler is dispatched. `.main` by default. - /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the - /// `completionHandler`. `PassthroughPreprocessor()` by default. - /// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined - /// from the server response, falling back to the default HTTP character set, `ISO-8859-1`. - /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default. - /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. - /// - completionHandler: A closure to be executed once the request has finished. - /// - /// - Returns: The request. - @discardableResult - public func responseString(queue: DispatchQueue = .main, - dataPreprocessor: DataPreprocessor = StringResponseSerializer.defaultDataPreprocessor, - encoding: String.Encoding? = nil, - emptyResponseCodes: Set = StringResponseSerializer.defaultEmptyResponseCodes, - emptyRequestMethods: Set = StringResponseSerializer.defaultEmptyRequestMethods, - completionHandler: @escaping (AFDownloadResponse) -> Void) -> Self { - response(queue: queue, - responseSerializer: StringResponseSerializer(dataPreprocessor: dataPreprocessor, - encoding: encoding, - emptyResponseCodes: emptyResponseCodes, - emptyRequestMethods: emptyRequestMethods), - completionHandler: completionHandler) - } -} - -// MARK: - JSON - -/// A `ResponseSerializer` that decodes the response data using `JSONSerialization`. By default, a request returning -/// `nil` or no data is considered an error. However, if the request has an `HTTPMethod` or the response has an -/// HTTP status code valid for empty responses, then an `NSNull` value is returned. -public final class JSONResponseSerializer: ResponseSerializer { - public let dataPreprocessor: DataPreprocessor - public let emptyResponseCodes: Set - public let emptyRequestMethods: Set - /// `JSONSerialization.ReadingOptions` used when serializing a response. - public let options: JSONSerialization.ReadingOptions - - /// Creates an instance with the provided values. - /// - /// - Parameters: - /// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization. - /// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default. - /// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default. - /// - options: The options to use. `.allowFragments` by default. - public init(dataPreprocessor: DataPreprocessor = JSONResponseSerializer.defaultDataPreprocessor, - emptyResponseCodes: Set = JSONResponseSerializer.defaultEmptyResponseCodes, - emptyRequestMethods: Set = JSONResponseSerializer.defaultEmptyRequestMethods, - options: JSONSerialization.ReadingOptions = .allowFragments) { - self.dataPreprocessor = dataPreprocessor - self.emptyResponseCodes = emptyResponseCodes - self.emptyRequestMethods = emptyRequestMethods - self.options = options - } - - public func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> Any { - guard error == nil else { throw error! } - - guard var data = data, !data.isEmpty else { - guard emptyResponseAllowed(forRequest: request, response: response) else { - throw AFError.responseSerializationFailed(reason: .inputDataNilOrZeroLength) - } - - return NSNull() - } - - data = try dataPreprocessor.preprocess(data) - - do { - return try JSONSerialization.jsonObject(with: data, options: options) - } catch { - throw AFError.responseSerializationFailed(reason: .jsonSerializationFailed(error: error)) - } - } -} - -extension DataRequest { - /// Adds a handler using a `JSONResponseSerializer` to be called once the request has finished. - /// - /// - Parameters: - /// - queue: The queue on which the completion handler is dispatched. `.main` by default. - /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the - /// `completionHandler`. `PassthroughPreprocessor()` by default. - /// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined - /// from the server response, falling back to the default HTTP character set, `ISO-8859-1`. - /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default. - /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. - /// - options: `JSONSerialization.ReadingOptions` used when parsing the response. `.allowFragments` - /// by default. - /// - completionHandler: A closure to be executed once the request has finished. - /// - /// - Returns: The request. - @discardableResult - public func responseJSON(queue: DispatchQueue = .main, - dataPreprocessor: DataPreprocessor = JSONResponseSerializer.defaultDataPreprocessor, - emptyResponseCodes: Set = JSONResponseSerializer.defaultEmptyResponseCodes, - emptyRequestMethods: Set = JSONResponseSerializer.defaultEmptyRequestMethods, - options: JSONSerialization.ReadingOptions = .allowFragments, - completionHandler: @escaping (AFDataResponse) -> Void) -> Self { - response(queue: queue, - responseSerializer: JSONResponseSerializer(dataPreprocessor: dataPreprocessor, - emptyResponseCodes: emptyResponseCodes, - emptyRequestMethods: emptyRequestMethods, - options: options), - completionHandler: completionHandler) - } -} - -extension DownloadRequest { - /// Adds a handler using a `JSONResponseSerializer` to be called once the request has finished. - /// - /// - Parameters: - /// - queue: The queue on which the completion handler is dispatched. `.main` by default. - /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the - /// `completionHandler`. `PassthroughPreprocessor()` by default. - /// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined - /// from the server response, falling back to the default HTTP character set, `ISO-8859-1`. - /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default. - /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. - /// - options: `JSONSerialization.ReadingOptions` used when parsing the response. `.allowFragments` - /// by default. - /// - completionHandler: A closure to be executed once the request has finished. - /// - /// - Returns: The request. - @discardableResult - public func responseJSON(queue: DispatchQueue = .main, - dataPreprocessor: DataPreprocessor = JSONResponseSerializer.defaultDataPreprocessor, - emptyResponseCodes: Set = JSONResponseSerializer.defaultEmptyResponseCodes, - emptyRequestMethods: Set = JSONResponseSerializer.defaultEmptyRequestMethods, - options: JSONSerialization.ReadingOptions = .allowFragments, - completionHandler: @escaping (AFDownloadResponse) -> Void) -> Self { - response(queue: queue, - responseSerializer: JSONResponseSerializer(dataPreprocessor: dataPreprocessor, - emptyResponseCodes: emptyResponseCodes, - emptyRequestMethods: emptyRequestMethods, - options: options), - completionHandler: completionHandler) - } -} - -// MARK: - Empty - -/// Protocol representing an empty response. Use `T.emptyValue()` to get an instance. -public protocol EmptyResponse { - /// Empty value for the conforming type. - /// - /// - Returns: Value of `Self` to use for empty values. - static func emptyValue() -> Self -} - -/// Type representing an empty value. Use `Empty.value` to get the static instance. -public struct Empty: Codable { - /// Static `Empty` instance used for all `Empty` responses. - public static let value = Empty() -} - -extension Empty: EmptyResponse { - public static func emptyValue() -> Empty { - value - } -} - -// MARK: - DataDecoder Protocol - -/// Any type which can decode `Data` into a `Decodable` type. -public protocol DataDecoder { - /// Decode `Data` into the provided type. - /// - /// - Parameters: - /// - type: The `Type` to be decoded. - /// - data: The `Data` to be decoded. - /// - /// - Returns: The decoded value of type `D`. - /// - Throws: Any error that occurs during decode. - func decode(_ type: D.Type, from data: Data) throws -> D -} - -/// `JSONDecoder` automatically conforms to `DataDecoder`. -extension JSONDecoder: DataDecoder {} -/// `PropertyListDecoder` automatically conforms to `DataDecoder`. -extension PropertyListDecoder: DataDecoder {} - -// MARK: - Decodable - -/// A `ResponseSerializer` that decodes the response data as a generic value using any type that conforms to -/// `DataDecoder`. By default, this is an instance of `JSONDecoder`. Additionally, a request returning `nil` or no data -/// is considered an error. However, if the request has an `HTTPMethod` or the response has an HTTP status code valid -/// for empty responses then an empty value will be returned. If the decoded type conforms to `EmptyResponse`, the -/// type's `emptyValue()` will be returned. If the decoded type is `Empty`, the `.value` instance is returned. If the -/// decoded type *does not* conform to `EmptyResponse` and isn't `Empty`, an error will be produced. -public final class DecodableResponseSerializer: ResponseSerializer { - public let dataPreprocessor: DataPreprocessor - /// The `DataDecoder` instance used to decode responses. - public let decoder: DataDecoder - public let emptyResponseCodes: Set - public let emptyRequestMethods: Set - - /// Creates an instance using the values provided. - /// - /// - Parameters: - /// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization. - /// - decoder: The `DataDecoder`. `JSONDecoder()` by default. - /// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default. - /// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default. - public init(dataPreprocessor: DataPreprocessor = DecodableResponseSerializer.defaultDataPreprocessor, - decoder: DataDecoder = JSONDecoder(), - emptyResponseCodes: Set = DecodableResponseSerializer.defaultEmptyResponseCodes, - emptyRequestMethods: Set = DecodableResponseSerializer.defaultEmptyRequestMethods) { - self.dataPreprocessor = dataPreprocessor - self.decoder = decoder - self.emptyResponseCodes = emptyResponseCodes - self.emptyRequestMethods = emptyRequestMethods - } - - public func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> T { - guard error == nil else { throw error! } - - guard var data = data, !data.isEmpty else { - guard emptyResponseAllowed(forRequest: request, response: response) else { - throw AFError.responseSerializationFailed(reason: .inputDataNilOrZeroLength) - } - - guard let emptyResponseType = T.self as? EmptyResponse.Type, let emptyValue = emptyResponseType.emptyValue() as? T else { - throw AFError.responseSerializationFailed(reason: .invalidEmptyResponse(type: "\(T.self)")) - } - - return emptyValue - } - - data = try dataPreprocessor.preprocess(data) - - do { - return try decoder.decode(T.self, from: data) - } catch { - throw AFError.responseSerializationFailed(reason: .decodingFailed(error: error)) - } - } -} - -extension DataRequest { - /// Adds a handler using a `DecodableResponseSerializer` to be called once the request has finished. - /// - /// - Parameters: - /// - type: `Decodable` type to decode from response data. - /// - queue: The queue on which the completion handler is dispatched. `.main` by default. - /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the - /// `completionHandler`. `PassthroughPreprocessor()` by default. - /// - decoder: `DataDecoder` to use to decode the response. `JSONDecoder()` by default. - /// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined - /// from the server response, falling back to the default HTTP character set, `ISO-8859-1`. - /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default. - /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. - /// - options: `JSONSerialization.ReadingOptions` used when parsing the response. `.allowFragments` - /// by default. - /// - completionHandler: A closure to be executed once the request has finished. - /// - /// - Returns: The request. - @discardableResult - public func responseDecodable(of type: T.Type = T.self, - queue: DispatchQueue = .main, - dataPreprocessor: DataPreprocessor = DecodableResponseSerializer.defaultDataPreprocessor, - decoder: DataDecoder = JSONDecoder(), - emptyResponseCodes: Set = DecodableResponseSerializer.defaultEmptyResponseCodes, - emptyRequestMethods: Set = DecodableResponseSerializer.defaultEmptyRequestMethods, - completionHandler: @escaping (AFDataResponse) -> Void) -> Self { - response(queue: queue, - responseSerializer: DecodableResponseSerializer(dataPreprocessor: dataPreprocessor, - decoder: decoder, - emptyResponseCodes: emptyResponseCodes, - emptyRequestMethods: emptyRequestMethods), - completionHandler: completionHandler) - } -} - -extension DownloadRequest { - /// Adds a handler using a `DecodableResponseSerializer` to be called once the request has finished. - /// - /// - Parameters: - /// - type: `Decodable` type to decode from response data. - /// - queue: The queue on which the completion handler is dispatched. `.main` by default. - /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the - /// `completionHandler`. `PassthroughPreprocessor()` by default. - /// - decoder: `DataDecoder` to use to decode the response. `JSONDecoder()` by default. - /// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined - /// from the server response, falling back to the default HTTP character set, `ISO-8859-1`. - /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default. - /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default. - /// - options: `JSONSerialization.ReadingOptions` used when parsing the response. `.allowFragments` - /// by default. - /// - completionHandler: A closure to be executed once the request has finished. - /// - /// - Returns: The request. - @discardableResult - public func responseDecodable(of type: T.Type = T.self, - queue: DispatchQueue = .main, - dataPreprocessor: DataPreprocessor = DecodableResponseSerializer.defaultDataPreprocessor, - decoder: DataDecoder = JSONDecoder(), - emptyResponseCodes: Set = DecodableResponseSerializer.defaultEmptyResponseCodes, - emptyRequestMethods: Set = DecodableResponseSerializer.defaultEmptyRequestMethods, - completionHandler: @escaping (AFDownloadResponse) -> Void) -> Self { - response(queue: queue, - responseSerializer: DecodableResponseSerializer(dataPreprocessor: dataPreprocessor, - decoder: decoder, - emptyResponseCodes: emptyResponseCodes, - emptyRequestMethods: emptyRequestMethods), - completionHandler: completionHandler) - } -} - -// MARK: - DataStreamRequest - -/// A type which can serialize incoming `Data`. -public protocol DataStreamSerializer { - /// Type produced from the serialized `Data`. - associatedtype SerializedObject - - /// Serializes incoming `Data` into a `SerializedObject` value. - /// - /// - Parameter data: `Data` to be serialized. - /// - /// - Throws: Any error produced during serialization. - func serialize(_ data: Data) throws -> SerializedObject -} - -/// `DataStreamSerializer` which uses the provided `DataPreprocessor` and `DataDecoder` to serialize the incoming `Data`. -public struct DecodableStreamSerializer: DataStreamSerializer { - /// `DataDecoder` used to decode incoming `Data`. - public let decoder: DataDecoder - /// `DataPreprocessor` incoming `Data` is passed through before being passed to the `DataDecoder`. - public let dataPreprocessor: DataPreprocessor - - /// Creates an instance with the provided `DataDecoder` and `DataPreprocessor`. - /// - Parameters: - /// - decoder: ` DataDecoder` used to decode incoming `Data`. - /// - dataPreprocessor: `DataPreprocessor` used to process incoming `Data` before it's passed through the `decoder`. - public init(decoder: DataDecoder = JSONDecoder(), dataPreprocessor: DataPreprocessor = PassthroughPreprocessor()) { - self.decoder = decoder - self.dataPreprocessor = dataPreprocessor - } - - public func serialize(_ data: Data) throws -> T { - let processedData = try dataPreprocessor.preprocess(data) - do { - return try decoder.decode(T.self, from: processedData) - } catch { - throw AFError.responseSerializationFailed(reason: .decodingFailed(error: error)) - } - } -} - -/// `DataStreamSerializer` which performs no serialization on incoming `Data`. -public struct PassthroughStreamSerializer: DataStreamSerializer { - public func serialize(_ data: Data) throws -> Data { data } -} - -/// `DataStreamSerializer` which serializes incoming stream `Data` into `UTF8`-decoded `String` values. -public struct StringStreamSerializer: DataStreamSerializer { - public func serialize(_ data: Data) throws -> String { - String(decoding: data, as: UTF8.self) - } -} - -extension DataStreamRequest { - /// Adds a `StreamHandler` which performs no parsing on incoming `Data`. - /// - /// - Parameters: - /// - queue: `DispatchQueue` on which to perform `StreamHandler` closure. - /// - stream: `StreamHandler` closure called as `Data` is received. May be called multiple times. - /// - /// - Returns: The `DataStreamRequest`. - @discardableResult - public func responseStream(on queue: DispatchQueue = .main, stream: @escaping Handler) -> Self { - let parser = { [unowned self] (data: Data) in - queue.async { - self.capturingError { - try stream(.init(event: .stream(.success(data)), token: .init(self))) - } - - self.updateAndCompleteIfPossible() - } - } - - $streamMutableState.write { $0.streams.append(parser) } - appendStreamCompletion(on: queue, stream: stream) - - return self - } - - /// Adds a `StreamHandler` which uses the provided `DataStreamSerializer` to process incoming `Data`. - /// - /// - Parameters: - /// - serializer: `DataStreamSerializer` used to process incoming `Data`. Its work is done on the `serializationQueue`. - /// - queue: `DispatchQueue` on which to perform `StreamHandler` closure. - /// - stream: `StreamHandler` closure called as `Data` is received. May be called multiple times. - /// - /// - Returns: The `DataStreamRequest`. - @discardableResult - public func responseStream(using serializer: Serializer, - on queue: DispatchQueue = .main, - stream: @escaping Handler) -> Self { - let parser = { [unowned self] (data: Data) in - self.serializationQueue.async { - // Start work on serialization queue. - let result = Result { try serializer.serialize(data) } - .mapError { $0.asAFError(or: .responseSerializationFailed(reason: .customSerializationFailed(error: $0))) } - // End work on serialization queue. - self.underlyingQueue.async { - self.eventMonitor?.request(self, didParseStream: result) - - if result.isFailure, self.automaticallyCancelOnStreamError { - self.cancel() - } - - queue.async { - self.capturingError { - try stream(.init(event: .stream(result), token: .init(self))) - } - - self.updateAndCompleteIfPossible() - } - } - } - } - - $streamMutableState.write { $0.streams.append(parser) } - appendStreamCompletion(on: queue, stream: stream) - - return self - } - - /// Adds a `StreamHandler` which parses incoming `Data` as a UTF8 `String`. - /// - /// - Parameters: - /// - queue: `DispatchQueue` on which to perform `StreamHandler` closure. - /// - stream: `StreamHandler` closure called as `Data` is received. May be called multiple times. - /// - /// - Returns: The `DataStreamRequest`. - @discardableResult - public func responseStreamString(on queue: DispatchQueue = .main, - stream: @escaping Handler) -> Self { - let parser = { [unowned self] (data: Data) in - self.serializationQueue.async { - // Start work on serialization queue. - let string = String(decoding: data, as: UTF8.self) - // End work on serialization queue. - self.underlyingQueue.async { - self.eventMonitor?.request(self, didParseStream: .success(string)) - - queue.async { - self.capturingError { - try stream(.init(event: .stream(.success(string)), token: .init(self))) - } - - self.updateAndCompleteIfPossible() - } - } - } - } - - $streamMutableState.write { $0.streams.append(parser) } - appendStreamCompletion(on: queue, stream: stream) - - return self - } - - private func updateAndCompleteIfPossible() { - $streamMutableState.write { state in - state.numberOfExecutingStreams -= 1 - - guard state.numberOfExecutingStreams == 0, !state.enqueuedCompletionEvents.isEmpty else { return } - - let completionEvents = state.enqueuedCompletionEvents - self.underlyingQueue.async { completionEvents.forEach { $0() } } - state.enqueuedCompletionEvents.removeAll() - } - } - - /// Adds a `StreamHandler` which parses incoming `Data` using the provided `DataDecoder`. - /// - /// - Parameters: - /// - type: `Decodable` type to parse incoming `Data` into. - /// - queue: `DispatchQueue` on which to perform `StreamHandler` closure. - /// - decoder: `DataDecoder` used to decode the incoming `Data`. - /// - preprocessor: `DataPreprocessor` used to process the incoming `Data` before it's passed to the `decoder`. - /// - stream: `StreamHandler` closure called as `Data` is received. May be called multiple times. - /// - /// - Returns: The `DataStreamRequest`. - @discardableResult - public func responseStreamDecodable(of type: T.Type = T.self, - on queue: DispatchQueue = .main, - using decoder: DataDecoder = JSONDecoder(), - preprocessor: DataPreprocessor = PassthroughPreprocessor(), - stream: @escaping Handler) -> Self { - responseStream(using: DecodableStreamSerializer(decoder: decoder, dataPreprocessor: preprocessor), - stream: stream) - } -} diff --git a/Pods/Alamofire/Source/Result+Alamofire.swift b/Pods/Alamofire/Source/Result+Alamofire.swift deleted file mode 100644 index 39ac28607..000000000 --- a/Pods/Alamofire/Source/Result+Alamofire.swift +++ /dev/null @@ -1,120 +0,0 @@ -// -// Result+Alamofire.swift -// -// Copyright (c) 2019 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -/// Default type of `Result` returned by Alamofire, with an `AFError` `Failure` type. -public typealias AFResult = Result - -// MARK: - Internal APIs - -extension Result { - /// Returns whether the instance is `.success`. - var isSuccess: Bool { - guard case .success = self else { return false } - return true - } - - /// Returns whether the instance is `.failure`. - var isFailure: Bool { - !isSuccess - } - - /// Returns the associated value if the result is a success, `nil` otherwise. - var success: Success? { - guard case let .success(value) = self else { return nil } - return value - } - - /// Returns the associated error value if the result is a failure, `nil` otherwise. - var failure: Failure? { - guard case let .failure(error) = self else { return nil } - return error - } - - /// Initializes a `Result` from value or error. Returns `.failure` if the error is non-nil, `.success` otherwise. - /// - /// - Parameters: - /// - value: A value. - /// - error: An `Error`. - init(value: Success, error: Failure?) { - if let error = error { - self = .failure(error) - } else { - self = .success(value) - } - } - - /// Evaluates the specified closure when the `Result` is a success, passing the unwrapped value as a parameter. - /// - /// Use the `tryMap` method with a closure that may throw an error. For example: - /// - /// let possibleData: Result = .success(Data(...)) - /// let possibleObject = possibleData.tryMap { - /// try JSONSerialization.jsonObject(with: $0) - /// } - /// - /// - parameter transform: A closure that takes the success value of the instance. - /// - /// - returns: A `Result` containing the result of the given closure. If this instance is a failure, returns the - /// same failure. - func tryMap(_ transform: (Success) throws -> NewSuccess) -> Result { - switch self { - case let .success(value): - do { - return try .success(transform(value)) - } catch { - return .failure(error) - } - case let .failure(error): - return .failure(error) - } - } - - /// Evaluates the specified closure when the `Result` is a failure, passing the unwrapped error as a parameter. - /// - /// Use the `tryMapError` function with a closure that may throw an error. For example: - /// - /// let possibleData: Result = .success(Data(...)) - /// let possibleObject = possibleData.tryMapError { - /// try someFailableFunction(taking: $0) - /// } - /// - /// - Parameter transform: A throwing closure that takes the error of the instance. - /// - /// - Returns: A `Result` instance containing the result of the transform. If this instance is a success, returns - /// the same success. - func tryMapError(_ transform: (Failure) throws -> NewFailure) -> Result { - switch self { - case let .failure(error): - do { - return try .failure(transform(error)) - } catch { - return .failure(error) - } - case let .success(value): - return .success(value) - } - } -} diff --git a/Pods/Alamofire/Source/RetryPolicy.swift b/Pods/Alamofire/Source/RetryPolicy.swift deleted file mode 100644 index e9cbcaf45..000000000 --- a/Pods/Alamofire/Source/RetryPolicy.swift +++ /dev/null @@ -1,370 +0,0 @@ -// -// RetryPolicy.swift -// -// Copyright (c) 2019-2020 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -/// A retry policy that retries requests using an exponential backoff for allowed HTTP methods and HTTP status codes -/// as well as certain types of networking errors. -open class RetryPolicy: RequestInterceptor { - /// The default retry limit for retry policies. - public static let defaultRetryLimit: UInt = 2 - - /// The default exponential backoff base for retry policies (must be a minimum of 2). - public static let defaultExponentialBackoffBase: UInt = 2 - - /// The default exponential backoff scale for retry policies. - public static let defaultExponentialBackoffScale: Double = 0.5 - - /// The default HTTP methods to retry. - /// See [RFC 2616 - Section 9.1.2](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html) for more information. - public static let defaultRetryableHTTPMethods: Set = [.delete, // [Delete](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.7) - not always idempotent - .get, // [GET](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3) - generally idempotent - .head, // [HEAD](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4) - generally idempotent - .options, // [OPTIONS](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.2) - inherently idempotent - .put, // [PUT](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6) - not always idempotent - .trace // [TRACE](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.8) - inherently idempotent - ] - - /// The default HTTP status codes to retry. - /// See [RFC 2616 - Section 10](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10) for more information. - public static let defaultRetryableHTTPStatusCodes: Set = [408, // [Request Timeout](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.9) - 500, // [Internal Server Error](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1) - 502, // [Bad Gateway](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.3) - 503, // [Service Unavailable](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.4) - 504 // [Gateway Timeout](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.5) - ] - - /// The default URL error codes to retry. - public static let defaultRetryableURLErrorCodes: Set = [// [Security] App Transport Security disallowed a connection because there is no secure network connection. - // - [Disabled] ATS settings do not change at runtime. - // .appTransportSecurityRequiresSecureConnection, - - // [System] An app or app extension attempted to connect to a background session that is already connected to a - // process. - // - [Enabled] The other process could release the background session. - .backgroundSessionInUseByAnotherProcess, - - // [System] The shared container identifier of the URL session configuration is needed but has not been set. - // - [Disabled] Cannot change at runtime. - // .backgroundSessionRequiresSharedContainer, - - // [System] The app is suspended or exits while a background data task is processing. - // - [Enabled] App can be foregrounded or launched to recover. - .backgroundSessionWasDisconnected, - - // [Network] The URL Loading system received bad data from the server. - // - [Enabled] Server could return valid data when retrying. - .badServerResponse, - - // [Resource] A malformed URL prevented a URL request from being initiated. - // - [Disabled] URL was most likely constructed incorrectly. - // .badURL, - - // [System] A connection was attempted while a phone call is active on a network that does not support - // simultaneous phone and data communication (EDGE or GPRS). - // - [Enabled] Phone call could be ended to allow request to recover. - .callIsActive, - - // [Client] An asynchronous load has been canceled. - // - [Disabled] Request was cancelled by the client. - // .cancelled, - - // [File System] A download task couldn’t close the downloaded file on disk. - // - [Disabled] File system error is unlikely to recover with retry. - // .cannotCloseFile, - - // [Network] An attempt to connect to a host failed. - // - [Enabled] Server or DNS lookup could recover during retry. - .cannotConnectToHost, - - // [File System] A download task couldn’t create the downloaded file on disk because of an I/O failure. - // - [Disabled] File system error is unlikely to recover with retry. - // .cannotCreateFile, - - // [Data] Content data received during a connection request had an unknown content encoding. - // - [Disabled] Server is unlikely to modify the content encoding during a retry. - // .cannotDecodeContentData, - - // [Data] Content data received during a connection request could not be decoded for a known content encoding. - // - [Disabled] Server is unlikely to modify the content encoding during a retry. - // .cannotDecodeRawData, - - // [Network] The host name for a URL could not be resolved. - // - [Enabled] Server or DNS lookup could recover during retry. - .cannotFindHost, - - // [Network] A request to load an item only from the cache could not be satisfied. - // - [Enabled] Cache could be populated during a retry. - .cannotLoadFromNetwork, - - // [File System] A download task was unable to move a downloaded file on disk. - // - [Disabled] File system error is unlikely to recover with retry. - // .cannotMoveFile, - - // [File System] A download task was unable to open the downloaded file on disk. - // - [Disabled] File system error is unlikely to recover with retry. - // .cannotOpenFile, - - // [Data] A task could not parse a response. - // - [Disabled] Invalid response is unlikely to recover with retry. - // .cannotParseResponse, - - // [File System] A download task was unable to remove a downloaded file from disk. - // - [Disabled] File system error is unlikely to recover with retry. - // .cannotRemoveFile, - - // [File System] A download task was unable to write to the downloaded file on disk. - // - [Disabled] File system error is unlikely to recover with retry. - // .cannotWriteToFile, - - // [Security] A client certificate was rejected. - // - [Disabled] Client certificate is unlikely to change with retry. - // .clientCertificateRejected, - - // [Security] A client certificate was required to authenticate an SSL connection during a request. - // - [Disabled] Client certificate is unlikely to be provided with retry. - // .clientCertificateRequired, - - // [Data] The length of the resource data exceeds the maximum allowed. - // - [Disabled] Resource will likely still exceed the length maximum on retry. - // .dataLengthExceedsMaximum, - - // [System] The cellular network disallowed a connection. - // - [Enabled] WiFi connection could be established during retry. - .dataNotAllowed, - - // [Network] The host address could not be found via DNS lookup. - // - [Enabled] DNS lookup could succeed during retry. - .dnsLookupFailed, - - // [Data] A download task failed to decode an encoded file during the download. - // - [Enabled] Server could correct the decoding issue with retry. - .downloadDecodingFailedMidStream, - - // [Data] A download task failed to decode an encoded file after downloading. - // - [Enabled] Server could correct the decoding issue with retry. - .downloadDecodingFailedToComplete, - - // [File System] A file does not exist. - // - [Disabled] File system error is unlikely to recover with retry. - // .fileDoesNotExist, - - // [File System] A request for an FTP file resulted in the server responding that the file is not a plain file, - // but a directory. - // - [Disabled] FTP directory is not likely to change to a file during a retry. - // .fileIsDirectory, - - // [Network] A redirect loop has been detected or the threshold for number of allowable redirects has been - // exceeded (currently 16). - // - [Disabled] The redirect loop is unlikely to be resolved within the retry window. - // .httpTooManyRedirects, - - // [System] The attempted connection required activating a data context while roaming, but international roaming - // is disabled. - // - [Enabled] WiFi connection could be established during retry. - .internationalRoamingOff, - - // [Connectivity] A client or server connection was severed in the middle of an in-progress load. - // - [Enabled] A network connection could be established during retry. - .networkConnectionLost, - - // [File System] A resource couldn’t be read because of insufficient permissions. - // - [Disabled] Permissions are unlikely to be granted during retry. - // .noPermissionsToReadFile, - - // [Connectivity] A network resource was requested, but an internet connection has not been established and - // cannot be established automatically. - // - [Enabled] A network connection could be established during retry. - .notConnectedToInternet, - - // [Resource] A redirect was specified by way of server response code, but the server did not accompany this - // code with a redirect URL. - // - [Disabled] The redirect URL is unlikely to be supplied during a retry. - // .redirectToNonExistentLocation, - - // [Client] A body stream is needed but the client did not provide one. - // - [Disabled] The client will be unlikely to supply a body stream during retry. - // .requestBodyStreamExhausted, - - // [Resource] A requested resource couldn’t be retrieved. - // - [Disabled] The resource is unlikely to become available during the retry window. - // .resourceUnavailable, - - // [Security] An attempt to establish a secure connection failed for reasons that can’t be expressed more - // specifically. - // - [Enabled] The secure connection could be established during a retry given the lack of specificity - // provided by the error. - .secureConnectionFailed, - - // [Security] A server certificate had a date which indicates it has expired, or is not yet valid. - // - [Enabled] The server certificate could become valid within the retry window. - .serverCertificateHasBadDate, - - // [Security] A server certificate was not signed by any root server. - // - [Disabled] The server certificate is unlikely to change during the retry window. - // .serverCertificateHasUnknownRoot, - - // [Security] A server certificate is not yet valid. - // - [Enabled] The server certificate could become valid within the retry window. - .serverCertificateNotYetValid, - - // [Security] A server certificate was signed by a root server that isn’t trusted. - // - [Disabled] The server certificate is unlikely to become trusted within the retry window. - // .serverCertificateUntrusted, - - // [Network] An asynchronous operation timed out. - // - [Enabled] The request timed out for an unknown reason and should be retried. - .timedOut - - // [System] The URL Loading System encountered an error that it can’t interpret. - // - [Disabled] The error could not be interpreted and is unlikely to be recovered from during a retry. - // .unknown, - - // [Resource] A properly formed URL couldn’t be handled by the framework. - // - [Disabled] The URL is unlikely to change during a retry. - // .unsupportedURL, - - // [Client] Authentication is required to access a resource. - // - [Disabled] The user authentication is unlikely to be provided by retrying. - // .userAuthenticationRequired, - - // [Client] An asynchronous request for authentication has been canceled by the user. - // - [Disabled] The user cancelled authentication and explicitly took action to not retry. - // .userCancelledAuthentication, - - // [Resource] A server reported that a URL has a non-zero content length, but terminated the network connection - // gracefully without sending any data. - // - [Disabled] The server is unlikely to provide data during the retry window. - // .zeroByteResource, - ] - - /// The total number of times the request is allowed to be retried. - public let retryLimit: UInt - - /// The base of the exponential backoff policy (should always be greater than or equal to 2). - public let exponentialBackoffBase: UInt - - /// The scale of the exponential backoff. - public let exponentialBackoffScale: Double - - /// The HTTP methods that are allowed to be retried. - public let retryableHTTPMethods: Set - - /// The HTTP status codes that are automatically retried by the policy. - public let retryableHTTPStatusCodes: Set - - /// The URL error codes that are automatically retried by the policy. - public let retryableURLErrorCodes: Set - - /// Creates an `ExponentialBackoffRetryPolicy` from the specified parameters. - /// - /// - Parameters: - /// - retryLimit: The total number of times the request is allowed to be retried. `2` by default. - /// - exponentialBackoffBase: The base of the exponential backoff policy. `2` by default. - /// - exponentialBackoffScale: The scale of the exponential backoff. `0.5` by default. - /// - retryableHTTPMethods: The HTTP methods that are allowed to be retried. - /// `RetryPolicy.defaultRetryableHTTPMethods` by default. - /// - retryableHTTPStatusCodes: The HTTP status codes that are automatically retried by the policy. - /// `RetryPolicy.defaultRetryableHTTPStatusCodes` by default. - /// - retryableURLErrorCodes: The URL error codes that are automatically retried by the policy. - /// `RetryPolicy.defaultRetryableURLErrorCodes` by default. - public init(retryLimit: UInt = RetryPolicy.defaultRetryLimit, - exponentialBackoffBase: UInt = RetryPolicy.defaultExponentialBackoffBase, - exponentialBackoffScale: Double = RetryPolicy.defaultExponentialBackoffScale, - retryableHTTPMethods: Set = RetryPolicy.defaultRetryableHTTPMethods, - retryableHTTPStatusCodes: Set = RetryPolicy.defaultRetryableHTTPStatusCodes, - retryableURLErrorCodes: Set = RetryPolicy.defaultRetryableURLErrorCodes) { - precondition(exponentialBackoffBase >= 2, "The `exponentialBackoffBase` must be a minimum of 2.") - - self.retryLimit = retryLimit - self.exponentialBackoffBase = exponentialBackoffBase - self.exponentialBackoffScale = exponentialBackoffScale - self.retryableHTTPMethods = retryableHTTPMethods - self.retryableHTTPStatusCodes = retryableHTTPStatusCodes - self.retryableURLErrorCodes = retryableURLErrorCodes - } - - open func retry(_ request: Request, - for session: Session, - dueTo error: Error, - completion: @escaping (RetryResult) -> Void) { - if request.retryCount < retryLimit, shouldRetry(request: request, dueTo: error) { - completion(.retryWithDelay(pow(Double(exponentialBackoffBase), Double(request.retryCount)) * exponentialBackoffScale)) - } else { - completion(.doNotRetry) - } - } - - /// Determines whether or not to retry the provided `Request`. - /// - /// - Parameters: - /// - request: `Request` that failed due to the provided `Error`. - /// - error: `Error` encountered while executing the `Request`. - /// - /// - Returns: `Bool` determining whether or not to retry the `Request`. - open func shouldRetry(request: Request, dueTo error: Error) -> Bool { - guard let httpMethod = request.request?.method, retryableHTTPMethods.contains(httpMethod) else { return false } - - if let statusCode = request.response?.statusCode, retryableHTTPStatusCodes.contains(statusCode) { - return true - } else { - let errorCode = (error as? URLError)?.code - let afErrorCode = (error.asAFError?.underlyingError as? URLError)?.code - - guard let code = errorCode ?? afErrorCode else { return false } - - return retryableURLErrorCodes.contains(code) - } - } -} - -// MARK: - - -/// A retry policy that automatically retries idempotent requests for network connection lost errors. For more -/// information about retrying network connection lost errors, please refer to Apple's -/// [technical document](https://developer.apple.com/library/content/qa/qa1941/_index.html). -open class ConnectionLostRetryPolicy: RetryPolicy { - /// Creates a `ConnectionLostRetryPolicy` instance from the specified parameters. - /// - /// - Parameters: - /// - retryLimit: The total number of times the request is allowed to be retried. - /// `RetryPolicy.defaultRetryLimit` by default. - /// - exponentialBackoffBase: The base of the exponential backoff policy. - /// `RetryPolicy.defaultExponentialBackoffBase` by default. - /// - exponentialBackoffScale: The scale of the exponential backoff. - /// `RetryPolicy.defaultExponentialBackoffScale` by default. - /// - retryableHTTPMethods: The idempotent http methods to retry. - /// `RetryPolicy.defaultRetryableHTTPMethods` by default. - public init(retryLimit: UInt = RetryPolicy.defaultRetryLimit, - exponentialBackoffBase: UInt = RetryPolicy.defaultExponentialBackoffBase, - exponentialBackoffScale: Double = RetryPolicy.defaultExponentialBackoffScale, - retryableHTTPMethods: Set = RetryPolicy.defaultRetryableHTTPMethods) { - super.init(retryLimit: retryLimit, - exponentialBackoffBase: exponentialBackoffBase, - exponentialBackoffScale: exponentialBackoffScale, - retryableHTTPMethods: retryableHTTPMethods, - retryableHTTPStatusCodes: [], - retryableURLErrorCodes: [.networkConnectionLost]) - } -} diff --git a/Pods/Alamofire/Source/ServerTrustEvaluation.swift b/Pods/Alamofire/Source/ServerTrustEvaluation.swift deleted file mode 100644 index 9ca94f161..000000000 --- a/Pods/Alamofire/Source/ServerTrustEvaluation.swift +++ /dev/null @@ -1,619 +0,0 @@ -// -// ServerTrustPolicy.swift -// -// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -/// Responsible for managing the mapping of `ServerTrustEvaluating` values to given hosts. -open class ServerTrustManager { - /// Determines whether all hosts for this `ServerTrustManager` must be evaluated. `true` by default. - public let allHostsMustBeEvaluated: Bool - - /// The dictionary of policies mapped to a particular host. - public let evaluators: [String: ServerTrustEvaluating] - - /// Initializes the `ServerTrustManager` instance with the given evaluators. - /// - /// Since different servers and web services can have different leaf certificates, intermediate and even root - /// certificates, it is important to have the flexibility to specify evaluation policies on a per host basis. This - /// allows for scenarios such as using default evaluation for host1, certificate pinning for host2, public key - /// pinning for host3 and disabling evaluation for host4. - /// - /// - Parameters: - /// - allHostsMustBeEvaluated: The value determining whether all hosts for this instance must be evaluated. `true` - /// by default. - /// - evaluators: A dictionary of evaluators mapped to hosts. - public init(allHostsMustBeEvaluated: Bool = true, evaluators: [String: ServerTrustEvaluating]) { - self.allHostsMustBeEvaluated = allHostsMustBeEvaluated - self.evaluators = evaluators - } - - /// Returns the `ServerTrustEvaluating` value for the given host, if one is set. - /// - /// By default, this method will return the policy that perfectly matches the given host. Subclasses could override - /// this method and implement more complex mapping implementations such as wildcards. - /// - /// - Parameter host: The host to use when searching for a matching policy. - /// - /// - Returns: The `ServerTrustEvaluating` value for the given host if found, `nil` otherwise. - /// - Throws: `AFError.serverTrustEvaluationFailed` if `allHostsMustBeEvaluated` is `true` and no matching - /// evaluators are found. - open func serverTrustEvaluator(forHost host: String) throws -> ServerTrustEvaluating? { - guard let evaluator = evaluators[host] else { - if allHostsMustBeEvaluated { - throw AFError.serverTrustEvaluationFailed(reason: .noRequiredEvaluator(host: host)) - } - - return nil - } - - return evaluator - } -} - -/// A protocol describing the API used to evaluate server trusts. -public protocol ServerTrustEvaluating { - #if os(Linux) - // Implement this once Linux has API for evaluating server trusts. - #else - /// Evaluates the given `SecTrust` value for the given `host`. - /// - /// - Parameters: - /// - trust: The `SecTrust` value to evaluate. - /// - host: The host for which to evaluate the `SecTrust` value. - /// - /// - Returns: A `Bool` indicating whether the evaluator considers the `SecTrust` value valid for `host`. - func evaluate(_ trust: SecTrust, forHost host: String) throws - #endif -} - -// MARK: - Server Trust Evaluators - -/// An evaluator which uses the default server trust evaluation while allowing you to control whether to validate the -/// host provided by the challenge. Applications are encouraged to always validate the host in production environments -/// to guarantee the validity of the server's certificate chain. -public final class DefaultTrustEvaluator: ServerTrustEvaluating { - private let validateHost: Bool - - /// Creates a `DefaultTrustEvaluator`. - /// - /// - Parameter validateHost: Determines whether or not the evaluator should validate the host. `true` by default. - public init(validateHost: Bool = true) { - self.validateHost = validateHost - } - - public func evaluate(_ trust: SecTrust, forHost host: String) throws { - if validateHost { - try trust.af.performValidation(forHost: host) - } - - try trust.af.performDefaultValidation(forHost: host) - } -} - -/// An evaluator which Uses the default and revoked server trust evaluations allowing you to control whether to validate -/// the host provided by the challenge as well as specify the revocation flags for testing for revoked certificates. -/// Apple platforms did not start testing for revoked certificates automatically until iOS 10.1, macOS 10.12 and tvOS -/// 10.1 which is demonstrated in our TLS tests. Applications are encouraged to always validate the host in production -/// environments to guarantee the validity of the server's certificate chain. -public final class RevocationTrustEvaluator: ServerTrustEvaluating { - /// Represents the options to be use when evaluating the status of a certificate. - /// Only Revocation Policy Constants are valid, and can be found in [Apple's documentation](https://developer.apple.com/documentation/security/certificate_key_and_trust_services/policies/1563600-revocation_policy_constants). - public struct Options: OptionSet { - /// Perform revocation checking using the CRL (Certification Revocation List) method. - public static let crl = Options(rawValue: kSecRevocationCRLMethod) - /// Consult only locally cached replies; do not use network access. - public static let networkAccessDisabled = Options(rawValue: kSecRevocationNetworkAccessDisabled) - /// Perform revocation checking using OCSP (Online Certificate Status Protocol). - public static let ocsp = Options(rawValue: kSecRevocationOCSPMethod) - /// Prefer CRL revocation checking over OCSP; by default, OCSP is preferred. - public static let preferCRL = Options(rawValue: kSecRevocationPreferCRL) - /// Require a positive response to pass the policy. If the flag is not set, revocation checking is done on a - /// "best attempt" basis, where failure to reach the server is not considered fatal. - public static let requirePositiveResponse = Options(rawValue: kSecRevocationRequirePositiveResponse) - /// Perform either OCSP or CRL checking. The checking is performed according to the method(s) specified in the - /// certificate and the value of `preferCRL`. - public static let any = Options(rawValue: kSecRevocationUseAnyAvailableMethod) - - /// The raw value of the option. - public let rawValue: CFOptionFlags - - /// Creates an `Options` value with the given `CFOptionFlags`. - /// - /// - Parameter rawValue: The `CFOptionFlags` value to initialize with. - public init(rawValue: CFOptionFlags) { - self.rawValue = rawValue - } - } - - private let performDefaultValidation: Bool - private let validateHost: Bool - private let options: Options - - /// Creates a `RevocationTrustEvaluator`. - /// - /// - Note: Default and host validation will fail when using this evaluator with self-signed certificates. Use - /// `PinnedCertificatesTrustEvaluator` if you need to use self-signed certificates. - /// - /// - Parameters: - /// - performDefaultValidation: Determines whether default validation should be performed in addition to - /// evaluating the pinned certificates. `true` by default. - /// - validateHost: Determines whether or not the evaluator should validate the host, in addition - /// to performing the default evaluation, even if `performDefaultValidation` is - /// `false`. `true` by default. - /// - options: The `Options` to use to check the revocation status of the certificate. `.any` - /// by default. - public init(performDefaultValidation: Bool = true, validateHost: Bool = true, options: Options = .any) { - self.performDefaultValidation = performDefaultValidation - self.validateHost = validateHost - self.options = options - } - - public func evaluate(_ trust: SecTrust, forHost host: String) throws { - if performDefaultValidation { - try trust.af.performDefaultValidation(forHost: host) - } - - if validateHost { - try trust.af.performValidation(forHost: host) - } - - if #available(iOS 12, macOS 10.14, tvOS 12, watchOS 5, *) { - try trust.af.evaluate(afterApplying: SecPolicy.af.revocation(options: options)) - } else { - try trust.af.validate(policy: SecPolicy.af.revocation(options: options)) { status, result in - AFError.serverTrustEvaluationFailed(reason: .revocationCheckFailed(output: .init(host, trust, status, result), options: options)) - } - } - } -} - -/// Uses the pinned certificates to validate the server trust. The server trust is considered valid if one of the pinned -/// certificates match one of the server certificates. By validating both the certificate chain and host, certificate -/// pinning provides a very secure form of server trust validation mitigating most, if not all, MITM attacks. -/// Applications are encouraged to always validate the host and require a valid certificate chain in production -/// environments. -public final class PinnedCertificatesTrustEvaluator: ServerTrustEvaluating { - private let certificates: [SecCertificate] - private let acceptSelfSignedCertificates: Bool - private let performDefaultValidation: Bool - private let validateHost: Bool - - /// Creates a `PinnedCertificatesTrustEvaluator`. - /// - /// - Parameters: - /// - certificates: The certificates to use to evaluate the trust. All `cer`, `crt`, and `der` - /// certificates in `Bundle.main` by default. - /// - acceptSelfSignedCertificates: Adds the provided certificates as anchors for the trust evaluation, allowing - /// self-signed certificates to pass. `false` by default. THIS SETTING SHOULD BE - /// FALSE IN PRODUCTION! - /// - performDefaultValidation: Determines whether default validation should be performed in addition to - /// evaluating the pinned certificates. `true` by default. - /// - validateHost: Determines whether or not the evaluator should validate the host, in addition - /// to performing the default evaluation, even if `performDefaultValidation` is - /// `false`. `true` by default. - public init(certificates: [SecCertificate] = Bundle.main.af.certificates, - acceptSelfSignedCertificates: Bool = false, - performDefaultValidation: Bool = true, - validateHost: Bool = true) { - self.certificates = certificates - self.acceptSelfSignedCertificates = acceptSelfSignedCertificates - self.performDefaultValidation = performDefaultValidation - self.validateHost = validateHost - } - - public func evaluate(_ trust: SecTrust, forHost host: String) throws { - guard !certificates.isEmpty else { - throw AFError.serverTrustEvaluationFailed(reason: .noCertificatesFound) - } - - if acceptSelfSignedCertificates { - try trust.af.setAnchorCertificates(certificates) - } - - if performDefaultValidation { - try trust.af.performDefaultValidation(forHost: host) - } - - if validateHost { - try trust.af.performValidation(forHost: host) - } - - let serverCertificatesData = Set(trust.af.certificateData) - let pinnedCertificatesData = Set(certificates.af.data) - let pinnedCertificatesInServerData = !serverCertificatesData.isDisjoint(with: pinnedCertificatesData) - if !pinnedCertificatesInServerData { - throw AFError.serverTrustEvaluationFailed(reason: .certificatePinningFailed(host: host, - trust: trust, - pinnedCertificates: certificates, - serverCertificates: trust.af.certificates)) - } - } -} - -/// Uses the pinned public keys to validate the server trust. The server trust is considered valid if one of the pinned -/// public keys match one of the server certificate public keys. By validating both the certificate chain and host, -/// public key pinning provides a very secure form of server trust validation mitigating most, if not all, MITM attacks. -/// Applications are encouraged to always validate the host and require a valid certificate chain in production -/// environments. -public final class PublicKeysTrustEvaluator: ServerTrustEvaluating { - private let keys: [SecKey] - private let performDefaultValidation: Bool - private let validateHost: Bool - - /// Creates a `PublicKeysTrustEvaluator`. - /// - /// - Note: Default and host validation will fail when using this evaluator with self-signed certificates. Use - /// `PinnedCertificatesTrustEvaluator` if you need to use self-signed certificates. - /// - /// - Parameters: - /// - keys: The `SecKey`s to use to validate public keys. Defaults to the public keys of all - /// certificates included in the main bundle. - /// - performDefaultValidation: Determines whether default validation should be performed in addition to - /// evaluating the pinned certificates. `true` by default. - /// - validateHost: Determines whether or not the evaluator should validate the host, in addition to - /// performing the default evaluation, even if `performDefaultValidation` is `false`. - /// `true` by default. - public init(keys: [SecKey] = Bundle.main.af.publicKeys, - performDefaultValidation: Bool = true, - validateHost: Bool = true) { - self.keys = keys - self.performDefaultValidation = performDefaultValidation - self.validateHost = validateHost - } - - public func evaluate(_ trust: SecTrust, forHost host: String) throws { - guard !keys.isEmpty else { - throw AFError.serverTrustEvaluationFailed(reason: .noPublicKeysFound) - } - - if performDefaultValidation { - try trust.af.performDefaultValidation(forHost: host) - } - - if validateHost { - try trust.af.performValidation(forHost: host) - } - - let pinnedKeysInServerKeys: Bool = { - for serverPublicKey in trust.af.publicKeys { - for pinnedPublicKey in keys { - if serverPublicKey == pinnedPublicKey { - return true - } - } - } - return false - }() - - if !pinnedKeysInServerKeys { - throw AFError.serverTrustEvaluationFailed(reason: .publicKeyPinningFailed(host: host, - trust: trust, - pinnedKeys: keys, - serverKeys: trust.af.publicKeys)) - } - } -} - -/// Uses the provided evaluators to validate the server trust. The trust is only considered valid if all of the -/// evaluators consider it valid. -public final class CompositeTrustEvaluator: ServerTrustEvaluating { - private let evaluators: [ServerTrustEvaluating] - - /// Creates a `CompositeTrustEvaluator`. - /// - /// - Parameter evaluators: The `ServerTrustEvaluating` values used to evaluate the server trust. - public init(evaluators: [ServerTrustEvaluating]) { - self.evaluators = evaluators - } - - public func evaluate(_ trust: SecTrust, forHost host: String) throws { - try evaluators.evaluate(trust, forHost: host) - } -} - -/// Disables all evaluation which in turn will always consider any server trust as valid. -/// -/// - Note: Instead of disabling server trust evaluation, it's a better idea to configure systems to properly trust test -/// certificates, as outlined in [this Apple tech note](https://developer.apple.com/library/archive/qa/qa1948/_index.html). -/// -/// **THIS EVALUATOR SHOULD NEVER BE USED IN PRODUCTION!** -@available(*, deprecated, renamed: "DisabledTrustEvaluator", message: "DisabledEvaluator has been renamed DisabledTrustEvaluator.") -public typealias DisabledEvaluator = DisabledTrustEvaluator - -/// Disables all evaluation which in turn will always consider any server trust as valid. -/// -/// -/// - Note: Instead of disabling server trust evaluation, it's a better idea to configure systems to properly trust test -/// certificates, as outlined in [this Apple tech note](https://developer.apple.com/library/archive/qa/qa1948/_index.html). -/// -/// **THIS EVALUATOR SHOULD NEVER BE USED IN PRODUCTION!** -public final class DisabledTrustEvaluator: ServerTrustEvaluating { - /// Creates an instance. - public init() {} - - public func evaluate(_ trust: SecTrust, forHost host: String) throws {} -} - -// MARK: - Extensions - -extension Array where Element == ServerTrustEvaluating { - #if os(Linux) - // Add this same convenience method for Linux. - #else - /// Evaluates the given `SecTrust` value for the given `host`. - /// - /// - Parameters: - /// - trust: The `SecTrust` value to evaluate. - /// - host: The host for which to evaluate the `SecTrust` value. - /// - /// - Returns: Whether or not the evaluator considers the `SecTrust` value valid for `host`. - public func evaluate(_ trust: SecTrust, forHost host: String) throws { - for evaluator in self { - try evaluator.evaluate(trust, forHost: host) - } - } - #endif -} - -extension Bundle: AlamofireExtended {} -extension AlamofireExtension where ExtendedType: Bundle { - /// Returns all valid `cer`, `crt`, and `der` certificates in the bundle. - public var certificates: [SecCertificate] { - paths(forResourcesOfTypes: [".cer", ".CER", ".crt", ".CRT", ".der", ".DER"]).compactMap { path in - guard - let certificateData = try? Data(contentsOf: URL(fileURLWithPath: path)) as CFData, - let certificate = SecCertificateCreateWithData(nil, certificateData) else { return nil } - - return certificate - } - } - - /// Returns all public keys for the valid certificates in the bundle. - public var publicKeys: [SecKey] { - certificates.af.publicKeys - } - - /// Returns all pathnames for the resources identified by the provided file extensions. - /// - /// - Parameter types: The filename extensions locate. - /// - /// - Returns: All pathnames for the given filename extensions. - public func paths(forResourcesOfTypes types: [String]) -> [String] { - Array(Set(types.flatMap { type.paths(forResourcesOfType: $0, inDirectory: nil) })) - } -} - -extension SecTrust: AlamofireExtended {} -extension AlamofireExtension where ExtendedType == SecTrust { - /// Evaluates `self` after applying the `SecPolicy` value provided. - /// - /// - Parameter policy: The `SecPolicy` to apply to `self` before evaluation. - /// - /// - Throws: Any `Error` from applying the `SecPolicy` or from evaluation. - @available(iOS 12, macOS 10.14, tvOS 12, watchOS 5, *) - public func evaluate(afterApplying policy: SecPolicy) throws { - try apply(policy: policy).af.evaluate() - } - - /// Attempts to validate `self` using the `SecPolicy` provided and transforming any error produced using the closure passed. - /// - /// - Parameters: - /// - policy: The `SecPolicy` used to evaluate `self`. - /// - errorProducer: The closure used transform the failed `OSStatus` and `SecTrustResultType`. - /// - Throws: Any `Error` from applying the `policy`, or the result of `errorProducer` if validation fails. - @available(iOS, introduced: 10, deprecated: 12, renamed: "evaluate(afterApplying:)") - @available(macOS, introduced: 10.12, deprecated: 10.14, renamed: "evaluate(afterApplying:)") - @available(tvOS, introduced: 10, deprecated: 12, renamed: "evaluate(afterApplying:)") - @available(watchOS, introduced: 3, deprecated: 5, renamed: "evaluate(afterApplying:)") - public func validate(policy: SecPolicy, errorProducer: (_ status: OSStatus, _ result: SecTrustResultType) -> Error) throws { - try apply(policy: policy).af.validate(errorProducer: errorProducer) - } - - /// Applies a `SecPolicy` to `self`, throwing if it fails. - /// - /// - Parameter policy: The `SecPolicy`. - /// - /// - Returns: `self`, with the policy applied. - /// - Throws: An `AFError.serverTrustEvaluationFailed` instance with a `.policyApplicationFailed` reason. - public func apply(policy: SecPolicy) throws -> SecTrust { - let status = SecTrustSetPolicies(type, policy) - - guard status.af.isSuccess else { - throw AFError.serverTrustEvaluationFailed(reason: .policyApplicationFailed(trust: type, - policy: policy, - status: status)) - } - - return type - } - - /// Evaluate `self`, throwing an `Error` if evaluation fails. - /// - /// - Throws: `AFError.serverTrustEvaluationFailed` with reason `.trustValidationFailed` and associated error from - /// the underlying evaluation. - @available(iOS 12, macOS 10.14, tvOS 12, watchOS 5, *) - public func evaluate() throws { - var error: CFError? - let evaluationSucceeded = SecTrustEvaluateWithError(type, &error) - - if !evaluationSucceeded { - throw AFError.serverTrustEvaluationFailed(reason: .trustEvaluationFailed(error: error)) - } - } - - /// Validate `self`, passing any failure values through `errorProducer`. - /// - /// - Parameter errorProducer: The closure used to transform the failed `OSStatus` and `SecTrustResultType` into an - /// `Error`. - /// - Throws: The `Error` produced by the `errorProducer` closure. - @available(iOS, introduced: 10, deprecated: 12, renamed: "evaluate()") - @available(macOS, introduced: 10.12, deprecated: 10.14, renamed: "evaluate()") - @available(tvOS, introduced: 10, deprecated: 12, renamed: "evaluate()") - @available(watchOS, introduced: 3, deprecated: 5, renamed: "evaluate()") - public func validate(errorProducer: (_ status: OSStatus, _ result: SecTrustResultType) -> Error) throws { - var result = SecTrustResultType.invalid - let status = SecTrustEvaluate(type, &result) - - guard status.af.isSuccess && result.af.isSuccess else { - throw errorProducer(status, result) - } - } - - /// Sets a custom certificate chain on `self`, allowing full validation of a self-signed certificate and its chain. - /// - /// - Parameter certificates: The `SecCertificate`s to add to the chain. - /// - Throws: Any error produced when applying the new certificate chain. - public func setAnchorCertificates(_ certificates: [SecCertificate]) throws { - // Add additional anchor certificates. - let status = SecTrustSetAnchorCertificates(type, certificates as CFArray) - guard status.af.isSuccess else { - throw AFError.serverTrustEvaluationFailed(reason: .settingAnchorCertificatesFailed(status: status, - certificates: certificates)) - } - - // Trust only the set anchor certs. - let onlyStatus = SecTrustSetAnchorCertificatesOnly(type, true) - guard onlyStatus.af.isSuccess else { - throw AFError.serverTrustEvaluationFailed(reason: .settingAnchorCertificatesFailed(status: onlyStatus, - certificates: certificates)) - } - } - - /// The public keys contained in `self`. - public var publicKeys: [SecKey] { - certificates.af.publicKeys - } - - /// The `SecCertificate`s contained i `self`. - public var certificates: [SecCertificate] { - (0.. SecPolicy { - SecPolicyCreateSSL(true, hostname as CFString) - } - - /// Creates a `SecPolicy` which checks the revocation of certificates. - /// - /// - Parameter options: The `RevocationTrustEvaluator.Options` for evaluation. - /// - /// - Returns: The `SecPolicy`. - /// - Throws: An `AFError.serverTrustEvaluationFailed` error with reason `.revocationPolicyCreationFailed` - /// if the policy cannot be created. - public static func revocation(options: RevocationTrustEvaluator.Options) throws -> SecPolicy { - guard let policy = SecPolicyCreateRevocation(options.rawValue) else { - throw AFError.serverTrustEvaluationFailed(reason: .revocationPolicyCreationFailed) - } - - return policy - } -} - -extension Array: AlamofireExtended {} -extension AlamofireExtension where ExtendedType == [SecCertificate] { - /// All `Data` values for the contained `SecCertificate`s. - public var data: [Data] { - type.map { SecCertificateCopyData($0) as Data } - } - - /// All public `SecKey` values for the contained `SecCertificate`s. - public var publicKeys: [SecKey] { - type.compactMap { $0.af.publicKey } - } -} - -extension SecCertificate: AlamofireExtended {} -extension AlamofireExtension where ExtendedType == SecCertificate { - /// The public key for `self`, if it can be extracted. - public var publicKey: SecKey? { - let policy = SecPolicyCreateBasicX509() - var trust: SecTrust? - let trustCreationStatus = SecTrustCreateWithCertificates(type, policy, &trust) - - guard let createdTrust = trust, trustCreationStatus == errSecSuccess else { return nil } - - return SecTrustCopyPublicKey(createdTrust) - } -} - -extension OSStatus: AlamofireExtended {} -extension AlamofireExtension where ExtendedType == OSStatus { - /// Returns whether `self` is `errSecSuccess`. - public var isSuccess: Bool { type == errSecSuccess } -} - -extension SecTrustResultType: AlamofireExtended {} -extension AlamofireExtension where ExtendedType == SecTrustResultType { - /// Returns whether `self is `.unspecified` or `.proceed`. - public var isSuccess: Bool { - type == .unspecified || type == .proceed - } -} diff --git a/Pods/Alamofire/Source/Session.swift b/Pods/Alamofire/Source/Session.swift deleted file mode 100644 index ac0ab2295..000000000 --- a/Pods/Alamofire/Source/Session.swift +++ /dev/null @@ -1,1258 +0,0 @@ -// -// Session.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -/// `Session` creates and manages Alamofire's `Request` types during their lifetimes. It also provides common -/// functionality for all `Request`s, including queuing, interception, trust management, redirect handling, and response -/// cache handling. -open class Session { - /// Shared singleton instance used by all `AF.request` APIs. Cannot be modified. - public static let `default` = Session() - - /// Underlying `URLSession` used to create `URLSessionTasks` for this instance, and for which this instance's - /// `delegate` handles `URLSessionDelegate` callbacks. - /// - /// - Note: This instance should **NOT** be used to interact with the underlying `URLSessionTask`s. Doing so will - /// break internal Alamofire logic that tracks those tasks. - /// - public let session: URLSession - /// Instance's `SessionDelegate`, which handles the `URLSessionDelegate` methods and `Request` interaction. - public let delegate: SessionDelegate - /// Root `DispatchQueue` for all internal callbacks and state update. **MUST** be a serial queue. - public let rootQueue: DispatchQueue - /// Value determining whether this instance automatically calls `resume()` on all created `Request`s. - public let startRequestsImmediately: Bool - /// `DispatchQueue` on which `URLRequest`s are created asynchronously. By default this queue uses `rootQueue` as its - /// `target`, but a separate queue can be used if request creation is determined to be a bottleneck. Always profile - /// and test before introducing an additional queue. - public let requestQueue: DispatchQueue - /// `DispatchQueue` passed to all `Request`s on which they perform their response serialization. By default this - /// queue uses `rootQueue` as its `target` but a separate queue can be used if response serialization is determined - /// to be a bottleneck. Always profile and test before introducing an additional queue. - public let serializationQueue: DispatchQueue - /// `RequestInterceptor` used for all `Request` created by the instance. `RequestInterceptor`s can also be set on a - /// per-`Request` basis, in which case the `Request`'s interceptor takes precedence over this value. - public let interceptor: RequestInterceptor? - /// `ServerTrustManager` instance used to evaluate all trust challenges and provide certificate and key pinning. - public let serverTrustManager: ServerTrustManager? - /// `RedirectHandler` instance used to provide customization for request redirection. - public let redirectHandler: RedirectHandler? - /// `CachedResponseHandler` instance used to provide customization of cached response handling. - public let cachedResponseHandler: CachedResponseHandler? - /// `CompositeEventMonitor` used to compose Alamofire's `defaultEventMonitors` and any passed `EventMonitor`s. - public let eventMonitor: CompositeEventMonitor - /// `EventMonitor`s included in all instances. `[AlamofireNotifications()]` by default. - public let defaultEventMonitors: [EventMonitor] = [AlamofireNotifications()] - - /// Internal map between `Request`s and any `URLSessionTasks` that may be in flight for them. - var requestTaskMap = RequestTaskMap() - /// `Set` of currently active `Request`s. - var activeRequests: Set = [] - /// Completion events awaiting `URLSessionTaskMetrics`. - var waitingCompletions: [URLSessionTask: () -> Void] = [:] - - /// Creates a `Session` from a `URLSession` and other parameters. - /// - /// - Note: When passing a `URLSession`, you must create the `URLSession` with a specific `delegateQueue` value and - /// pass the `delegateQueue`'s `underlyingQueue` as the `rootQueue` parameter of this initializer. - /// - /// - Parameters: - /// - session: Underlying `URLSession` for this instance. - /// - delegate: `SessionDelegate` that handles `session`'s delegate callbacks as well as `Request` - /// interaction. - /// - rootQueue: Root `DispatchQueue` for all internal callbacks and state updates. **MUST** be a - /// serial queue. - /// - startRequestsImmediately: Determines whether this instance will automatically start all `Request`s. `true` - /// by default. If set to `false`, all `Request`s created must have `.resume()` called. - /// on them for them to start. - /// - requestQueue: `DispatchQueue` on which to perform `URLRequest` creation. By default this queue - /// will use the `rootQueue` as its `target`. A separate queue can be used if it's - /// determined request creation is a bottleneck, but that should only be done after - /// careful testing and profiling. `nil` by default. - /// - serializationQueue: `DispatchQueue` on which to perform all response serialization. By default this - /// queue will use the `rootQueue` as its `target`. A separate queue can be used if - /// it's determined response serialization is a bottleneck, but that should only be - /// done after careful testing and profiling. `nil` by default. - /// - interceptor: `RequestInterceptor` to be used for all `Request`s created by this instance. `nil` - /// by default. - /// - serverTrustManager: `ServerTrustManager` to be used for all trust evaluations by this instance. `nil` - /// by default. - /// - redirectHandler: `RedirectHandler` to be used by all `Request`s created by this instance. `nil` by - /// default. - /// - cachedResponseHandler: `CachedResponseHandler` to be used by all `Request`s created by this instance. - /// `nil` by default. - /// - eventMonitors: Additional `EventMonitor`s used by the instance. Alamofire always adds a - /// `AlamofireNotifications` `EventMonitor` to the array passed here. `[]` by default. - public init(session: URLSession, - delegate: SessionDelegate, - rootQueue: DispatchQueue, - startRequestsImmediately: Bool = true, - requestQueue: DispatchQueue? = nil, - serializationQueue: DispatchQueue? = nil, - interceptor: RequestInterceptor? = nil, - serverTrustManager: ServerTrustManager? = nil, - redirectHandler: RedirectHandler? = nil, - cachedResponseHandler: CachedResponseHandler? = nil, - eventMonitors: [EventMonitor] = []) { - precondition(session.configuration.identifier == nil, - "Alamofire does not support background URLSessionConfigurations.") - precondition(session.delegateQueue.underlyingQueue === rootQueue, - "Session(session:) initializer must be passed the DispatchQueue used as the delegateQueue's underlyingQueue as rootQueue.") - - self.session = session - self.delegate = delegate - self.rootQueue = rootQueue - self.startRequestsImmediately = startRequestsImmediately - self.requestQueue = requestQueue ?? DispatchQueue(label: "\(rootQueue.label).requestQueue", target: rootQueue) - self.serializationQueue = serializationQueue ?? DispatchQueue(label: "\(rootQueue.label).serializationQueue", target: rootQueue) - self.interceptor = interceptor - self.serverTrustManager = serverTrustManager - self.redirectHandler = redirectHandler - self.cachedResponseHandler = cachedResponseHandler - eventMonitor = CompositeEventMonitor(monitors: defaultEventMonitors + eventMonitors) - delegate.eventMonitor = eventMonitor - delegate.stateProvider = self - } - - /// Creates a `Session` from a `URLSessionConfiguration`. - /// - /// - Note: This initializer lets Alamofire handle the creation of the underlying `URLSession` and its - /// `delegateQueue`, and is the recommended initializer for most uses. - /// - /// - Parameters: - /// - configuration: `URLSessionConfiguration` to be used to create the underlying `URLSession`. Changes - /// to this value after being passed to this initializer will have no effect. - /// `URLSessionConfiguration.af.default` by default. - /// - delegate: `SessionDelegate` that handles `session`'s delegate callbacks as well as `Request` - /// interaction. `SessionDelegate()` by default. - /// - rootQueue: Root `DispatchQueue` for all internal callbacks and state updates. **MUST** be a - /// serial queue. `DispatchQueue(label: "org.alamofire.session.rootQueue")` by default. - /// - startRequestsImmediately: Determines whether this instance will automatically start all `Request`s. `true` - /// by default. If set to `false`, all `Request`s created must have `.resume()` called. - /// on them for them to start. - /// - requestQueue: `DispatchQueue` on which to perform `URLRequest` creation. By default this queue - /// will use the `rootQueue` as its `target`. A separate queue can be used if it's - /// determined request creation is a bottleneck, but that should only be done after - /// careful testing and profiling. `nil` by default. - /// - serializationQueue: `DispatchQueue` on which to perform all response serialization. By default this - /// queue will use the `rootQueue` as its `target`. A separate queue can be used if - /// it's determined response serialization is a bottleneck, but that should only be - /// done after careful testing and profiling. `nil` by default. - /// - interceptor: `RequestInterceptor` to be used for all `Request`s created by this instance. `nil` - /// by default. - /// - serverTrustManager: `ServerTrustManager` to be used for all trust evaluations by this instance. `nil` - /// by default. - /// - redirectHandler: `RedirectHandler` to be used by all `Request`s created by this instance. `nil` by - /// default. - /// - cachedResponseHandler: `CachedResponseHandler` to be used by all `Request`s created by this instance. - /// `nil` by default. - /// - eventMonitors: Additional `EventMonitor`s used by the instance. Alamofire always adds a - /// `AlamofireNotifications` `EventMonitor` to the array passed here. `[]` by default. - public convenience init(configuration: URLSessionConfiguration = URLSessionConfiguration.af.default, - delegate: SessionDelegate = SessionDelegate(), - rootQueue: DispatchQueue = DispatchQueue(label: "org.alamofire.session.rootQueue"), - startRequestsImmediately: Bool = true, - requestQueue: DispatchQueue? = nil, - serializationQueue: DispatchQueue? = nil, - interceptor: RequestInterceptor? = nil, - serverTrustManager: ServerTrustManager? = nil, - redirectHandler: RedirectHandler? = nil, - cachedResponseHandler: CachedResponseHandler? = nil, - eventMonitors: [EventMonitor] = []) { - precondition(configuration.identifier == nil, "Alamofire does not support background URLSessionConfigurations.") - - let delegateQueue = OperationQueue(maxConcurrentOperationCount: 1, underlyingQueue: rootQueue, name: "org.alamofire.session.sessionDelegateQueue") - let session = URLSession(configuration: configuration, delegate: delegate, delegateQueue: delegateQueue) - - self.init(session: session, - delegate: delegate, - rootQueue: rootQueue, - startRequestsImmediately: startRequestsImmediately, - requestQueue: requestQueue, - serializationQueue: serializationQueue, - interceptor: interceptor, - serverTrustManager: serverTrustManager, - redirectHandler: redirectHandler, - cachedResponseHandler: cachedResponseHandler, - eventMonitors: eventMonitors) - } - - deinit { - finishRequestsForDeinit() - session.invalidateAndCancel() - } - - // MARK: - All Requests API - - /// Perform an action on all active `Request`s. - /// - /// - Note: The provided `action` closure is performed asynchronously, meaning that some `Request`s may complete and - /// be unavailable by time it runs. Additionally, this action is performed on the instances's `rootQueue`, - /// so care should be taken that actions are fast. Once the work on the `Request`s is complete, any - /// additional work should be performed on another queue. - /// - /// - Parameters: - /// - action: Closure to perform with all `Request`s. - public func withAllRequests(perform action: @escaping (Set) -> Void) { - rootQueue.async { - action(self.activeRequests) - } - } - - /// Cancel all active `Request`s, optionally calling a completion handler when complete. - /// - /// - Note: This is an asynchronous operation and does not block the creation of future `Request`s. Cancelled - /// `Request`s may not cancel immediately due internal work, and may not cancel at all if they are close to - /// completion when cancelled. - /// - /// - Parameters: - /// - queue: `DispatchQueue` on which the completion handler is run. `.main` by default. - /// - completion: Closure to be called when all `Request`s have been cancelled. - public func cancelAllRequests(completingOnQueue queue: DispatchQueue = .main, completion: (() -> Void)? = nil) { - withAllRequests { requests in - requests.forEach { $0.cancel() } - queue.async { - completion?() - } - } - } - - // MARK: - DataRequest - - /// Closure which provides a `URLRequest` for mutation. - public typealias RequestModifier = (inout URLRequest) throws -> Void - - struct RequestConvertible: URLRequestConvertible { - let url: URLConvertible - let method: HTTPMethod - let parameters: Parameters? - let encoding: ParameterEncoding - let headers: HTTPHeaders? - let requestModifier: RequestModifier? - - func asURLRequest() throws -> URLRequest { - var request = try URLRequest(url: url, method: method, headers: headers) - try requestModifier?(&request) - - return try encoding.encode(request, with: parameters) - } - } - - /// Creates a `DataRequest` from a `URLRequest` created using the passed components and a `RequestInterceptor`. - /// - /// - Parameters: - /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. - /// - method: `HTTPMethod` for the `URLRequest`. `.get` by default. - /// - parameters: `Parameters` (a.k.a. `[String: Any]`) value to be encoded into the `URLRequest`. `nil` by - /// default. - /// - encoding: `ParameterEncoding` to be used to encode the `parameters` value into the `URLRequest`. - /// `URLEncoding.default` by default. - /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. - /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from the provided - /// parameters. `nil` by default. - /// - /// - Returns: The created `DataRequest`. - open func request(_ convertible: URLConvertible, - method: HTTPMethod = .get, - parameters: Parameters? = nil, - encoding: ParameterEncoding = URLEncoding.default, - headers: HTTPHeaders? = nil, - interceptor: RequestInterceptor? = nil, - requestModifier: RequestModifier? = nil) -> DataRequest { - let convertible = RequestConvertible(url: convertible, - method: method, - parameters: parameters, - encoding: encoding, - headers: headers, - requestModifier: requestModifier) - - return request(convertible, interceptor: interceptor) - } - - struct RequestEncodableConvertible: URLRequestConvertible { - let url: URLConvertible - let method: HTTPMethod - let parameters: Parameters? - let encoder: ParameterEncoder - let headers: HTTPHeaders? - let requestModifier: RequestModifier? - - func asURLRequest() throws -> URLRequest { - var request = try URLRequest(url: url, method: method, headers: headers) - try requestModifier?(&request) - - return try parameters.map { try encoder.encode($0, into: request) } ?? request - } - } - - /// Creates a `DataRequest` from a `URLRequest` created using the passed components, `Encodable` parameters, and a - /// `RequestInterceptor`. - /// - /// - Parameters: - /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. - /// - method: `HTTPMethod` for the `URLRequest`. `.get` by default. - /// - parameters: `Encodable` value to be encoded into the `URLRequest`. `nil` by default. - /// - encoder: `ParameterEncoder` to be used to encode the `parameters` value into the `URLRequest`. - /// `URLEncodedFormParameterEncoder.default` by default. - /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. - /// - /// - Returns: The created `DataRequest`. - open func request(_ convertible: URLConvertible, - method: HTTPMethod = .get, - parameters: Parameters? = nil, - encoder: ParameterEncoder = URLEncodedFormParameterEncoder.default, - headers: HTTPHeaders? = nil, - interceptor: RequestInterceptor? = nil, - requestModifier: RequestModifier? = nil) -> DataRequest { - let convertible = RequestEncodableConvertible(url: convertible, - method: method, - parameters: parameters, - encoder: encoder, - headers: headers, - requestModifier: requestModifier) - - return request(convertible, interceptor: interceptor) - } - - /// Creates a `DataRequest` from a `URLRequestConvertible` value and a `RequestInterceptor`. - /// - /// - Parameters: - /// - convertible: `URLRequestConvertible` value to be used to create the `URLRequest`. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. - /// - /// - Returns: The created `DataRequest`. - open func request(_ convertible: URLRequestConvertible, interceptor: RequestInterceptor? = nil) -> DataRequest { - let request = DataRequest(convertible: convertible, - underlyingQueue: rootQueue, - serializationQueue: serializationQueue, - eventMonitor: eventMonitor, - interceptor: interceptor, - delegate: self) - - perform(request) - - return request - } - - // MARK: - DataStreamRequest - - /// Creates a `DataStreamRequest` from the passed components, `Encodable` parameters, and `RequestInterceptor`. - /// - /// - Parameters: - /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. - /// - method: `HTTPMethod` for the `URLRequest`. `.get` by default. - /// - parameters: `Encodable` value to be encoded into the `URLRequest`. `nil` by default. - /// - encoder: `ParameterEncoder` to be used to encode the `parameters` value into the - /// `URLRequest`. - /// `URLEncodedFormParameterEncoder.default` by default. - /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. - /// - automaticallyCancelOnStreamError: `Bool` indicating whether the instance should be canceled when an `Error` - /// is thrown while serializing stream `Data`. `false` by default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` - /// by default. - /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from - /// the provided parameters. `nil` by default. - /// - /// - Returns: The created `DataStream` request. - open func streamRequest(_ convertible: URLConvertible, - method: HTTPMethod = .get, - parameters: Parameters? = nil, - encoder: ParameterEncoder = URLEncodedFormParameterEncoder.default, - headers: HTTPHeaders? = nil, - automaticallyCancelOnStreamError: Bool = false, - interceptor: RequestInterceptor? = nil, - requestModifier: RequestModifier? = nil) -> DataStreamRequest { - let convertible = RequestEncodableConvertible(url: convertible, - method: method, - parameters: parameters, - encoder: encoder, - headers: headers, - requestModifier: requestModifier) - - return streamRequest(convertible, - automaticallyCancelOnStreamError: automaticallyCancelOnStreamError, - interceptor: interceptor) - } - - /// Creates a `DataStreamRequest` from the passed components and `RequestInterceptor`. - /// - /// - Parameters: - /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. - /// - method: `HTTPMethod` for the `URLRequest`. `.get` by default. - /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. - /// - automaticallyCancelOnStreamError: `Bool` indicating whether the instance should be canceled when an `Error` - /// is thrown while serializing stream `Data`. `false` by default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` - /// by default. - /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from - /// the provided parameters. `nil` by default. - /// - /// - Returns: The created `DataStream` request. - open func streamRequest(_ convertible: URLConvertible, - method: HTTPMethod = .get, - headers: HTTPHeaders? = nil, - automaticallyCancelOnStreamError: Bool = false, - interceptor: RequestInterceptor? = nil, - requestModifier: RequestModifier? = nil) -> DataStreamRequest { - let convertible = RequestEncodableConvertible(url: convertible, - method: method, - parameters: Empty?.none, - encoder: URLEncodedFormParameterEncoder.default, - headers: headers, - requestModifier: requestModifier) - - return streamRequest(convertible, - automaticallyCancelOnStreamError: automaticallyCancelOnStreamError, - interceptor: interceptor) - } - - /// Creates a `DataStreamRequest` from the passed `URLRequestConvertible` value and `RequestInterceptor`. - /// - /// - Parameters: - /// - convertible: `URLRequestConvertible` value to be used to create the `URLRequest`. - /// - automaticallyCancelOnStreamError: `Bool` indicating whether the instance should be canceled when an `Error` - /// is thrown while serializing stream `Data`. `false` by default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` - /// by default. - /// - /// - Returns: The created `DataStreamRequest`. - open func streamRequest(_ convertible: URLRequestConvertible, - automaticallyCancelOnStreamError: Bool = false, - interceptor: RequestInterceptor? = nil) -> DataStreamRequest { - let request = DataStreamRequest(convertible: convertible, - automaticallyCancelOnStreamError: automaticallyCancelOnStreamError, - underlyingQueue: rootQueue, - serializationQueue: serializationQueue, - eventMonitor: eventMonitor, - interceptor: interceptor, - delegate: self) - - perform(request) - - return request - } - - // MARK: - DownloadRequest - - /// Creates a `DownloadRequest` using a `URLRequest` created using the passed components, `RequestInterceptor`, and - /// `Destination`. - /// - /// - Parameters: - /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. - /// - method: `HTTPMethod` for the `URLRequest`. `.get` by default. - /// - parameters: `Parameters` (a.k.a. `[String: Any]`) value to be encoded into the `URLRequest`. `nil` by - /// default. - /// - encoding: `ParameterEncoding` to be used to encode the `parameters` value into the `URLRequest`. - /// Defaults to `URLEncoding.default`. - /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. - /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from the provided - /// parameters. `nil` by default. - /// - destination: `DownloadRequest.Destination` closure used to determine how and where the downloaded file - /// should be moved. `nil` by default. - /// - /// - Returns: The created `DownloadRequest`. - open func download(_ convertible: URLConvertible, - method: HTTPMethod = .get, - parameters: Parameters? = nil, - encoding: ParameterEncoding = URLEncoding.default, - headers: HTTPHeaders? = nil, - interceptor: RequestInterceptor? = nil, - requestModifier: RequestModifier? = nil, - to destination: DownloadRequest.Destination? = nil) -> DownloadRequest { - let convertible = RequestConvertible(url: convertible, - method: method, - parameters: parameters, - encoding: encoding, - headers: headers, - requestModifier: requestModifier) - - return download(convertible, interceptor: interceptor, to: destination) - } - - /// Creates a `DownloadRequest` from a `URLRequest` created using the passed components, `Encodable` parameters, and - /// a `RequestInterceptor`. - /// - /// - Parameters: - /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. - /// - method: `HTTPMethod` for the `URLRequest`. `.get` by default. - /// - parameters: Value conforming to `Encodable` to be encoded into the `URLRequest`. `nil` by default. - /// - encoder: `ParameterEncoder` to be used to encode the `parameters` value into the `URLRequest`. - /// Defaults to `URLEncodedFormParameterEncoder.default`. - /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. - /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from the provided - /// parameters. `nil` by default. - /// - destination: `DownloadRequest.Destination` closure used to determine how and where the downloaded file - /// should be moved. `nil` by default. - /// - /// - Returns: The created `DownloadRequest`. - open func download(_ convertible: URLConvertible, - method: HTTPMethod = .get, - parameters: Parameters? = nil, - encoder: ParameterEncoder = URLEncodedFormParameterEncoder.default, - headers: HTTPHeaders? = nil, - interceptor: RequestInterceptor? = nil, - requestModifier: RequestModifier? = nil, - to destination: DownloadRequest.Destination? = nil) -> DownloadRequest { - let convertible = RequestEncodableConvertible(url: convertible, - method: method, - parameters: parameters, - encoder: encoder, - headers: headers, - requestModifier: requestModifier) - - return download(convertible, interceptor: interceptor, to: destination) - } - - /// Creates a `DownloadRequest` from a `URLRequestConvertible` value, a `RequestInterceptor`, and a `Destination`. - /// - /// - Parameters: - /// - convertible: `URLRequestConvertible` value to be used to create the `URLRequest`. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. - /// - destination: `DownloadRequest.Destination` closure used to determine how and where the downloaded file - /// should be moved. `nil` by default. - /// - /// - Returns: The created `DownloadRequest`. - open func download(_ convertible: URLRequestConvertible, - interceptor: RequestInterceptor? = nil, - to destination: DownloadRequest.Destination? = nil) -> DownloadRequest { - let request = DownloadRequest(downloadable: .request(convertible), - underlyingQueue: rootQueue, - serializationQueue: serializationQueue, - eventMonitor: eventMonitor, - interceptor: interceptor, - delegate: self, - destination: destination ?? DownloadRequest.defaultDestination) - - perform(request) - - return request - } - - /// Creates a `DownloadRequest` from the `resumeData` produced from a previously cancelled `DownloadRequest`, as - /// well as a `RequestInterceptor`, and a `Destination`. - /// - /// - Note: If `destination` is not specified, the download will be moved to a temporary location determined by - /// Alamofire. The file will not be deleted until the system purges the temporary files. - /// - /// - Note: On some versions of all Apple platforms (iOS 10 - 10.2, macOS 10.12 - 10.12.2, tvOS 10 - 10.1, watchOS 3 - 3.1.1), - /// `resumeData` is broken on background URL session configurations. There's an underlying bug in the `resumeData` - /// generation logic where the data is written incorrectly and will always fail to resume the download. For more - /// information about the bug and possible workarounds, please refer to the [this Stack Overflow post](http://stackoverflow.com/a/39347461/1342462). - /// - /// - Parameters: - /// - data: The resume data from a previously cancelled `DownloadRequest` or `URLSessionDownloadTask`. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. - /// - destination: `DownloadRequest.Destination` closure used to determine how and where the downloaded file - /// should be moved. `nil` by default. - /// - /// - Returns: The created `DownloadRequest`. - open func download(resumingWith data: Data, - interceptor: RequestInterceptor? = nil, - to destination: DownloadRequest.Destination? = nil) -> DownloadRequest { - let request = DownloadRequest(downloadable: .resumeData(data), - underlyingQueue: rootQueue, - serializationQueue: serializationQueue, - eventMonitor: eventMonitor, - interceptor: interceptor, - delegate: self, - destination: destination ?? DownloadRequest.defaultDestination) - - perform(request) - - return request - } - - // MARK: - UploadRequest - - struct ParameterlessRequestConvertible: URLRequestConvertible { - let url: URLConvertible - let method: HTTPMethod - let headers: HTTPHeaders? - let requestModifier: RequestModifier? - - func asURLRequest() throws -> URLRequest { - var request = try URLRequest(url: url, method: method, headers: headers) - try requestModifier?(&request) - - return request - } - } - - struct Upload: UploadConvertible { - let request: URLRequestConvertible - let uploadable: UploadableConvertible - - func createUploadable() throws -> UploadRequest.Uploadable { - try uploadable.createUploadable() - } - - func asURLRequest() throws -> URLRequest { - try request.asURLRequest() - } - } - - // MARK: Data - - /// Creates an `UploadRequest` for the given `Data`, `URLRequest` components, and `RequestInterceptor`. - /// - /// - Parameters: - /// - data: The `Data` to upload. - /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. - /// - method: `HTTPMethod` for the `URLRequest`. `.post` by default. - /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. - /// - fileManager: `FileManager` instance to be used by the returned `UploadRequest`. `.default` instance by - /// default. - /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from the provided - /// parameters. `nil` by default. - /// - /// - Returns: The created `UploadRequest`. - open func upload(_ data: Data, - to convertible: URLConvertible, - method: HTTPMethod = .post, - headers: HTTPHeaders? = nil, - interceptor: RequestInterceptor? = nil, - fileManager: FileManager = .default, - requestModifier: RequestModifier? = nil) -> UploadRequest { - let convertible = ParameterlessRequestConvertible(url: convertible, - method: method, - headers: headers, - requestModifier: requestModifier) - - return upload(data, with: convertible, interceptor: interceptor, fileManager: fileManager) - } - - /// Creates an `UploadRequest` for the given `Data` using the `URLRequestConvertible` value and `RequestInterceptor`. - /// - /// - Parameters: - /// - data: The `Data` to upload. - /// - convertible: `URLRequestConvertible` value to be used to create the `URLRequest`. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. - /// - fileManager: `FileManager` instance to be used by the returned `UploadRequest`. `.default` instance by - /// default. - /// - /// - Returns: The created `UploadRequest`. - open func upload(_ data: Data, - with convertible: URLRequestConvertible, - interceptor: RequestInterceptor? = nil, - fileManager: FileManager = .default) -> UploadRequest { - upload(.data(data), with: convertible, interceptor: interceptor, fileManager: fileManager) - } - - // MARK: File - - /// Creates an `UploadRequest` for the file at the given file `URL`, using a `URLRequest` from the provided - /// components and `RequestInterceptor`. - /// - /// - Parameters: - /// - fileURL: The `URL` of the file to upload. - /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. - /// - method: `HTTPMethod` for the `URLRequest`. `.post` by default. - /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `UploadRequest`. `nil` by default. - /// - fileManager: `FileManager` instance to be used by the returned `UploadRequest`. `.default` instance by - /// default. - /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from the provided - /// parameters. `nil` by default. - /// - /// - Returns: The created `UploadRequest`. - open func upload(_ fileURL: URL, - to convertible: URLConvertible, - method: HTTPMethod = .post, - headers: HTTPHeaders? = nil, - interceptor: RequestInterceptor? = nil, - fileManager: FileManager = .default, - requestModifier: RequestModifier? = nil) -> UploadRequest { - let convertible = ParameterlessRequestConvertible(url: convertible, - method: method, - headers: headers, - requestModifier: requestModifier) - - return upload(fileURL, with: convertible, interceptor: interceptor, fileManager: fileManager) - } - - /// Creates an `UploadRequest` for the file at the given file `URL` using the `URLRequestConvertible` value and - /// `RequestInterceptor`. - /// - /// - Parameters: - /// - fileURL: The `URL` of the file to upload. - /// - convertible: `URLRequestConvertible` value to be used to create the `URLRequest`. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. - /// - fileManager: `FileManager` instance to be used by the returned `UploadRequest`. `.default` instance by - /// default. - /// - /// - Returns: The created `UploadRequest`. - open func upload(_ fileURL: URL, - with convertible: URLRequestConvertible, - interceptor: RequestInterceptor? = nil, - fileManager: FileManager = .default) -> UploadRequest { - upload(.file(fileURL, shouldRemove: false), with: convertible, interceptor: interceptor, fileManager: fileManager) - } - - // MARK: InputStream - - /// Creates an `UploadRequest` from the `InputStream` provided using a `URLRequest` from the provided components and - /// `RequestInterceptor`. - /// - /// - Parameters: - /// - stream: The `InputStream` that provides the data to upload. - /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. - /// - method: `HTTPMethod` for the `URLRequest`. `.post` by default. - /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. - /// - fileManager: `FileManager` instance to be used by the returned `UploadRequest`. `.default` instance by - /// default. - /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from the provided - /// parameters. `nil` by default. - /// - /// - Returns: The created `UploadRequest`. - open func upload(_ stream: InputStream, - to convertible: URLConvertible, - method: HTTPMethod = .post, - headers: HTTPHeaders? = nil, - interceptor: RequestInterceptor? = nil, - fileManager: FileManager = .default, - requestModifier: RequestModifier? = nil) -> UploadRequest { - let convertible = ParameterlessRequestConvertible(url: convertible, - method: method, - headers: headers, - requestModifier: requestModifier) - - return upload(stream, with: convertible, interceptor: interceptor, fileManager: fileManager) - } - - /// Creates an `UploadRequest` from the provided `InputStream` using the `URLRequestConvertible` value and - /// `RequestInterceptor`. - /// - /// - Parameters: - /// - stream: The `InputStream` that provides the data to upload. - /// - convertible: `URLRequestConvertible` value to be used to create the `URLRequest`. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. - /// - fileManager: `FileManager` instance to be used by the returned `UploadRequest`. `.default` instance by - /// default. - /// - /// - Returns: The created `UploadRequest`. - open func upload(_ stream: InputStream, - with convertible: URLRequestConvertible, - interceptor: RequestInterceptor? = nil, - fileManager: FileManager = .default) -> UploadRequest { - upload(.stream(stream), with: convertible, interceptor: interceptor, fileManager: fileManager) - } - - // MARK: MultipartFormData - - /// Creates an `UploadRequest` for the multipart form data built using a closure and sent using the provided - /// `URLRequest` components and `RequestInterceptor`. - /// - /// It is important to understand the memory implications of uploading `MultipartFormData`. If the cumulative - /// payload is small, encoding the data in-memory and directly uploading to a server is the by far the most - /// efficient approach. However, if the payload is too large, encoding the data in-memory could cause your app to - /// be terminated. Larger payloads must first be written to disk using input and output streams to keep the memory - /// footprint low, then the data can be uploaded as a stream from the resulting file. Streaming from disk MUST be - /// used for larger payloads such as video content. - /// - /// The `encodingMemoryThreshold` parameter allows Alamofire to automatically determine whether to encode in-memory - /// or stream from disk. If the content length of the `MultipartFormData` is below the `encodingMemoryThreshold`, - /// encoding takes place in-memory. If the content length exceeds the threshold, the data is streamed to disk - /// during the encoding process. Then the result is uploaded as data or as a stream depending on which encoding - /// technique was used. - /// - /// - Parameters: - /// - multipartFormData: `MultipartFormData` building closure. - /// - convertible: `URLConvertible` value to be used as the `URLRequest`'s `URL`. - /// - encodingMemoryThreshold: Byte threshold used to determine whether the form data is encoded into memory or - /// onto disk before being uploaded. `MultipartFormData.encodingMemoryThreshold` by - /// default. - /// - method: `HTTPMethod` for the `URLRequest`. `.post` by default. - /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. - /// - fileManager: `FileManager` to be used if the form data exceeds the memory threshold and is - /// written to disk before being uploaded. `.default` instance by default. - /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from the - /// provided parameters. `nil` by default. - /// - /// - Returns: The created `UploadRequest`. - open func upload(multipartFormData: @escaping (MultipartFormData) -> Void, - to url: URLConvertible, - usingThreshold encodingMemoryThreshold: UInt64 = MultipartFormData.encodingMemoryThreshold, - method: HTTPMethod = .post, - headers: HTTPHeaders? = nil, - interceptor: RequestInterceptor? = nil, - fileManager: FileManager = .default, - requestModifier: RequestModifier? = nil) -> UploadRequest { - let convertible = ParameterlessRequestConvertible(url: url, - method: method, - headers: headers, - requestModifier: requestModifier) - - let formData = MultipartFormData(fileManager: fileManager) - multipartFormData(formData) - - return upload(multipartFormData: formData, - with: convertible, - usingThreshold: encodingMemoryThreshold, - interceptor: interceptor, - fileManager: fileManager) - } - - /// Creates an `UploadRequest` using a `MultipartFormData` building closure, the provided `URLRequestConvertible` - /// value, and a `RequestInterceptor`. - /// - /// It is important to understand the memory implications of uploading `MultipartFormData`. If the cumulative - /// payload is small, encoding the data in-memory and directly uploading to a server is the by far the most - /// efficient approach. However, if the payload is too large, encoding the data in-memory could cause your app to - /// be terminated. Larger payloads must first be written to disk using input and output streams to keep the memory - /// footprint low, then the data can be uploaded as a stream from the resulting file. Streaming from disk MUST be - /// used for larger payloads such as video content. - /// - /// The `encodingMemoryThreshold` parameter allows Alamofire to automatically determine whether to encode in-memory - /// or stream from disk. If the content length of the `MultipartFormData` is below the `encodingMemoryThreshold`, - /// encoding takes place in-memory. If the content length exceeds the threshold, the data is streamed to disk - /// during the encoding process. Then the result is uploaded as data or as a stream depending on which encoding - /// technique was used. - /// - /// - Parameters: - /// - multipartFormData: `MultipartFormData` building closure. - /// - request: `URLRequestConvertible` value to be used to create the `URLRequest`. - /// - encodingMemoryThreshold: Byte threshold used to determine whether the form data is encoded into memory or - /// onto disk before being uploaded. `MultipartFormData.encodingMemoryThreshold` by - /// default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. - /// - fileManager: `FileManager` to be used if the form data exceeds the memory threshold and is - /// written to disk before being uploaded. `.default` instance by default. - /// - /// - Returns: The created `UploadRequest`. - open func upload(multipartFormData: @escaping (MultipartFormData) -> Void, - with request: URLRequestConvertible, - usingThreshold encodingMemoryThreshold: UInt64 = MultipartFormData.encodingMemoryThreshold, - interceptor: RequestInterceptor? = nil, - fileManager: FileManager = .default) -> UploadRequest { - let formData = MultipartFormData(fileManager: fileManager) - multipartFormData(formData) - - return upload(multipartFormData: formData, - with: request, - usingThreshold: encodingMemoryThreshold, - interceptor: interceptor, - fileManager: fileManager) - } - - /// Creates an `UploadRequest` for the prebuilt `MultipartFormData` value using the provided `URLRequest` components - /// and `RequestInterceptor`. - /// - /// It is important to understand the memory implications of uploading `MultipartFormData`. If the cumulative - /// payload is small, encoding the data in-memory and directly uploading to a server is the by far the most - /// efficient approach. However, if the payload is too large, encoding the data in-memory could cause your app to - /// be terminated. Larger payloads must first be written to disk using input and output streams to keep the memory - /// footprint low, then the data can be uploaded as a stream from the resulting file. Streaming from disk MUST be - /// used for larger payloads such as video content. - /// - /// The `encodingMemoryThreshold` parameter allows Alamofire to automatically determine whether to encode in-memory - /// or stream from disk. If the content length of the `MultipartFormData` is below the `encodingMemoryThreshold`, - /// encoding takes place in-memory. If the content length exceeds the threshold, the data is streamed to disk - /// during the encoding process. Then the result is uploaded as data or as a stream depending on which encoding - /// technique was used. - /// - /// - Parameters: - /// - multipartFormData: `MultipartFormData` instance to upload. - /// - url: `URLConvertible` value to be used as the `URLRequest`'s `URL`. - /// - encodingMemoryThreshold: Byte threshold used to determine whether the form data is encoded into memory or - /// onto disk before being uploaded. `MultipartFormData.encodingMemoryThreshold` by - /// default. - /// - method: `HTTPMethod` for the `URLRequest`. `.post` by default. - /// - headers: `HTTPHeaders` value to be added to the `URLRequest`. `nil` by default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. - /// - fileManager: `FileManager` to be used if the form data exceeds the memory threshold and is - /// written to disk before being uploaded. `.default` instance by default. - /// - requestModifier: `RequestModifier` which will be applied to the `URLRequest` created from the - /// provided parameters. `nil` by default. - /// - /// - Returns: The created `UploadRequest`. - open func upload(multipartFormData: MultipartFormData, - to url: URLConvertible, - usingThreshold encodingMemoryThreshold: UInt64 = MultipartFormData.encodingMemoryThreshold, - method: HTTPMethod = .post, - headers: HTTPHeaders? = nil, - interceptor: RequestInterceptor? = nil, - fileManager: FileManager = .default, - requestModifier: RequestModifier? = nil) -> UploadRequest { - let convertible = ParameterlessRequestConvertible(url: url, - method: method, - headers: headers, - requestModifier: requestModifier) - - let multipartUpload = MultipartUpload(encodingMemoryThreshold: encodingMemoryThreshold, - request: convertible, - multipartFormData: multipartFormData) - - return upload(multipartUpload, interceptor: interceptor, fileManager: fileManager) - } - - /// Creates an `UploadRequest` for the prebuilt `MultipartFormData` value using the providing `URLRequestConvertible` - /// value and `RequestInterceptor`. - /// - /// It is important to understand the memory implications of uploading `MultipartFormData`. If the cumulative - /// payload is small, encoding the data in-memory and directly uploading to a server is the by far the most - /// efficient approach. However, if the payload is too large, encoding the data in-memory could cause your app to - /// be terminated. Larger payloads must first be written to disk using input and output streams to keep the memory - /// footprint low, then the data can be uploaded as a stream from the resulting file. Streaming from disk MUST be - /// used for larger payloads such as video content. - /// - /// The `encodingMemoryThreshold` parameter allows Alamofire to automatically determine whether to encode in-memory - /// or stream from disk. If the content length of the `MultipartFormData` is below the `encodingMemoryThreshold`, - /// encoding takes place in-memory. If the content length exceeds the threshold, the data is streamed to disk - /// during the encoding process. Then the result is uploaded as data or as a stream depending on which encoding - /// technique was used. - /// - /// - Parameters: - /// - multipartFormData: `MultipartFormData` instance to upload. - /// - request: `URLRequestConvertible` value to be used to create the `URLRequest`. - /// - encodingMemoryThreshold: Byte threshold used to determine whether the form data is encoded into memory or - /// onto disk before being uploaded. `MultipartFormData.encodingMemoryThreshold` by - /// default. - /// - interceptor: `RequestInterceptor` value to be used by the returned `DataRequest`. `nil` by default. - /// - fileManager: `FileManager` instance to be used by the returned `UploadRequest`. `.default` instance by - /// default. - /// - /// - Returns: The created `UploadRequest`. - open func upload(multipartFormData: MultipartFormData, - with request: URLRequestConvertible, - usingThreshold encodingMemoryThreshold: UInt64 = MultipartFormData.encodingMemoryThreshold, - interceptor: RequestInterceptor? = nil, - fileManager: FileManager = .default) -> UploadRequest { - let multipartUpload = MultipartUpload(encodingMemoryThreshold: encodingMemoryThreshold, - request: request, - multipartFormData: multipartFormData) - - return upload(multipartUpload, interceptor: interceptor, fileManager: fileManager) - } - - // MARK: - Internal API - - // MARK: Uploadable - - func upload(_ uploadable: UploadRequest.Uploadable, - with convertible: URLRequestConvertible, - interceptor: RequestInterceptor?, - fileManager: FileManager) -> UploadRequest { - let uploadable = Upload(request: convertible, uploadable: uploadable) - - return upload(uploadable, interceptor: interceptor, fileManager: fileManager) - } - - func upload(_ upload: UploadConvertible, interceptor: RequestInterceptor?, fileManager: FileManager) -> UploadRequest { - let request = UploadRequest(convertible: upload, - underlyingQueue: rootQueue, - serializationQueue: serializationQueue, - eventMonitor: eventMonitor, - interceptor: interceptor, - fileManager: fileManager, - delegate: self) - - perform(request) - - return request - } - - // MARK: Perform - - /// Starts performing the provided `Request`. - /// - /// - Parameter request: The `Request` to perform. - func perform(_ request: Request) { - rootQueue.async { - guard !request.isCancelled else { return } - - self.activeRequests.insert(request) - - self.requestQueue.async { - // Leaf types must come first, otherwise they will cast as their superclass. - switch request { - case let r as UploadRequest: self.performUploadRequest(r) // UploadRequest must come before DataRequest due to subtype relationship. - case let r as DataRequest: self.performDataRequest(r) - case let r as DownloadRequest: self.performDownloadRequest(r) - case let r as DataStreamRequest: self.performDataStreamRequest(r) - default: fatalError("Attempted to perform unsupported Request subclass: \(type(of: request))") - } - } - } - } - - func performDataRequest(_ request: DataRequest) { - dispatchPrecondition(condition: .onQueue(requestQueue)) - - performSetupOperations(for: request, convertible: request.convertible) - } - - func performDataStreamRequest(_ request: DataStreamRequest) { - dispatchPrecondition(condition: .onQueue(requestQueue)) - - performSetupOperations(for: request, convertible: request.convertible) - } - - func performUploadRequest(_ request: UploadRequest) { - dispatchPrecondition(condition: .onQueue(requestQueue)) - - performSetupOperations(for: request, convertible: request.convertible) { - do { - let uploadable = try request.upload.createUploadable() - self.rootQueue.async { request.didCreateUploadable(uploadable) } - return true - } catch { - self.rootQueue.async { request.didFailToCreateUploadable(with: error.asAFError(or: .createUploadableFailed(error: error))) } - return false - } - } - } - - func performDownloadRequest(_ request: DownloadRequest) { - dispatchPrecondition(condition: .onQueue(requestQueue)) - - switch request.downloadable { - case let .request(convertible): - performSetupOperations(for: request, convertible: convertible) - case let .resumeData(resumeData): - rootQueue.async { self.didReceiveResumeData(resumeData, for: request) } - } - } - - func performSetupOperations(for request: Request, - convertible: URLRequestConvertible, - shouldCreateTask: @escaping () -> Bool = { true }) - { - dispatchPrecondition(condition: .onQueue(requestQueue)) - - let initialRequest: URLRequest - - do { - initialRequest = try convertible.asURLRequest() - try initialRequest.validate() - } catch { - rootQueue.async { request.didFailToCreateURLRequest(with: error.asAFError(or: .createURLRequestFailed(error: error))) } - return - } - - rootQueue.async { request.didCreateInitialURLRequest(initialRequest) } - - guard !request.isCancelled else { return } - - guard let adapter = adapter(for: request) else { - guard shouldCreateTask() else { return } - rootQueue.async { self.didCreateURLRequest(initialRequest, for: request) } - return - } - - adapter.adapt(initialRequest, for: self) { result in - do { - let adaptedRequest = try result.get() - try adaptedRequest.validate() - - self.rootQueue.async { request.didAdaptInitialRequest(initialRequest, to: adaptedRequest) } - - guard shouldCreateTask() else { return } - - self.rootQueue.async { self.didCreateURLRequest(adaptedRequest, for: request) } - } catch { - self.rootQueue.async { request.didFailToAdaptURLRequest(initialRequest, withError: .requestAdaptationFailed(error: error)) } - } - } - } - - // MARK: - Task Handling - - func didCreateURLRequest(_ urlRequest: URLRequest, for request: Request) { - dispatchPrecondition(condition: .onQueue(rootQueue)) - - request.didCreateURLRequest(urlRequest) - - guard !request.isCancelled else { return } - - let task = request.task(for: urlRequest, using: session) - requestTaskMap[request] = task - request.didCreateTask(task) - - updateStatesForTask(task, request: request) - } - - func didReceiveResumeData(_ data: Data, for request: DownloadRequest) { - dispatchPrecondition(condition: .onQueue(rootQueue)) - - guard !request.isCancelled else { return } - - let task = request.task(forResumeData: data, using: session) - requestTaskMap[request] = task - request.didCreateTask(task) - - updateStatesForTask(task, request: request) - } - - func updateStatesForTask(_ task: URLSessionTask, request: Request) { - dispatchPrecondition(condition: .onQueue(rootQueue)) - - request.withState { state in - switch state { - case .initialized, .finished: - // Do nothing. - break - case .resumed: - task.resume() - rootQueue.async { request.didResumeTask(task) } - case .suspended: - task.suspend() - rootQueue.async { request.didSuspendTask(task) } - case .cancelled: - // Resume to ensure metrics are gathered. - task.resume() - task.cancel() - rootQueue.async { request.didCancelTask(task) } - } - } - } - - // MARK: - Adapters and Retriers - - func adapter(for request: Request) -> RequestAdapter? { - if let requestInterceptor = request.interceptor, let sessionInterceptor = interceptor { - return Interceptor(adapters: [requestInterceptor, sessionInterceptor]) - } else { - return request.interceptor ?? interceptor - } - } - - func retrier(for request: Request) -> RequestRetrier? { - if let requestInterceptor = request.interceptor, let sessionInterceptor = interceptor { - return Interceptor(retriers: [requestInterceptor, sessionInterceptor]) - } else { - return request.interceptor ?? interceptor - } - } - - // MARK: - Invalidation - - func finishRequestsForDeinit() { - requestTaskMap.requests.forEach { request in - rootQueue.async { - request.finish(error: AFError.sessionDeinitialized) - } - } - } -} - -// MARK: - RequestDelegate - -extension Session: RequestDelegate { - public var sessionConfiguration: URLSessionConfiguration { - session.configuration - } - - public var startImmediately: Bool { startRequestsImmediately } - - public func cleanup(after request: Request) { - activeRequests.remove(request) - } - - public func retryResult(for request: Request, dueTo error: AFError, completion: @escaping (RetryResult) -> Void) { - guard let retrier = retrier(for: request) else { - rootQueue.async { completion(.doNotRetry) } - return - } - - retrier.retry(request, for: self, dueTo: error) { retryResult in - self.rootQueue.async { - guard let retryResultError = retryResult.error else { completion(retryResult); return } - - let retryError = AFError.requestRetryFailed(retryError: retryResultError, originalError: error) - completion(.doNotRetryWithError(retryError)) - } - } - } - - public func retryRequest(_ request: Request, withDelay timeDelay: TimeInterval?) { - rootQueue.async { - let retry: () -> Void = { - guard !request.isCancelled else { return } - - request.prepareForRetry() - self.perform(request) - } - - if let retryDelay = timeDelay { - self.rootQueue.after(retryDelay) { retry() } - } else { - retry() - } - } - } -} - -// MARK: - SessionStateProvider - -extension Session: SessionStateProvider { - func request(for task: URLSessionTask) -> Request? { - dispatchPrecondition(condition: .onQueue(rootQueue)) - - return requestTaskMap[task] - } - - func didGatherMetricsForTask(_ task: URLSessionTask) { - dispatchPrecondition(condition: .onQueue(rootQueue)) - - let didDisassociate = requestTaskMap.disassociateIfNecessaryAfterGatheringMetricsForTask(task) - - if didDisassociate { - waitingCompletions[task]?() - waitingCompletions[task] = nil - } - } - - func didCompleteTask(_ task: URLSessionTask, completion: @escaping () -> Void) { - dispatchPrecondition(condition: .onQueue(rootQueue)) - - let didDisassociate = requestTaskMap.disassociateIfNecessaryAfterCompletingTask(task) - - if didDisassociate { - completion() - } else { - waitingCompletions[task] = completion - } - } - - func credential(for task: URLSessionTask, in protectionSpace: URLProtectionSpace) -> URLCredential? { - dispatchPrecondition(condition: .onQueue(rootQueue)) - - return requestTaskMap[task]?.credential ?? - session.configuration.urlCredentialStorage?.defaultCredential(for: protectionSpace) - } - - func cancelRequestsForSessionInvalidation(with error: Error?) { - dispatchPrecondition(condition: .onQueue(rootQueue)) - - requestTaskMap.requests.forEach { $0.finish(error: AFError.sessionInvalidated(error: error)) } - } -} diff --git a/Pods/Alamofire/Source/SessionDelegate.swift b/Pods/Alamofire/Source/SessionDelegate.swift deleted file mode 100644 index befc80eab..000000000 --- a/Pods/Alamofire/Source/SessionDelegate.swift +++ /dev/null @@ -1,330 +0,0 @@ -// -// SessionDelegate.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -/// Class which implements the various `URLSessionDelegate` methods to connect various Alamofire features. -open class SessionDelegate: NSObject { - private let fileManager: FileManager - - weak var stateProvider: SessionStateProvider? - var eventMonitor: EventMonitor? - - /// Creates an instance from the given `FileManager`. - /// - /// - Parameter fileManager: `FileManager` to use for underlying file management, such as moving downloaded files. - /// `.default` by default. - public init(fileManager: FileManager = .default) { - self.fileManager = fileManager - } - - /// Internal method to find and cast requests while maintaining some integrity checking. - /// - /// - Parameters: - /// - task: The `URLSessionTask` for which to find the associated `Request`. - /// - type: The `Request` subclass type to cast any `Request` associate with `task`. - func request(for task: URLSessionTask, as type: R.Type) -> R? { - guard let provider = stateProvider else { - assertionFailure("StateProvider is nil.") - return nil - } - - return provider.request(for: task) as? R - } -} - -/// Type which provides various `Session` state values. -protocol SessionStateProvider: AnyObject { - var serverTrustManager: ServerTrustManager? { get } - var redirectHandler: RedirectHandler? { get } - var cachedResponseHandler: CachedResponseHandler? { get } - - func request(for task: URLSessionTask) -> Request? - func didGatherMetricsForTask(_ task: URLSessionTask) - func didCompleteTask(_ task: URLSessionTask, completion: @escaping () -> Void) - func credential(for task: URLSessionTask, in protectionSpace: URLProtectionSpace) -> URLCredential? - func cancelRequestsForSessionInvalidation(with error: Error?) -} - -// MARK: URLSessionDelegate - -extension SessionDelegate: URLSessionDelegate { - open func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) { - eventMonitor?.urlSession(session, didBecomeInvalidWithError: error) - - stateProvider?.cancelRequestsForSessionInvalidation(with: error) - } -} - -// MARK: URLSessionTaskDelegate - -extension SessionDelegate: URLSessionTaskDelegate { - /// Result of a `URLAuthenticationChallenge` evaluation. - typealias ChallengeEvaluation = (disposition: URLSession.AuthChallengeDisposition, credential: URLCredential?, error: AFError?) - - open func urlSession(_ session: URLSession, - task: URLSessionTask, - didReceive challenge: URLAuthenticationChallenge, - completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { - eventMonitor?.urlSession(session, task: task, didReceive: challenge) - - let evaluation: ChallengeEvaluation - switch challenge.protectionSpace.authenticationMethod { - case NSURLAuthenticationMethodServerTrust: - evaluation = attemptServerTrustAuthentication(with: challenge) - case NSURLAuthenticationMethodHTTPBasic, NSURLAuthenticationMethodHTTPDigest, NSURLAuthenticationMethodNTLM, - NSURLAuthenticationMethodNegotiate, NSURLAuthenticationMethodClientCertificate: - evaluation = attemptCredentialAuthentication(for: challenge, belongingTo: task) - default: - evaluation = (.performDefaultHandling, nil, nil) - } - - if let error = evaluation.error { - stateProvider?.request(for: task)?.didFailTask(task, earlyWithError: error) - } - - completionHandler(evaluation.disposition, evaluation.credential) - } - - /// Evaluates the server trust `URLAuthenticationChallenge` received. - /// - /// - Parameter challenge: The `URLAuthenticationChallenge`. - /// - /// - Returns: The `ChallengeEvaluation`. - func attemptServerTrustAuthentication(with challenge: URLAuthenticationChallenge) -> ChallengeEvaluation { - let host = challenge.protectionSpace.host - - guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust, - let trust = challenge.protectionSpace.serverTrust - else { - return (.performDefaultHandling, nil, nil) - } - - do { - guard let evaluator = try stateProvider?.serverTrustManager?.serverTrustEvaluator(forHost: host) else { - return (.performDefaultHandling, nil, nil) - } - - try evaluator.evaluate(trust, forHost: host) - - return (.useCredential, URLCredential(trust: trust), nil) - } catch { - return (.cancelAuthenticationChallenge, nil, error.asAFError(or: .serverTrustEvaluationFailed(reason: .customEvaluationFailed(error: error)))) - } - } - - /// Evaluates the credential-based authentication `URLAuthenticationChallenge` received for `task`. - /// - /// - Parameters: - /// - challenge: The `URLAuthenticationChallenge`. - /// - task: The `URLSessionTask` which received the challenge. - /// - /// - Returns: The `ChallengeEvaluation`. - func attemptCredentialAuthentication(for challenge: URLAuthenticationChallenge, - belongingTo task: URLSessionTask) -> ChallengeEvaluation { - guard challenge.previousFailureCount == 0 else { - return (.rejectProtectionSpace, nil, nil) - } - - guard let credential = stateProvider?.credential(for: task, in: challenge.protectionSpace) else { - return (.performDefaultHandling, nil, nil) - } - - return (.useCredential, credential, nil) - } - - open func urlSession(_ session: URLSession, - task: URLSessionTask, - didSendBodyData bytesSent: Int64, - totalBytesSent: Int64, - totalBytesExpectedToSend: Int64) { - eventMonitor?.urlSession(session, - task: task, - didSendBodyData: bytesSent, - totalBytesSent: totalBytesSent, - totalBytesExpectedToSend: totalBytesExpectedToSend) - - stateProvider?.request(for: task)?.updateUploadProgress(totalBytesSent: totalBytesSent, - totalBytesExpectedToSend: totalBytesExpectedToSend) - } - - open func urlSession(_ session: URLSession, - task: URLSessionTask, - needNewBodyStream completionHandler: @escaping (InputStream?) -> Void) { - eventMonitor?.urlSession(session, taskNeedsNewBodyStream: task) - - guard let request = request(for: task, as: UploadRequest.self) else { - assertionFailure("needNewBodyStream did not find UploadRequest.") - completionHandler(nil) - return - } - - completionHandler(request.inputStream()) - } - - open func urlSession(_ session: URLSession, - task: URLSessionTask, - willPerformHTTPRedirection response: HTTPURLResponse, - newRequest request: URLRequest, - completionHandler: @escaping (URLRequest?) -> Void) { - eventMonitor?.urlSession(session, task: task, willPerformHTTPRedirection: response, newRequest: request) - - if let redirectHandler = stateProvider?.request(for: task)?.redirectHandler ?? stateProvider?.redirectHandler { - redirectHandler.task(task, willBeRedirectedTo: request, for: response, completion: completionHandler) - } else { - completionHandler(request) - } - } - - open func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) { - eventMonitor?.urlSession(session, task: task, didFinishCollecting: metrics) - - stateProvider?.request(for: task)?.didGatherMetrics(metrics) - - stateProvider?.didGatherMetricsForTask(task) - } - - open func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { - eventMonitor?.urlSession(session, task: task, didCompleteWithError: error) - - let request = stateProvider?.request(for: task) - - stateProvider?.didCompleteTask(task) { - request?.didCompleteTask(task, with: error.map { $0.asAFError(or: .sessionTaskFailed(error: $0)) }) - } - } - - @available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) - open func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) { - eventMonitor?.urlSession(session, taskIsWaitingForConnectivity: task) - } -} - -// MARK: URLSessionDataDelegate - -extension SessionDelegate: URLSessionDataDelegate { - open func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { - eventMonitor?.urlSession(session, dataTask: dataTask, didReceive: data) - - if let request = request(for: dataTask, as: DataRequest.self) { - request.didReceive(data: data) - } else if let request = request(for: dataTask, as: DataStreamRequest.self) { - request.didReceive(data: data) - } else { - assertionFailure("dataTask did not find DataRequest or DataStreamRequest in didReceive") - return - } - } - - open func urlSession(_ session: URLSession, - dataTask: URLSessionDataTask, - willCacheResponse proposedResponse: CachedURLResponse, - completionHandler: @escaping (CachedURLResponse?) -> Void) { - eventMonitor?.urlSession(session, dataTask: dataTask, willCacheResponse: proposedResponse) - - if let handler = stateProvider?.request(for: dataTask)?.cachedResponseHandler ?? stateProvider?.cachedResponseHandler { - handler.dataTask(dataTask, willCacheResponse: proposedResponse, completion: completionHandler) - } else { - completionHandler(proposedResponse) - } - } -} - -// MARK: URLSessionDownloadDelegate - -extension SessionDelegate: URLSessionDownloadDelegate { - open func urlSession(_ session: URLSession, - downloadTask: URLSessionDownloadTask, - didResumeAtOffset fileOffset: Int64, - expectedTotalBytes: Int64) { - eventMonitor?.urlSession(session, - downloadTask: downloadTask, - didResumeAtOffset: fileOffset, - expectedTotalBytes: expectedTotalBytes) - guard let downloadRequest = request(for: downloadTask, as: DownloadRequest.self) else { - assertionFailure("downloadTask did not find DownloadRequest.") - return - } - - downloadRequest.updateDownloadProgress(bytesWritten: fileOffset, - totalBytesExpectedToWrite: expectedTotalBytes) - } - - open func urlSession(_ session: URLSession, - downloadTask: URLSessionDownloadTask, - didWriteData bytesWritten: Int64, - totalBytesWritten: Int64, - totalBytesExpectedToWrite: Int64) { - eventMonitor?.urlSession(session, - downloadTask: downloadTask, - didWriteData: bytesWritten, - totalBytesWritten: totalBytesWritten, - totalBytesExpectedToWrite: totalBytesExpectedToWrite) - guard let downloadRequest = request(for: downloadTask, as: DownloadRequest.self) else { - assertionFailure("downloadTask did not find DownloadRequest.") - return - } - - downloadRequest.updateDownloadProgress(bytesWritten: bytesWritten, - totalBytesExpectedToWrite: totalBytesExpectedToWrite) - } - - open func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { - eventMonitor?.urlSession(session, downloadTask: downloadTask, didFinishDownloadingTo: location) - - guard let request = request(for: downloadTask, as: DownloadRequest.self) else { - assertionFailure("downloadTask did not find DownloadRequest.") - return - } - - let (destination, options): (URL, DownloadRequest.Options) - if let response = request.response { - (destination, options) = request.destination(location, response) - } else { - // If there's no response this is likely a local file download, so generate the temporary URL directly. - (destination, options) = (DownloadRequest.defaultDestinationURL(location), []) - } - - eventMonitor?.request(request, didCreateDestinationURL: destination) - - do { - if options.contains(.removePreviousFile), fileManager.fileExists(atPath: destination.path) { - try fileManager.removeItem(at: destination) - } - - if options.contains(.createIntermediateDirectories) { - let directory = destination.deletingLastPathComponent() - try fileManager.createDirectory(at: directory, withIntermediateDirectories: true) - } - - try fileManager.moveItem(at: location, to: destination) - - request.didFinishDownloading(using: downloadTask, with: .success(destination)) - } catch { - request.didFinishDownloading(using: downloadTask, with: .failure(.downloadedFileMoveFailed(error: error, - source: location, - destination: destination))) - } - } -} diff --git a/Pods/Alamofire/Source/StringEncoding+Alamofire.swift b/Pods/Alamofire/Source/StringEncoding+Alamofire.swift deleted file mode 100644 index 8fa613336..000000000 --- a/Pods/Alamofire/Source/StringEncoding+Alamofire.swift +++ /dev/null @@ -1,55 +0,0 @@ -// -// StringEncoding+Alamofire.swift -// -// Copyright (c) 2020 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -extension String.Encoding { - /// Creates an encoding from the IANA charset name. - /// - /// - Notes: These mappings match those [provided by CoreFoundation](https://opensource.apple.com/source/CF/CF-476.18/CFStringUtilities.c.auto.html) - /// - /// - Parameter name: IANA charset name. - init?(ianaCharsetName name: String) { - switch name.lowercased() { - case "utf-8": - self = .utf8 - case "iso-8859-1": - self = .isoLatin1 - case "unicode-1-1", "iso-10646-ucs-2", "utf-16": - self = .utf16 - case "utf-16be": - self = .utf16BigEndian - case "utf-16le": - self = .utf16LittleEndian - case "utf-32": - self = .utf32 - case "utf-32be": - self = .utf32BigEndian - case "utf-32le": - self = .utf32LittleEndian - default: - return nil - } - } -} diff --git a/Pods/Alamofire/Source/URLConvertible+URLRequestConvertible.swift b/Pods/Alamofire/Source/URLConvertible+URLRequestConvertible.swift deleted file mode 100644 index 455c4bcbb..000000000 --- a/Pods/Alamofire/Source/URLConvertible+URLRequestConvertible.swift +++ /dev/null @@ -1,105 +0,0 @@ -// -// URLConvertible+URLRequestConvertible.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -/// Types adopting the `URLConvertible` protocol can be used to construct `URL`s, which can then be used to construct -/// `URLRequests`. -public protocol URLConvertible { - /// Returns a `URL` from the conforming instance or throws. - /// - /// - Returns: The `URL` created from the instance. - /// - Throws: Any error thrown while creating the `URL`. - func asURL() throws -> URL -} - -extension String: URLConvertible { - /// Returns a `URL` if `self` can be used to initialize a `URL` instance, otherwise throws. - /// - /// - Returns: The `URL` initialized with `self`. - /// - Throws: An `AFError.invalidURL` instance. - public func asURL() throws -> URL { - guard let url = URL(string: self) else { throw AFError.invalidURL(url: self) } - - return url - } -} - -extension URL: URLConvertible { - /// Returns `self`. - public func asURL() throws -> URL { self } -} - -extension URLComponents: URLConvertible { - /// Returns a `URL` if the `self`'s `url` is not nil, otherwise throws. - /// - /// - Returns: The `URL` from the `url` property. - /// - Throws: An `AFError.invalidURL` instance. - public func asURL() throws -> URL { - guard let url = url else { throw AFError.invalidURL(url: self) } - - return url - } -} - -// MARK: - - -/// Types adopting the `URLRequestConvertible` protocol can be used to safely construct `URLRequest`s. -public protocol URLRequestConvertible { - /// Returns a `URLRequest` or throws if an `Error` was encountered. - /// - /// - Returns: A `URLRequest`. - /// - Throws: Any error thrown while constructing the `URLRequest`. - func asURLRequest() throws -> URLRequest -} - -extension URLRequestConvertible { - /// The `URLRequest` returned by discarding any `Error` encountered. - public var urlRequest: URLRequest? { try? asURLRequest() } -} - -extension URLRequest: URLRequestConvertible { - /// Returns `self`. - public func asURLRequest() throws -> URLRequest { self } -} - -// MARK: - - -extension URLRequest { - /// Creates an instance with the specified `url`, `method`, and `headers`. - /// - /// - Parameters: - /// - url: The `URLConvertible` value. - /// - method: The `HTTPMethod`. - /// - headers: The `HTTPHeaders`, `nil` by default. - /// - Throws: Any error thrown while converting the `URLConvertible` to a `URL`. - public init(url: URLConvertible, method: HTTPMethod, headers: HTTPHeaders? = nil) throws { - let url = try url.asURL() - - self.init(url: url) - - httpMethod = method.rawValue - allHTTPHeaderFields = headers?.dictionary - } -} diff --git a/Pods/Alamofire/Source/URLEncodedFormEncoder.swift b/Pods/Alamofire/Source/URLEncodedFormEncoder.swift deleted file mode 100644 index e5cc0c50f..000000000 --- a/Pods/Alamofire/Source/URLEncodedFormEncoder.swift +++ /dev/null @@ -1,976 +0,0 @@ -// -// URLEncodedFormEncoder.swift -// -// Copyright (c) 2019 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -/// An object that encodes instances into URL-encoded query strings. -/// -/// There is no published specification for how to encode collection types. By default, the convention of appending -/// `[]` to the key for array values (`foo[]=1&foo[]=2`), and appending the key surrounded by square brackets for -/// nested dictionary values (`foo[bar]=baz`) is used. Optionally, `ArrayEncoding` can be used to omit the -/// square brackets appended to array keys. -/// -/// `BoolEncoding` can be used to configure how `Bool` values are encoded. The default behavior is to encode -/// `true` as 1 and `false` as 0. -/// -/// `DateEncoding` can be used to configure how `Date` values are encoded. By default, the `.deferredToDate` -/// strategy is used, which formats dates from their structure. -/// -/// `SpaceEncoding` can be used to configure how spaces are encoded. Modern encodings use percent replacement (`%20`), -/// while older encodings may expect spaces to be replaced with `+`. -/// -/// This type is largely based on Vapor's [`url-encoded-form`](https://github.com/vapor/url-encoded-form) project. -public final class URLEncodedFormEncoder { - /// Encoding to use for `Array` values. - public enum ArrayEncoding { - /// An empty set of square brackets ("[]") are appended to the key for every value. This is the default encoding. - case brackets - /// No brackets are appended to the key and the key is encoded as is. - case noBrackets - - /// Encodes the key according to the encoding. - /// - /// - Parameter key: The `key` to encode. - /// - Returns: The encoded key. - func encode(_ key: String) -> String { - switch self { - case .brackets: return "\(key)[]" - case .noBrackets: return key - } - } - } - - /// Encoding to use for `Bool` values. - public enum BoolEncoding { - /// Encodes `true` as `1`, `false` as `0`. - case numeric - /// Encodes `true` as "true", `false` as "false". This is the default encoding. - case literal - - /// Encodes the given `Bool` as a `String`. - /// - /// - Parameter value: The `Bool` to encode. - /// - /// - Returns: The encoded `String`. - func encode(_ value: Bool) -> String { - switch self { - case .numeric: return value ? "1" : "0" - case .literal: return value ? "true" : "false" - } - } - } - - /// Encoding to use for `Data` values. - public enum DataEncoding { - /// Defers encoding to the `Data` type. - case deferredToData - /// Encodes `Data` as a Base64-encoded string. This is the default encoding. - case base64 - /// Encode the `Data` as a custom value encoded by the given closure. - case custom((Data) throws -> String) - - /// Encodes `Data` according to the encoding. - /// - /// - Parameter data: The `Data` to encode. - /// - /// - Returns: The encoded `String`, or `nil` if the `Data` should be encoded according to its - /// `Encodable` implementation. - func encode(_ data: Data) throws -> String? { - switch self { - case .deferredToData: return nil - case .base64: return data.base64EncodedString() - case let .custom(encoding): return try encoding(data) - } - } - } - - /// Encoding to use for `Date` values. - public enum DateEncoding { - /// ISO8601 and RFC3339 formatter. - private static let iso8601Formatter: ISO8601DateFormatter = { - let formatter = ISO8601DateFormatter() - formatter.formatOptions = .withInternetDateTime - return formatter - }() - - /// Defers encoding to the `Date` type. This is the default encoding. - case deferredToDate - /// Encodes `Date`s as seconds since midnight UTC on January 1, 1970. - case secondsSince1970 - /// Encodes `Date`s as milliseconds since midnight UTC on January 1, 1970. - case millisecondsSince1970 - /// Encodes `Date`s according to the ISO8601 and RFC3339 standards. - case iso8601 - /// Encodes `Date`s using the given `DateFormatter`. - case formatted(DateFormatter) - /// Encodes `Date`s using the given closure. - case custom((Date) throws -> String) - - /// Encodes the date according to the encoding. - /// - /// - Parameter date: The `Date` to encode. - /// - /// - Returns: The encoded `String`, or `nil` if the `Date` should be encoded according to its - /// `Encodable` implementation. - func encode(_ date: Date) throws -> String? { - switch self { - case .deferredToDate: - return nil - case .secondsSince1970: - return String(date.timeIntervalSince1970) - case .millisecondsSince1970: - return String(date.timeIntervalSince1970 * 1000.0) - case .iso8601: - return DateEncoding.iso8601Formatter.string(from: date) - case let .formatted(formatter): - return formatter.string(from: date) - case let .custom(closure): - return try closure(date) - } - } - } - - /// Encoding to use for keys. - /// - /// This type is derived from [`JSONEncoder`'s `KeyEncodingStrategy`](https://github.com/apple/swift/blob/6aa313b8dd5f05135f7f878eccc1db6f9fbe34ff/stdlib/public/Darwin/Foundation/JSONEncoder.swift#L128) - /// and [`XMLEncoder`s `KeyEncodingStrategy`](https://github.com/MaxDesiatov/XMLCoder/blob/master/Sources/XMLCoder/Encoder/XMLEncoder.swift#L102). - public enum KeyEncoding { - /// Use the keys specified by each type. This is the default encoding. - case useDefaultKeys - /// Convert from "camelCaseKeys" to "snake_case_keys" before writing a key. - /// - /// Capital characters are determined by testing membership in - /// `CharacterSet.uppercaseLetters` and `CharacterSet.lowercaseLetters` - /// (Unicode General Categories Lu and Lt). - /// The conversion to lower case uses `Locale.system`, also known as - /// the ICU "root" locale. This means the result is consistent - /// regardless of the current user's locale and language preferences. - /// - /// Converting from camel case to snake case: - /// 1. Splits words at the boundary of lower-case to upper-case - /// 2. Inserts `_` between words - /// 3. Lowercases the entire string - /// 4. Preserves starting and ending `_`. - /// - /// For example, `oneTwoThree` becomes `one_two_three`. `_oneTwoThree_` becomes `_one_two_three_`. - /// - /// - Note: Using a key encoding strategy has a nominal performance cost, as each string key has to be converted. - case convertToSnakeCase - /// Same as convertToSnakeCase, but using `-` instead of `_`. - /// For example `oneTwoThree` becomes `one-two-three`. - case convertToKebabCase - /// Capitalize the first letter only. - /// For example `oneTwoThree` becomes `OneTwoThree`. - case capitalized - /// Uppercase all letters. - /// For example `oneTwoThree` becomes `ONETWOTHREE`. - case uppercased - /// Lowercase all letters. - /// For example `oneTwoThree` becomes `onetwothree`. - case lowercased - /// A custom encoding using the provided closure. - case custom((String) -> String) - - func encode(_ key: String) -> String { - switch self { - case .useDefaultKeys: return key - case .convertToSnakeCase: return convertToSnakeCase(key) - case .convertToKebabCase: return convertToKebabCase(key) - case .capitalized: return String(key.prefix(1).uppercased() + key.dropFirst()) - case .uppercased: return key.uppercased() - case .lowercased: return key.lowercased() - case let .custom(encoding): return encoding(key) - } - } - - private func convertToSnakeCase(_ key: String) -> String { - convert(key, usingSeparator: "_") - } - - private func convertToKebabCase(_ key: String) -> String { - convert(key, usingSeparator: "-") - } - - private func convert(_ key: String, usingSeparator separator: String) -> String { - guard !key.isEmpty else { return key } - - var words: [Range] = [] - // The general idea of this algorithm is to split words on - // transition from lower to upper case, then on transition of >1 - // upper case characters to lowercase - // - // myProperty -> my_property - // myURLProperty -> my_url_property - // - // It is assumed, per Swift naming conventions, that the first character of the key is lowercase. - var wordStart = key.startIndex - var searchRange = key.index(after: wordStart)..1 capital letters. Turn those into a word, stopping at the capital before the lower case character. - let beforeLowerIndex = key.index(before: lowerCaseRange.lowerBound) - words.append(upperCaseRange.lowerBound.. String { - switch self { - case .percentEscaped: return string.replacingOccurrences(of: " ", with: "%20") - case .plusReplaced: return string.replacingOccurrences(of: " ", with: "+") - } - } - } - - /// `URLEncodedFormEncoder` error. - public enum Error: Swift.Error { - /// An invalid root object was created by the encoder. Only keyed values are valid. - case invalidRootObject(String) - - var localizedDescription: String { - switch self { - case let .invalidRootObject(object): - return "URLEncodedFormEncoder requires keyed root object. Received \(object) instead." - } - } - } - - /// Whether or not to sort the encoded key value pairs. - /// - /// - Note: This setting ensures a consistent ordering for all encodings of the same parameters. When set to `false`, - /// encoded `Dictionary` values may have a different encoded order each time they're encoded due to - /// ` Dictionary`'s random storage order, but `Encodable` types will maintain their encoded order. - public let alphabetizeKeyValuePairs: Bool - /// The `ArrayEncoding` to use. - public let arrayEncoding: ArrayEncoding - /// The `BoolEncoding` to use. - public let boolEncoding: BoolEncoding - /// THe `DataEncoding` to use. - public let dataEncoding: DataEncoding - /// The `DateEncoding` to use. - public let dateEncoding: DateEncoding - /// The `KeyEncoding` to use. - public let keyEncoding: KeyEncoding - /// The `SpaceEncoding` to use. - public let spaceEncoding: SpaceEncoding - /// The `CharacterSet` of allowed (non-escaped) characters. - public var allowedCharacters: CharacterSet - - /// Creates an instance from the supplied parameters. - /// - /// - Parameters: - /// - alphabetizeKeyValuePairs: Whether or not to sort the encoded key value pairs. `true` by default. - /// - arrayEncoding: The `ArrayEncoding` to use. `.brackets` by default. - /// - boolEncoding: The `BoolEncoding` to use. `.numeric` by default. - /// - dataEncoding: The `DataEncoding` to use. `.base64` by default. - /// - dateEncoding: The `DateEncoding` to use. `.deferredToDate` by default. - /// - keyEncoding: The `KeyEncoding` to use. `.useDefaultKeys` by default. - /// - spaceEncoding: The `SpaceEncoding` to use. `.percentEscaped` by default. - /// - allowedCharacters: The `CharacterSet` of allowed (non-escaped) characters. `.afURLQueryAllowed` by - /// default. - public init(alphabetizeKeyValuePairs: Bool = true, - arrayEncoding: ArrayEncoding = .brackets, - boolEncoding: BoolEncoding = .numeric, - dataEncoding: DataEncoding = .base64, - dateEncoding: DateEncoding = .deferredToDate, - keyEncoding: KeyEncoding = .useDefaultKeys, - spaceEncoding: SpaceEncoding = .percentEscaped, - allowedCharacters: CharacterSet = .afURLQueryAllowed) { - self.alphabetizeKeyValuePairs = alphabetizeKeyValuePairs - self.arrayEncoding = arrayEncoding - self.boolEncoding = boolEncoding - self.dataEncoding = dataEncoding - self.dateEncoding = dateEncoding - self.keyEncoding = keyEncoding - self.spaceEncoding = spaceEncoding - self.allowedCharacters = allowedCharacters - } - - func encode(_ value: Encodable) throws -> URLEncodedFormComponent { - let context = URLEncodedFormContext(.object([])) - let encoder = _URLEncodedFormEncoder(context: context, - boolEncoding: boolEncoding, - dataEncoding: dataEncoding, - dateEncoding: dateEncoding) - try value.encode(to: encoder) - - return context.component - } - - /// Encodes the `value` as a URL form encoded `String`. - /// - /// - Parameter value: The `Encodable` value.` - /// - /// - Returns: The encoded `String`. - /// - Throws: An `Error` or `EncodingError` instance if encoding fails. - public func encode(_ value: Encodable) throws -> String { - let component: URLEncodedFormComponent = try encode(value) - - guard case let .object(object) = component else { - throw Error.invalidRootObject("\(component)") - } - - let serializer = URLEncodedFormSerializer(alphabetizeKeyValuePairs: alphabetizeKeyValuePairs, - arrayEncoding: arrayEncoding, - keyEncoding: keyEncoding, - spaceEncoding: spaceEncoding, - allowedCharacters: allowedCharacters) - let query = serializer.serialize(object) - - return query - } - - /// Encodes the value as `Data`. This is performed by first creating an encoded `String` and then returning the - /// `.utf8` data. - /// - /// - Parameter value: The `Encodable` value. - /// - /// - Returns: The encoded `Data`. - /// - /// - Throws: An `Error` or `EncodingError` instance if encoding fails. - public func encode(_ value: Encodable) throws -> Data { - let string: String = try encode(value) - - return Data(string.utf8) - } -} - -final class _URLEncodedFormEncoder { - var codingPath: [CodingKey] - // Returns an empty dictionary, as this encoder doesn't support userInfo. - var userInfo: [CodingUserInfoKey: Any] { [:] } - - let context: URLEncodedFormContext - - private let boolEncoding: URLEncodedFormEncoder.BoolEncoding - private let dataEncoding: URLEncodedFormEncoder.DataEncoding - private let dateEncoding: URLEncodedFormEncoder.DateEncoding - - init(context: URLEncodedFormContext, - codingPath: [CodingKey] = [], - boolEncoding: URLEncodedFormEncoder.BoolEncoding, - dataEncoding: URLEncodedFormEncoder.DataEncoding, - dateEncoding: URLEncodedFormEncoder.DateEncoding) { - self.context = context - self.codingPath = codingPath - self.boolEncoding = boolEncoding - self.dataEncoding = dataEncoding - self.dateEncoding = dateEncoding - } -} - -extension _URLEncodedFormEncoder: Encoder { - func container(keyedBy type: Key.Type) -> KeyedEncodingContainer where Key: CodingKey { - let container = _URLEncodedFormEncoder.KeyedContainer(context: context, - codingPath: codingPath, - boolEncoding: boolEncoding, - dataEncoding: dataEncoding, - dateEncoding: dateEncoding) - return KeyedEncodingContainer(container) - } - - func unkeyedContainer() -> UnkeyedEncodingContainer { - _URLEncodedFormEncoder.UnkeyedContainer(context: context, - codingPath: codingPath, - boolEncoding: boolEncoding, - dataEncoding: dataEncoding, - dateEncoding: dateEncoding) - } - - func singleValueContainer() -> SingleValueEncodingContainer { - _URLEncodedFormEncoder.SingleValueContainer(context: context, - codingPath: codingPath, - boolEncoding: boolEncoding, - dataEncoding: dataEncoding, - dateEncoding: dateEncoding) - } -} - -final class URLEncodedFormContext { - var component: URLEncodedFormComponent - - init(_ component: URLEncodedFormComponent) { - self.component = component - } -} - -enum URLEncodedFormComponent { - typealias Object = [(key: String, value: URLEncodedFormComponent)] - - case string(String) - case array([URLEncodedFormComponent]) - case object(Object) - - /// Converts self to an `[URLEncodedFormData]` or returns `nil` if not convertible. - var array: [URLEncodedFormComponent]? { - switch self { - case let .array(array): return array - default: return nil - } - } - - /// Converts self to an `Object` or returns `nil` if not convertible. - var object: Object? { - switch self { - case let .object(object): return object - default: return nil - } - } - - /// Sets self to the supplied value at a given path. - /// - /// data.set(to: "hello", at: ["path", "to", "value"]) - /// - /// - parameters: - /// - value: Value of `Self` to set at the supplied path. - /// - path: `CodingKey` path to update with the supplied value. - public mutating func set(to value: URLEncodedFormComponent, at path: [CodingKey]) { - set(&self, to: value, at: path) - } - - /// Recursive backing method to `set(to:at:)`. - private func set(_ context: inout URLEncodedFormComponent, to value: URLEncodedFormComponent, at path: [CodingKey]) { - guard path.count >= 1 else { - context = value - return - } - - let end = path[0] - var child: URLEncodedFormComponent - switch path.count { - case 1: - child = value - case 2...: - if let index = end.intValue { - let array = context.array ?? [] - if array.count > index { - child = array[index] - } else { - child = .array([]) - } - set(&child, to: value, at: Array(path[1...])) - } else { - child = context.object?.first { $0.key == end.stringValue }?.value ?? .object(.init()) - set(&child, to: value, at: Array(path[1...])) - } - default: fatalError("Unreachable") - } - - if let index = end.intValue { - if var array = context.array { - if array.count > index { - array[index] = child - } else { - array.append(child) - } - context = .array(array) - } else { - context = .array([child]) - } - } else { - if var object = context.object { - if let index = object.firstIndex(where: { $0.key == end.stringValue }) { - object[index] = (key: end.stringValue, value: child) - } else { - object.append((key: end.stringValue, value: child)) - } - context = .object(object) - } else { - context = .object([(key: end.stringValue, value: child)]) - } - } - } -} - -struct AnyCodingKey: CodingKey, Hashable { - let stringValue: String - let intValue: Int? - - init?(stringValue: String) { - self.stringValue = stringValue - intValue = nil - } - - init?(intValue: Int) { - stringValue = "\(intValue)" - self.intValue = intValue - } - - init(_ base: Key) where Key: CodingKey { - if let intValue = base.intValue { - self.init(intValue: intValue)! - } else { - self.init(stringValue: base.stringValue)! - } - } -} - -extension _URLEncodedFormEncoder { - final class KeyedContainer where Key: CodingKey { - var codingPath: [CodingKey] - - private let context: URLEncodedFormContext - private let boolEncoding: URLEncodedFormEncoder.BoolEncoding - private let dataEncoding: URLEncodedFormEncoder.DataEncoding - private let dateEncoding: URLEncodedFormEncoder.DateEncoding - - init(context: URLEncodedFormContext, - codingPath: [CodingKey], - boolEncoding: URLEncodedFormEncoder.BoolEncoding, - dataEncoding: URLEncodedFormEncoder.DataEncoding, - dateEncoding: URLEncodedFormEncoder.DateEncoding) { - self.context = context - self.codingPath = codingPath - self.boolEncoding = boolEncoding - self.dataEncoding = dataEncoding - self.dateEncoding = dateEncoding - } - - private func nestedCodingPath(for key: CodingKey) -> [CodingKey] { - codingPath + [key] - } - } -} - -extension _URLEncodedFormEncoder.KeyedContainer: KeyedEncodingContainerProtocol { - func encodeNil(forKey key: Key) throws { - let context = EncodingError.Context(codingPath: codingPath, - debugDescription: "URLEncodedFormEncoder cannot encode nil values.") - throw EncodingError.invalidValue("\(key): nil", context) - } - - func encode(_ value: T, forKey key: Key) throws where T: Encodable { - var container = nestedSingleValueEncoder(for: key) - try container.encode(value) - } - - func nestedSingleValueEncoder(for key: Key) -> SingleValueEncodingContainer { - let container = _URLEncodedFormEncoder.SingleValueContainer(context: context, - codingPath: nestedCodingPath(for: key), - boolEncoding: boolEncoding, - dataEncoding: dataEncoding, - dateEncoding: dateEncoding) - - return container - } - - func nestedUnkeyedContainer(forKey key: Key) -> UnkeyedEncodingContainer { - let container = _URLEncodedFormEncoder.UnkeyedContainer(context: context, - codingPath: nestedCodingPath(for: key), - boolEncoding: boolEncoding, - dataEncoding: dataEncoding, - dateEncoding: dateEncoding) - - return container - } - - func nestedContainer(keyedBy keyType: NestedKey.Type, forKey key: Key) -> KeyedEncodingContainer where NestedKey: CodingKey { - let container = _URLEncodedFormEncoder.KeyedContainer(context: context, - codingPath: nestedCodingPath(for: key), - boolEncoding: boolEncoding, - dataEncoding: dataEncoding, - dateEncoding: dateEncoding) - - return KeyedEncodingContainer(container) - } - - func superEncoder() -> Encoder { - _URLEncodedFormEncoder(context: context, - codingPath: codingPath, - boolEncoding: boolEncoding, - dataEncoding: dataEncoding, - dateEncoding: dateEncoding) - } - - func superEncoder(forKey key: Key) -> Encoder { - _URLEncodedFormEncoder(context: context, - codingPath: nestedCodingPath(for: key), - boolEncoding: boolEncoding, - dataEncoding: dataEncoding, - dateEncoding: dateEncoding) - } -} - -extension _URLEncodedFormEncoder { - final class SingleValueContainer { - var codingPath: [CodingKey] - - private var canEncodeNewValue = true - - private let context: URLEncodedFormContext - private let boolEncoding: URLEncodedFormEncoder.BoolEncoding - private let dataEncoding: URLEncodedFormEncoder.DataEncoding - private let dateEncoding: URLEncodedFormEncoder.DateEncoding - - init(context: URLEncodedFormContext, - codingPath: [CodingKey], - boolEncoding: URLEncodedFormEncoder.BoolEncoding, - dataEncoding: URLEncodedFormEncoder.DataEncoding, - dateEncoding: URLEncodedFormEncoder.DateEncoding) { - self.context = context - self.codingPath = codingPath - self.boolEncoding = boolEncoding - self.dataEncoding = dataEncoding - self.dateEncoding = dateEncoding - } - - private func checkCanEncode(value: Any?) throws { - guard canEncodeNewValue else { - let context = EncodingError.Context(codingPath: codingPath, - debugDescription: "Attempt to encode value through single value container when previously value already encoded.") - throw EncodingError.invalidValue(value as Any, context) - } - } - } -} - -extension _URLEncodedFormEncoder.SingleValueContainer: SingleValueEncodingContainer { - func encodeNil() throws { - try checkCanEncode(value: nil) - defer { canEncodeNewValue = false } - - let context = EncodingError.Context(codingPath: codingPath, - debugDescription: "URLEncodedFormEncoder cannot encode nil values.") - throw EncodingError.invalidValue("nil", context) - } - - func encode(_ value: Bool) throws { - try encode(value, as: String(boolEncoding.encode(value))) - } - - func encode(_ value: String) throws { - try encode(value, as: value) - } - - func encode(_ value: Double) throws { - try encode(value, as: String(value)) - } - - func encode(_ value: Float) throws { - try encode(value, as: String(value)) - } - - func encode(_ value: Int) throws { - try encode(value, as: String(value)) - } - - func encode(_ value: Int8) throws { - try encode(value, as: String(value)) - } - - func encode(_ value: Int16) throws { - try encode(value, as: String(value)) - } - - func encode(_ value: Int32) throws { - try encode(value, as: String(value)) - } - - func encode(_ value: Int64) throws { - try encode(value, as: String(value)) - } - - func encode(_ value: UInt) throws { - try encode(value, as: String(value)) - } - - func encode(_ value: UInt8) throws { - try encode(value, as: String(value)) - } - - func encode(_ value: UInt16) throws { - try encode(value, as: String(value)) - } - - func encode(_ value: UInt32) throws { - try encode(value, as: String(value)) - } - - func encode(_ value: UInt64) throws { - try encode(value, as: String(value)) - } - - private func encode(_ value: T, as string: String) throws where T: Encodable { - try checkCanEncode(value: value) - defer { canEncodeNewValue = false } - - context.component.set(to: .string(string), at: codingPath) - } - - func encode(_ value: T) throws where T: Encodable { - switch value { - case let date as Date: - guard let string = try dateEncoding.encode(date) else { - try attemptToEncode(value) - return - } - - try encode(value, as: string) - case let data as Data: - guard let string = try dataEncoding.encode(data) else { - try attemptToEncode(value) - return - } - - try encode(value, as: string) - case let decimal as Decimal: - // Decimal's `Encodable` implementation returns an object, not a single value, so override it. - try encode(value, as: String(describing: decimal)) - default: - try attemptToEncode(value) - } - } - - private func attemptToEncode(_ value: T) throws where T: Encodable { - try checkCanEncode(value: value) - defer { canEncodeNewValue = false } - - let encoder = _URLEncodedFormEncoder(context: context, - codingPath: codingPath, - boolEncoding: boolEncoding, - dataEncoding: dataEncoding, - dateEncoding: dateEncoding) - try value.encode(to: encoder) - } -} - -extension _URLEncodedFormEncoder { - final class UnkeyedContainer { - var codingPath: [CodingKey] - - var count = 0 - var nestedCodingPath: [CodingKey] { - codingPath + [AnyCodingKey(intValue: count)!] - } - - private let context: URLEncodedFormContext - private let boolEncoding: URLEncodedFormEncoder.BoolEncoding - private let dataEncoding: URLEncodedFormEncoder.DataEncoding - private let dateEncoding: URLEncodedFormEncoder.DateEncoding - - init(context: URLEncodedFormContext, - codingPath: [CodingKey], - boolEncoding: URLEncodedFormEncoder.BoolEncoding, - dataEncoding: URLEncodedFormEncoder.DataEncoding, - dateEncoding: URLEncodedFormEncoder.DateEncoding) { - self.context = context - self.codingPath = codingPath - self.boolEncoding = boolEncoding - self.dataEncoding = dataEncoding - self.dateEncoding = dateEncoding - } - } -} - -extension _URLEncodedFormEncoder.UnkeyedContainer: UnkeyedEncodingContainer { - func encodeNil() throws { - let context = EncodingError.Context(codingPath: codingPath, - debugDescription: "URLEncodedFormEncoder cannot encode nil values.") - throw EncodingError.invalidValue("nil", context) - } - - func encode(_ value: T) throws where T: Encodable { - var container = nestedSingleValueContainer() - try container.encode(value) - } - - func nestedSingleValueContainer() -> SingleValueEncodingContainer { - defer { count += 1 } - - return _URLEncodedFormEncoder.SingleValueContainer(context: context, - codingPath: nestedCodingPath, - boolEncoding: boolEncoding, - dataEncoding: dataEncoding, - dateEncoding: dateEncoding) - } - - func nestedContainer(keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer where NestedKey: CodingKey { - defer { count += 1 } - let container = _URLEncodedFormEncoder.KeyedContainer(context: context, - codingPath: nestedCodingPath, - boolEncoding: boolEncoding, - dataEncoding: dataEncoding, - dateEncoding: dateEncoding) - - return KeyedEncodingContainer(container) - } - - func nestedUnkeyedContainer() -> UnkeyedEncodingContainer { - defer { count += 1 } - - return _URLEncodedFormEncoder.UnkeyedContainer(context: context, - codingPath: nestedCodingPath, - boolEncoding: boolEncoding, - dataEncoding: dataEncoding, - dateEncoding: dateEncoding) - } - - func superEncoder() -> Encoder { - defer { count += 1 } - - return _URLEncodedFormEncoder(context: context, - codingPath: codingPath, - boolEncoding: boolEncoding, - dataEncoding: dataEncoding, - dateEncoding: dateEncoding) - } -} - -final class URLEncodedFormSerializer { - private let alphabetizeKeyValuePairs: Bool - private let arrayEncoding: URLEncodedFormEncoder.ArrayEncoding - private let keyEncoding: URLEncodedFormEncoder.KeyEncoding - private let spaceEncoding: URLEncodedFormEncoder.SpaceEncoding - private let allowedCharacters: CharacterSet - - init(alphabetizeKeyValuePairs: Bool, - arrayEncoding: URLEncodedFormEncoder.ArrayEncoding, - keyEncoding: URLEncodedFormEncoder.KeyEncoding, - spaceEncoding: URLEncodedFormEncoder.SpaceEncoding, - allowedCharacters: CharacterSet) { - self.alphabetizeKeyValuePairs = alphabetizeKeyValuePairs - self.arrayEncoding = arrayEncoding - self.keyEncoding = keyEncoding - self.spaceEncoding = spaceEncoding - self.allowedCharacters = allowedCharacters - } - - func serialize(_ object: URLEncodedFormComponent.Object) -> String { - var output: [String] = [] - for (key, component) in object { - let value = serialize(component, forKey: key) - output.append(value) - } - output = alphabetizeKeyValuePairs ? output.sorted() : output - - return output.joinedWithAmpersands() - } - - func serialize(_ component: URLEncodedFormComponent, forKey key: String) -> String { - switch component { - case let .string(string): return "\(escape(keyEncoding.encode(key)))=\(escape(string))" - case let .array(array): return serialize(array, forKey: key) - case let .object(object): return serialize(object, forKey: key) - } - } - - func serialize(_ object: URLEncodedFormComponent.Object, forKey key: String) -> String { - var segments: [String] = object.map { subKey, value in - let keyPath = "[\(subKey)]" - return serialize(value, forKey: key + keyPath) - } - segments = alphabetizeKeyValuePairs ? segments.sorted() : segments - - return segments.joinedWithAmpersands() - } - - func serialize(_ array: [URLEncodedFormComponent], forKey key: String) -> String { - var segments: [String] = array.map { component in - let keyPath = arrayEncoding.encode(key) - return serialize(component, forKey: keyPath) - } - segments = alphabetizeKeyValuePairs ? segments.sorted() : segments - - return segments.joinedWithAmpersands() - } - - func escape(_ query: String) -> String { - var allowedCharactersWithSpace = allowedCharacters - allowedCharactersWithSpace.insert(charactersIn: " ") - let escapedQuery = query.addingPercentEncoding(withAllowedCharacters: allowedCharactersWithSpace) ?? query - let spaceEncodedQuery = spaceEncoding.encode(escapedQuery) - - return spaceEncodedQuery - } -} - -extension Array where Element == String { - func joinedWithAmpersands() -> String { - joined(separator: "&") - } -} - -extension CharacterSet { - /// Creates a CharacterSet from RFC 3986 allowed characters. - /// - /// RFC 3986 states that the following characters are "reserved" characters. - /// - /// - General Delimiters: ":", "#", "[", "]", "@", "?", "/" - /// - Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "=" - /// - /// In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow - /// query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/" - /// should be percent-escaped in the query string. - public static let afURLQueryAllowed: CharacterSet = { - let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4 - let subDelimitersToEncode = "!$&'()*+,;=" - let encodableDelimiters = CharacterSet(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)") - - return CharacterSet.urlQueryAllowed.subtracting(encodableDelimiters) - }() -} diff --git a/Pods/Alamofire/Source/URLRequest+Alamofire.swift b/Pods/Alamofire/Source/URLRequest+Alamofire.swift deleted file mode 100644 index be27c8ed0..000000000 --- a/Pods/Alamofire/Source/URLRequest+Alamofire.swift +++ /dev/null @@ -1,39 +0,0 @@ -// -// URLRequest+Alamofire.swift -// -// Copyright (c) 2019 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -extension URLRequest { - /// Returns the `httpMethod` as Alamofire's `HTTPMethod` type. - public var method: HTTPMethod? { - get { httpMethod.flatMap(HTTPMethod.init) } - set { httpMethod = newValue?.rawValue } - } - - public func validate() throws { - if method == .get, let bodyData = httpBody { - throw AFError.urlRequestValidationFailed(reason: .bodyDataInGETRequest(bodyData)) - } - } -} diff --git a/Pods/Alamofire/Source/URLSessionConfiguration+Alamofire.swift b/Pods/Alamofire/Source/URLSessionConfiguration+Alamofire.swift deleted file mode 100644 index de3e290a3..000000000 --- a/Pods/Alamofire/Source/URLSessionConfiguration+Alamofire.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// URLSessionConfiguration+Alamofire.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -extension URLSessionConfiguration: AlamofireExtended {} -extension AlamofireExtension where ExtendedType: URLSessionConfiguration { - /// Alamofire's default configuration. Same as `URLSessionConfiguration.default` but adds Alamofire default - /// `Accept-Language`, `Accept-Encoding`, and `User-Agent` headers. - public static var `default`: URLSessionConfiguration { - let configuration = URLSessionConfiguration.default - configuration.headers = .default - - return configuration - } -} diff --git a/Pods/Alamofire/Source/Validation.swift b/Pods/Alamofire/Source/Validation.swift deleted file mode 100644 index bd2a27953..000000000 --- a/Pods/Alamofire/Source/Validation.swift +++ /dev/null @@ -1,302 +0,0 @@ -// -// Validation.swift -// -// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -import Foundation - -extension Request { - // MARK: Helper Types - - fileprivate typealias ErrorReason = AFError.ResponseValidationFailureReason - - /// Used to represent whether a validation succeeded or failed. - public typealias ValidationResult = Result - - fileprivate struct MIMEType { - let type: String - let subtype: String - - var isWildcard: Bool { type == "*" && subtype == "*" } - - init?(_ string: String) { - let components: [String] = { - let stripped = string.trimmingCharacters(in: .whitespacesAndNewlines) - let split = stripped[..<(stripped.range(of: ";")?.lowerBound ?? stripped.endIndex)] - - return split.components(separatedBy: "/") - }() - - if let type = components.first, let subtype = components.last { - self.type = type - self.subtype = subtype - } else { - return nil - } - } - - func matches(_ mime: MIMEType) -> Bool { - switch (type, subtype) { - case (mime.type, mime.subtype), (mime.type, "*"), ("*", mime.subtype), ("*", "*"): - return true - default: - return false - } - } - } - - // MARK: Properties - - fileprivate var acceptableStatusCodes: Range { 200..<300 } - - fileprivate var acceptableContentTypes: [String] { - if let accept = request?.value(forHTTPHeaderField: "Accept") { - return accept.components(separatedBy: ",") - } - - return ["*/*"] - } - - // MARK: Status Code - - fileprivate func validate(statusCode acceptableStatusCodes: S, - response: HTTPURLResponse) - -> ValidationResult - where S.Iterator.Element == Int { - if acceptableStatusCodes.contains(response.statusCode) { - return .success(()) - } else { - let reason: ErrorReason = .unacceptableStatusCode(code: response.statusCode) - return .failure(AFError.responseValidationFailed(reason: reason)) - } - } - - // MARK: Content Type - - fileprivate func validate(contentType acceptableContentTypes: S, - response: HTTPURLResponse, - data: Data?) - -> ValidationResult - where S.Iterator.Element == String { - guard let data = data, !data.isEmpty else { return .success(()) } - - return validate(contentType: acceptableContentTypes, response: response) - } - - fileprivate func validate(contentType acceptableContentTypes: S, - response: HTTPURLResponse) - -> ValidationResult - where S.Iterator.Element == String { - guard - let responseContentType = response.mimeType, - let responseMIMEType = MIMEType(responseContentType) - else { - for contentType in acceptableContentTypes { - if let mimeType = MIMEType(contentType), mimeType.isWildcard { - return .success(()) - } - } - - let error: AFError = { - let reason: ErrorReason = .missingContentType(acceptableContentTypes: Array(acceptableContentTypes)) - return AFError.responseValidationFailed(reason: reason) - }() - - return .failure(error) - } - - for contentType in acceptableContentTypes { - if let acceptableMIMEType = MIMEType(contentType), acceptableMIMEType.matches(responseMIMEType) { - return .success(()) - } - } - - let error: AFError = { - let reason: ErrorReason = .unacceptableContentType(acceptableContentTypes: Array(acceptableContentTypes), - responseContentType: responseContentType) - - return AFError.responseValidationFailed(reason: reason) - }() - - return .failure(error) - } -} - -// MARK: - - -extension DataRequest { - /// A closure used to validate a request that takes a URL request, a URL response and data, and returns whether the - /// request was valid. - public typealias Validation = (URLRequest?, HTTPURLResponse, Data?) -> ValidationResult - - /// Validates that the response has a status code in the specified sequence. - /// - /// If validation fails, subsequent calls to response handlers will have an associated error. - /// - /// - Parameter statusCode: `Sequence` of acceptable response status codes. - /// - /// - Returns: The instance. - @discardableResult - public func validate(statusCode acceptableStatusCodes: S) -> Self where S.Iterator.Element == Int { - validate { [unowned self] _, response, _ in - self.validate(statusCode: acceptableStatusCodes, response: response) - } - } - - /// Validates that the response has a content type in the specified sequence. - /// - /// If validation fails, subsequent calls to response handlers will have an associated error. - /// - /// - parameter contentType: The acceptable content types, which may specify wildcard types and/or subtypes. - /// - /// - returns: The request. - @discardableResult - public func validate(contentType acceptableContentTypes: @escaping @autoclosure () -> S) -> Self where S.Iterator.Element == String { - validate { [unowned self] _, response, data in - self.validate(contentType: acceptableContentTypes(), response: response, data: data) - } - } - - /// Validates that the response has a status code in the default acceptable range of 200...299, and that the content - /// type matches any specified in the Accept HTTP header field. - /// - /// If validation fails, subsequent calls to response handlers will have an associated error. - /// - /// - returns: The request. - @discardableResult - public func validate() -> Self { - let contentTypes: () -> [String] = { [unowned self] in - self.acceptableContentTypes - } - return validate(statusCode: acceptableStatusCodes).validate(contentType: contentTypes()) - } -} - -extension DataStreamRequest { - /// A closure used to validate a request that takes a `URLRequest` and `HTTPURLResponse` and returns whether the - /// request was valid. - public typealias Validation = (_ request: URLRequest?, _ response: HTTPURLResponse) -> ValidationResult - - /// Validates that the response has a status code in the specified sequence. - /// - /// If validation fails, subsequent calls to response handlers will have an associated error. - /// - /// - Parameter statusCode: `Sequence` of acceptable response status codes. - /// - /// - Returns: The instance. - @discardableResult - public func validate(statusCode acceptableStatusCodes: S) -> Self where S.Iterator.Element == Int { - validate { [unowned self] _, response in - self.validate(statusCode: acceptableStatusCodes, response: response) - } - } - - /// Validates that the response has a content type in the specified sequence. - /// - /// If validation fails, subsequent calls to response handlers will have an associated error. - /// - /// - parameter contentType: The acceptable content types, which may specify wildcard types and/or subtypes. - /// - /// - returns: The request. - @discardableResult - public func validate(contentType acceptableContentTypes: @escaping @autoclosure () -> S) -> Self where S.Iterator.Element == String { - validate { [unowned self] _, response in - self.validate(contentType: acceptableContentTypes(), response: response) - } - } - - /// Validates that the response has a status code in the default acceptable range of 200...299, and that the content - /// type matches any specified in the Accept HTTP header field. - /// - /// If validation fails, subsequent calls to response handlers will have an associated error. - /// - /// - Returns: The instance. - @discardableResult - public func validate() -> Self { - let contentTypes: () -> [String] = { [unowned self] in - self.acceptableContentTypes - } - return validate(statusCode: acceptableStatusCodes).validate(contentType: contentTypes()) - } -} - -// MARK: - - -extension DownloadRequest { - /// A closure used to validate a request that takes a URL request, a URL response, a temporary URL and a - /// destination URL, and returns whether the request was valid. - public typealias Validation = (_ request: URLRequest?, - _ response: HTTPURLResponse, - _ fileURL: URL?) - -> ValidationResult - - /// Validates that the response has a status code in the specified sequence. - /// - /// If validation fails, subsequent calls to response handlers will have an associated error. - /// - /// - Parameter statusCode: `Sequence` of acceptable response status codes. - /// - /// - Returns: The instance. - @discardableResult - public func validate(statusCode acceptableStatusCodes: S) -> Self where S.Iterator.Element == Int { - validate { [unowned self] _, response, _ in - self.validate(statusCode: acceptableStatusCodes, response: response) - } - } - - /// Validates that the response has a content type in the specified sequence. - /// - /// If validation fails, subsequent calls to response handlers will have an associated error. - /// - /// - parameter contentType: The acceptable content types, which may specify wildcard types and/or subtypes. - /// - /// - returns: The request. - @discardableResult - public func validate(contentType acceptableContentTypes: @escaping @autoclosure () -> S) -> Self where S.Iterator.Element == String { - validate { [unowned self] _, response, fileURL in - guard let validFileURL = fileURL else { - return .failure(AFError.responseValidationFailed(reason: .dataFileNil)) - } - - do { - let data = try Data(contentsOf: validFileURL) - return self.validate(contentType: acceptableContentTypes(), response: response, data: data) - } catch { - return .failure(AFError.responseValidationFailed(reason: .dataFileReadFailed(at: validFileURL))) - } - } - } - - /// Validates that the response has a status code in the default acceptable range of 200...299, and that the content - /// type matches any specified in the Accept HTTP header field. - /// - /// If validation fails, subsequent calls to response handlers will have an associated error. - /// - /// - returns: The request. - @discardableResult - public func validate() -> Self { - let contentTypes = { [unowned self] in - self.acceptableContentTypes - } - return validate(statusCode: acceptableStatusCodes).validate(contentType: contentTypes()) - } -} diff --git a/Pods/BRLOptionParser/BRLOptionParser/BRLOptionParser.h b/Pods/BRLOptionParser/BRLOptionParser/BRLOptionParser.h deleted file mode 100644 index 3dbfdbad7..000000000 --- a/Pods/BRLOptionParser/BRLOptionParser/BRLOptionParser.h +++ /dev/null @@ -1,62 +0,0 @@ -// BRLOptionParser.h -// -// Copyright © 2013–2015 Stephen Celis () -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - - -@import Foundation; - - -typedef void (^BRLOptionParserOptionBlock)(); -typedef void (^BRLOptionParserOptionBlockWithArgument)(NSString *value); - - -static NSString *const BRLOptionParserErrorDomain = @"BRLOptionParserErrorDomain"; - - -typedef NS_ENUM(NSUInteger, BRLOptionParserErrorCode) { - BRLOptionParserErrorCodeUnrecognized = 1, - BRLOptionParserErrorCodeRequired -}; - - -@interface BRLOptionParser : NSObject - -+ (instancetype)parser; -+ (instancetype)longOnlyParser; - -@property (nonatomic, getter = isLongOnly) BOOL longOnly; - -@property (nonatomic, copy) NSString *banner; - -- (void)setBanner:(NSString *)banner, ...; - -- (void)addOption:(char *)option flag:(unichar)flag description:(NSString *)description block:(BRLOptionParserOptionBlock)block; -- (void)addOption:(char *)option flag:(unichar)flag description:(NSString *)description blockWithArgument:(BRLOptionParserOptionBlockWithArgument)blockWithArgument; - -- (void)addOption:(char *)option flag:(unichar)flag description:(NSString *)description value:(BOOL *)value; -- (void)addOption:(char *)option flag:(unichar)flag description:(NSString *)description argument:(NSString *__strong *)argument; - -- (void)addSeparator; -- (void)addSeparator:(NSString *)separator; - -- (BOOL)parseArgc:(int)argc argv:(const char **)argv error:(NSError **)error; - -@end diff --git a/Pods/BRLOptionParser/BRLOptionParser/BRLOptionParser.m b/Pods/BRLOptionParser/BRLOptionParser/BRLOptionParser.m deleted file mode 100644 index 066cdf5e8..000000000 --- a/Pods/BRLOptionParser/BRLOptionParser/BRLOptionParser.m +++ /dev/null @@ -1,306 +0,0 @@ -// BRLOptionParser.m -// -// Copyright © 2013–2015 Stephen Celis () -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - - -#import "BRLOptionParser.h" -#import - - -typedef NS_ENUM(NSUInteger, BRLOptionArgument) { - BRLOptionArgumentNone = no_argument, - BRLOptionArgumentRequired = required_argument -}; - - -@interface BRLOption : NSObject - -@property (assign) BRLOptionArgument argument; -@property (assign) char * name; -@property (assign) unichar flag; -@property (strong) NSString *description; -@property (copy) id block; - -+ (instancetype)optionWithName:(char *)name flag:(unichar)flag description:(NSString *)description block:(BRLOptionParserOptionBlock)block; -+ (instancetype)optionWithName:(char *)name flag:(unichar)flag description:(NSString *)description blockWithArgument:(BRLOptionParserOptionBlockWithArgument)blockWithArgument; - -@end - - -@implementation BRLOption - -@synthesize description = _description; - -+ (instancetype)optionWithName:(char *)name flag:(unichar)flag description:(NSString *)description block:(BRLOptionParserOptionBlock)block -{ - BRLOption *option = [[self alloc] initWithName:name flag:flag description:description argument:BRLOptionArgumentNone block:block]; - return option; -} - -+ (instancetype)optionWithName:(char *)name flag:(unichar)flag description:(NSString *)description blockWithArgument:(BRLOptionParserOptionBlockWithArgument)blockWithArgument -{ - BRLOption *option = [[self alloc] initWithName:name flag:flag description:description argument:BRLOptionArgumentRequired block:blockWithArgument]; - return option; -} - -- (instancetype)initWithName:(char *)name flag:(unichar)flag description:(NSString *)description argument:(BRLOptionArgument)argument block:(id)block -{ - if (self = [super init]) { - _argument = argument; - _name = name; - _flag = flag; - _block = block; - _description = description; - } - return self; -} - -@end - - -@interface BRLOptionParser () - -@property NSMutableArray *options; - -@end - - -@implementation BRLOptionParser - -+ (instancetype)parser -{ - return [self new]; -} - -+ (instancetype)longOnlyParser -{ - BRLOptionParser *parser = [self parser]; - if (parser) { - parser.longOnly = YES; - } - return parser; -} - -- (id)init -{ - if (self = [super init]) { - [self setBanner:@"usage: %@ [options]", [NSProcessInfo processInfo].processName]; - _options = [NSMutableArray new]; - } - return self; -} - -- (void)setBanner:(NSString *)banner, ... -{ - va_list args; - va_start(args, banner); - _banner = [[NSString alloc] initWithFormat:banner arguments:args]; - va_end(args); - return; -} - -- (void)addOption:(char *)option flag:(unichar)flag description:(NSString *)description block:(BRLOptionParserOptionBlock)block -{ - [self.options addObject:[BRLOption optionWithName:option flag:flag description:description block:block]]; -} - -- (void)addOption:(char *)option flag:(unichar)flag description:(NSString *)description blockWithArgument:(BRLOptionParserOptionBlockWithArgument)blockWithArgument -{ - [self.options addObject:[BRLOption optionWithName:option flag:flag description:description blockWithArgument:blockWithArgument]]; -} - -- (void)addOption:(char *)option flag:(unichar)flag description:(NSString *)description value:(BOOL *)value -{ - [self addOption:option flag:flag description:description block:^{ - *value = YES; - }]; -} - -- (void)addOption:(char *)option flag:(unichar)flag description:(NSString *)description argument:(NSString *__strong *)argument -{ - [self addOption:option flag:flag description:description blockWithArgument:^(NSString *value) { - *argument = value; - }]; -} - -- (void)addSeparator -{ - [self addSeparator:nil]; -} - -- (void)addSeparator:(NSString *)separator -{ - if (separator == nil) { - separator = @""; - } - [self.options addObject:separator]; -} - -- (BOOL)parseArgc:(int)argc argv:(const char **)argv error:(NSError *__autoreleasing *)error -{ - NSMapTable *mapTable = NSCreateMapTable(NSIntegerMapKeyCallBacks, NSNonRetainedObjectMapValueCallBacks, self.options.count); - - NSUInteger i = 0; - NSUInteger c = 0; - - struct option * long_options = malloc((self.options.count + 1) * sizeof(struct option)); - char * short_options = malloc(((self.options.count * 2) + 1) * sizeof(char)); - - for (id each in self.options) { - if (![each isKindOfClass:[BRLOption class]]) { - continue; - } - BRLOption *option = each; - if (option.name) { - NSMapInsert(mapTable, (const void *)option.name, (__bridge void *)option); - long_options[i++] = (struct option){option.name, option.argument, NULL, option.flag}; - } - if (option.flag) { - NSMapInsert(mapTable, (const void *)(NSUInteger)option.flag, (__bridge void *)option); - short_options[c++] = option.flag; - if (option.argument == BRLOptionArgumentRequired) { - short_options[c++] = ':'; - }; - } - } - long_options[i] = (struct option){0, 0, 0, 0}; - short_options[c] = '\0'; - - int ch = 0; - int long_options_index = 0; - - opterr = 0; - - int (* getopt_long_method)(int, char * const *, const char *, const struct option *, int *); - getopt_long_method = self.isLongOnly ? &getopt_long_only : &getopt_long; - - int cached_optind = optind; - while ((ch = getopt_long_method(argc, (char **)argv, short_options, long_options, &long_options_index)) != -1) { - @try { - BRLOption *option = nil; - - switch (ch) { - case '?': { - if (error) { - // I wish this could be done more cleanly, but getopt doesn't appear to expose the current failing option as originally input. - NSString *arg = [NSString stringWithUTF8String:argv[cached_optind]]; - if ([arg hasPrefix:[self longPrefix]]) { - arg = [arg componentsSeparatedByString:@"="].firstObject; - } else if (optopt) { - arg = [NSString stringWithFormat:@"-%c", optopt]; - } - - if (optopt) { - option = (__bridge BRLOption *)NSMapGet(mapTable, (const void *)(NSUInteger)optopt); - } else { - NSString *longOption = [NSString stringWithFormat:@"%@%s", [self longPrefix], long_options[long_options_index].name]; - if ([arg isEqualToString:longOption]) { - option = (__bridge BRLOption *)NSMapGet(mapTable, (const void *)long_options[long_options_index].name); - } - } - - if (option && option.argument == BRLOptionArgumentRequired) { - *error = [NSError errorWithDomain:BRLOptionParserErrorDomain code:BRLOptionParserErrorCodeRequired userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"option `%@' requires an argument", arg]}]; - } else { - *error = [NSError errorWithDomain:BRLOptionParserErrorDomain code:BRLOptionParserErrorCodeUnrecognized userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"unrecognized option `%@'", arg]}]; - } - } - return NO; - break; - } - case ':': - - break; - case 0: - option = (__bridge BRLOption *)NSMapGet(mapTable, (const void *)long_options[long_options_index].name); - break; - default: { - option = (__bridge BRLOption *)NSMapGet(mapTable, (const void *)(NSUInteger)ch); - break; - } - } - - if (option.argument == BRLOptionArgumentRequired) { - BRLOptionParserOptionBlockWithArgument block = option.block; - block([NSString stringWithUTF8String:optarg]); - } else { - BRLOptionParserOptionBlock block = option.block; - block(); - } - } @finally { - cached_optind = optind; - } - } - - return YES; -} - -- (NSString *)description -{ - NSMutableString *(^trimLine)(NSMutableString *) = ^NSMutableString *(NSMutableString *line) { - NSRange range = [line rangeOfCharacterFromSet:[[NSCharacterSet whitespaceCharacterSet] invertedSet] options:NSBackwardsSearch]; - if (range.location != NSNotFound) { - line = [[line substringToIndex:range.location + 1] mutableCopy]; - } - return line; - }; - - NSMutableArray *description = [NSMutableArray arrayWithObject:self.banner]; - for (id each in self.options) { - NSMutableString *line = [NSMutableString new]; - if ([each isKindOfClass:[BRLOption class]]) { - BRLOption *option = each; - [line appendString:@" "]; - if (option.flag) { - [line appendFormat:@"-%c", option.flag]; - [line appendString:option.name ? @", " : @" "]; - } else { - [line appendString:@" "]; - } - if (option.name) { - [line appendFormat:@"%@%-24s ", [self longPrefix], option.name]; - } else { - [line appendString:@" "]; - } - if (line.length > 37) { - line = trimLine(line); - [line appendString:@"\n "]; - } - if (option.description) { - [line appendString:option.description]; - } - line = trimLine(line); - } else { - [line appendFormat:@"%@", each]; - } - [description addObject:line]; - } - return [[description componentsJoinedByString:@"\n"] stringByAppendingString:@"\n"]; -} - -#pragma mark - - -- (NSString *)longPrefix -{ - return self.isLongOnly ? @"-" : @"--"; -} - -@end diff --git a/Pods/BRLOptionParser/LICENSE b/Pods/BRLOptionParser/LICENSE deleted file mode 100644 index f3de6b535..000000000 --- a/Pods/BRLOptionParser/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright © 2013-2015 Stephen Celis () - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/Pods/BRLOptionParser/README.markdown b/Pods/BRLOptionParser/README.markdown deleted file mode 100644 index 3e2284c75..000000000 --- a/Pods/BRLOptionParser/README.markdown +++ /dev/null @@ -1,88 +0,0 @@ -# BRLOptionParser [![Build Status][1]][2] - -A short wrapper for [getopt_long(3)][3] (and getopt_long_only(3)). - -[1]: https://img.shields.io/travis/stephencelis/BRLOptionParser.svg?style=flat -[2]: https://travis-ci.org/stephencelis/BRLOptionParser -[3]: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/getopt_long.3.html - -## Install - -With [CocoaPods][4]: - -``` rb -# Podfile -pod 'BRLOptionParser', '~> 0.3.1' -``` - -[4]: http://cocoapods.org - -## Example - -``` objc -// main.m -#import - -int main(int argc, const char * argv[]) -{ - @autoreleasepool { - NSString *name = @"world"; - BOOL verbose = NO; - - BRLOptionParser *options = [BRLOptionParser new]; - - [options setBanner:@"usage: %s [-n ] [-vh]", argv[0]]; - [options addOption:"name" flag:'n' description:@"Your name" argument:&name]; - [options addSeparator]; - [options addOption:"verbose" flag:'v' description:nil value:&verbose]; - __weak typeof(options) weakOptions = options; - [options addOption:"help" flag:'h' description:@"Show this message" block:^{ - printf("%s", [[weakOptions description] UTF8String]); - exit(EXIT_SUCCESS); - }]; - - NSError *error = nil; - if (![options parseArgc:argc argv:argv error:&error]) { - const char * message = error.localizedDescription.UTF8String; - fprintf(stderr, "%s: %s\n", argv[0], message); - exit(EXIT_FAILURE); - } - - if (verbose) { - fprintf(stderr, "(Preparing to say hello...)\n"); - } - - printf("Hello, %s!\n", name.UTF8String); - } - - return EXIT_SUCCESS; -} -``` - -In practice: - -``` -$ hello -Hello, world! -$ hello -h -usage: hello [-n ] [-vh] - -n, --name Your name - - -v, --verbose - -h, --help Show this message -$ hello -n -hello: option `-n' requires an argument -$ hello --name Stephen -Hello, Stephen! -$ hello -vngoodbye -(Preparing to say hello...) -Hello, goodbye! -$ hello --goodbye -hello: unrecognized option `--goodbye' -``` - -## License - -BRLOptionParser is available under the MIT license. See the LICENSE file -for more information. - diff --git a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServer.h b/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServer.h deleted file mode 100644 index 70cb70c60..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServer.h +++ /dev/null @@ -1,637 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import - -#import "GCDWebServerRequest.h" -#import "GCDWebServerResponse.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - * The GCDWebServerMatchBlock is called for every handler added to the - * GCDWebServer whenever a new HTTP request has started (i.e. HTTP headers have - * been received). The block is passed the basic info for the request (HTTP method, - * URL, headers...) and must decide if it wants to handle it or not. - * - * If the handler can handle the request, the block must return a new - * GCDWebServerRequest instance created with the same basic info. - * Otherwise, it simply returns nil. - */ -typedef GCDWebServerRequest* _Nullable (^GCDWebServerMatchBlock)(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery); - -/** - * The GCDWebServerProcessBlock is called after the HTTP request has been fully - * received (i.e. the entire HTTP body has been read). The block is passed the - * GCDWebServerRequest created at the previous step by the GCDWebServerMatchBlock. - * - * The block must return a GCDWebServerResponse or nil on error, which will - * result in a 500 HTTP status code returned to the client. It's however - * recommended to return a GCDWebServerErrorResponse on error so more useful - * information can be returned to the client. - */ -typedef GCDWebServerResponse* _Nullable (^GCDWebServerProcessBlock)(__kindof GCDWebServerRequest* request); - -/** - * The GCDWebServerAsynchronousProcessBlock works like the GCDWebServerProcessBlock - * except the GCDWebServerResponse can be returned to the server at a later time - * allowing for asynchronous generation of the response. - * - * The block must eventually call "completionBlock" passing a GCDWebServerResponse - * or nil on error, which will result in a 500 HTTP status code returned to the client. - * It's however recommended to return a GCDWebServerErrorResponse on error so more - * useful information can be returned to the client. - */ -typedef void (^GCDWebServerCompletionBlock)(GCDWebServerResponse* _Nullable response); -typedef void (^GCDWebServerAsyncProcessBlock)(__kindof GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock); - -/** - * The GCDWebServerBuiltInLoggerBlock is used to override the built-in logger at runtime. - * The block will be passed the log level and the log message, see setLogLevel for - * documentation of the log levels for the built-in logger. - */ -typedef void (^GCDWebServerBuiltInLoggerBlock)(int level, NSString* _Nonnull message); - -/** - * The port used by the GCDWebServer (NSNumber / NSUInteger). - * - * The default value is 0 i.e. let the OS pick a random port. - */ -extern NSString* const GCDWebServerOption_Port; - -/** - * The Bonjour name used by the GCDWebServer (NSString). If set to an empty string, - * the name will automatically take the value of the GCDWebServerOption_ServerName - * option. If this option is set to nil, Bonjour will be disabled. - * - * The default value is nil. - */ -extern NSString* const GCDWebServerOption_BonjourName; - -/** - * The Bonjour service type used by the GCDWebServer (NSString). - * - * The default value is "_http._tcp", the service type for HTTP web servers. - */ -extern NSString* const GCDWebServerOption_BonjourType; - -/** - * Request a port mapping in the NAT gateway (NSNumber / BOOL). - * - * This uses the DNSService API under the hood which supports IPv4 mappings only. - * - * The default value is NO. - * - * @warning The external port set up by the NAT gateway may be different than - * the one used by the GCDWebServer. - */ -extern NSString* const GCDWebServerOption_RequestNATPortMapping; - -/** - * Only accept HTTP requests coming from localhost i.e. not from the outside - * network (NSNumber / BOOL). - * - * The default value is NO. - * - * @warning Bonjour and NAT port mapping should be disabled if using this option - * since the server will not be reachable from the outside network anyway. - */ -extern NSString* const GCDWebServerOption_BindToLocalhost; - -/** - * The maximum number of incoming HTTP requests that can be queued waiting to - * be handled before new ones are dropped (NSNumber / NSUInteger). - * - * The default value is 16. - */ -extern NSString* const GCDWebServerOption_MaxPendingConnections; - -/** - * The value for "Server" HTTP header used by the GCDWebServer (NSString). - * - * The default value is the GCDWebServer class name. - */ -extern NSString* const GCDWebServerOption_ServerName; - -/** - * The authentication method used by the GCDWebServer - * (one of "GCDWebServerAuthenticationMethod_..."). - * - * The default value is nil i.e. authentication is disabled. - */ -extern NSString* const GCDWebServerOption_AuthenticationMethod; - -/** - * The authentication realm used by the GCDWebServer (NSString). - * - * The default value is the same as the GCDWebServerOption_ServerName option. - */ -extern NSString* const GCDWebServerOption_AuthenticationRealm; - -/** - * The authentication accounts used by the GCDWebServer - * (NSDictionary of username / password pairs). - * - * The default value is nil i.e. no accounts. - */ -extern NSString* const GCDWebServerOption_AuthenticationAccounts; - -/** - * The class used by the GCDWebServer when instantiating GCDWebServerConnection - * (subclass of GCDWebServerConnection). - * - * The default value is the GCDWebServerConnection class. - */ -extern NSString* const GCDWebServerOption_ConnectionClass; - -/** - * Allow the GCDWebServer to pretend "HEAD" requests are actually "GET" ones - * and automatically discard the HTTP body of the response (NSNumber / BOOL). - * - * The default value is YES. - */ -extern NSString* const GCDWebServerOption_AutomaticallyMapHEADToGET; - -/** - * The interval expressed in seconds used by the GCDWebServer to decide how to - * coalesce calls to -webServerDidConnect: and -webServerDidDisconnect: - * (NSNumber / double). Coalescing will be disabled if the interval is <= 0.0. - * - * The default value is 1.0 second. - */ -extern NSString* const GCDWebServerOption_ConnectedStateCoalescingInterval; - -/** - * Set the dispatch queue priority on which server connection will be - * run (NSNumber / long). - * - * - * The default value is DISPATCH_QUEUE_PRIORITY_DEFAULT. - */ -extern NSString* const GCDWebServerOption_DispatchQueuePriority; - -#if TARGET_OS_IPHONE - -/** - * Enables the GCDWebServer to automatically suspend itself (as if -stop was - * called) when the iOS app goes into the background and the last - * GCDWebServerConnection is closed, then resume itself (as if -start was called) - * when the iOS app comes back to the foreground (NSNumber / BOOL). - * - * See the README.md file for more information about this option. - * - * The default value is YES. - * - * @warning The running property will be NO while the GCDWebServer is suspended. - */ -extern NSString* const GCDWebServerOption_AutomaticallySuspendInBackground; - -#endif - -/** - * HTTP Basic Authentication scheme (see https://tools.ietf.org/html/rfc2617). - * - * @warning Use of this authentication scheme is not recommended as the - * passwords are sent in clear. - */ -extern NSString* const GCDWebServerAuthenticationMethod_Basic; - -/** - * HTTP Digest Access Authentication scheme (see https://tools.ietf.org/html/rfc2617). - */ -extern NSString* const GCDWebServerAuthenticationMethod_DigestAccess; - -@class GCDWebServer; - -/** - * Delegate methods for GCDWebServer. - * - * @warning These methods are always called on the main thread in a serialized way. - */ -@protocol GCDWebServerDelegate -@optional - -/** - * This method is called after the server has successfully started. - */ -- (void)webServerDidStart:(GCDWebServer*)server; - -/** - * This method is called after the Bonjour registration for the server has - * successfully completed. - * - * Use the "bonjourServerURL" property to retrieve the Bonjour address of the - * server. - */ -- (void)webServerDidCompleteBonjourRegistration:(GCDWebServer*)server; - -/** - * This method is called after the NAT port mapping for the server has been - * updated. - * - * Use the "publicServerURL" property to retrieve the public address of the - * server. - */ -- (void)webServerDidUpdateNATPortMapping:(GCDWebServer*)server; - -/** - * This method is called when the first GCDWebServerConnection is opened by the - * server to serve a series of HTTP requests. - * - * A series of HTTP requests is considered ongoing as long as new HTTP requests - * keep coming (and new GCDWebServerConnection instances keep being opened), - * until before the last HTTP request has been responded to (and the - * corresponding last GCDWebServerConnection closed). - */ -- (void)webServerDidConnect:(GCDWebServer*)server; - -/** - * This method is called when the last GCDWebServerConnection is closed after - * the server has served a series of HTTP requests. - * - * The GCDWebServerOption_ConnectedStateCoalescingInterval option can be used - * to have the server wait some extra delay before considering that the series - * of HTTP requests has ended (in case there some latency between consecutive - * requests). This effectively coalesces the calls to -webServerDidConnect: - * and -webServerDidDisconnect:. - */ -- (void)webServerDidDisconnect:(GCDWebServer*)server; - -/** - * This method is called after the server has stopped. - */ -- (void)webServerDidStop:(GCDWebServer*)server; - -@end - -/** - * The GCDWebServer class listens for incoming HTTP requests on a given port, - * then passes each one to a "handler" capable of generating an HTTP response - * for it, which is then sent back to the client. - * - * GCDWebServer instances can be created and used from any thread but it's - * recommended to have the main thread's runloop be running so internal callbacks - * can be handled e.g. for Bonjour registration. - * - * See the README.md file for more information about the architecture of GCDWebServer. - */ -@interface GCDWebServer : NSObject - -/** - * Sets the delegate for the server. - */ -@property(nonatomic, weak, nullable) id delegate; - -/** - * Returns YES if the server is currently running. - */ -@property(nonatomic, readonly, getter=isRunning) BOOL running; - -/** - * Returns the port used by the server. - * - * @warning This property is only valid if the server is running. - */ -@property(nonatomic, readonly) NSUInteger port; - -/** - * Returns the Bonjour name used by the server. - * - * @warning This property is only valid if the server is running and Bonjour - * registration has successfully completed, which can take up to a few seconds. - */ -@property(nonatomic, readonly, nullable) NSString* bonjourName; - -/** - * Returns the Bonjour service type used by the server. - * - * @warning This property is only valid if the server is running and Bonjour - * registration has successfully completed, which can take up to a few seconds. - */ -@property(nonatomic, readonly, nullable) NSString* bonjourType; - -/** - * This method is the designated initializer for the class. - */ -- (instancetype)init; - -/** - * Adds to the server a handler that generates responses synchronously when handling incoming HTTP requests. - * - * Handlers are called in a LIFO queue, so if multiple handlers can potentially - * respond to a given request, the latest added one wins. - * - * @warning Addling handlers while the server is running is not allowed. - */ -- (void)addHandlerWithMatchBlock:(GCDWebServerMatchBlock)matchBlock processBlock:(GCDWebServerProcessBlock)processBlock; - -/** - * Adds to the server a handler that generates responses asynchronously when handling incoming HTTP requests. - * - * Handlers are called in a LIFO queue, so if multiple handlers can potentially - * respond to a given request, the latest added one wins. - * - * @warning Addling handlers while the server is running is not allowed. - */ -- (void)addHandlerWithMatchBlock:(GCDWebServerMatchBlock)matchBlock asyncProcessBlock:(GCDWebServerAsyncProcessBlock)processBlock; - -/** - * Removes all handlers previously added to the server. - * - * @warning Removing handlers while the server is running is not allowed. - */ -- (void)removeAllHandlers; - -/** - * Starts the server with explicit options. This method is the designated way - * to start the server. - * - * Returns NO if the server failed to start and sets "error" argument if not NULL. - */ -- (BOOL)startWithOptions:(nullable NSDictionary*)options error:(NSError** _Nullable)error; - -/** - * Stops the server and prevents it to accepts new HTTP requests. - * - * @warning Stopping the server does not abort GCDWebServerConnection instances - * currently handling already received HTTP requests. These connections will - * continue to execute normally until completion. - */ -- (void)stop; - -@end - -@interface GCDWebServer (Extensions) - -/** - * Returns the server's URL. - * - * @warning This property is only valid if the server is running. - */ -@property(nonatomic, readonly, nullable) NSURL* serverURL; - -/** - * Returns the server's Bonjour URL. - * - * @warning This property is only valid if the server is running and Bonjour - * registration has successfully completed, which can take up to a few seconds. - * Also be aware this property will not automatically update if the Bonjour hostname - * has been dynamically changed after the server started running (this should be rare). - */ -@property(nonatomic, readonly, nullable) NSURL* bonjourServerURL; - -/** - * Returns the server's public URL. - * - * @warning This property is only valid if the server is running and NAT port - * mapping is active. - */ -@property(nonatomic, readonly, nullable) NSURL* publicServerURL; - -/** - * Starts the server on port 8080 (OS X & iOS Simulator) or port 80 (iOS) - * using the default Bonjour name. - * - * Returns NO if the server failed to start. - */ -- (BOOL)start; - -/** - * Starts the server on a given port and with a specific Bonjour name. - * Pass a nil Bonjour name to disable Bonjour entirely or an empty string to - * use the default name. - * - * Returns NO if the server failed to start. - */ -- (BOOL)startWithPort:(NSUInteger)port bonjourName:(nullable NSString*)name; - -#if !TARGET_OS_IPHONE - -/** - * Runs the server synchronously using -startWithPort:bonjourName: until a - * SIGINT signal is received i.e. Ctrl-C. This method is intended to be used - * by command line tools. - * - * Returns NO if the server failed to start. - * - * @warning This method must be used from the main thread only. - */ -- (BOOL)runWithPort:(NSUInteger)port bonjourName:(nullable NSString*)name; - -/** - * Runs the server synchronously using -startWithOptions: until a SIGTERM or - * SIGINT signal is received i.e. Ctrl-C in Terminal. This method is intended to - * be used by command line tools. - * - * Returns NO if the server failed to start and sets "error" argument if not NULL. - * - * @warning This method must be used from the main thread only. - */ -- (BOOL)runWithOptions:(nullable NSDictionary*)options error:(NSError** _Nullable)error; - -#endif - -@end - -@interface GCDWebServer (Handlers) - -/** - * Adds a default handler to the server to handle all incoming HTTP requests - * with a given HTTP method and generate responses synchronously. - */ -- (void)addDefaultHandlerForMethod:(NSString*)method requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block; - -/** - * Adds a default handler to the server to handle all incoming HTTP requests - * with a given HTTP method and generate responses asynchronously. - */ -- (void)addDefaultHandlerForMethod:(NSString*)method requestClass:(Class)aClass asyncProcessBlock:(GCDWebServerAsyncProcessBlock)block; - -/** - * Adds a handler to the server to handle incoming HTTP requests with a given - * HTTP method and a specific case-insensitive path and generate responses - * synchronously. - */ -- (void)addHandlerForMethod:(NSString*)method path:(NSString*)path requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block; - -/** - * Adds a handler to the server to handle incoming HTTP requests with a given - * HTTP method and a specific case-insensitive path and generate responses - * asynchronously. - */ -- (void)addHandlerForMethod:(NSString*)method path:(NSString*)path requestClass:(Class)aClass asyncProcessBlock:(GCDWebServerAsyncProcessBlock)block; - -/** - * Adds a handler to the server to handle incoming HTTP requests with a given - * HTTP method and a path matching a case-insensitive regular expression and - * generate responses synchronously. - */ -- (void)addHandlerForMethod:(NSString*)method pathRegex:(NSString*)regex requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block; - -/** - * Adds a handler to the server to handle incoming HTTP requests with a given - * HTTP method and a path matching a case-insensitive regular expression and - * generate responses asynchronously. - */ -- (void)addHandlerForMethod:(NSString*)method pathRegex:(NSString*)regex requestClass:(Class)aClass asyncProcessBlock:(GCDWebServerAsyncProcessBlock)block; - -@end - -@interface GCDWebServer (GETHandlers) - -/** - * Adds a handler to the server to respond to incoming "GET" HTTP requests - * with a specific case-insensitive path with in-memory data. - */ -- (void)addGETHandlerForPath:(NSString*)path staticData:(NSData*)staticData contentType:(nullable NSString*)contentType cacheAge:(NSUInteger)cacheAge; - -/** - * Adds a handler to the server to respond to incoming "GET" HTTP requests - * with a specific case-insensitive path with a file. - */ -- (void)addGETHandlerForPath:(NSString*)path filePath:(NSString*)filePath isAttachment:(BOOL)isAttachment cacheAge:(NSUInteger)cacheAge allowRangeRequests:(BOOL)allowRangeRequests; - -/** - * Adds a handler to the server to respond to incoming "GET" HTTP requests - * with a case-insensitive path inside a base path with the corresponding file - * inside a local directory. If no local file matches the request path, a 401 - * HTTP status code is returned to the client. - * - * The "indexFilename" argument allows to specify an "index" file name to use - * when the request path corresponds to a directory. - */ -- (void)addGETHandlerForBasePath:(NSString*)basePath directoryPath:(NSString*)directoryPath indexFilename:(nullable NSString*)indexFilename cacheAge:(NSUInteger)cacheAge allowRangeRequests:(BOOL)allowRangeRequests; - -@end - -/** - * GCDWebServer provides its own built-in logging facility which is used by - * default. It simply sends log messages to stderr assuming it is connected - * to a terminal type device. - * - * GCDWebServer is also compatible with a limited set of third-party logging - * facilities. If one of them is available at compile time, GCDWebServer will - * automatically use it in place of the built-in one. - * - * Currently supported third-party logging facilities are: - * - XLFacility (by the same author as GCDWebServer): https://github.com/swisspol/XLFacility - * - * For the built-in logging facility, the default logging level is INFO - * (or DEBUG if the preprocessor constant "DEBUG" evaluates to non-zero at - * compile time). - * - * It's possible to have GCDWebServer use a custom logging facility by defining - * the "__GCDWEBSERVER_LOGGING_HEADER__" preprocessor constant in Xcode build - * settings to the name of a custom header file (escaped like \"MyLogging.h\"). - * This header file must define the following set of macros: - * - * GWS_LOG_DEBUG(...) - * GWS_LOG_VERBOSE(...) - * GWS_LOG_INFO(...) - * GWS_LOG_WARNING(...) - * GWS_LOG_ERROR(...) - * - * IMPORTANT: These macros must behave like NSLog(). Furthermore the GWS_LOG_DEBUG() - * macro should not do anything unless the preprocessor constant "DEBUG" evaluates - * to non-zero. - * - * The logging methods below send log messages to the same logging facility - * used by GCDWebServer. They can be used for consistency wherever you interact - * with GCDWebServer in your code (e.g. in the implementation of handlers). - */ -@interface GCDWebServer (Logging) - -/** - * Sets the log level of the logging facility below which log messages are discarded. - * - * @warning The interpretation of the "level" argument depends on the logging - * facility used at compile time. - * - * If using the built-in logging facility, the log levels are as follow: - * DEBUG = 0 - * VERBOSE = 1 - * INFO = 2 - * WARNING = 3 - * ERROR = 4 - */ -+ (void)setLogLevel:(int)level; - -/** - * Set a logger to be used instead of the built-in logger which logs to stderr. - * - * IMPORTANT: In order for this override to work, you should not be specifying - * a custom logger at compile time with "__GCDWEBSERVER_LOGGING_HEADER__". - */ -+ (void)setBuiltInLogger:(GCDWebServerBuiltInLoggerBlock)block; - -/** - * Logs a message to the logging facility at the VERBOSE level. - */ -- (void)logVerbose:(NSString*)format, ... NS_FORMAT_FUNCTION(1, 2); - -/** - * Logs a message to the logging facility at the INFO level. - */ -- (void)logInfo:(NSString*)format, ... NS_FORMAT_FUNCTION(1, 2); - -/** - * Logs a message to the logging facility at the WARNING level. - */ -- (void)logWarning:(NSString*)format, ... NS_FORMAT_FUNCTION(1, 2); - -/** - * Logs a message to the logging facility at the ERROR level. - */ -- (void)logError:(NSString*)format, ... NS_FORMAT_FUNCTION(1, 2); - -@end - -#ifdef __GCDWEBSERVER_ENABLE_TESTING__ - -@interface GCDWebServer (Testing) - -/** - * Activates recording of HTTP requests and responses which create files in the - * current directory containing the raw data for all requests and responses. - * - * @warning The current directory must not contain any prior recording files. - */ -@property(nonatomic, getter=isRecordingEnabled) BOOL recordingEnabled; - -/** - * Runs tests by playing back pre-recorded HTTP requests in the given directory - * and comparing the generated responses with the pre-recorded ones. - * - * Returns the number of failed tests or -1 if server failed to start. - */ -- (NSInteger)runTestsWithOptions:(nullable NSDictionary*)options inDirectory:(NSString*)path; - -@end - -#endif - -NS_ASSUME_NONNULL_END diff --git a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServer.m b/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServer.m deleted file mode 100644 index 655b2bda7..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServer.m +++ /dev/null @@ -1,1310 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !__has_feature(objc_arc) -#error GCDWebServer requires ARC -#endif - -#import -#if TARGET_OS_IPHONE -#import -#else -#ifdef __GCDWEBSERVER_ENABLE_TESTING__ -#import -#endif -#endif -#import -#import - -#import "GCDWebServerPrivate.h" - -#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR -#define kDefaultPort 80 -#else -#define kDefaultPort 8080 -#endif - -#define kBonjourResolutionTimeout 5.0 - -NSString* const GCDWebServerOption_Port = @"Port"; -NSString* const GCDWebServerOption_BonjourName = @"BonjourName"; -NSString* const GCDWebServerOption_BonjourType = @"BonjourType"; -NSString* const GCDWebServerOption_RequestNATPortMapping = @"RequestNATPortMapping"; -NSString* const GCDWebServerOption_BindToLocalhost = @"BindToLocalhost"; -NSString* const GCDWebServerOption_MaxPendingConnections = @"MaxPendingConnections"; -NSString* const GCDWebServerOption_ServerName = @"ServerName"; -NSString* const GCDWebServerOption_AuthenticationMethod = @"AuthenticationMethod"; -NSString* const GCDWebServerOption_AuthenticationRealm = @"AuthenticationRealm"; -NSString* const GCDWebServerOption_AuthenticationAccounts = @"AuthenticationAccounts"; -NSString* const GCDWebServerOption_ConnectionClass = @"ConnectionClass"; -NSString* const GCDWebServerOption_AutomaticallyMapHEADToGET = @"AutomaticallyMapHEADToGET"; -NSString* const GCDWebServerOption_ConnectedStateCoalescingInterval = @"ConnectedStateCoalescingInterval"; -NSString* const GCDWebServerOption_DispatchQueuePriority = @"DispatchQueuePriority"; -#if TARGET_OS_IPHONE -NSString* const GCDWebServerOption_AutomaticallySuspendInBackground = @"AutomaticallySuspendInBackground"; -#endif - -NSString* const GCDWebServerAuthenticationMethod_Basic = @"Basic"; -NSString* const GCDWebServerAuthenticationMethod_DigestAccess = @"DigestAccess"; - -#if defined(__GCDWEBSERVER_LOGGING_FACILITY_BUILTIN__) -#if DEBUG -GCDWebServerLoggingLevel GCDWebServerLogLevel = kGCDWebServerLoggingLevel_Debug; -#else -GCDWebServerLoggingLevel GCDWebServerLogLevel = kGCDWebServerLoggingLevel_Info; -#endif -#endif - -#if !TARGET_OS_IPHONE -static BOOL _run; -#endif - -#ifdef __GCDWEBSERVER_LOGGING_FACILITY_BUILTIN__ - -static GCDWebServerBuiltInLoggerBlock _builtInLoggerBlock; - -void GCDWebServerLogMessage(GCDWebServerLoggingLevel level, NSString* format, ...) { - static const char* levelNames[] = {"DEBUG", "VERBOSE", "INFO", "WARNING", "ERROR"}; - static int enableLogging = -1; - if (enableLogging < 0) { - enableLogging = (isatty(STDERR_FILENO) ? 1 : 0); - } - if (_builtInLoggerBlock || enableLogging) { - va_list arguments; - va_start(arguments, format); - NSString* message = [[NSString alloc] initWithFormat:format arguments:arguments]; - va_end(arguments); - if (_builtInLoggerBlock) { - _builtInLoggerBlock(level, message); - } else { - fprintf(stderr, "[%s] %s\n", levelNames[level], [message UTF8String]); - } - } -} - -#endif - -#if !TARGET_OS_IPHONE - -static void _SignalHandler(int signal) { - _run = NO; - printf("\n"); -} - -#endif - -#if !TARGET_OS_IPHONE || defined(__GCDWEBSERVER_ENABLE_TESTING__) - -// This utility function is used to ensure scheduled callbacks on the main thread are called when running the server synchronously -// https://developer.apple.com/library/mac/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html -// The main queue works with the application’s run loop to interleave the execution of queued tasks with the execution of other event sources attached to the run loop -// TODO: Ensure all scheduled blocks on the main queue are also executed -static void _ExecuteMainThreadRunLoopSources() { - SInt32 result; - do { - result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.0, true); - } while (result == kCFRunLoopRunHandledSource); -} - -#endif - -@implementation GCDWebServerHandler - -- (instancetype)initWithMatchBlock:(GCDWebServerMatchBlock _Nonnull)matchBlock asyncProcessBlock:(GCDWebServerAsyncProcessBlock _Nonnull)processBlock { - if ((self = [super init])) { - _matchBlock = [matchBlock copy]; - _asyncProcessBlock = [processBlock copy]; - } - return self; -} - -@end - -@implementation GCDWebServer { - dispatch_queue_t _syncQueue; - dispatch_group_t _sourceGroup; - NSMutableArray* _handlers; - NSInteger _activeConnections; // Accessed through _syncQueue only - BOOL _connected; // Accessed on main thread only - CFRunLoopTimerRef _disconnectTimer; // Accessed on main thread only - - NSDictionary* _options; - NSMutableDictionary* _authenticationBasicAccounts; - NSMutableDictionary* _authenticationDigestAccounts; - Class _connectionClass; - CFTimeInterval _disconnectDelay; - dispatch_source_t _source4; - dispatch_source_t _source6; - CFNetServiceRef _registrationService; - CFNetServiceRef _resolutionService; - DNSServiceRef _dnsService; - CFSocketRef _dnsSocket; - CFRunLoopSourceRef _dnsSource; - NSString* _dnsAddress; - NSUInteger _dnsPort; - BOOL _bindToLocalhost; -#if TARGET_OS_IPHONE - BOOL _suspendInBackground; - UIBackgroundTaskIdentifier _backgroundTask; -#endif -#ifdef __GCDWEBSERVER_ENABLE_TESTING__ - BOOL _recording; -#endif -} - -+ (void)initialize { - GCDWebServerInitializeFunctions(); -} - -- (instancetype)init { - if ((self = [super init])) { - _syncQueue = dispatch_queue_create([NSStringFromClass([self class]) UTF8String], DISPATCH_QUEUE_SERIAL); - _sourceGroup = dispatch_group_create(); - _handlers = [[NSMutableArray alloc] init]; -#if TARGET_OS_IPHONE - _backgroundTask = UIBackgroundTaskInvalid; -#endif - } - return self; -} - -- (void)dealloc { - GWS_DCHECK(_connected == NO); - GWS_DCHECK(_activeConnections == 0); - GWS_DCHECK(_options == nil); // The server can never be dealloc'ed while running because of the retain-cycle with the dispatch source - GWS_DCHECK(_disconnectTimer == NULL); // The server can never be dealloc'ed while the disconnect timer is pending because of the retain-cycle - -#if !OS_OBJECT_USE_OBJC_RETAIN_RELEASE - dispatch_release(_sourceGroup); - dispatch_release(_syncQueue); -#endif -} - -#if TARGET_OS_IPHONE - -// Always called on main thread -- (void)_startBackgroundTask { - GWS_DCHECK([NSThread isMainThread]); - if (_backgroundTask == UIBackgroundTaskInvalid) { - GWS_LOG_DEBUG(@"Did start background task"); - _backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ - GWS_LOG_WARNING(@"Application is being suspended while %@ is still connected", [self class]); - [self _endBackgroundTask]; - }]; - } else { - GWS_DNOT_REACHED(); - } -} - -#endif - -// Always called on main thread -- (void)_didConnect { - GWS_DCHECK([NSThread isMainThread]); - GWS_DCHECK(_connected == NO); - _connected = YES; - GWS_LOG_DEBUG(@"Did connect"); - -#if TARGET_OS_IPHONE - if ([[UIApplication sharedApplication] applicationState] != UIApplicationStateBackground) { - [self _startBackgroundTask]; - } -#endif - - if ([_delegate respondsToSelector:@selector(webServerDidConnect:)]) { - [_delegate webServerDidConnect:self]; - } -} - -- (void)willStartConnection:(GCDWebServerConnection*)connection { - dispatch_sync(_syncQueue, ^{ - GWS_DCHECK(self->_activeConnections >= 0); - if (self->_activeConnections == 0) { - dispatch_async(dispatch_get_main_queue(), ^{ - if (self->_disconnectTimer) { - CFRunLoopTimerInvalidate(self->_disconnectTimer); - CFRelease(self->_disconnectTimer); - self->_disconnectTimer = NULL; - } - if (self->_connected == NO) { - [self _didConnect]; - } - }); - } - self->_activeConnections += 1; - }); -} - -#if TARGET_OS_IPHONE - -// Always called on main thread -- (void)_endBackgroundTask { - GWS_DCHECK([NSThread isMainThread]); - if (_backgroundTask != UIBackgroundTaskInvalid) { - if (_suspendInBackground && ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground) && _source4) { - [self _stop]; - } - [[UIApplication sharedApplication] endBackgroundTask:_backgroundTask]; - _backgroundTask = UIBackgroundTaskInvalid; - GWS_LOG_DEBUG(@"Did end background task"); - } -} - -#endif - -// Always called on main thread -- (void)_didDisconnect { - GWS_DCHECK([NSThread isMainThread]); - GWS_DCHECK(_connected == YES); - _connected = NO; - GWS_LOG_DEBUG(@"Did disconnect"); - -#if TARGET_OS_IPHONE - [self _endBackgroundTask]; -#endif - - if ([_delegate respondsToSelector:@selector(webServerDidDisconnect:)]) { - [_delegate webServerDidDisconnect:self]; - } -} - -- (void)didEndConnection:(GCDWebServerConnection*)connection { - dispatch_sync(_syncQueue, ^{ - GWS_DCHECK(self->_activeConnections > 0); - self->_activeConnections -= 1; - if (self->_activeConnections == 0) { - dispatch_async(dispatch_get_main_queue(), ^{ - if ((self->_disconnectDelay > 0.0) && (self->_source4 != NULL)) { - if (self->_disconnectTimer) { - CFRunLoopTimerInvalidate(self->_disconnectTimer); - CFRelease(self->_disconnectTimer); - } - self->_disconnectTimer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + self->_disconnectDelay, 0.0, 0, 0, ^(CFRunLoopTimerRef timer) { - GWS_DCHECK([NSThread isMainThread]); - [self _didDisconnect]; - CFRelease(self->_disconnectTimer); - self->_disconnectTimer = NULL; - }); - CFRunLoopAddTimer(CFRunLoopGetMain(), self->_disconnectTimer, kCFRunLoopCommonModes); - } else { - [self _didDisconnect]; - } - }); - } - }); -} - -- (NSString*)bonjourName { - CFStringRef name = _resolutionService ? CFNetServiceGetName(_resolutionService) : NULL; - return name && CFStringGetLength(name) ? CFBridgingRelease(CFStringCreateCopy(kCFAllocatorDefault, name)) : nil; -} - -- (NSString*)bonjourType { - CFStringRef type = _resolutionService ? CFNetServiceGetType(_resolutionService) : NULL; - return type && CFStringGetLength(type) ? CFBridgingRelease(CFStringCreateCopy(kCFAllocatorDefault, type)) : nil; -} - -- (void)addHandlerWithMatchBlock:(GCDWebServerMatchBlock)matchBlock processBlock:(GCDWebServerProcessBlock)processBlock { - [self addHandlerWithMatchBlock:matchBlock - asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) { - completionBlock(processBlock(request)); - }]; -} - -- (void)addHandlerWithMatchBlock:(GCDWebServerMatchBlock)matchBlock asyncProcessBlock:(GCDWebServerAsyncProcessBlock)processBlock { - GWS_DCHECK(_options == nil); - GCDWebServerHandler* handler = [[GCDWebServerHandler alloc] initWithMatchBlock:matchBlock asyncProcessBlock:processBlock]; - [_handlers insertObject:handler atIndex:0]; -} - -- (void)removeAllHandlers { - GWS_DCHECK(_options == nil); - [_handlers removeAllObjects]; -} - -static void _NetServiceRegisterCallBack(CFNetServiceRef service, CFStreamError* error, void* info) { - GWS_DCHECK([NSThread isMainThread]); - @autoreleasepool { - if (error->error) { - GWS_LOG_ERROR(@"Bonjour registration error %i (domain %i)", (int)error->error, (int)error->domain); - } else { - GCDWebServer* server = (__bridge GCDWebServer*)info; - GWS_LOG_VERBOSE(@"Bonjour registration complete for %@", [server class]); - if (!CFNetServiceResolveWithTimeout(server->_resolutionService, kBonjourResolutionTimeout, NULL)) { - GWS_LOG_ERROR(@"Failed starting Bonjour resolution"); - GWS_DNOT_REACHED(); - } - } - } -} - -static void _NetServiceResolveCallBack(CFNetServiceRef service, CFStreamError* error, void* info) { - GWS_DCHECK([NSThread isMainThread]); - @autoreleasepool { - if (error->error) { - if ((error->domain != kCFStreamErrorDomainNetServices) && (error->error != kCFNetServicesErrorTimeout)) { - GWS_LOG_ERROR(@"Bonjour resolution error %i (domain %i)", (int)error->error, (int)error->domain); - } - } else { - GCDWebServer* server = (__bridge GCDWebServer*)info; - GWS_LOG_INFO(@"%@ now locally reachable at %@", [server class], server.bonjourServerURL); - if ([server.delegate respondsToSelector:@selector(webServerDidCompleteBonjourRegistration:)]) { - [server.delegate webServerDidCompleteBonjourRegistration:server]; - } - } - } -} - -static void _DNSServiceCallBack(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, uint32_t externalAddress, DNSServiceProtocol protocol, uint16_t internalPort, uint16_t externalPort, uint32_t ttl, void* context) { - GWS_DCHECK([NSThread isMainThread]); - @autoreleasepool { - GCDWebServer* server = (__bridge GCDWebServer*)context; - if ((errorCode == kDNSServiceErr_NoError) || (errorCode == kDNSServiceErr_DoubleNAT)) { - struct sockaddr_in addr4; - bzero(&addr4, sizeof(addr4)); - addr4.sin_len = sizeof(addr4); - addr4.sin_family = AF_INET; - addr4.sin_addr.s_addr = externalAddress; // Already in network byte order - server->_dnsAddress = GCDWebServerStringFromSockAddr((const struct sockaddr*)&addr4, NO); - server->_dnsPort = ntohs(externalPort); - GWS_LOG_INFO(@"%@ now publicly reachable at %@", [server class], server.publicServerURL); - } else { - GWS_LOG_ERROR(@"DNS service error %i", errorCode); - server->_dnsAddress = nil; - server->_dnsPort = 0; - } - if ([server.delegate respondsToSelector:@selector(webServerDidUpdateNATPortMapping:)]) { - [server.delegate webServerDidUpdateNATPortMapping:server]; - } - } -} - -static void _SocketCallBack(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void* data, void* info) { - GWS_DCHECK([NSThread isMainThread]); - @autoreleasepool { - GCDWebServer* server = (__bridge GCDWebServer*)info; - DNSServiceErrorType status = DNSServiceProcessResult(server->_dnsService); - if (status != kDNSServiceErr_NoError) { - GWS_LOG_ERROR(@"DNS service error %i", status); - } - } -} - -static inline id _GetOption(NSDictionary* options, NSString* key, id defaultValue) { - id value = [options objectForKey:key]; - return value ? value : defaultValue; -} - -static inline NSString* _EncodeBase64(NSString* string) { - NSData* data = [string dataUsingEncoding:NSUTF8StringEncoding]; -#if TARGET_OS_IPHONE || (__MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_9) - return [[NSString alloc] initWithData:[data base64EncodedDataWithOptions:0] encoding:NSASCIIStringEncoding]; -#else - if (@available(macOS 10.9, *)) { - return [[NSString alloc] initWithData:[data base64EncodedDataWithOptions:0] encoding:NSASCIIStringEncoding]; - } - return [data base64Encoding]; -#endif -} - -- (int)_createListeningSocket:(BOOL)useIPv6 - localAddress:(const void*)address - length:(socklen_t)length - maxPendingConnections:(NSUInteger)maxPendingConnections - error:(NSError**)error { - int listeningSocket = socket(useIPv6 ? PF_INET6 : PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (listeningSocket > 0) { - int yes = 1; - setsockopt(listeningSocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); - - if (bind(listeningSocket, address, length) == 0) { - if (listen(listeningSocket, (int)maxPendingConnections) == 0) { - GWS_LOG_DEBUG(@"Did open %s listening socket %i", useIPv6 ? "IPv6" : "IPv4", listeningSocket); - return listeningSocket; - } else { - if (error) { - *error = GCDWebServerMakePosixError(errno); - } - GWS_LOG_ERROR(@"Failed starting %s listening socket: %s (%i)", useIPv6 ? "IPv6" : "IPv4", strerror(errno), errno); - close(listeningSocket); - } - } else { - if (error) { - *error = GCDWebServerMakePosixError(errno); - } - GWS_LOG_ERROR(@"Failed binding %s listening socket: %s (%i)", useIPv6 ? "IPv6" : "IPv4", strerror(errno), errno); - close(listeningSocket); - } - - } else { - if (error) { - *error = GCDWebServerMakePosixError(errno); - } - GWS_LOG_ERROR(@"Failed creating %s listening socket: %s (%i)", useIPv6 ? "IPv6" : "IPv4", strerror(errno), errno); - } - return -1; -} - -- (dispatch_source_t)_createDispatchSourceWithListeningSocket:(int)listeningSocket isIPv6:(BOOL)isIPv6 { - dispatch_group_enter(_sourceGroup); - dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, listeningSocket, 0, dispatch_get_global_queue(_dispatchQueuePriority, 0)); - dispatch_source_set_cancel_handler(source, ^{ - @autoreleasepool { - int result = close(listeningSocket); - if (result != 0) { - GWS_LOG_ERROR(@"Failed closing %s listening socket: %s (%i)", isIPv6 ? "IPv6" : "IPv4", strerror(errno), errno); - } else { - GWS_LOG_DEBUG(@"Did close %s listening socket %i", isIPv6 ? "IPv6" : "IPv4", listeningSocket); - } - } - dispatch_group_leave(self->_sourceGroup); - }); - dispatch_source_set_event_handler(source, ^{ - @autoreleasepool { - struct sockaddr_storage remoteSockAddr; - socklen_t remoteAddrLen = sizeof(remoteSockAddr); - int socket = accept(listeningSocket, (struct sockaddr*)&remoteSockAddr, &remoteAddrLen); - if (socket > 0) { - NSData* remoteAddress = [NSData dataWithBytes:&remoteSockAddr length:remoteAddrLen]; - - struct sockaddr_storage localSockAddr; - socklen_t localAddrLen = sizeof(localSockAddr); - NSData* localAddress = nil; - if (getsockname(socket, (struct sockaddr*)&localSockAddr, &localAddrLen) == 0) { - localAddress = [NSData dataWithBytes:&localSockAddr length:localAddrLen]; - GWS_DCHECK((!isIPv6 && localSockAddr.ss_family == AF_INET) || (isIPv6 && localSockAddr.ss_family == AF_INET6)); - } else { - GWS_DNOT_REACHED(); - } - - int noSigPipe = 1; - setsockopt(socket, SOL_SOCKET, SO_NOSIGPIPE, &noSigPipe, sizeof(noSigPipe)); // Make sure this socket cannot generate SIG_PIPE - - GCDWebServerConnection* connection = [(GCDWebServerConnection*)[self->_connectionClass alloc] initWithServer:self localAddress:localAddress remoteAddress:remoteAddress socket:socket]; // Connection will automatically retain itself while opened - [connection self]; // Prevent compiler from complaining about unused variable / useless statement - } else { - GWS_LOG_ERROR(@"Failed accepting %s socket: %s (%i)", isIPv6 ? "IPv6" : "IPv4", strerror(errno), errno); - } - } - }); - return source; -} - -- (BOOL)_start:(NSError**)error { - GWS_DCHECK(_source4 == NULL); - - NSUInteger port = [(NSNumber*)_GetOption(_options, GCDWebServerOption_Port, @0) unsignedIntegerValue]; - BOOL bindToLocalhost = [(NSNumber*)_GetOption(_options, GCDWebServerOption_BindToLocalhost, @NO) boolValue]; - NSUInteger maxPendingConnections = [(NSNumber*)_GetOption(_options, GCDWebServerOption_MaxPendingConnections, @16) unsignedIntegerValue]; - - struct sockaddr_in addr4; - bzero(&addr4, sizeof(addr4)); - addr4.sin_len = sizeof(addr4); - addr4.sin_family = AF_INET; - addr4.sin_port = htons(port); - addr4.sin_addr.s_addr = bindToLocalhost ? htonl(INADDR_LOOPBACK) : htonl(INADDR_ANY); - int listeningSocket4 = [self _createListeningSocket:NO localAddress:&addr4 length:sizeof(addr4) maxPendingConnections:maxPendingConnections error:error]; - if (listeningSocket4 <= 0) { - return NO; - } - if (port == 0) { - struct sockaddr_in addr; - socklen_t addrlen = sizeof(addr); - if (getsockname(listeningSocket4, (struct sockaddr*)&addr, &addrlen) == 0) { - port = ntohs(addr.sin_port); - } else { - GWS_LOG_ERROR(@"Failed retrieving socket address: %s (%i)", strerror(errno), errno); - } - } - - struct sockaddr_in6 addr6; - bzero(&addr6, sizeof(addr6)); - addr6.sin6_len = sizeof(addr6); - addr6.sin6_family = AF_INET6; - addr6.sin6_port = htons(port); - addr6.sin6_addr = bindToLocalhost ? in6addr_loopback : in6addr_any; - int listeningSocket6 = [self _createListeningSocket:YES localAddress:&addr6 length:sizeof(addr6) maxPendingConnections:maxPendingConnections error:error]; - if (listeningSocket6 <= 0) { - close(listeningSocket4); - return NO; - } - - _serverName = [(NSString*)_GetOption(_options, GCDWebServerOption_ServerName, NSStringFromClass([self class])) copy]; - NSString* authenticationMethod = _GetOption(_options, GCDWebServerOption_AuthenticationMethod, nil); - if ([authenticationMethod isEqualToString:GCDWebServerAuthenticationMethod_Basic]) { - _authenticationRealm = [(NSString*)_GetOption(_options, GCDWebServerOption_AuthenticationRealm, _serverName) copy]; - _authenticationBasicAccounts = [[NSMutableDictionary alloc] init]; - NSDictionary* accounts = _GetOption(_options, GCDWebServerOption_AuthenticationAccounts, @{}); - [accounts enumerateKeysAndObjectsUsingBlock:^(NSString* username, NSString* password, BOOL* stop) { - [self->_authenticationBasicAccounts setObject:_EncodeBase64([NSString stringWithFormat:@"%@:%@", username, password]) forKey:username]; - }]; - } else if ([authenticationMethod isEqualToString:GCDWebServerAuthenticationMethod_DigestAccess]) { - _authenticationRealm = [(NSString*)_GetOption(_options, GCDWebServerOption_AuthenticationRealm, _serverName) copy]; - _authenticationDigestAccounts = [[NSMutableDictionary alloc] init]; - NSDictionary* accounts = _GetOption(_options, GCDWebServerOption_AuthenticationAccounts, @{}); - [accounts enumerateKeysAndObjectsUsingBlock:^(NSString* username, NSString* password, BOOL* stop) { - [self->_authenticationDigestAccounts setObject:GCDWebServerComputeMD5Digest(@"%@:%@:%@", username, self->_authenticationRealm, password) forKey:username]; - }]; - } - _connectionClass = _GetOption(_options, GCDWebServerOption_ConnectionClass, [GCDWebServerConnection class]); - _shouldAutomaticallyMapHEADToGET = [(NSNumber*)_GetOption(_options, GCDWebServerOption_AutomaticallyMapHEADToGET, @YES) boolValue]; - _disconnectDelay = [(NSNumber*)_GetOption(_options, GCDWebServerOption_ConnectedStateCoalescingInterval, @1.0) doubleValue]; - _dispatchQueuePriority = [(NSNumber*)_GetOption(_options, GCDWebServerOption_DispatchQueuePriority, @(DISPATCH_QUEUE_PRIORITY_DEFAULT)) longValue]; - - _source4 = [self _createDispatchSourceWithListeningSocket:listeningSocket4 isIPv6:NO]; - _source6 = [self _createDispatchSourceWithListeningSocket:listeningSocket6 isIPv6:YES]; - _port = port; - _bindToLocalhost = bindToLocalhost; - - NSString* bonjourName = _GetOption(_options, GCDWebServerOption_BonjourName, nil); - NSString* bonjourType = _GetOption(_options, GCDWebServerOption_BonjourType, @"_http._tcp"); - if (bonjourName) { - _registrationService = CFNetServiceCreate(kCFAllocatorDefault, CFSTR("local."), (__bridge CFStringRef)bonjourType, (__bridge CFStringRef)(bonjourName.length ? bonjourName : _serverName), (SInt32)_port); - if (_registrationService) { - CFNetServiceClientContext context = {0, (__bridge void*)self, NULL, NULL, NULL}; - - CFNetServiceSetClient(_registrationService, _NetServiceRegisterCallBack, &context); - CFNetServiceScheduleWithRunLoop(_registrationService, CFRunLoopGetMain(), kCFRunLoopCommonModes); - CFStreamError streamError = {0}; - CFNetServiceRegisterWithOptions(_registrationService, 0, &streamError); - - _resolutionService = CFNetServiceCreateCopy(kCFAllocatorDefault, _registrationService); - if (_resolutionService) { - CFNetServiceSetClient(_resolutionService, _NetServiceResolveCallBack, &context); - CFNetServiceScheduleWithRunLoop(_resolutionService, CFRunLoopGetMain(), kCFRunLoopCommonModes); - } else { - GWS_LOG_ERROR(@"Failed creating CFNetService for resolution"); - } - } else { - GWS_LOG_ERROR(@"Failed creating CFNetService for registration"); - } - } - - if ([(NSNumber*)_GetOption(_options, GCDWebServerOption_RequestNATPortMapping, @NO) boolValue]) { - DNSServiceErrorType status = DNSServiceNATPortMappingCreate(&_dnsService, 0, 0, kDNSServiceProtocol_TCP, htons(port), htons(port), 0, _DNSServiceCallBack, (__bridge void*)self); - if (status == kDNSServiceErr_NoError) { - CFSocketContext context = {0, (__bridge void*)self, NULL, NULL, NULL}; - _dnsSocket = CFSocketCreateWithNative(kCFAllocatorDefault, DNSServiceRefSockFD(_dnsService), kCFSocketReadCallBack, _SocketCallBack, &context); - if (_dnsSocket) { - CFSocketSetSocketFlags(_dnsSocket, CFSocketGetSocketFlags(_dnsSocket) & ~kCFSocketCloseOnInvalidate); - _dnsSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, _dnsSocket, 0); - if (_dnsSource) { - CFRunLoopAddSource(CFRunLoopGetMain(), _dnsSource, kCFRunLoopCommonModes); - } else { - GWS_LOG_ERROR(@"Failed creating CFRunLoopSource"); - GWS_DNOT_REACHED(); - } - } else { - GWS_LOG_ERROR(@"Failed creating CFSocket"); - GWS_DNOT_REACHED(); - } - } else { - GWS_LOG_ERROR(@"Failed creating NAT port mapping (%i)", status); - } - } - - dispatch_resume(_source4); - dispatch_resume(_source6); - GWS_LOG_INFO(@"%@ started on port %i and reachable at %@", [self class], (int)_port, self.serverURL); - if ([_delegate respondsToSelector:@selector(webServerDidStart:)]) { - dispatch_async(dispatch_get_main_queue(), ^{ - [self->_delegate webServerDidStart:self]; - }); - } - - return YES; -} - -- (void)_stop { - GWS_DCHECK(_source4 != NULL); - - if (_dnsService) { - _dnsAddress = nil; - _dnsPort = 0; - if (_dnsSource) { - CFRunLoopSourceInvalidate(_dnsSource); - CFRelease(_dnsSource); - _dnsSource = NULL; - } - if (_dnsSocket) { - CFRelease(_dnsSocket); - _dnsSocket = NULL; - } - DNSServiceRefDeallocate(_dnsService); - _dnsService = NULL; - } - - if (_registrationService) { - if (_resolutionService) { - CFNetServiceUnscheduleFromRunLoop(_resolutionService, CFRunLoopGetMain(), kCFRunLoopCommonModes); - CFNetServiceSetClient(_resolutionService, NULL, NULL); - CFNetServiceCancel(_resolutionService); - CFRelease(_resolutionService); - _resolutionService = NULL; - } - CFNetServiceUnscheduleFromRunLoop(_registrationService, CFRunLoopGetMain(), kCFRunLoopCommonModes); - CFNetServiceSetClient(_registrationService, NULL, NULL); - CFNetServiceCancel(_registrationService); - CFRelease(_registrationService); - _registrationService = NULL; - } - - dispatch_source_cancel(_source6); - dispatch_source_cancel(_source4); - dispatch_group_wait(_sourceGroup, DISPATCH_TIME_FOREVER); // Wait until the cancellation handlers have been called which guarantees the listening sockets are closed -#if !OS_OBJECT_USE_OBJC_RETAIN_RELEASE - dispatch_release(_source6); -#endif - _source6 = NULL; -#if !OS_OBJECT_USE_OBJC_RETAIN_RELEASE - dispatch_release(_source4); -#endif - _source4 = NULL; - _port = 0; - _bindToLocalhost = NO; - - _serverName = nil; - _authenticationRealm = nil; - _authenticationBasicAccounts = nil; - _authenticationDigestAccounts = nil; - - dispatch_async(dispatch_get_main_queue(), ^{ - if (self->_disconnectTimer) { - CFRunLoopTimerInvalidate(self->_disconnectTimer); - CFRelease(self->_disconnectTimer); - self->_disconnectTimer = NULL; - [self _didDisconnect]; - } - }); - - GWS_LOG_INFO(@"%@ stopped", [self class]); - if ([_delegate respondsToSelector:@selector(webServerDidStop:)]) { - dispatch_async(dispatch_get_main_queue(), ^{ - [self->_delegate webServerDidStop:self]; - }); - } -} - -#if TARGET_OS_IPHONE - -- (void)_didEnterBackground:(NSNotification*)notification { - GWS_DCHECK([NSThread isMainThread]); - GWS_LOG_DEBUG(@"Did enter background"); - if ((_backgroundTask == UIBackgroundTaskInvalid) && _source4) { - [self _stop]; - } -} - -- (void)_willEnterForeground:(NSNotification*)notification { - GWS_DCHECK([NSThread isMainThread]); - GWS_LOG_DEBUG(@"Will enter foreground"); - if (!_source4) { - [self _start:NULL]; // TODO: There's probably nothing we can do on failure - } -} - -#endif - -- (BOOL)startWithOptions:(NSDictionary*)options error:(NSError**)error { - if (_options == nil) { - _options = options ? [options copy] : @{}; -#if TARGET_OS_IPHONE - _suspendInBackground = [(NSNumber*)_GetOption(_options, GCDWebServerOption_AutomaticallySuspendInBackground, @YES) boolValue]; - if (((_suspendInBackground == NO) || ([[UIApplication sharedApplication] applicationState] != UIApplicationStateBackground)) && ![self _start:error]) -#else - if (![self _start:error]) -#endif - { - _options = nil; - return NO; - } -#if TARGET_OS_IPHONE - if (_suspendInBackground) { - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_willEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil]; - } -#endif - return YES; - } else { - GWS_DNOT_REACHED(); - } - return NO; -} - -- (BOOL)isRunning { - return (_options ? YES : NO); -} - -- (void)stop { - if (_options) { -#if TARGET_OS_IPHONE - if (_suspendInBackground) { - [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil]; - } -#endif - if (_source4) { - [self _stop]; - } - _options = nil; - } else { - GWS_DNOT_REACHED(); - } -} - -@end - -@implementation GCDWebServer (Extensions) - -- (NSURL*)serverURL { - if (_source4) { - NSString* ipAddress = _bindToLocalhost ? @"localhost" : GCDWebServerGetPrimaryIPAddress(NO); // We can't really use IPv6 anyway as it doesn't work great with HTTP URLs in practice - if (ipAddress) { - if (_port != 80) { - return [NSURL URLWithString:[NSString stringWithFormat:@"http://%@:%i/", ipAddress, (int)_port]]; - } else { - return [NSURL URLWithString:[NSString stringWithFormat:@"http://%@/", ipAddress]]; - } - } - } - return nil; -} - -- (NSURL*)bonjourServerURL { - if (_source4 && _resolutionService) { - NSString* name = (__bridge NSString*)CFNetServiceGetTargetHost(_resolutionService); - if (name.length) { - name = [name substringToIndex:(name.length - 1)]; // Strip trailing period at end of domain - if (_port != 80) { - return [NSURL URLWithString:[NSString stringWithFormat:@"http://%@:%i/", name, (int)_port]]; - } else { - return [NSURL URLWithString:[NSString stringWithFormat:@"http://%@/", name]]; - } - } - } - return nil; -} - -- (NSURL*)publicServerURL { - if (_source4 && _dnsService && _dnsAddress && _dnsPort) { - if (_dnsPort != 80) { - return [NSURL URLWithString:[NSString stringWithFormat:@"http://%@:%i/", _dnsAddress, (int)_dnsPort]]; - } else { - return [NSURL URLWithString:[NSString stringWithFormat:@"http://%@/", _dnsAddress]]; - } - } - return nil; -} - -- (BOOL)start { - return [self startWithPort:kDefaultPort bonjourName:@""]; -} - -- (BOOL)startWithPort:(NSUInteger)port bonjourName:(NSString*)name { - NSMutableDictionary* options = [NSMutableDictionary dictionary]; - [options setObject:[NSNumber numberWithInteger:port] forKey:GCDWebServerOption_Port]; - [options setValue:name forKey:GCDWebServerOption_BonjourName]; - return [self startWithOptions:options error:NULL]; -} - -#if !TARGET_OS_IPHONE - -- (BOOL)runWithPort:(NSUInteger)port bonjourName:(NSString*)name { - NSMutableDictionary* options = [NSMutableDictionary dictionary]; - [options setObject:[NSNumber numberWithInteger:port] forKey:GCDWebServerOption_Port]; - [options setValue:name forKey:GCDWebServerOption_BonjourName]; - return [self runWithOptions:options error:NULL]; -} - -- (BOOL)runWithOptions:(NSDictionary*)options error:(NSError**)error { - GWS_DCHECK([NSThread isMainThread]); - BOOL success = NO; - _run = YES; - void (*termHandler)(int) = signal(SIGTERM, _SignalHandler); - void (*intHandler)(int) = signal(SIGINT, _SignalHandler); - if ((termHandler != SIG_ERR) && (intHandler != SIG_ERR)) { - if ([self startWithOptions:options error:error]) { - while (_run) { - CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0, true); - } - [self stop]; - success = YES; - } - _ExecuteMainThreadRunLoopSources(); - signal(SIGINT, intHandler); - signal(SIGTERM, termHandler); - } - return success; -} - -#endif - -@end - -@implementation GCDWebServer (Handlers) - -- (void)addDefaultHandlerForMethod:(NSString*)method requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block { - [self addDefaultHandlerForMethod:method - requestClass:aClass - asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) { - completionBlock(block(request)); - }]; -} - -- (void)addDefaultHandlerForMethod:(NSString*)method requestClass:(Class)aClass asyncProcessBlock:(GCDWebServerAsyncProcessBlock)block { - [self - addHandlerWithMatchBlock:^GCDWebServerRequest*(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) { - if (![requestMethod isEqualToString:method]) { - return nil; - } - return [(GCDWebServerRequest*)[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]; - } - asyncProcessBlock:block]; -} - -- (void)addHandlerForMethod:(NSString*)method path:(NSString*)path requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block { - [self addHandlerForMethod:method - path:path - requestClass:aClass - asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) { - completionBlock(block(request)); - }]; -} - -- (void)addHandlerForMethod:(NSString*)method path:(NSString*)path requestClass:(Class)aClass asyncProcessBlock:(GCDWebServerAsyncProcessBlock)block { - if ([path hasPrefix:@"/"] && [aClass isSubclassOfClass:[GCDWebServerRequest class]]) { - [self - addHandlerWithMatchBlock:^GCDWebServerRequest*(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) { - if (![requestMethod isEqualToString:method]) { - return nil; - } - if ([urlPath caseInsensitiveCompare:path] != NSOrderedSame) { - return nil; - } - return [(GCDWebServerRequest*)[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]; - } - asyncProcessBlock:block]; - } else { - GWS_DNOT_REACHED(); - } -} - -- (void)addHandlerForMethod:(NSString*)method pathRegex:(NSString*)regex requestClass:(Class)aClass processBlock:(GCDWebServerProcessBlock)block { - [self addHandlerForMethod:method - pathRegex:regex - requestClass:aClass - asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) { - completionBlock(block(request)); - }]; -} - -- (void)addHandlerForMethod:(NSString*)method pathRegex:(NSString*)regex requestClass:(Class)aClass asyncProcessBlock:(GCDWebServerAsyncProcessBlock)block { - NSRegularExpression* expression = [NSRegularExpression regularExpressionWithPattern:regex options:NSRegularExpressionCaseInsensitive error:NULL]; - if (expression && [aClass isSubclassOfClass:[GCDWebServerRequest class]]) { - [self - addHandlerWithMatchBlock:^GCDWebServerRequest*(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) { - if (![requestMethod isEqualToString:method]) { - return nil; - } - - NSArray* matches = [expression matchesInString:urlPath options:0 range:NSMakeRange(0, urlPath.length)]; - if (matches.count == 0) { - return nil; - } - - NSMutableArray* captures = [NSMutableArray array]; - for (NSTextCheckingResult* result in matches) { - // Start at 1; index 0 is the whole string - for (NSUInteger i = 1; i < result.numberOfRanges; i++) { - NSRange range = [result rangeAtIndex:i]; - // range is {NSNotFound, 0} "if one of the capture groups did not participate in this particular match" - // see discussion in -[NSRegularExpression firstMatchInString:options:range:] - if (range.location != NSNotFound) { - [captures addObject:[urlPath substringWithRange:range]]; - } - } - } - - GCDWebServerRequest* request = [(GCDWebServerRequest*)[aClass alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]; - [request setAttribute:captures forKey:GCDWebServerRequestAttribute_RegexCaptures]; - return request; - } - asyncProcessBlock:block]; - } else { - GWS_DNOT_REACHED(); - } -} - -@end - -@implementation GCDWebServer (GETHandlers) - -- (void)addGETHandlerForPath:(NSString*)path staticData:(NSData*)staticData contentType:(NSString*)contentType cacheAge:(NSUInteger)cacheAge { - [self addHandlerForMethod:@"GET" - path:path - requestClass:[GCDWebServerRequest class] - processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) { - GCDWebServerResponse* response = [GCDWebServerDataResponse responseWithData:staticData contentType:contentType]; - response.cacheControlMaxAge = cacheAge; - return response; - }]; -} - -- (void)addGETHandlerForPath:(NSString*)path filePath:(NSString*)filePath isAttachment:(BOOL)isAttachment cacheAge:(NSUInteger)cacheAge allowRangeRequests:(BOOL)allowRangeRequests { - [self addHandlerForMethod:@"GET" - path:path - requestClass:[GCDWebServerRequest class] - processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) { - GCDWebServerResponse* response = nil; - if (allowRangeRequests) { - response = [GCDWebServerFileResponse responseWithFile:filePath byteRange:request.byteRange isAttachment:isAttachment]; - [response setValue:@"bytes" forAdditionalHeader:@"Accept-Ranges"]; - } else { - response = [GCDWebServerFileResponse responseWithFile:filePath isAttachment:isAttachment]; - } - response.cacheControlMaxAge = cacheAge; - return response; - }]; -} - -- (GCDWebServerResponse*)_responseWithContentsOfDirectory:(NSString*)path { - NSArray* contents = [[[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:NULL] sortedArrayUsingSelector:@selector(localizedStandardCompare:)]; - if (contents == nil) { - return nil; - } - NSMutableString* html = [NSMutableString string]; - [html appendString:@"\n"]; - [html appendString:@"\n"]; - [html appendString:@"
    \n"]; - for (NSString* entry in contents) { - if (![entry hasPrefix:@"."]) { - NSString* type = [[[NSFileManager defaultManager] attributesOfItemAtPath:[path stringByAppendingPathComponent:entry] error:NULL] objectForKey:NSFileType]; - GWS_DCHECK(type); -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - NSString* escapedFile = [entry stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; -#pragma clang diagnostic pop - GWS_DCHECK(escapedFile); - if ([type isEqualToString:NSFileTypeRegular]) { - [html appendFormat:@"
  • %@
  • \n", escapedFile, entry]; - } else if ([type isEqualToString:NSFileTypeDirectory]) { - [html appendFormat:@"
  • %@/
  • \n", escapedFile, entry]; - } - } - } - [html appendString:@"
\n"]; - [html appendString:@"\n"]; - return [GCDWebServerDataResponse responseWithHTML:html]; -} - -- (void)addGETHandlerForBasePath:(NSString*)basePath directoryPath:(NSString*)directoryPath indexFilename:(NSString*)indexFilename cacheAge:(NSUInteger)cacheAge allowRangeRequests:(BOOL)allowRangeRequests { - if ([basePath hasPrefix:@"/"] && [basePath hasSuffix:@"/"]) { - GCDWebServer* __unsafe_unretained server = self; - [self - addHandlerWithMatchBlock:^GCDWebServerRequest*(NSString* requestMethod, NSURL* requestURL, NSDictionary* requestHeaders, NSString* urlPath, NSDictionary* urlQuery) { - if (![requestMethod isEqualToString:@"GET"]) { - return nil; - } - if (![urlPath hasPrefix:basePath]) { - return nil; - } - return [[GCDWebServerRequest alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:urlPath query:urlQuery]; - } - processBlock:^GCDWebServerResponse*(GCDWebServerRequest* request) { - GCDWebServerResponse* response = nil; - NSString* filePath = [directoryPath stringByAppendingPathComponent:GCDWebServerNormalizePath([request.path substringFromIndex:basePath.length])]; - NSString* fileType = [[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:NULL] fileType]; - if (fileType) { - if ([fileType isEqualToString:NSFileTypeDirectory]) { - if (indexFilename) { - NSString* indexPath = [filePath stringByAppendingPathComponent:indexFilename]; - NSString* indexType = [[[NSFileManager defaultManager] attributesOfItemAtPath:indexPath error:NULL] fileType]; - if ([indexType isEqualToString:NSFileTypeRegular]) { - return [GCDWebServerFileResponse responseWithFile:indexPath]; - } - } - response = [server _responseWithContentsOfDirectory:filePath]; - } else if ([fileType isEqualToString:NSFileTypeRegular]) { - if (allowRangeRequests) { - response = [GCDWebServerFileResponse responseWithFile:filePath byteRange:request.byteRange]; - [response setValue:@"bytes" forAdditionalHeader:@"Accept-Ranges"]; - } else { - response = [GCDWebServerFileResponse responseWithFile:filePath]; - } - } - } - if (response) { - response.cacheControlMaxAge = cacheAge; - } else { - response = [GCDWebServerResponse responseWithStatusCode:kGCDWebServerHTTPStatusCode_NotFound]; - } - return response; - }]; - } else { - GWS_DNOT_REACHED(); - } -} - -@end - -@implementation GCDWebServer (Logging) - -+ (void)setLogLevel:(int)level { -#if defined(__GCDWEBSERVER_LOGGING_FACILITY_XLFACILITY__) - [XLSharedFacility setMinLogLevel:level]; -#elif defined(__GCDWEBSERVER_LOGGING_FACILITY_BUILTIN__) - GCDWebServerLogLevel = level; -#endif -} - -+ (void)setBuiltInLogger:(GCDWebServerBuiltInLoggerBlock)block { -#if defined(__GCDWEBSERVER_LOGGING_FACILITY_BUILTIN__) - _builtInLoggerBlock = block; -#else - GWS_DNOT_REACHED(); // Built-in logger must be enabled in order to override -#endif -} - -- (void)logVerbose:(NSString*)format, ... { - va_list arguments; - va_start(arguments, format); - GWS_LOG_VERBOSE(@"%@", [[NSString alloc] initWithFormat:format arguments:arguments]); - va_end(arguments); -} - -- (void)logInfo:(NSString*)format, ... { - va_list arguments; - va_start(arguments, format); - GWS_LOG_INFO(@"%@", [[NSString alloc] initWithFormat:format arguments:arguments]); - va_end(arguments); -} - -- (void)logWarning:(NSString*)format, ... { - va_list arguments; - va_start(arguments, format); - GWS_LOG_WARNING(@"%@", [[NSString alloc] initWithFormat:format arguments:arguments]); - va_end(arguments); -} - -- (void)logError:(NSString*)format, ... { - va_list arguments; - va_start(arguments, format); - GWS_LOG_ERROR(@"%@", [[NSString alloc] initWithFormat:format arguments:arguments]); - va_end(arguments); -} - -@end - -#ifdef __GCDWEBSERVER_ENABLE_TESTING__ - -@implementation GCDWebServer (Testing) - -- (void)setRecordingEnabled:(BOOL)flag { - _recording = flag; -} - -- (BOOL)isRecordingEnabled { - return _recording; -} - -static CFHTTPMessageRef _CreateHTTPMessageFromData(NSData* data, BOOL isRequest) { - CFHTTPMessageRef message = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, isRequest); - if (CFHTTPMessageAppendBytes(message, data.bytes, data.length)) { - return message; - } - CFRelease(message); - return NULL; -} - -static CFHTTPMessageRef _CreateHTTPMessageFromPerformingRequest(NSData* inData, NSUInteger port) { - CFHTTPMessageRef response = NULL; - int httpSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (httpSocket > 0) { - struct sockaddr_in addr4; - bzero(&addr4, sizeof(addr4)); - addr4.sin_len = sizeof(addr4); - addr4.sin_family = AF_INET; - addr4.sin_port = htons(port); - addr4.sin_addr.s_addr = htonl(INADDR_ANY); - if (connect(httpSocket, (void*)&addr4, sizeof(addr4)) == 0) { - if (write(httpSocket, inData.bytes, inData.length) == (ssize_t)inData.length) { - NSMutableData* outData = [[NSMutableData alloc] initWithLength:(256 * 1024)]; - NSUInteger length = 0; - while (1) { - ssize_t result = read(httpSocket, (char*)outData.mutableBytes + length, outData.length - length); - if (result < 0) { - length = NSUIntegerMax; - break; - } else if (result == 0) { - break; - } - length += result; - if (length >= outData.length) { - outData.length = 2 * outData.length; - } - } - if (length != NSUIntegerMax) { - outData.length = length; - response = _CreateHTTPMessageFromData(outData, NO); - } else { - GWS_DNOT_REACHED(); - } - } - } - close(httpSocket); - } - return response; -} - -static void _LogResult(NSString* format, ...) { - va_list arguments; - va_start(arguments, format); - NSString* message = [[NSString alloc] initWithFormat:format arguments:arguments]; - va_end(arguments); - fprintf(stdout, "%s\n", [message UTF8String]); -} - -- (NSInteger)runTestsWithOptions:(NSDictionary*)options inDirectory:(NSString*)path { - GWS_DCHECK([NSThread isMainThread]); - NSArray* ignoredHeaders = @[ @"Date", @"Etag" ]; // Dates are always different by definition and ETags depend on file system node IDs - NSInteger result = -1; - if ([self startWithOptions:options error:NULL]) { - _ExecuteMainThreadRunLoopSources(); - - result = 0; - NSArray* files = [[[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:NULL] sortedArrayUsingSelector:@selector(localizedStandardCompare:)]; - for (NSString* requestFile in files) { - if (![requestFile hasSuffix:@".request"]) { - continue; - } - @autoreleasepool { - NSString* index = [[requestFile componentsSeparatedByString:@"-"] firstObject]; - BOOL success = NO; - NSData* requestData = [NSData dataWithContentsOfFile:[path stringByAppendingPathComponent:requestFile]]; - if (requestData) { - CFHTTPMessageRef request = _CreateHTTPMessageFromData(requestData, YES); - if (request) { - NSString* requestMethod = CFBridgingRelease(CFHTTPMessageCopyRequestMethod(request)); - NSURL* requestURL = CFBridgingRelease(CFHTTPMessageCopyRequestURL(request)); - _LogResult(@"[%i] %@ %@", (int)[index integerValue], requestMethod, requestURL.path); - NSString* prefix = [index stringByAppendingString:@"-"]; - for (NSString* responseFile in files) { - if ([responseFile hasPrefix:prefix] && [responseFile hasSuffix:@".response"]) { - NSData* responseData = [NSData dataWithContentsOfFile:[path stringByAppendingPathComponent:responseFile]]; - if (responseData) { - CFHTTPMessageRef expectedResponse = _CreateHTTPMessageFromData(responseData, NO); - if (expectedResponse) { - CFHTTPMessageRef actualResponse = _CreateHTTPMessageFromPerformingRequest(requestData, self.port); - if (actualResponse) { - success = YES; - - CFIndex expectedStatusCode = CFHTTPMessageGetResponseStatusCode(expectedResponse); - CFIndex actualStatusCode = CFHTTPMessageGetResponseStatusCode(actualResponse); - if (actualStatusCode != expectedStatusCode) { - _LogResult(@" Status code not matching:\n Expected: %i\n Actual: %i", (int)expectedStatusCode, (int)actualStatusCode); - success = NO; - } - - NSDictionary* expectedHeaders = CFBridgingRelease(CFHTTPMessageCopyAllHeaderFields(expectedResponse)); - NSDictionary* actualHeaders = CFBridgingRelease(CFHTTPMessageCopyAllHeaderFields(actualResponse)); - for (NSString* expectedHeader in expectedHeaders) { - if ([ignoredHeaders containsObject:expectedHeader]) { - continue; - } - NSString* expectedValue = [expectedHeaders objectForKey:expectedHeader]; - NSString* actualValue = [actualHeaders objectForKey:expectedHeader]; - if (![actualValue isEqualToString:expectedValue]) { - _LogResult(@" Header '%@' not matching:\n Expected: \"%@\"\n Actual: \"%@\"", expectedHeader, expectedValue, actualValue); - success = NO; - } - } - for (NSString* actualHeader in actualHeaders) { - if (![expectedHeaders objectForKey:actualHeader]) { - _LogResult(@" Header '%@' not matching:\n Expected: \"%@\"\n Actual: \"%@\"", actualHeader, nil, [actualHeaders objectForKey:actualHeader]); - success = NO; - } - } - - NSString* expectedContentLength = CFBridgingRelease(CFHTTPMessageCopyHeaderFieldValue(expectedResponse, CFSTR("Content-Length"))); - NSData* expectedBody = CFBridgingRelease(CFHTTPMessageCopyBody(expectedResponse)); - NSString* actualContentLength = CFBridgingRelease(CFHTTPMessageCopyHeaderFieldValue(actualResponse, CFSTR("Content-Length"))); - NSData* actualBody = CFBridgingRelease(CFHTTPMessageCopyBody(actualResponse)); - if ([actualContentLength isEqualToString:expectedContentLength] && (actualBody.length > expectedBody.length)) { // Handle web browser closing connection before retrieving entire body (e.g. when playing a video file) - actualBody = [actualBody subdataWithRange:NSMakeRange(0, expectedBody.length)]; - } - if ((actualBody && expectedBody && ![actualBody isEqualToData:expectedBody]) || (actualBody && !expectedBody) || (!actualBody && expectedBody)) { - _LogResult(@" Bodies not matching:\n Expected: %lu bytes\n Actual: %lu bytes", (unsigned long)expectedBody.length, (unsigned long)actualBody.length); - success = NO; -#if !TARGET_OS_IPHONE -#if DEBUG - if (GCDWebServerIsTextContentType((NSString*)[expectedHeaders objectForKey:@"Content-Type"])) { - NSString* expectedPath = [NSTemporaryDirectory() stringByAppendingPathComponent:(NSString*)[[[NSProcessInfo processInfo] globallyUniqueString] stringByAppendingPathExtension:@"txt"]]; - NSString* actualPath = [NSTemporaryDirectory() stringByAppendingPathComponent:(NSString*)[[[NSProcessInfo processInfo] globallyUniqueString] stringByAppendingPathExtension:@"txt"]]; - if ([expectedBody writeToFile:expectedPath atomically:YES] && [actualBody writeToFile:actualPath atomically:YES]) { - NSTask* task = [[NSTask alloc] init]; - [task setLaunchPath:@"/usr/bin/opendiff"]; - [task setArguments:@[ expectedPath, actualPath ]]; - [task launch]; - } - } -#endif -#endif - } - - CFRelease(actualResponse); - } - CFRelease(expectedResponse); - } - } else { - GWS_DNOT_REACHED(); - } - break; - } - } - CFRelease(request); - } - } else { - GWS_DNOT_REACHED(); - } - _LogResult(@""); - if (!success) { - ++result; - } - } - _ExecuteMainThreadRunLoopSources(); - } - - [self stop]; - - _ExecuteMainThreadRunLoopSources(); - } - return result; -} - -@end - -#endif diff --git a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerConnection.h b/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerConnection.h deleted file mode 100644 index 4d59b9f1f..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerConnection.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "GCDWebServer.h" - -NS_ASSUME_NONNULL_BEGIN - -@class GCDWebServerHandler; - -/** - * The GCDWebServerConnection class is instantiated by GCDWebServer to handle - * each new HTTP connection. Each instance stays alive until the connection is - * closed. - * - * You cannot use this class directly, but it is made public so you can - * subclass it to override some hooks. Use the GCDWebServerOption_ConnectionClass - * option for GCDWebServer to install your custom subclass. - * - * @warning The GCDWebServerConnection retains the GCDWebServer until the - * connection is closed. - */ -@interface GCDWebServerConnection : NSObject - -/** - * Returns the GCDWebServer that owns the connection. - */ -@property(nonatomic, readonly) GCDWebServer* server; - -/** - * Returns YES if the connection is using IPv6. - */ -@property(nonatomic, readonly, getter=isUsingIPv6) BOOL usingIPv6; - -/** - * Returns the address of the local peer (i.e. server) of the connection - * as a raw "struct sockaddr". - */ -@property(nonatomic, readonly) NSData* localAddressData; - -/** - * Returns the address of the local peer (i.e. server) of the connection - * as a string. - */ -@property(nonatomic, readonly) NSString* localAddressString; - -/** - * Returns the address of the remote peer (i.e. client) of the connection - * as a raw "struct sockaddr". - */ -@property(nonatomic, readonly) NSData* remoteAddressData; - -/** - * Returns the address of the remote peer (i.e. client) of the connection - * as a string. - */ -@property(nonatomic, readonly) NSString* remoteAddressString; - -/** - * Returns the total number of bytes received from the remote peer (i.e. client) - * so far. - */ -@property(nonatomic, readonly) NSUInteger totalBytesRead; - -/** - * Returns the total number of bytes sent to the remote peer (i.e. client) so far. - */ -@property(nonatomic, readonly) NSUInteger totalBytesWritten; - -@end - -/** - * Hooks to customize the behavior of GCDWebServer HTTP connections. - * - * @warning These methods can be called on any GCD thread. - * Be sure to also call "super" when overriding them. - */ -@interface GCDWebServerConnection (Subclassing) - -/** - * This method is called when the connection is opened. - * - * Return NO to reject the connection e.g. after validating the local - * or remote address. - */ -- (BOOL)open; - -/** - * This method is called whenever data has been received - * from the remote peer (i.e. client). - * - * @warning Do not attempt to modify this data. - */ -- (void)didReadBytes:(const void*)bytes length:(NSUInteger)length; - -/** - * This method is called whenever data has been sent - * to the remote peer (i.e. client). - * - * @warning Do not attempt to modify this data. - */ -- (void)didWriteBytes:(const void*)bytes length:(NSUInteger)length; - -/** - * This method is called after the HTTP headers have been received to - * allow replacing the request URL by another one. - * - * The default implementation returns the original URL. - */ -- (NSURL*)rewriteRequestURL:(NSURL*)url withMethod:(NSString*)method headers:(NSDictionary*)headers; - -/** - * Assuming a valid HTTP request was received, this method is called before - * the request is processed. - * - * Return a non-nil GCDWebServerResponse to bypass the request processing entirely. - * - * The default implementation checks for HTTP authentication if applicable - * and returns a barebone 401 status code response if authentication failed. - */ -- (nullable GCDWebServerResponse*)preflightRequest:(GCDWebServerRequest*)request; - -/** - * Assuming a valid HTTP request was received and -preflightRequest: returned nil, - * this method is called to process the request by executing the handler's - * process block. - */ -- (void)processRequest:(GCDWebServerRequest*)request completion:(GCDWebServerCompletionBlock)completion; - -/** - * Assuming a valid HTTP request was received and either -preflightRequest: - * or -processRequest:completion: returned a non-nil GCDWebServerResponse, - * this method is called to override the response. - * - * You can either modify the current response and return it, or return a - * completely new one. - * - * The default implementation replaces any response matching the "ETag" or - * "Last-Modified-Date" header of the request by a barebone "Not-Modified" (304) - * one. - */ -- (GCDWebServerResponse*)overrideResponse:(GCDWebServerResponse*)response forRequest:(GCDWebServerRequest*)request; - -/** - * This method is called if any error happens while validing or processing - * the request or if no GCDWebServerResponse was generated during processing. - * - * @warning If the request was invalid (e.g. the HTTP headers were malformed), - * the "request" argument will be nil. - */ -- (void)abortRequest:(nullable GCDWebServerRequest*)request withStatusCode:(NSInteger)statusCode; - -/** - * Called when the connection is closed. - */ -- (void)close; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerConnection.m b/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerConnection.m deleted file mode 100644 index 574079459..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerConnection.m +++ /dev/null @@ -1,843 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !__has_feature(objc_arc) -#error GCDWebServer requires ARC -#endif - -#import -#import -#ifdef __GCDWEBSERVER_ENABLE_TESTING__ -#import -#endif - -#import "GCDWebServerPrivate.h" - -#define kHeadersReadCapacity (1 * 1024) -#define kBodyReadCapacity (256 * 1024) - -typedef void (^ReadDataCompletionBlock)(BOOL success); -typedef void (^ReadHeadersCompletionBlock)(NSData* extraData); -typedef void (^ReadBodyCompletionBlock)(BOOL success); - -typedef void (^WriteDataCompletionBlock)(BOOL success); -typedef void (^WriteHeadersCompletionBlock)(BOOL success); -typedef void (^WriteBodyCompletionBlock)(BOOL success); - -static NSData* _CRLFData = nil; -static NSData* _CRLFCRLFData = nil; -static NSData* _continueData = nil; -static NSData* _lastChunkData = nil; -static NSString* _digestAuthenticationNonce = nil; -#ifdef __GCDWEBSERVER_ENABLE_TESTING__ -static int32_t _connectionCounter = 0; -#endif - -NS_ASSUME_NONNULL_BEGIN - -@interface GCDWebServerConnection (Read) -- (void)readData:(NSMutableData*)data withLength:(NSUInteger)length completionBlock:(ReadDataCompletionBlock)block; -- (void)readHeaders:(NSMutableData*)headersData withCompletionBlock:(ReadHeadersCompletionBlock)block; -- (void)readBodyWithRemainingLength:(NSUInteger)length completionBlock:(ReadBodyCompletionBlock)block; -- (void)readNextBodyChunk:(NSMutableData*)chunkData completionBlock:(ReadBodyCompletionBlock)block; -@end - -@interface GCDWebServerConnection (Write) -- (void)writeData:(NSData*)data withCompletionBlock:(WriteDataCompletionBlock)block; -- (void)writeHeadersWithCompletionBlock:(WriteHeadersCompletionBlock)block; -- (void)writeBodyWithCompletionBlock:(WriteBodyCompletionBlock)block; -@end - -NS_ASSUME_NONNULL_END - -@implementation GCDWebServerConnection { - CFSocketNativeHandle _socket; - BOOL _virtualHEAD; - - CFHTTPMessageRef _requestMessage; - GCDWebServerRequest* _request; - GCDWebServerHandler* _handler; - CFHTTPMessageRef _responseMessage; - GCDWebServerResponse* _response; - NSInteger _statusCode; - - BOOL _opened; -#ifdef __GCDWEBSERVER_ENABLE_TESTING__ - NSUInteger _connectionIndex; - NSString* _requestPath; - int _requestFD; - NSString* _responsePath; - int _responseFD; -#endif -} - -+ (void)initialize { - if (_CRLFData == nil) { - _CRLFData = [[NSData alloc] initWithBytes:"\r\n" length:2]; - GWS_DCHECK(_CRLFData); - } - if (_CRLFCRLFData == nil) { - _CRLFCRLFData = [[NSData alloc] initWithBytes:"\r\n\r\n" length:4]; - GWS_DCHECK(_CRLFCRLFData); - } - if (_continueData == nil) { - CFHTTPMessageRef message = CFHTTPMessageCreateResponse(kCFAllocatorDefault, 100, NULL, kCFHTTPVersion1_1); - _continueData = CFBridgingRelease(CFHTTPMessageCopySerializedMessage(message)); - CFRelease(message); - GWS_DCHECK(_continueData); - } - if (_lastChunkData == nil) { - _lastChunkData = [[NSData alloc] initWithBytes:"0\r\n\r\n" length:5]; - } - if (_digestAuthenticationNonce == nil) { - CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault); - _digestAuthenticationNonce = GCDWebServerComputeMD5Digest(@"%@", CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, uuid))); - CFRelease(uuid); - } -} - -- (BOOL)isUsingIPv6 { - const struct sockaddr* localSockAddr = _localAddressData.bytes; - return (localSockAddr->sa_family == AF_INET6); -} - -- (void)_initializeResponseHeadersWithStatusCode:(NSInteger)statusCode { - _statusCode = statusCode; - _responseMessage = CFHTTPMessageCreateResponse(kCFAllocatorDefault, statusCode, NULL, kCFHTTPVersion1_1); - CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Connection"), CFSTR("Close")); - CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Server"), (__bridge CFStringRef)_server.serverName); - CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Date"), (__bridge CFStringRef)GCDWebServerFormatRFC822([NSDate date])); -} - -- (void)_startProcessingRequest { - GWS_DCHECK(_responseMessage == NULL); - - GCDWebServerResponse* preflightResponse = [self preflightRequest:_request]; - if (preflightResponse) { - [self _finishProcessingRequest:preflightResponse]; - } else { - [self processRequest:_request - completion:^(GCDWebServerResponse* processResponse) { - [self _finishProcessingRequest:processResponse]; - }]; - } -} - -// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html -- (void)_finishProcessingRequest:(GCDWebServerResponse*)response { - GWS_DCHECK(_responseMessage == NULL); - BOOL hasBody = NO; - - if (response) { - response = [self overrideResponse:response forRequest:_request]; - } - if (response) { - if ([response hasBody]) { - [response prepareForReading]; - hasBody = !_virtualHEAD; - } - NSError* error = nil; - if (hasBody && ![response performOpen:&error]) { - GWS_LOG_ERROR(@"Failed opening response body for socket %i: %@", _socket, error); - } else { - _response = response; - } - } - - if (_response) { - [self _initializeResponseHeadersWithStatusCode:_response.statusCode]; - if (_response.lastModifiedDate) { - CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Last-Modified"), (__bridge CFStringRef)GCDWebServerFormatRFC822((NSDate*)_response.lastModifiedDate)); - } - if (_response.eTag) { - CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("ETag"), (__bridge CFStringRef)_response.eTag); - } - if ((_response.statusCode >= 200) && (_response.statusCode < 300)) { - if (_response.cacheControlMaxAge > 0) { - CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Cache-Control"), (__bridge CFStringRef)[NSString stringWithFormat:@"max-age=%i, public", (int)_response.cacheControlMaxAge]); - } else { - CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Cache-Control"), CFSTR("no-cache")); - } - } - if (_response.contentType != nil) { - CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Content-Type"), (__bridge CFStringRef)GCDWebServerNormalizeHeaderValue(_response.contentType)); - } - if (_response.contentLength != NSUIntegerMax) { - CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Content-Length"), (__bridge CFStringRef)[NSString stringWithFormat:@"%lu", (unsigned long)_response.contentLength]); - } - if (_response.usesChunkedTransferEncoding) { - CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Transfer-Encoding"), CFSTR("chunked")); - } - [_response.additionalHeaders enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL* stop) { - CFHTTPMessageSetHeaderFieldValue(self->_responseMessage, (__bridge CFStringRef)key, (__bridge CFStringRef)obj); - }]; - [self writeHeadersWithCompletionBlock:^(BOOL success) { - if (success) { - if (hasBody) { - [self writeBodyWithCompletionBlock:^(BOOL successInner) { - [self->_response performClose]; // TODO: There's nothing we can do on failure as headers have already been sent - }]; - } - } else if (hasBody) { - [self->_response performClose]; - } - }]; - } else { - [self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError]; - } -} - -- (void)_readBodyWithLength:(NSUInteger)length initialData:(NSData*)initialData { - NSError* error = nil; - if (![_request performOpen:&error]) { - GWS_LOG_ERROR(@"Failed opening request body for socket %i: %@", _socket, error); - [self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError]; - return; - } - - if (initialData.length) { - if (![_request performWriteData:initialData error:&error]) { - GWS_LOG_ERROR(@"Failed writing request body on socket %i: %@", _socket, error); - if (![_request performClose:&error]) { - GWS_LOG_ERROR(@"Failed closing request body for socket %i: %@", _socket, error); - } - [self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError]; - return; - } - length -= initialData.length; - } - - if (length) { - [self readBodyWithRemainingLength:length - completionBlock:^(BOOL success) { - NSError* localError = nil; - if ([self->_request performClose:&localError]) { - [self _startProcessingRequest]; - } else { - GWS_LOG_ERROR(@"Failed closing request body for socket %i: %@", self->_socket, error); - [self abortRequest:self->_request withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError]; - } - }]; - } else { - if ([_request performClose:&error]) { - [self _startProcessingRequest]; - } else { - GWS_LOG_ERROR(@"Failed closing request body for socket %i: %@", _socket, error); - [self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError]; - } - } -} - -- (void)_readChunkedBodyWithInitialData:(NSData*)initialData { - NSError* error = nil; - if (![_request performOpen:&error]) { - GWS_LOG_ERROR(@"Failed opening request body for socket %i: %@", _socket, error); - [self abortRequest:_request withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError]; - return; - } - - NSMutableData* chunkData = [[NSMutableData alloc] initWithData:initialData]; - [self readNextBodyChunk:chunkData - completionBlock:^(BOOL success) { - NSError* localError = nil; - if ([self->_request performClose:&localError]) { - [self _startProcessingRequest]; - } else { - GWS_LOG_ERROR(@"Failed closing request body for socket %i: %@", self->_socket, error); - [self abortRequest:self->_request withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError]; - } - }]; -} - -- (void)_readRequestHeaders { - _requestMessage = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, true); - NSMutableData* headersData = [[NSMutableData alloc] initWithCapacity:kHeadersReadCapacity]; - [self readHeaders:headersData - withCompletionBlock:^(NSData* extraData) { - if (extraData) { - NSString* requestMethod = CFBridgingRelease(CFHTTPMessageCopyRequestMethod(self->_requestMessage)); // Method verbs are case-sensitive and uppercase - if (self->_server.shouldAutomaticallyMapHEADToGET && [requestMethod isEqualToString:@"HEAD"]) { - requestMethod = @"GET"; - self->_virtualHEAD = YES; - } - NSDictionary* requestHeaders = CFBridgingRelease(CFHTTPMessageCopyAllHeaderFields(self->_requestMessage)); // Header names are case-insensitive but CFHTTPMessageCopyAllHeaderFields() will standardize the common ones - NSURL* requestURL = CFBridgingRelease(CFHTTPMessageCopyRequestURL(self->_requestMessage)); - if (requestURL) { - requestURL = [self rewriteRequestURL:requestURL withMethod:requestMethod headers:requestHeaders]; - GWS_DCHECK(requestURL); - } - NSString* urlPath = requestURL ? CFBridgingRelease(CFURLCopyPath((CFURLRef)requestURL)) : nil; // Don't use -[NSURL path] which strips the ending slash - if (urlPath == nil) { - urlPath = @"/"; // CFURLCopyPath() returns NULL for a relative URL with path "//" contrary to -[NSURL path] which returns "/" - } - NSString* requestPath = urlPath ? GCDWebServerUnescapeURLString(urlPath) : nil; - NSString* queryString = requestURL ? CFBridgingRelease(CFURLCopyQueryString((CFURLRef)requestURL, NULL)) : nil; // Don't use -[NSURL query] to make sure query is not unescaped; - NSDictionary* requestQuery = queryString ? GCDWebServerParseURLEncodedForm(queryString) : @{}; - if (requestMethod && requestURL && requestHeaders && requestPath && requestQuery) { - for (self->_handler in self->_server.handlers) { - self->_request = self->_handler.matchBlock(requestMethod, requestURL, requestHeaders, requestPath, requestQuery); - if (self->_request) { - break; - } - } - if (self->_request) { - self->_request.localAddressData = self.localAddressData; - self->_request.remoteAddressData = self.remoteAddressData; - if ([self->_request hasBody]) { - [self->_request prepareForWriting]; - if (self->_request.usesChunkedTransferEncoding || (extraData.length <= self->_request.contentLength)) { - NSString* expectHeader = [requestHeaders objectForKey:@"Expect"]; - if (expectHeader) { - if ([expectHeader caseInsensitiveCompare:@"100-continue"] == NSOrderedSame) { // TODO: Actually validate request before continuing - [self writeData:_continueData - withCompletionBlock:^(BOOL success) { - if (success) { - if (self->_request.usesChunkedTransferEncoding) { - [self _readChunkedBodyWithInitialData:extraData]; - } else { - [self _readBodyWithLength:self->_request.contentLength initialData:extraData]; - } - } - }]; - } else { - GWS_LOG_ERROR(@"Unsupported 'Expect' / 'Content-Length' header combination on socket %i", self->_socket); - [self abortRequest:self->_request withStatusCode:kGCDWebServerHTTPStatusCode_ExpectationFailed]; - } - } else { - if (self->_request.usesChunkedTransferEncoding) { - [self _readChunkedBodyWithInitialData:extraData]; - } else { - [self _readBodyWithLength:self->_request.contentLength initialData:extraData]; - } - } - } else { - GWS_LOG_ERROR(@"Unexpected 'Content-Length' header value on socket %i", self->_socket); - [self abortRequest:self->_request withStatusCode:kGCDWebServerHTTPStatusCode_BadRequest]; - } - } else { - [self _startProcessingRequest]; - } - } else { - self->_request = [[GCDWebServerRequest alloc] initWithMethod:requestMethod url:requestURL headers:requestHeaders path:requestPath query:requestQuery]; - GWS_DCHECK(self->_request); - [self abortRequest:self->_request withStatusCode:kGCDWebServerHTTPStatusCode_NotImplemented]; - } - } else { - [self abortRequest:nil withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError]; - GWS_DNOT_REACHED(); - } - } else { - [self abortRequest:nil withStatusCode:kGCDWebServerHTTPStatusCode_InternalServerError]; - } - }]; -} - -- (instancetype)initWithServer:(GCDWebServer*)server localAddress:(NSData*)localAddress remoteAddress:(NSData*)remoteAddress socket:(CFSocketNativeHandle)socket { - if ((self = [super init])) { - _server = server; - _localAddressData = localAddress; - _remoteAddressData = remoteAddress; - _socket = socket; - GWS_LOG_DEBUG(@"Did open connection on socket %i", _socket); - - [_server willStartConnection:self]; - - if (![self open]) { - close(_socket); - return nil; - } - _opened = YES; - - [self _readRequestHeaders]; - } - return self; -} - -- (NSString*)localAddressString { - return GCDWebServerStringFromSockAddr(_localAddressData.bytes, YES); -} - -- (NSString*)remoteAddressString { - return GCDWebServerStringFromSockAddr(_remoteAddressData.bytes, YES); -} - -- (void)dealloc { - int result = close(_socket); - if (result != 0) { - GWS_LOG_ERROR(@"Failed closing socket %i for connection: %s (%i)", _socket, strerror(errno), errno); - } else { - GWS_LOG_DEBUG(@"Did close connection on socket %i", _socket); - } - - if (_opened) { - [self close]; - } - - [_server didEndConnection:self]; - - if (_requestMessage) { - CFRelease(_requestMessage); - } - - if (_responseMessage) { - CFRelease(_responseMessage); - } -} - -@end - -@implementation GCDWebServerConnection (Read) - -- (void)readData:(NSMutableData*)data withLength:(NSUInteger)length completionBlock:(ReadDataCompletionBlock)block { - dispatch_read(_socket, length, dispatch_get_global_queue(_server.dispatchQueuePriority, 0), ^(dispatch_data_t buffer, int error) { - @autoreleasepool { - if (error == 0) { - size_t size = dispatch_data_get_size(buffer); - if (size > 0) { - NSUInteger originalLength = data.length; - dispatch_data_apply(buffer, ^bool(dispatch_data_t region, size_t chunkOffset, const void* chunkBytes, size_t chunkSize) { - [data appendBytes:chunkBytes length:chunkSize]; - return true; - }); - [self didReadBytes:((char*)data.bytes + originalLength) length:(data.length - originalLength)]; - block(YES); - } else { - if (self->_totalBytesRead > 0) { - GWS_LOG_ERROR(@"No more data available on socket %i", self->_socket); - } else { - GWS_LOG_WARNING(@"No data received from socket %i", self->_socket); - } - block(NO); - } - } else { - GWS_LOG_ERROR(@"Error while reading from socket %i: %s (%i)", self->_socket, strerror(error), error); - block(NO); - } - } - }); -} - -- (void)readHeaders:(NSMutableData*)headersData withCompletionBlock:(ReadHeadersCompletionBlock)block { - GWS_DCHECK(_requestMessage); - [self readData:headersData - withLength:NSUIntegerMax - completionBlock:^(BOOL success) { - if (success) { - NSRange range = [headersData rangeOfData:_CRLFCRLFData options:0 range:NSMakeRange(0, headersData.length)]; - if (range.location == NSNotFound) { - [self readHeaders:headersData withCompletionBlock:block]; - } else { - NSUInteger length = range.location + range.length; - if (CFHTTPMessageAppendBytes(self->_requestMessage, headersData.bytes, length)) { - if (CFHTTPMessageIsHeaderComplete(self->_requestMessage)) { - block([headersData subdataWithRange:NSMakeRange(length, headersData.length - length)]); - } else { - GWS_LOG_ERROR(@"Failed parsing request headers from socket %i", self->_socket); - block(nil); - } - } else { - GWS_LOG_ERROR(@"Failed appending request headers data from socket %i", self->_socket); - block(nil); - } - } - } else { - block(nil); - } - }]; -} - -- (void)readBodyWithRemainingLength:(NSUInteger)length completionBlock:(ReadBodyCompletionBlock)block { - GWS_DCHECK([_request hasBody] && ![_request usesChunkedTransferEncoding]); - NSMutableData* bodyData = [[NSMutableData alloc] initWithCapacity:kBodyReadCapacity]; - [self readData:bodyData - withLength:length - completionBlock:^(BOOL success) { - if (success) { - if (bodyData.length <= length) { - NSError* error = nil; - if ([self->_request performWriteData:bodyData error:&error]) { - NSUInteger remainingLength = length - bodyData.length; - if (remainingLength) { - [self readBodyWithRemainingLength:remainingLength completionBlock:block]; - } else { - block(YES); - } - } else { - GWS_LOG_ERROR(@"Failed writing request body on socket %i: %@", self->_socket, error); - block(NO); - } - } else { - GWS_LOG_ERROR(@"Unexpected extra content reading request body on socket %i", self->_socket); - block(NO); - GWS_DNOT_REACHED(); - } - } else { - block(NO); - } - }]; -} - -static inline NSUInteger _ScanHexNumber(const void* bytes, NSUInteger size) { - char buffer[size + 1]; - bcopy(bytes, buffer, size); - buffer[size] = 0; - char* end = NULL; - long result = strtol(buffer, &end, 16); - return ((end != NULL) && (*end == 0) && (result >= 0) ? result : NSNotFound); -} - -- (void)readNextBodyChunk:(NSMutableData*)chunkData completionBlock:(ReadBodyCompletionBlock)block { - GWS_DCHECK([_request hasBody] && [_request usesChunkedTransferEncoding]); - - while (1) { - NSRange range = [chunkData rangeOfData:_CRLFData options:0 range:NSMakeRange(0, chunkData.length)]; - if (range.location == NSNotFound) { - break; - } - NSRange extensionRange = [chunkData rangeOfData:[NSData dataWithBytes:";" length:1] options:0 range:NSMakeRange(0, range.location)]; // Ignore chunk extensions - NSUInteger length = _ScanHexNumber((char*)chunkData.bytes, extensionRange.location != NSNotFound ? extensionRange.location : range.location); - if (length != NSNotFound) { - if (length) { - if (chunkData.length < range.location + range.length + length + 2) { - break; - } - const char* ptr = (char*)chunkData.bytes + range.location + range.length + length; - if ((*ptr == '\r') && (*(ptr + 1) == '\n')) { - NSError* error = nil; - if ([_request performWriteData:[chunkData subdataWithRange:NSMakeRange(range.location + range.length, length)] error:&error]) { - [chunkData replaceBytesInRange:NSMakeRange(0, range.location + range.length + length + 2) withBytes:NULL length:0]; - } else { - GWS_LOG_ERROR(@"Failed writing request body on socket %i: %@", _socket, error); - block(NO); - return; - } - } else { - GWS_LOG_ERROR(@"Missing terminating CRLF sequence for chunk reading request body on socket %i", _socket); - block(NO); - return; - } - } else { - NSRange trailerRange = [chunkData rangeOfData:_CRLFCRLFData options:0 range:NSMakeRange(range.location, chunkData.length - range.location)]; // Ignore trailers - if (trailerRange.location != NSNotFound) { - block(YES); - return; - } - } - } else { - GWS_LOG_ERROR(@"Invalid chunk length reading request body on socket %i", _socket); - block(NO); - return; - } - } - - [self readData:chunkData - withLength:NSUIntegerMax - completionBlock:^(BOOL success) { - if (success) { - [self readNextBodyChunk:chunkData completionBlock:block]; - } else { - block(NO); - } - }]; -} - -@end - -@implementation GCDWebServerConnection (Write) - -- (void)writeData:(NSData*)data withCompletionBlock:(WriteDataCompletionBlock)block { - dispatch_data_t buffer = dispatch_data_create(data.bytes, data.length, dispatch_get_global_queue(_server.dispatchQueuePriority, 0), ^{ - [data self]; // Keeps ARC from releasing data too early - }); - dispatch_write(_socket, buffer, dispatch_get_global_queue(_server.dispatchQueuePriority, 0), ^(dispatch_data_t remainingData, int error) { - @autoreleasepool { - if (error == 0) { - GWS_DCHECK(remainingData == NULL); - [self didWriteBytes:data.bytes length:data.length]; - block(YES); - } else { - GWS_LOG_ERROR(@"Error while writing to socket %i: %s (%i)", self->_socket, strerror(error), error); - block(NO); - } - } - }); -#if !OS_OBJECT_USE_OBJC_RETAIN_RELEASE - dispatch_release(buffer); -#endif -} - -- (void)writeHeadersWithCompletionBlock:(WriteHeadersCompletionBlock)block { - GWS_DCHECK(_responseMessage); - CFDataRef data = CFHTTPMessageCopySerializedMessage(_responseMessage); - [self writeData:(__bridge NSData*)data withCompletionBlock:block]; - CFRelease(data); -} - -- (void)writeBodyWithCompletionBlock:(WriteBodyCompletionBlock)block { - GWS_DCHECK([_response hasBody]); - [_response performReadDataWithCompletion:^(NSData* data, NSError* error) { - if (data) { - if (data.length) { - if (self->_response.usesChunkedTransferEncoding) { - const char* hexString = [[NSString stringWithFormat:@"%lx", (unsigned long)data.length] UTF8String]; - size_t hexLength = strlen(hexString); - NSData* chunk = [NSMutableData dataWithLength:(hexLength + 2 + data.length + 2)]; - if (chunk == nil) { - GWS_LOG_ERROR(@"Failed allocating memory for response body chunk for socket %i: %@", self->_socket, error); - block(NO); - return; - } - char* ptr = (char*)[(NSMutableData*)chunk mutableBytes]; - bcopy(hexString, ptr, hexLength); - ptr += hexLength; - *ptr++ = '\r'; - *ptr++ = '\n'; - bcopy(data.bytes, ptr, data.length); - ptr += data.length; - *ptr++ = '\r'; - *ptr = '\n'; - data = chunk; - } - [self writeData:data - withCompletionBlock:^(BOOL success) { - if (success) { - [self writeBodyWithCompletionBlock:block]; - } else { - block(NO); - } - }]; - } else { - if (self->_response.usesChunkedTransferEncoding) { - [self writeData:_lastChunkData - withCompletionBlock:^(BOOL success) { - block(success); - }]; - } else { - block(YES); - } - } - } else { - GWS_LOG_ERROR(@"Failed reading response body for socket %i: %@", self->_socket, error); - block(NO); - } - }]; -} - -@end - -@implementation GCDWebServerConnection (Subclassing) - -- (BOOL)open { -#ifdef __GCDWEBSERVER_ENABLE_TESTING__ - if (_server.recordingEnabled) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - _connectionIndex = OSAtomicIncrement32(&_connectionCounter); -#pragma clang diagnostic pop - - _requestPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]]; - _requestFD = open([_requestPath fileSystemRepresentation], O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - GWS_DCHECK(_requestFD > 0); - - _responsePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]]; - _responseFD = open([_responsePath fileSystemRepresentation], O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - GWS_DCHECK(_responseFD > 0); - } -#endif - - return YES; -} - -- (void)didReadBytes:(const void*)bytes length:(NSUInteger)length { - GWS_LOG_DEBUG(@"Connection received %lu bytes on socket %i", (unsigned long)length, _socket); - _totalBytesRead += length; - -#ifdef __GCDWEBSERVER_ENABLE_TESTING__ - if ((_requestFD > 0) && (write(_requestFD, bytes, length) != (ssize_t)length)) { - GWS_LOG_ERROR(@"Failed recording request data: %s (%i)", strerror(errno), errno); - close(_requestFD); - _requestFD = 0; - } -#endif -} - -- (void)didWriteBytes:(const void*)bytes length:(NSUInteger)length { - GWS_LOG_DEBUG(@"Connection sent %lu bytes on socket %i", (unsigned long)length, _socket); - _totalBytesWritten += length; - -#ifdef __GCDWEBSERVER_ENABLE_TESTING__ - if ((_responseFD > 0) && (write(_responseFD, bytes, length) != (ssize_t)length)) { - GWS_LOG_ERROR(@"Failed recording response data: %s (%i)", strerror(errno), errno); - close(_responseFD); - _responseFD = 0; - } -#endif -} - -- (NSURL*)rewriteRequestURL:(NSURL*)url withMethod:(NSString*)method headers:(NSDictionary*)headers { - return url; -} - -// https://tools.ietf.org/html/rfc2617 -- (GCDWebServerResponse*)preflightRequest:(GCDWebServerRequest*)request { - GWS_LOG_DEBUG(@"Connection on socket %i preflighting request \"%@ %@\" with %lu bytes body", _socket, _virtualHEAD ? @"HEAD" : _request.method, _request.path, (unsigned long)_totalBytesRead); - GCDWebServerResponse* response = nil; - if (_server.authenticationBasicAccounts) { - __block BOOL authenticated = NO; - NSString* authorizationHeader = [request.headers objectForKey:@"Authorization"]; - if ([authorizationHeader hasPrefix:@"Basic "]) { - NSString* basicAccount = [authorizationHeader substringFromIndex:6]; - [_server.authenticationBasicAccounts enumerateKeysAndObjectsUsingBlock:^(NSString* username, NSString* digest, BOOL* stop) { - if ([basicAccount isEqualToString:digest]) { - authenticated = YES; - *stop = YES; - } - }]; - } - if (!authenticated) { - response = [GCDWebServerResponse responseWithStatusCode:kGCDWebServerHTTPStatusCode_Unauthorized]; - [response setValue:[NSString stringWithFormat:@"Basic realm=\"%@\"", _server.authenticationRealm] forAdditionalHeader:@"WWW-Authenticate"]; - } - } else if (_server.authenticationDigestAccounts) { - BOOL authenticated = NO; - BOOL isStaled = NO; - NSString* authorizationHeader = [request.headers objectForKey:@"Authorization"]; - if ([authorizationHeader hasPrefix:@"Digest "]) { - NSString* realm = GCDWebServerExtractHeaderValueParameter(authorizationHeader, @"realm"); - if (realm && [_server.authenticationRealm isEqualToString:realm]) { - NSString* nonce = GCDWebServerExtractHeaderValueParameter(authorizationHeader, @"nonce"); - if ([nonce isEqualToString:_digestAuthenticationNonce]) { - NSString* username = GCDWebServerExtractHeaderValueParameter(authorizationHeader, @"username"); - NSString* uri = GCDWebServerExtractHeaderValueParameter(authorizationHeader, @"uri"); - NSString* actualResponse = GCDWebServerExtractHeaderValueParameter(authorizationHeader, @"response"); - NSString* ha1 = [_server.authenticationDigestAccounts objectForKey:username]; - NSString* ha2 = GCDWebServerComputeMD5Digest(@"%@:%@", request.method, uri); // We cannot use "request.path" as the query string is required - NSString* expectedResponse = GCDWebServerComputeMD5Digest(@"%@:%@:%@", ha1, _digestAuthenticationNonce, ha2); - if ([actualResponse isEqualToString:expectedResponse]) { - authenticated = YES; - } - } else if (nonce.length) { - isStaled = YES; - } - } - } - if (!authenticated) { - response = [GCDWebServerResponse responseWithStatusCode:kGCDWebServerHTTPStatusCode_Unauthorized]; - [response setValue:[NSString stringWithFormat:@"Digest realm=\"%@\", nonce=\"%@\"%@", _server.authenticationRealm, _digestAuthenticationNonce, isStaled ? @", stale=TRUE" : @""] forAdditionalHeader:@"WWW-Authenticate"]; // TODO: Support Quality of Protection ("qop") - } - } - return response; -} - -- (void)processRequest:(GCDWebServerRequest*)request completion:(GCDWebServerCompletionBlock)completion { - GWS_LOG_DEBUG(@"Connection on socket %i processing request \"%@ %@\" with %lu bytes body", _socket, _virtualHEAD ? @"HEAD" : _request.method, _request.path, (unsigned long)_totalBytesRead); - _handler.asyncProcessBlock(request, [completion copy]); -} - -// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25 -// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26 -static inline BOOL _CompareResources(NSString* responseETag, NSString* requestETag, NSDate* responseLastModified, NSDate* requestLastModified) { - if (requestLastModified && responseLastModified) { - if ([responseLastModified compare:requestLastModified] != NSOrderedDescending) { - return YES; - } - } - if (requestETag && responseETag) { // Per the specs "If-None-Match" must be checked after "If-Modified-Since" - if ([requestETag isEqualToString:@"*"]) { - return YES; - } - if ([responseETag isEqualToString:requestETag]) { - return YES; - } - } - return NO; -} - -- (GCDWebServerResponse*)overrideResponse:(GCDWebServerResponse*)response forRequest:(GCDWebServerRequest*)request { - if ((response.statusCode >= 200) && (response.statusCode < 300) && _CompareResources(response.eTag, request.ifNoneMatch, response.lastModifiedDate, request.ifModifiedSince)) { - NSInteger code = [request.method isEqualToString:@"HEAD"] || [request.method isEqualToString:@"GET"] ? kGCDWebServerHTTPStatusCode_NotModified : kGCDWebServerHTTPStatusCode_PreconditionFailed; - GCDWebServerResponse* newResponse = [GCDWebServerResponse responseWithStatusCode:code]; - newResponse.cacheControlMaxAge = response.cacheControlMaxAge; - newResponse.lastModifiedDate = response.lastModifiedDate; - newResponse.eTag = response.eTag; - GWS_DCHECK(newResponse); - return newResponse; - } - return response; -} - -- (void)abortRequest:(GCDWebServerRequest*)request withStatusCode:(NSInteger)statusCode { - GWS_DCHECK(_responseMessage == NULL); - GWS_DCHECK((statusCode >= 400) && (statusCode < 600)); - [self _initializeResponseHeadersWithStatusCode:statusCode]; - [self writeHeadersWithCompletionBlock:^(BOOL success){ - // Nothing more to do - }]; - GWS_LOG_DEBUG(@"Connection aborted with status code %i on socket %i", (int)statusCode, _socket); -} - -- (void)close { -#ifdef __GCDWEBSERVER_ENABLE_TESTING__ - if (_requestPath) { - BOOL success = NO; - NSError* error = nil; - if (_requestFD > 0) { - close(_requestFD); - NSString* name = [NSString stringWithFormat:@"%03lu-%@.request", (unsigned long)_connectionIndex, _virtualHEAD ? @"HEAD" : _request.method]; - success = [[NSFileManager defaultManager] moveItemAtPath:_requestPath toPath:[[[NSFileManager defaultManager] currentDirectoryPath] stringByAppendingPathComponent:name] error:&error]; - } - if (!success) { - GWS_LOG_ERROR(@"Failed saving recorded request: %@", error); - GWS_DNOT_REACHED(); - } - unlink([_requestPath fileSystemRepresentation]); - } - - if (_responsePath) { - BOOL success = NO; - NSError* error = nil; - if (_responseFD > 0) { - close(_responseFD); - NSString* name = [NSString stringWithFormat:@"%03lu-%i.response", (unsigned long)_connectionIndex, (int)_statusCode]; - success = [[NSFileManager defaultManager] moveItemAtPath:_responsePath toPath:[[[NSFileManager defaultManager] currentDirectoryPath] stringByAppendingPathComponent:name] error:&error]; - } - if (!success) { - GWS_LOG_ERROR(@"Failed saving recorded response: %@", error); - GWS_DNOT_REACHED(); - } - unlink([_responsePath fileSystemRepresentation]); - } -#endif - - if (_request) { - GWS_LOG_VERBOSE(@"[%@] %@ %i \"%@ %@\" (%lu | %lu)", self.localAddressString, self.remoteAddressString, (int)_statusCode, _virtualHEAD ? @"HEAD" : _request.method, _request.path, (unsigned long)_totalBytesRead, (unsigned long)_totalBytesWritten); - } else { - GWS_LOG_VERBOSE(@"[%@] %@ %i \"(invalid request)\" (%lu | %lu)", self.localAddressString, self.remoteAddressString, (int)_statusCode, (unsigned long)_totalBytesRead, (unsigned long)_totalBytesWritten); - } -} - -@end diff --git a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerFunctions.h b/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerFunctions.h deleted file mode 100644 index 217fb1431..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerFunctions.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import - -NS_ASSUME_NONNULL_BEGIN - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Converts a file extension to the corresponding MIME type. - * If there is no match, "application/octet-stream" is returned. - * - * Overrides allow to customize the built-in mapping from extensions to MIME - * types. Keys of the dictionary must be lowercased file extensions without - * the period, and the values must be the corresponding MIME types. - */ -NSString* GCDWebServerGetMimeTypeForExtension(NSString* extension, NSDictionary* _Nullable overrides); - -/** - * Add percent-escapes to a string so it can be used in a URL. - * The legal characters ":@/?&=+" are also escaped to ensure compatibility - * with URL encoded forms and URL queries. - */ -NSString* _Nullable GCDWebServerEscapeURLString(NSString* string); - -/** - * Unescapes a URL percent-encoded string. - */ -NSString* _Nullable GCDWebServerUnescapeURLString(NSString* string); - -/** - * Extracts the unescaped names and values from an - * "application/x-www-form-urlencoded" form. - * http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1 - */ -NSDictionary* GCDWebServerParseURLEncodedForm(NSString* form); - -/** - * On OS X, returns the IPv4 or IPv6 address as a string of the primary - * connected service or nil if not available. - * - * On iOS, returns the IPv4 or IPv6 address as a string of the WiFi - * interface if connected or nil otherwise. - */ -NSString* _Nullable GCDWebServerGetPrimaryIPAddress(BOOL useIPv6); - -/** - * Converts a date into a string using RFC822 formatting. - * https://tools.ietf.org/html/rfc822#section-5 - * https://tools.ietf.org/html/rfc1123#section-5.2.14 - */ -NSString* GCDWebServerFormatRFC822(NSDate* date); - -/** - * Converts a RFC822 formatted string into a date. - * https://tools.ietf.org/html/rfc822#section-5 - * https://tools.ietf.org/html/rfc1123#section-5.2.14 - * - * @warning Timezones other than GMT are not supported by this function. - */ -NSDate* _Nullable GCDWebServerParseRFC822(NSString* string); - -/** - * Converts a date into a string using IOS 8601 formatting. - * http://tools.ietf.org/html/rfc3339#section-5.6 - */ -NSString* GCDWebServerFormatISO8601(NSDate* date); - -/** - * Converts a ISO 8601 formatted string into a date. - * http://tools.ietf.org/html/rfc3339#section-5.6 - * - * @warning Only "calendar" variant is supported at this time and timezones - * other than GMT are not supported either. - */ -NSDate* _Nullable GCDWebServerParseISO8601(NSString* string); - -/** - * Removes "//", "/./" and "/../" components from path as well as any trailing slash. - */ -NSString* GCDWebServerNormalizePath(NSString* path); - -#ifdef __cplusplus -} -#endif - -NS_ASSUME_NONNULL_END diff --git a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerFunctions.m b/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerFunctions.m deleted file mode 100644 index c855556ca..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerFunctions.m +++ /dev/null @@ -1,334 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !__has_feature(objc_arc) -#error GCDWebServer requires ARC -#endif - -#import -#if TARGET_OS_IPHONE -#import -#else -#import -#endif -#import - -#import -#import -#import - -#import "GCDWebServerPrivate.h" - -static NSDateFormatter* _dateFormatterRFC822 = nil; -static NSDateFormatter* _dateFormatterISO8601 = nil; -static dispatch_queue_t _dateFormatterQueue = NULL; - -// TODO: Handle RFC 850 and ANSI C's asctime() format -void GCDWebServerInitializeFunctions() { - GWS_DCHECK([NSThread isMainThread]); // NSDateFormatter should be initialized on main thread - if (_dateFormatterRFC822 == nil) { - _dateFormatterRFC822 = [[NSDateFormatter alloc] init]; - _dateFormatterRFC822.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"]; - _dateFormatterRFC822.dateFormat = @"EEE',' dd MMM yyyy HH':'mm':'ss 'GMT'"; - _dateFormatterRFC822.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]; - GWS_DCHECK(_dateFormatterRFC822); - } - if (_dateFormatterISO8601 == nil) { - _dateFormatterISO8601 = [[NSDateFormatter alloc] init]; - _dateFormatterISO8601.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"]; - _dateFormatterISO8601.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'+00:00'"; - _dateFormatterISO8601.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]; - GWS_DCHECK(_dateFormatterISO8601); - } - if (_dateFormatterQueue == NULL) { - _dateFormatterQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); - GWS_DCHECK(_dateFormatterQueue); - } -} - -NSString* GCDWebServerNormalizeHeaderValue(NSString* value) { - if (value) { - NSRange range = [value rangeOfString:@";"]; // Assume part before ";" separator is case-insensitive - if (range.location != NSNotFound) { - value = [[[value substringToIndex:range.location] lowercaseString] stringByAppendingString:[value substringFromIndex:range.location]]; - } else { - value = [value lowercaseString]; - } - } - return value; -} - -NSString* GCDWebServerTruncateHeaderValue(NSString* value) { - if (value) { - NSRange range = [value rangeOfString:@";"]; - if (range.location != NSNotFound) { - return [value substringToIndex:range.location]; - } - } - return value; -} - -NSString* GCDWebServerExtractHeaderValueParameter(NSString* value, NSString* name) { - NSString* parameter = nil; - if (value) { - NSScanner* scanner = [[NSScanner alloc] initWithString:value]; - [scanner setCaseSensitive:NO]; // Assume parameter names are case-insensitive - NSString* string = [NSString stringWithFormat:@"%@=", name]; - if ([scanner scanUpToString:string intoString:NULL]) { - [scanner scanString:string intoString:NULL]; - if ([scanner scanString:@"\"" intoString:NULL]) { - [scanner scanUpToString:@"\"" intoString:¶meter]; - } else { - [scanner scanUpToCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:¶meter]; - } - } - } - return parameter; -} - -// http://www.w3schools.com/tags/ref_charactersets.asp -NSStringEncoding GCDWebServerStringEncodingFromCharset(NSString* charset) { - NSStringEncoding encoding = kCFStringEncodingInvalidId; - if (charset) { - encoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef)charset)); - } - return (encoding != kCFStringEncodingInvalidId ? encoding : NSUTF8StringEncoding); -} - -NSString* GCDWebServerFormatRFC822(NSDate* date) { - __block NSString* string; - dispatch_sync(_dateFormatterQueue, ^{ - string = [_dateFormatterRFC822 stringFromDate:date]; - }); - return string; -} - -NSDate* GCDWebServerParseRFC822(NSString* string) { - __block NSDate* date; - dispatch_sync(_dateFormatterQueue, ^{ - date = [_dateFormatterRFC822 dateFromString:string]; - }); - return date; -} - -NSString* GCDWebServerFormatISO8601(NSDate* date) { - __block NSString* string; - dispatch_sync(_dateFormatterQueue, ^{ - string = [_dateFormatterISO8601 stringFromDate:date]; - }); - return string; -} - -NSDate* GCDWebServerParseISO8601(NSString* string) { - __block NSDate* date; - dispatch_sync(_dateFormatterQueue, ^{ - date = [_dateFormatterISO8601 dateFromString:string]; - }); - return date; -} - -BOOL GCDWebServerIsTextContentType(NSString* type) { - return ([type hasPrefix:@"text/"] || [type hasPrefix:@"application/json"] || [type hasPrefix:@"application/xml"]); -} - -NSString* GCDWebServerDescribeData(NSData* data, NSString* type) { - if (GCDWebServerIsTextContentType(type)) { - NSString* charset = GCDWebServerExtractHeaderValueParameter(type, @"charset"); - NSString* string = [[NSString alloc] initWithData:data encoding:GCDWebServerStringEncodingFromCharset(charset)]; - if (string) { - return string; - } - } - return [NSString stringWithFormat:@"<%lu bytes>", (unsigned long)data.length]; -} - -NSString* GCDWebServerGetMimeTypeForExtension(NSString* extension, NSDictionary* overrides) { - NSDictionary* builtInOverrides = @{@"css" : @"text/css"}; - NSString* mimeType = nil; - extension = [extension lowercaseString]; - if (extension.length) { - mimeType = [overrides objectForKey:extension]; - if (mimeType == nil) { - mimeType = [builtInOverrides objectForKey:extension]; - } - if (mimeType == nil) { - CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)extension, NULL); - if (uti) { - mimeType = CFBridgingRelease(UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)); - CFRelease(uti); - } - } - } - return mimeType ? mimeType : kGCDWebServerDefaultMimeType; -} - -NSString* GCDWebServerEscapeURLString(NSString* string) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)string, NULL, CFSTR(":@/?&=+"), kCFStringEncodingUTF8)); -#pragma clang diagnostic pop -} - -NSString* GCDWebServerUnescapeURLString(NSString* string) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - return CFBridgingRelease(CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault, (CFStringRef)string, CFSTR(""), kCFStringEncodingUTF8)); -#pragma clang diagnostic pop -} - -NSDictionary* GCDWebServerParseURLEncodedForm(NSString* form) { - NSMutableDictionary* parameters = [NSMutableDictionary dictionary]; - NSScanner* scanner = [[NSScanner alloc] initWithString:form]; - [scanner setCharactersToBeSkipped:nil]; - while (1) { - NSString* key = nil; - if (![scanner scanUpToString:@"=" intoString:&key] || [scanner isAtEnd]) { - break; - } - [scanner setScanLocation:([scanner scanLocation] + 1)]; - - NSString* value = nil; - [scanner scanUpToString:@"&" intoString:&value]; - if (value == nil) { - value = @""; - } - - key = [key stringByReplacingOccurrencesOfString:@"+" withString:@" "]; - NSString* unescapedKey = key ? GCDWebServerUnescapeURLString(key) : nil; - value = [value stringByReplacingOccurrencesOfString:@"+" withString:@" "]; - NSString* unescapedValue = value ? GCDWebServerUnescapeURLString(value) : nil; - if (unescapedKey && unescapedValue) { - [parameters setObject:unescapedValue forKey:unescapedKey]; - } else { - GWS_LOG_WARNING(@"Failed parsing URL encoded form for key \"%@\" and value \"%@\"", key, value); - GWS_DNOT_REACHED(); - } - - if ([scanner isAtEnd]) { - break; - } - [scanner setScanLocation:([scanner scanLocation] + 1)]; - } - return parameters; -} - -NSString* GCDWebServerStringFromSockAddr(const struct sockaddr* addr, BOOL includeService) { - char hostBuffer[NI_MAXHOST]; - char serviceBuffer[NI_MAXSERV]; - if (getnameinfo(addr, addr->sa_len, hostBuffer, sizeof(hostBuffer), serviceBuffer, sizeof(serviceBuffer), NI_NUMERICHOST | NI_NUMERICSERV | NI_NOFQDN) != 0) { -#if DEBUG - GWS_DNOT_REACHED(); -#else - return @""; -#endif - } - return includeService ? [NSString stringWithFormat:@"%s:%s", hostBuffer, serviceBuffer] : (NSString*)[NSString stringWithUTF8String:hostBuffer]; -} - -NSString* GCDWebServerGetPrimaryIPAddress(BOOL useIPv6) { - NSString* address = nil; -#if TARGET_OS_IPHONE -#if !TARGET_IPHONE_SIMULATOR && !TARGET_OS_TV - const char* primaryInterface = "en0"; // WiFi interface on iOS -#endif -#else - const char* primaryInterface = NULL; - SCDynamicStoreRef store = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("GCDWebServer"), NULL, NULL); - if (store) { - CFPropertyListRef info = SCDynamicStoreCopyValue(store, CFSTR("State:/Network/Global/IPv4")); // There is no equivalent for IPv6 but the primary interface should be the same - if (info) { - NSString* interface = [(__bridge NSDictionary*)info objectForKey:@"PrimaryInterface"]; - if (interface) { - primaryInterface = [[NSString stringWithString:interface] UTF8String]; // Copy string to auto-release pool - } - CFRelease(info); - } - CFRelease(store); - } - if (primaryInterface == NULL) { - primaryInterface = "lo0"; - } -#endif - struct ifaddrs* list; - if (getifaddrs(&list) >= 0) { - for (struct ifaddrs* ifap = list; ifap; ifap = ifap->ifa_next) { -#if TARGET_IPHONE_SIMULATOR || TARGET_OS_TV - // Assume en0 is Ethernet and en1 is WiFi since there is no way to use SystemConfiguration framework in iOS Simulator - // Assumption holds for Apple TV running tvOS - if (strcmp(ifap->ifa_name, "en0") && strcmp(ifap->ifa_name, "en1")) -#else - if (strcmp(ifap->ifa_name, primaryInterface)) -#endif - { - continue; - } - if ((ifap->ifa_flags & IFF_UP) && ((!useIPv6 && (ifap->ifa_addr->sa_family == AF_INET)) || (useIPv6 && (ifap->ifa_addr->sa_family == AF_INET6)))) { - address = GCDWebServerStringFromSockAddr(ifap->ifa_addr, NO); - break; - } - } - freeifaddrs(list); - } - return address; -} - -NSString* GCDWebServerComputeMD5Digest(NSString* format, ...) { - va_list arguments; - va_start(arguments, format); - const char* string = [[[NSString alloc] initWithFormat:format arguments:arguments] UTF8String]; - va_end(arguments); - unsigned char md5[CC_MD5_DIGEST_LENGTH]; -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - CC_MD5(string, (CC_LONG)strlen(string), md5); -#pragma clang diagnostic pop - char buffer[2 * CC_MD5_DIGEST_LENGTH + 1]; - for (int i = 0; i < CC_MD5_DIGEST_LENGTH; ++i) { - unsigned char byte = md5[i]; - unsigned char byteHi = (byte & 0xF0) >> 4; - buffer[2 * i + 0] = byteHi >= 10 ? 'a' + byteHi - 10 : '0' + byteHi; - unsigned char byteLo = byte & 0x0F; - buffer[2 * i + 1] = byteLo >= 10 ? 'a' + byteLo - 10 : '0' + byteLo; - } - buffer[2 * CC_MD5_DIGEST_LENGTH] = 0; - return (NSString*)[NSString stringWithUTF8String:buffer]; -} - -NSString* GCDWebServerNormalizePath(NSString* path) { - NSMutableArray* components = [[NSMutableArray alloc] init]; - for (NSString* component in [path componentsSeparatedByString:@"/"]) { - if ([component isEqualToString:@".."]) { - [components removeLastObject]; - } else if (component.length && ![component isEqualToString:@"."]) { - [components addObject:component]; - } - } - if (path.length && ([path characterAtIndex:0] == '/')) { - return [@"/" stringByAppendingString:[components componentsJoinedByString:@"/"]]; // Preserve initial slash - } - return [components componentsJoinedByString:@"/"]; -} diff --git a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerHTTPStatusCodes.h b/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerHTTPStatusCodes.h deleted file mode 100644 index 12b697e37..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerHTTPStatusCodes.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html -// http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml - -#import - -/** - * Convenience constants for "informational" HTTP status codes. - */ -typedef NS_ENUM(NSInteger, GCDWebServerInformationalHTTPStatusCode) { - kGCDWebServerHTTPStatusCode_Continue = 100, - kGCDWebServerHTTPStatusCode_SwitchingProtocols = 101, - kGCDWebServerHTTPStatusCode_Processing = 102 -}; - -/** - * Convenience constants for "successful" HTTP status codes. - */ -typedef NS_ENUM(NSInteger, GCDWebServerSuccessfulHTTPStatusCode) { - kGCDWebServerHTTPStatusCode_OK = 200, - kGCDWebServerHTTPStatusCode_Created = 201, - kGCDWebServerHTTPStatusCode_Accepted = 202, - kGCDWebServerHTTPStatusCode_NonAuthoritativeInformation = 203, - kGCDWebServerHTTPStatusCode_NoContent = 204, - kGCDWebServerHTTPStatusCode_ResetContent = 205, - kGCDWebServerHTTPStatusCode_PartialContent = 206, - kGCDWebServerHTTPStatusCode_MultiStatus = 207, - kGCDWebServerHTTPStatusCode_AlreadyReported = 208 -}; - -/** - * Convenience constants for "redirection" HTTP status codes. - */ -typedef NS_ENUM(NSInteger, GCDWebServerRedirectionHTTPStatusCode) { - kGCDWebServerHTTPStatusCode_MultipleChoices = 300, - kGCDWebServerHTTPStatusCode_MovedPermanently = 301, - kGCDWebServerHTTPStatusCode_Found = 302, - kGCDWebServerHTTPStatusCode_SeeOther = 303, - kGCDWebServerHTTPStatusCode_NotModified = 304, - kGCDWebServerHTTPStatusCode_UseProxy = 305, - kGCDWebServerHTTPStatusCode_TemporaryRedirect = 307, - kGCDWebServerHTTPStatusCode_PermanentRedirect = 308 -}; - -/** - * Convenience constants for "client error" HTTP status codes. - */ -typedef NS_ENUM(NSInteger, GCDWebServerClientErrorHTTPStatusCode) { - kGCDWebServerHTTPStatusCode_BadRequest = 400, - kGCDWebServerHTTPStatusCode_Unauthorized = 401, - kGCDWebServerHTTPStatusCode_PaymentRequired = 402, - kGCDWebServerHTTPStatusCode_Forbidden = 403, - kGCDWebServerHTTPStatusCode_NotFound = 404, - kGCDWebServerHTTPStatusCode_MethodNotAllowed = 405, - kGCDWebServerHTTPStatusCode_NotAcceptable = 406, - kGCDWebServerHTTPStatusCode_ProxyAuthenticationRequired = 407, - kGCDWebServerHTTPStatusCode_RequestTimeout = 408, - kGCDWebServerHTTPStatusCode_Conflict = 409, - kGCDWebServerHTTPStatusCode_Gone = 410, - kGCDWebServerHTTPStatusCode_LengthRequired = 411, - kGCDWebServerHTTPStatusCode_PreconditionFailed = 412, - kGCDWebServerHTTPStatusCode_RequestEntityTooLarge = 413, - kGCDWebServerHTTPStatusCode_RequestURITooLong = 414, - kGCDWebServerHTTPStatusCode_UnsupportedMediaType = 415, - kGCDWebServerHTTPStatusCode_RequestedRangeNotSatisfiable = 416, - kGCDWebServerHTTPStatusCode_ExpectationFailed = 417, - kGCDWebServerHTTPStatusCode_UnprocessableEntity = 422, - kGCDWebServerHTTPStatusCode_Locked = 423, - kGCDWebServerHTTPStatusCode_FailedDependency = 424, - kGCDWebServerHTTPStatusCode_UpgradeRequired = 426, - kGCDWebServerHTTPStatusCode_PreconditionRequired = 428, - kGCDWebServerHTTPStatusCode_TooManyRequests = 429, - kGCDWebServerHTTPStatusCode_RequestHeaderFieldsTooLarge = 431 -}; - -/** - * Convenience constants for "server error" HTTP status codes. - */ -typedef NS_ENUM(NSInteger, GCDWebServerServerErrorHTTPStatusCode) { - kGCDWebServerHTTPStatusCode_InternalServerError = 500, - kGCDWebServerHTTPStatusCode_NotImplemented = 501, - kGCDWebServerHTTPStatusCode_BadGateway = 502, - kGCDWebServerHTTPStatusCode_ServiceUnavailable = 503, - kGCDWebServerHTTPStatusCode_GatewayTimeout = 504, - kGCDWebServerHTTPStatusCode_HTTPVersionNotSupported = 505, - kGCDWebServerHTTPStatusCode_InsufficientStorage = 507, - kGCDWebServerHTTPStatusCode_LoopDetected = 508, - kGCDWebServerHTTPStatusCode_NotExtended = 510, - kGCDWebServerHTTPStatusCode_NetworkAuthenticationRequired = 511 -}; diff --git a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerPrivate.h b/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerPrivate.h deleted file mode 100644 index 4668a9787..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerPrivate.h +++ /dev/null @@ -1,224 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import -#import - -/** - * All GCDWebServer headers. - */ - -#import "GCDWebServerHTTPStatusCodes.h" -#import "GCDWebServerFunctions.h" - -#import "GCDWebServer.h" -#import "GCDWebServerConnection.h" - -#import "GCDWebServerDataRequest.h" -#import "GCDWebServerFileRequest.h" -#import "GCDWebServerMultiPartFormRequest.h" -#import "GCDWebServerURLEncodedFormRequest.h" - -#import "GCDWebServerDataResponse.h" -#import "GCDWebServerErrorResponse.h" -#import "GCDWebServerFileResponse.h" -#import "GCDWebServerStreamedResponse.h" - -/** - * Check if a custom logging facility should be used instead. - */ - -#if defined(__GCDWEBSERVER_LOGGING_HEADER__) - -#define __GCDWEBSERVER_LOGGING_FACILITY_CUSTOM__ - -#import __GCDWEBSERVER_LOGGING_HEADER__ - -/** - * Automatically detect if XLFacility is available and if so use it as a - * logging facility. - */ - -#elif defined(__has_include) && __has_include("XLFacilityMacros.h") - -#define __GCDWEBSERVER_LOGGING_FACILITY_XLFACILITY__ - -#undef XLOG_TAG -#define XLOG_TAG @"gcdwebserver.internal" - -#import "XLFacilityMacros.h" - -#define GWS_LOG_DEBUG(...) XLOG_DEBUG(__VA_ARGS__) -#define GWS_LOG_VERBOSE(...) XLOG_VERBOSE(__VA_ARGS__) -#define GWS_LOG_INFO(...) XLOG_INFO(__VA_ARGS__) -#define GWS_LOG_WARNING(...) XLOG_WARNING(__VA_ARGS__) -#define GWS_LOG_ERROR(...) XLOG_ERROR(__VA_ARGS__) - -#define GWS_DCHECK(__CONDITION__) XLOG_DEBUG_CHECK(__CONDITION__) -#define GWS_DNOT_REACHED() XLOG_DEBUG_UNREACHABLE() - -/** - * If all of the above fail, then use GCDWebServer built-in - * logging facility. - */ - -#else - -#define __GCDWEBSERVER_LOGGING_FACILITY_BUILTIN__ - -typedef NS_ENUM(int, GCDWebServerLoggingLevel) { - kGCDWebServerLoggingLevel_Debug = 0, - kGCDWebServerLoggingLevel_Verbose, - kGCDWebServerLoggingLevel_Info, - kGCDWebServerLoggingLevel_Warning, - kGCDWebServerLoggingLevel_Error -}; - -extern GCDWebServerLoggingLevel GCDWebServerLogLevel; -extern void GCDWebServerLogMessage(GCDWebServerLoggingLevel level, NSString* _Nonnull format, ...) NS_FORMAT_FUNCTION(2, 3); - -#if DEBUG -#define GWS_LOG_DEBUG(...) \ - do { \ - if (GCDWebServerLogLevel <= kGCDWebServerLoggingLevel_Debug) GCDWebServerLogMessage(kGCDWebServerLoggingLevel_Debug, __VA_ARGS__); \ - } while (0) -#else -#define GWS_LOG_DEBUG(...) -#endif -#define GWS_LOG_VERBOSE(...) \ - do { \ - if (GCDWebServerLogLevel <= kGCDWebServerLoggingLevel_Verbose) GCDWebServerLogMessage(kGCDWebServerLoggingLevel_Verbose, __VA_ARGS__); \ - } while (0) -#define GWS_LOG_INFO(...) \ - do { \ - if (GCDWebServerLogLevel <= kGCDWebServerLoggingLevel_Info) GCDWebServerLogMessage(kGCDWebServerLoggingLevel_Info, __VA_ARGS__); \ - } while (0) -#define GWS_LOG_WARNING(...) \ - do { \ - if (GCDWebServerLogLevel <= kGCDWebServerLoggingLevel_Warning) GCDWebServerLogMessage(kGCDWebServerLoggingLevel_Warning, __VA_ARGS__); \ - } while (0) -#define GWS_LOG_ERROR(...) \ - do { \ - if (GCDWebServerLogLevel <= kGCDWebServerLoggingLevel_Error) GCDWebServerLogMessage(kGCDWebServerLoggingLevel_Error, __VA_ARGS__); \ - } while (0) - -#endif - -/** - * Consistency check macros used when building Debug only. - */ - -#if !defined(GWS_DCHECK) || !defined(GWS_DNOT_REACHED) - -#if DEBUG - -#define GWS_DCHECK(__CONDITION__) \ - do { \ - if (!(__CONDITION__)) { \ - abort(); \ - } \ - } while (0) -#define GWS_DNOT_REACHED() abort() - -#else - -#define GWS_DCHECK(__CONDITION__) -#define GWS_DNOT_REACHED() - -#endif - -#endif - -NS_ASSUME_NONNULL_BEGIN - -/** - * GCDWebServer internal constants and APIs. - */ - -#define kGCDWebServerDefaultMimeType @"application/octet-stream" -#define kGCDWebServerErrorDomain @"GCDWebServerErrorDomain" - -static inline BOOL GCDWebServerIsValidByteRange(NSRange range) { - return ((range.location != NSUIntegerMax) || (range.length > 0)); -} - -static inline NSError* GCDWebServerMakePosixError(int code) { - return [NSError errorWithDomain:NSPOSIXErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey : (NSString*)[NSString stringWithUTF8String:strerror(code)]}]; -} - -extern void GCDWebServerInitializeFunctions(void); -extern NSString* _Nullable GCDWebServerNormalizeHeaderValue(NSString* _Nullable value); -extern NSString* _Nullable GCDWebServerTruncateHeaderValue(NSString* _Nullable value); -extern NSString* _Nullable GCDWebServerExtractHeaderValueParameter(NSString* _Nullable value, NSString* attribute); -extern NSStringEncoding GCDWebServerStringEncodingFromCharset(NSString* charset); -extern BOOL GCDWebServerIsTextContentType(NSString* type); -extern NSString* GCDWebServerDescribeData(NSData* data, NSString* contentType); -extern NSString* GCDWebServerComputeMD5Digest(NSString* format, ...) NS_FORMAT_FUNCTION(1, 2); -extern NSString* GCDWebServerStringFromSockAddr(const struct sockaddr* addr, BOOL includeService); - -@interface GCDWebServerConnection () -- (instancetype)initWithServer:(GCDWebServer*)server localAddress:(NSData*)localAddress remoteAddress:(NSData*)remoteAddress socket:(CFSocketNativeHandle)socket; -@end - -@interface GCDWebServer () -@property(nonatomic, readonly) NSMutableArray* handlers; -@property(nonatomic, readonly, nullable) NSString* serverName; -@property(nonatomic, readonly, nullable) NSString* authenticationRealm; -@property(nonatomic, readonly, nullable) NSMutableDictionary* authenticationBasicAccounts; -@property(nonatomic, readonly, nullable) NSMutableDictionary* authenticationDigestAccounts; -@property(nonatomic, readonly) BOOL shouldAutomaticallyMapHEADToGET; -@property(nonatomic, readonly) dispatch_queue_priority_t dispatchQueuePriority; -- (void)willStartConnection:(GCDWebServerConnection*)connection; -- (void)didEndConnection:(GCDWebServerConnection*)connection; -@end - -@interface GCDWebServerHandler : NSObject -@property(nonatomic, readonly) GCDWebServerMatchBlock matchBlock; -@property(nonatomic, readonly) GCDWebServerAsyncProcessBlock asyncProcessBlock; -@end - -@interface GCDWebServerRequest () -@property(nonatomic, readonly) BOOL usesChunkedTransferEncoding; -@property(nonatomic) NSData* localAddressData; -@property(nonatomic) NSData* remoteAddressData; -- (void)prepareForWriting; -- (BOOL)performOpen:(NSError**)error; -- (BOOL)performWriteData:(NSData*)data error:(NSError**)error; -- (BOOL)performClose:(NSError**)error; -- (void)setAttribute:(nullable id)attribute forKey:(NSString*)key; -@end - -@interface GCDWebServerResponse () -@property(nonatomic, readonly) NSDictionary* additionalHeaders; -@property(nonatomic, readonly) BOOL usesChunkedTransferEncoding; -- (void)prepareForReading; -- (BOOL)performOpen:(NSError**)error; -- (void)performReadDataWithCompletion:(GCDWebServerBodyReaderCompletionBlock)block; -- (void)performClose; -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerRequest.h b/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerRequest.h deleted file mode 100644 index 79b446a5d..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerRequest.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import - -NS_ASSUME_NONNULL_BEGIN - -/** - * Attribute key to retrieve an NSArray containing NSStrings from a GCDWebServerRequest - * with the contents of any regular expression captures done on the request path. - * - * @warning This attribute will only be set on the request if adding a handler using - * -addHandlerForMethod:pathRegex:requestClass:processBlock:. - */ -extern NSString* const GCDWebServerRequestAttribute_RegexCaptures; - -/** - * This protocol is used by the GCDWebServerConnection to communicate with - * the GCDWebServerRequest and write the received HTTP body data. - * - * Note that multiple GCDWebServerBodyWriter objects can be chained together - * internally e.g. to automatically decode gzip encoded content before - * passing it on to the GCDWebServerRequest. - * - * @warning These methods can be called on any GCD thread. - */ -@protocol GCDWebServerBodyWriter - -/** - * This method is called before any body data is received. - * - * It should return YES on success or NO on failure and set the "error" argument - * which is guaranteed to be non-NULL. - */ -- (BOOL)open:(NSError**)error; - -/** - * This method is called whenever body data has been received. - * - * It should return YES on success or NO on failure and set the "error" argument - * which is guaranteed to be non-NULL. - */ -- (BOOL)writeData:(NSData*)data error:(NSError**)error; - -/** - * This method is called after all body data has been received. - * - * It should return YES on success or NO on failure and set the "error" argument - * which is guaranteed to be non-NULL. - */ -- (BOOL)close:(NSError**)error; - -@end - -/** - * The GCDWebServerRequest class is instantiated by the GCDWebServerConnection - * after the HTTP headers have been received. Each instance wraps a single HTTP - * request. If a body is present, the methods from the GCDWebServerBodyWriter - * protocol will be called by the GCDWebServerConnection to receive it. - * - * The default implementation of the GCDWebServerBodyWriter protocol on the class - * simply ignores the body data. - * - * @warning GCDWebServerRequest instances can be created and used on any GCD thread. - */ -@interface GCDWebServerRequest : NSObject - -/** - * Returns the HTTP method for the request. - */ -@property(nonatomic, readonly) NSString* method; - -/** - * Returns the URL for the request. - */ -@property(nonatomic, readonly) NSURL* URL; - -/** - * Returns the HTTP headers for the request. - */ -@property(nonatomic, readonly) NSDictionary* headers; - -/** - * Returns the path component of the URL for the request. - */ -@property(nonatomic, readonly) NSString* path; - -/** - * Returns the parsed and unescaped query component of the URL for the request. - * - * @warning This property will be nil if there is no query in the URL. - */ -@property(nonatomic, readonly, nullable) NSDictionary* query; - -/** - * Returns the content type for the body of the request parsed from the - * "Content-Type" header. - * - * This property will be nil if the request has no body or set to - * "application/octet-stream" if a body is present but there was no - * "Content-Type" header. - */ -@property(nonatomic, readonly, nullable) NSString* contentType; - -/** - * Returns the content length for the body of the request parsed from the - * "Content-Length" header. - * - * This property will be set to "NSUIntegerMax" if the request has no body or - * if there is a body but no "Content-Length" header, typically because - * chunked transfer encoding is used. - */ -@property(nonatomic, readonly) NSUInteger contentLength; - -/** - * Returns the parsed "If-Modified-Since" header or nil if absent or malformed. - */ -@property(nonatomic, readonly, nullable) NSDate* ifModifiedSince; - -/** - * Returns the parsed "If-None-Match" header or nil if absent or malformed. - */ -@property(nonatomic, readonly, nullable) NSString* ifNoneMatch; - -/** - * Returns the parsed "Range" header or (NSUIntegerMax, 0) if absent or malformed. - * The range will be set to (offset, length) if expressed from the beginning - * of the entity body, or (NSUIntegerMax, length) if expressed from its end. - */ -@property(nonatomic, readonly) NSRange byteRange; - -/** - * Returns YES if the client supports gzip content encoding according to the - * "Accept-Encoding" header. - */ -@property(nonatomic, readonly) BOOL acceptsGzipContentEncoding; - -/** - * Returns the address of the local peer (i.e. server) for the request - * as a raw "struct sockaddr". - */ -@property(nonatomic, readonly) NSData* localAddressData; - -/** - * Returns the address of the local peer (i.e. server) for the request - * as a string. - */ -@property(nonatomic, readonly) NSString* localAddressString; - -/** - * Returns the address of the remote peer (i.e. client) for the request - * as a raw "struct sockaddr". - */ -@property(nonatomic, readonly) NSData* remoteAddressData; - -/** - * Returns the address of the remote peer (i.e. client) for the request - * as a string. - */ -@property(nonatomic, readonly) NSString* remoteAddressString; - -/** - * This method is the designated initializer for the class. - */ -- (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(nullable NSDictionary*)query; - -/** - * Convenience method that checks if the contentType property is defined. - */ -- (BOOL)hasBody; - -/** - * Convenience method that checks if the byteRange property is defined. - */ -- (BOOL)hasByteRange; - -/** - * Retrieves an attribute associated with this request using the given key. - * - * @return The attribute value for the key. - */ -- (nullable id)attributeForKey:(NSString*)key; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerRequest.m b/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerRequest.m deleted file mode 100644 index 5648eff7a..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerRequest.m +++ /dev/null @@ -1,303 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !__has_feature(objc_arc) -#error GCDWebServer requires ARC -#endif - -#import - -#import "GCDWebServerPrivate.h" - -NSString* const GCDWebServerRequestAttribute_RegexCaptures = @"GCDWebServerRequestAttribute_RegexCaptures"; - -#define kZlibErrorDomain @"ZlibErrorDomain" -#define kGZipInitialBufferSize (256 * 1024) - -@interface GCDWebServerBodyDecoder : NSObject -@end - -@interface GCDWebServerGZipDecoder : GCDWebServerBodyDecoder -@end - -@implementation GCDWebServerBodyDecoder { - GCDWebServerRequest* __unsafe_unretained _request; - id __unsafe_unretained _writer; -} - -- (instancetype)initWithRequest:(GCDWebServerRequest* _Nonnull)request writer:(id _Nonnull)writer { - if ((self = [super init])) { - _request = request; - _writer = writer; - } - return self; -} - -- (BOOL)open:(NSError**)error { - return [_writer open:error]; -} - -- (BOOL)writeData:(NSData*)data error:(NSError**)error { - return [_writer writeData:data error:error]; -} - -- (BOOL)close:(NSError**)error { - return [_writer close:error]; -} - -@end - -@implementation GCDWebServerGZipDecoder { - z_stream _stream; - BOOL _finished; -} - -- (BOOL)open:(NSError**)error { - int result = inflateInit2(&_stream, 15 + 16); - if (result != Z_OK) { - if (error) { - *error = [NSError errorWithDomain:kZlibErrorDomain code:result userInfo:nil]; - } - return NO; - } - if (![super open:error]) { - inflateEnd(&_stream); - return NO; - } - return YES; -} - -- (BOOL)writeData:(NSData*)data error:(NSError**)error { - GWS_DCHECK(!_finished); - _stream.next_in = (Bytef*)data.bytes; - _stream.avail_in = (uInt)data.length; - NSMutableData* decodedData = [[NSMutableData alloc] initWithLength:kGZipInitialBufferSize]; - if (decodedData == nil) { - GWS_DNOT_REACHED(); - return NO; - } - NSUInteger length = 0; - while (1) { - NSUInteger maxLength = decodedData.length - length; - _stream.next_out = (Bytef*)((char*)decodedData.mutableBytes + length); - _stream.avail_out = (uInt)maxLength; - int result = inflate(&_stream, Z_NO_FLUSH); - if ((result != Z_OK) && (result != Z_STREAM_END)) { - if (error) { - *error = [NSError errorWithDomain:kZlibErrorDomain code:result userInfo:nil]; - } - return NO; - } - length += maxLength - _stream.avail_out; - if (_stream.avail_out > 0) { - if (result == Z_STREAM_END) { - _finished = YES; - } - break; - } - decodedData.length = 2 * decodedData.length; // zlib has used all the output buffer so resize it and try again in case more data is available - } - decodedData.length = length; - BOOL success = length ? [super writeData:decodedData error:error] : YES; // No need to call writer if we have no data yet - return success; -} - -- (BOOL)close:(NSError**)error { - GWS_DCHECK(_finished); - inflateEnd(&_stream); - return [super close:error]; -} - -@end - -@implementation GCDWebServerRequest { - BOOL _opened; - NSMutableArray* _decoders; - id __unsafe_unretained _writer; - NSMutableDictionary* _attributes; -} - -- (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query { - if ((self = [super init])) { - _method = [method copy]; - _URL = url; - _headers = headers; - _path = [path copy]; - _query = query; - - _contentType = GCDWebServerNormalizeHeaderValue([_headers objectForKey:@"Content-Type"]); - _usesChunkedTransferEncoding = [GCDWebServerNormalizeHeaderValue([_headers objectForKey:@"Transfer-Encoding"]) isEqualToString:@"chunked"]; - NSString* lengthHeader = [_headers objectForKey:@"Content-Length"]; - if (lengthHeader) { - NSInteger length = [lengthHeader integerValue]; - if (_usesChunkedTransferEncoding || (length < 0)) { - GWS_LOG_WARNING(@"Invalid 'Content-Length' header '%@' for '%@' request on \"%@\"", lengthHeader, _method, _URL); - GWS_DNOT_REACHED(); - return nil; - } - _contentLength = length; - if (_contentType == nil) { - _contentType = kGCDWebServerDefaultMimeType; - } - } else if (_usesChunkedTransferEncoding) { - if (_contentType == nil) { - _contentType = kGCDWebServerDefaultMimeType; - } - _contentLength = NSUIntegerMax; - } else { - if (_contentType) { - GWS_LOG_WARNING(@"Ignoring 'Content-Type' header for '%@' request on \"%@\"", _method, _URL); - _contentType = nil; // Content-Type without Content-Length or chunked-encoding doesn't make sense - } - _contentLength = NSUIntegerMax; - } - - NSString* modifiedHeader = [_headers objectForKey:@"If-Modified-Since"]; - if (modifiedHeader) { - _ifModifiedSince = [GCDWebServerParseRFC822(modifiedHeader) copy]; - } - _ifNoneMatch = [_headers objectForKey:@"If-None-Match"]; - - _byteRange = NSMakeRange(NSUIntegerMax, 0); - NSString* rangeHeader = GCDWebServerNormalizeHeaderValue([_headers objectForKey:@"Range"]); - if (rangeHeader) { - if ([rangeHeader hasPrefix:@"bytes="]) { - NSArray* components = [[rangeHeader substringFromIndex:6] componentsSeparatedByString:@","]; - if (components.count == 1) { - components = [(NSString*)[components firstObject] componentsSeparatedByString:@"-"]; - if (components.count == 2) { - NSString* startString = [components objectAtIndex:0]; - NSInteger startValue = [startString integerValue]; - NSString* endString = [components objectAtIndex:1]; - NSInteger endValue = [endString integerValue]; - if (startString.length && (startValue >= 0) && endString.length && (endValue >= startValue)) { // The second 500 bytes: "500-999" - _byteRange.location = startValue; - _byteRange.length = endValue - startValue + 1; - } else if (startString.length && (startValue >= 0)) { // The bytes after 9500 bytes: "9500-" - _byteRange.location = startValue; - _byteRange.length = NSUIntegerMax; - } else if (endString.length && (endValue > 0)) { // The final 500 bytes: "-500" - _byteRange.location = NSUIntegerMax; - _byteRange.length = endValue; - } - } - } - } - if ((_byteRange.location == NSUIntegerMax) && (_byteRange.length == 0)) { // Ignore "Range" header if syntactically invalid - GWS_LOG_WARNING(@"Failed to parse 'Range' header \"%@\" for url: %@", rangeHeader, url); - } - } - - if ([[_headers objectForKey:@"Accept-Encoding"] rangeOfString:@"gzip"].location != NSNotFound) { - _acceptsGzipContentEncoding = YES; - } - - _decoders = [[NSMutableArray alloc] init]; - _attributes = [[NSMutableDictionary alloc] init]; - } - return self; -} - -- (BOOL)hasBody { - return _contentType ? YES : NO; -} - -- (BOOL)hasByteRange { - return GCDWebServerIsValidByteRange(_byteRange); -} - -- (id)attributeForKey:(NSString*)key { - return [_attributes objectForKey:key]; -} - -- (BOOL)open:(NSError**)error { - return YES; -} - -- (BOOL)writeData:(NSData*)data error:(NSError**)error { - return YES; -} - -- (BOOL)close:(NSError**)error { - return YES; -} - -- (void)prepareForWriting { - _writer = self; - if ([GCDWebServerNormalizeHeaderValue([self.headers objectForKey:@"Content-Encoding"]) isEqualToString:@"gzip"]) { - GCDWebServerGZipDecoder* decoder = [[GCDWebServerGZipDecoder alloc] initWithRequest:self writer:_writer]; - [_decoders addObject:decoder]; - _writer = decoder; - } -} - -- (BOOL)performOpen:(NSError**)error { - GWS_DCHECK(_contentType); - GWS_DCHECK(_writer); - if (_opened) { - GWS_DNOT_REACHED(); - return NO; - } - _opened = YES; - return [_writer open:error]; -} - -- (BOOL)performWriteData:(NSData*)data error:(NSError**)error { - GWS_DCHECK(_opened); - return [_writer writeData:data error:error]; -} - -- (BOOL)performClose:(NSError**)error { - GWS_DCHECK(_opened); - return [_writer close:error]; -} - -- (void)setAttribute:(id)attribute forKey:(NSString*)key { - [_attributes setValue:attribute forKey:key]; -} - -- (NSString*)localAddressString { - return GCDWebServerStringFromSockAddr(_localAddressData.bytes, YES); -} - -- (NSString*)remoteAddressString { - return GCDWebServerStringFromSockAddr(_remoteAddressData.bytes, YES); -} - -- (NSString*)description { - NSMutableString* description = [NSMutableString stringWithFormat:@"%@ %@", _method, _path]; - for (NSString* argument in [[_query allKeys] sortedArrayUsingSelector:@selector(compare:)]) { - [description appendFormat:@"\n %@ = %@", argument, [_query objectForKey:argument]]; - } - [description appendString:@"\n"]; - for (NSString* header in [[_headers allKeys] sortedArrayUsingSelector:@selector(compare:)]) { - [description appendFormat:@"\n%@: %@", header, [_headers objectForKey:header]]; - } - return description; -} - -@end diff --git a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerResponse.h b/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerResponse.h deleted file mode 100644 index 2e1365bfb..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerResponse.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import - -NS_ASSUME_NONNULL_BEGIN - -/** - * The GCDWebServerBodyReaderCompletionBlock is passed by GCDWebServer to the - * GCDWebServerBodyReader object when reading data from it asynchronously. - */ -typedef void (^GCDWebServerBodyReaderCompletionBlock)(NSData* _Nullable data, NSError* _Nullable error); - -/** - * This protocol is used by the GCDWebServerConnection to communicate with - * the GCDWebServerResponse and read the HTTP body data to send. - * - * Note that multiple GCDWebServerBodyReader objects can be chained together - * internally e.g. to automatically apply gzip encoding to the content before - * passing it on to the GCDWebServerResponse. - * - * @warning These methods can be called on any GCD thread. - */ -@protocol GCDWebServerBodyReader - -@required - -/** - * This method is called before any body data is sent. - * - * It should return YES on success or NO on failure and set the "error" argument - * which is guaranteed to be non-NULL. - */ -- (BOOL)open:(NSError**)error; - -/** - * This method is called whenever body data is sent. - * - * It should return a non-empty NSData if there is body data available, - * or an empty NSData there is no more body data, or nil on error and set - * the "error" argument which is guaranteed to be non-NULL. - */ -- (nullable NSData*)readData:(NSError**)error; - -/** - * This method is called after all body data has been sent. - */ -- (void)close; - -@optional - -/** - * If this method is implemented, it will be preferred over -readData:. - * - * It must call the passed block when data is available, passing a non-empty - * NSData if there is body data available, or an empty NSData there is no more - * body data, or nil on error and pass an NSError along. - */ -- (void)asyncReadDataWithCompletion:(GCDWebServerBodyReaderCompletionBlock)block; - -@end - -/** - * The GCDWebServerResponse class is used to wrap a single HTTP response. - * It is instantiated by the handler of the GCDWebServer that handled the request. - * If a body is present, the methods from the GCDWebServerBodyReader protocol - * will be called by the GCDWebServerConnection to send it. - * - * The default implementation of the GCDWebServerBodyReader protocol - * on the class simply returns an empty body. - * - * @warning GCDWebServerResponse instances can be created and used on any GCD thread. - */ -@interface GCDWebServerResponse : NSObject - -/** - * Sets the content type for the body of the response. - * - * The default value is nil i.e. the response has no body. - * - * @warning This property must be set if a body is present. - */ -@property(nonatomic, copy, nullable) NSString* contentType; - -/** - * Sets the content length for the body of the response. If a body is present - * but this property is set to "NSUIntegerMax", this means the length of the body - * cannot be known ahead of time. Chunked transfer encoding will be - * automatically enabled by the GCDWebServerConnection to comply with HTTP/1.1 - * specifications. - * - * The default value is "NSUIntegerMax" i.e. the response has no body or its length - * is undefined. - */ -@property(nonatomic) NSUInteger contentLength; - -/** - * Sets the HTTP status code for the response. - * - * The default value is 200 i.e. "OK". - */ -@property(nonatomic) NSInteger statusCode; - -/** - * Sets the caching hint for the response using the "Cache-Control" header. - * This value is expressed in seconds. - * - * The default value is 0 i.e. "no-cache". - */ -@property(nonatomic) NSUInteger cacheControlMaxAge; - -/** - * Sets the last modified date for the response using the "Last-Modified" header. - * - * The default value is nil. - */ -@property(nonatomic, nullable) NSDate* lastModifiedDate; - -/** - * Sets the ETag for the response using the "ETag" header. - * - * The default value is nil. - */ -@property(nonatomic, copy, nullable) NSString* eTag; - -/** - * Enables gzip encoding for the response body. - * - * The default value is NO. - * - * @warning Enabling gzip encoding will remove any "Content-Length" header - * since the length of the body is not known anymore. The client will still - * be able to determine the body length when connection is closed per - * HTTP/1.1 specifications. - */ -@property(nonatomic, getter=isGZipContentEncodingEnabled) BOOL gzipContentEncodingEnabled; - -/** - * Creates an empty response. - */ -+ (instancetype)response; - -/** - * This method is the designated initializer for the class. - */ -- (instancetype)init; - -/** - * Sets an additional HTTP header on the response. - * Pass a nil value to remove an additional header. - * - * @warning Do not attempt to override the primary headers used - * by GCDWebServerResponse like "Content-Type", "ETag", etc... - */ -- (void)setValue:(nullable NSString*)value forAdditionalHeader:(NSString*)header; - -/** - * Convenience method that checks if the contentType property is defined. - */ -- (BOOL)hasBody; - -@end - -@interface GCDWebServerResponse (Extensions) - -/** - * Creates a empty response with a specific HTTP status code. - */ -+ (instancetype)responseWithStatusCode:(NSInteger)statusCode; - -/** - * Creates an HTTP redirect response to a new URL. - */ -+ (instancetype)responseWithRedirect:(NSURL*)location permanent:(BOOL)permanent; - -/** - * Initializes an empty response with a specific HTTP status code. - */ -- (instancetype)initWithStatusCode:(NSInteger)statusCode; - -/** - * Initializes an HTTP redirect response to a new URL. - */ -- (instancetype)initWithRedirect:(NSURL*)location permanent:(BOOL)permanent; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerResponse.m b/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerResponse.m deleted file mode 100644 index 46042b21b..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Core/GCDWebServerResponse.m +++ /dev/null @@ -1,284 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !__has_feature(objc_arc) -#error GCDWebServer requires ARC -#endif - -#import - -#import "GCDWebServerPrivate.h" - -#define kZlibErrorDomain @"ZlibErrorDomain" -#define kGZipInitialBufferSize (256 * 1024) - -@interface GCDWebServerBodyEncoder : NSObject -@end - -@interface GCDWebServerGZipEncoder : GCDWebServerBodyEncoder -@end - -@implementation GCDWebServerBodyEncoder { - GCDWebServerResponse* __unsafe_unretained _response; - id __unsafe_unretained _reader; -} - -- (instancetype)initWithResponse:(GCDWebServerResponse* _Nonnull)response reader:(id _Nonnull)reader { - if ((self = [super init])) { - _response = response; - _reader = reader; - } - return self; -} - -- (BOOL)open:(NSError**)error { - return [_reader open:error]; -} - -- (NSData*)readData:(NSError**)error { - return [_reader readData:error]; -} - -- (void)close { - [_reader close]; -} - -@end - -@implementation GCDWebServerGZipEncoder { - z_stream _stream; - BOOL _finished; -} - -- (instancetype)initWithResponse:(GCDWebServerResponse* _Nonnull)response reader:(id _Nonnull)reader { - if ((self = [super initWithResponse:response reader:reader])) { - response.contentLength = NSUIntegerMax; // Make sure "Content-Length" header is not set since we don't know it - [response setValue:@"gzip" forAdditionalHeader:@"Content-Encoding"]; - } - return self; -} - -- (BOOL)open:(NSError**)error { - int result = deflateInit2(&_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY); - if (result != Z_OK) { - if (error) { - *error = [NSError errorWithDomain:kZlibErrorDomain code:result userInfo:nil]; - } - return NO; - } - if (![super open:error]) { - deflateEnd(&_stream); - return NO; - } - return YES; -} - -- (NSData*)readData:(NSError**)error { - NSMutableData* encodedData; - if (_finished) { - encodedData = [[NSMutableData alloc] init]; - } else { - encodedData = [[NSMutableData alloc] initWithLength:kGZipInitialBufferSize]; - if (encodedData == nil) { - GWS_DNOT_REACHED(); - return nil; - } - NSUInteger length = 0; - do { - NSData* data = [super readData:error]; - if (data == nil) { - return nil; - } - _stream.next_in = (Bytef*)data.bytes; - _stream.avail_in = (uInt)data.length; - while (1) { - NSUInteger maxLength = encodedData.length - length; - _stream.next_out = (Bytef*)((char*)encodedData.mutableBytes + length); - _stream.avail_out = (uInt)maxLength; - int result = deflate(&_stream, data.length ? Z_NO_FLUSH : Z_FINISH); - if (result == Z_STREAM_END) { - _finished = YES; - } else if (result != Z_OK) { - if (error) { - *error = [NSError errorWithDomain:kZlibErrorDomain code:result userInfo:nil]; - } - return nil; - } - length += maxLength - _stream.avail_out; - if (_stream.avail_out > 0) { - break; - } - encodedData.length = 2 * encodedData.length; // zlib has used all the output buffer so resize it and try again in case more data is available - } - GWS_DCHECK(_stream.avail_in == 0); - } while (length == 0); // Make sure we don't return an empty NSData if not in finished state - encodedData.length = length; - } - return encodedData; -} - -- (void)close { - deflateEnd(&_stream); - [super close]; -} - -@end - -@implementation GCDWebServerResponse { - BOOL _opened; - NSMutableArray* _encoders; - id __unsafe_unretained _reader; -} - -+ (instancetype)response { - return [(GCDWebServerResponse*)[[self class] alloc] init]; -} - -- (instancetype)init { - if ((self = [super init])) { - _contentType = nil; - _contentLength = NSUIntegerMax; - _statusCode = kGCDWebServerHTTPStatusCode_OK; - _cacheControlMaxAge = 0; - _additionalHeaders = [[NSMutableDictionary alloc] init]; - _encoders = [[NSMutableArray alloc] init]; - } - return self; -} - -- (void)setValue:(NSString*)value forAdditionalHeader:(NSString*)header { - [_additionalHeaders setValue:value forKey:header]; -} - -- (BOOL)hasBody { - return _contentType ? YES : NO; -} - -- (BOOL)usesChunkedTransferEncoding { - return (_contentType != nil) && (_contentLength == NSUIntegerMax); -} - -- (BOOL)open:(NSError**)error { - return YES; -} - -- (NSData*)readData:(NSError**)error { - return [NSData data]; -} - -- (void)close { - ; -} - -- (void)prepareForReading { - _reader = self; - if (_gzipContentEncodingEnabled) { - GCDWebServerGZipEncoder* encoder = [[GCDWebServerGZipEncoder alloc] initWithResponse:self reader:_reader]; - [_encoders addObject:encoder]; - _reader = encoder; - } -} - -- (BOOL)performOpen:(NSError**)error { - GWS_DCHECK(_contentType); - GWS_DCHECK(_reader); - if (_opened) { - GWS_DNOT_REACHED(); - return NO; - } - _opened = YES; - return [_reader open:error]; -} - -- (void)performReadDataWithCompletion:(GCDWebServerBodyReaderCompletionBlock)block { - GWS_DCHECK(_opened); - if ([_reader respondsToSelector:@selector(asyncReadDataWithCompletion:)]) { - [_reader asyncReadDataWithCompletion:[block copy]]; - } else { - NSError* error = nil; - NSData* data = [_reader readData:&error]; - block(data, error); - } -} - -- (void)performClose { - GWS_DCHECK(_opened); - [_reader close]; -} - -- (NSString*)description { - NSMutableString* description = [NSMutableString stringWithFormat:@"Status Code = %i", (int)_statusCode]; - if (_contentType) { - [description appendFormat:@"\nContent Type = %@", _contentType]; - } - if (_contentLength != NSUIntegerMax) { - [description appendFormat:@"\nContent Length = %lu", (unsigned long)_contentLength]; - } - [description appendFormat:@"\nCache Control Max Age = %lu", (unsigned long)_cacheControlMaxAge]; - if (_lastModifiedDate) { - [description appendFormat:@"\nLast Modified Date = %@", _lastModifiedDate]; - } - if (_eTag) { - [description appendFormat:@"\nETag = %@", _eTag]; - } - if (_additionalHeaders.count) { - [description appendString:@"\n"]; - for (NSString* header in [[_additionalHeaders allKeys] sortedArrayUsingSelector:@selector(compare:)]) { - [description appendFormat:@"\n%@: %@", header, [_additionalHeaders objectForKey:header]]; - } - } - return description; -} - -@end - -@implementation GCDWebServerResponse (Extensions) - -+ (instancetype)responseWithStatusCode:(NSInteger)statusCode { - return [(GCDWebServerResponse*)[self alloc] initWithStatusCode:statusCode]; -} - -+ (instancetype)responseWithRedirect:(NSURL*)location permanent:(BOOL)permanent { - return [(GCDWebServerResponse*)[self alloc] initWithRedirect:location permanent:permanent]; -} - -- (instancetype)initWithStatusCode:(NSInteger)statusCode { - if ((self = [self init])) { - self.statusCode = statusCode; - } - return self; -} - -- (instancetype)initWithRedirect:(NSURL*)location permanent:(BOOL)permanent { - if ((self = [self init])) { - self.statusCode = permanent ? kGCDWebServerHTTPStatusCode_MovedPermanently : kGCDWebServerHTTPStatusCode_TemporaryRedirect; - [self setValue:[location absoluteString] forAdditionalHeader:@"Location"]; - } - return self; -} - -@end diff --git a/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerDataRequest.h b/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerDataRequest.h deleted file mode 100644 index b105ce766..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerDataRequest.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "GCDWebServerRequest.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - * The GCDWebServerDataRequest subclass of GCDWebServerRequest stores the body - * of the HTTP request in memory. - */ -@interface GCDWebServerDataRequest : GCDWebServerRequest - -/** - * Returns the data for the request body. - */ -@property(nonatomic, readonly) NSData* data; - -@end - -@interface GCDWebServerDataRequest (Extensions) - -/** - * Returns the data for the request body interpreted as text. If the content - * type of the body is not a text one, or if an error occurs, nil is returned. - * - * The text encoding used to interpret the data is extracted from the - * "Content-Type" header or defaults to UTF-8. - */ -@property(nonatomic, readonly, nullable) NSString* text; - -/** - * Returns the data for the request body interpreted as a JSON object. If the - * content type of the body is not JSON, or if an error occurs, nil is returned. - */ -@property(nonatomic, readonly, nullable) id jsonObject; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerDataRequest.m b/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerDataRequest.m deleted file mode 100644 index fcb293211..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerDataRequest.m +++ /dev/null @@ -1,104 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !__has_feature(objc_arc) -#error GCDWebServer requires ARC -#endif - -#import "GCDWebServerPrivate.h" - -@interface GCDWebServerDataRequest () -@property(nonatomic) NSMutableData* data; -@end - -@implementation GCDWebServerDataRequest { - NSString* _text; - id _jsonObject; -} - -- (BOOL)open:(NSError**)error { - if (self.contentLength != NSUIntegerMax) { - _data = [[NSMutableData alloc] initWithCapacity:self.contentLength]; - } else { - _data = [[NSMutableData alloc] init]; - } - if (_data == nil) { - if (error) { - *error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Failed allocating memory"}]; - } - return NO; - } - return YES; -} - -- (BOOL)writeData:(NSData*)data error:(NSError**)error { - [_data appendData:data]; - return YES; -} - -- (BOOL)close:(NSError**)error { - return YES; -} - -- (NSString*)description { - NSMutableString* description = [NSMutableString stringWithString:[super description]]; - if (_data) { - [description appendString:@"\n\n"]; - [description appendString:GCDWebServerDescribeData(_data, (NSString*)self.contentType)]; - } - return description; -} - -@end - -@implementation GCDWebServerDataRequest (Extensions) - -- (NSString*)text { - if (_text == nil) { - if ([self.contentType hasPrefix:@"text/"]) { - NSString* charset = GCDWebServerExtractHeaderValueParameter(self.contentType, @"charset"); - _text = [[NSString alloc] initWithData:self.data encoding:GCDWebServerStringEncodingFromCharset(charset)]; - } else { - GWS_DNOT_REACHED(); - } - } - return _text; -} - -- (id)jsonObject { - if (_jsonObject == nil) { - NSString* mimeType = GCDWebServerTruncateHeaderValue(self.contentType); - if ([mimeType isEqualToString:@"application/json"] || [mimeType isEqualToString:@"text/json"] || [mimeType isEqualToString:@"text/javascript"]) { - _jsonObject = [NSJSONSerialization JSONObjectWithData:_data options:0 error:NULL]; - } else { - GWS_DNOT_REACHED(); - } - } - return _jsonObject; -} - -@end diff --git a/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerFileRequest.h b/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerFileRequest.h deleted file mode 100644 index 3c6a6d249..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerFileRequest.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "GCDWebServerRequest.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - * The GCDWebServerFileRequest subclass of GCDWebServerRequest stores the body - * of the HTTP request to a file on disk. - */ -@interface GCDWebServerFileRequest : GCDWebServerRequest - -/** - * Returns the path to the temporary file containing the request body. - * - * @warning This temporary file will be automatically deleted when the - * GCDWebServerFileRequest is deallocated. If you want to preserve this file, - * you must move it to a different location beforehand. - */ -@property(nonatomic, readonly) NSString* temporaryPath; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerFileRequest.m b/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerFileRequest.m deleted file mode 100644 index 0845d5e96..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerFileRequest.m +++ /dev/null @@ -1,102 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !__has_feature(objc_arc) -#error GCDWebServer requires ARC -#endif - -#import "GCDWebServerPrivate.h" - -@implementation GCDWebServerFileRequest { - int _file; -} - -- (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query { - if ((self = [super initWithMethod:method url:url headers:headers path:path query:query])) { - _temporaryPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]]; - } - return self; -} - -- (void)dealloc { - unlink([_temporaryPath fileSystemRepresentation]); -} - -- (BOOL)open:(NSError**)error { - _file = open([_temporaryPath fileSystemRepresentation], O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (_file <= 0) { - if (error) { - *error = GCDWebServerMakePosixError(errno); - } - return NO; - } - return YES; -} - -- (BOOL)writeData:(NSData*)data error:(NSError**)error { - if (write(_file, data.bytes, data.length) != (ssize_t)data.length) { - if (error) { - *error = GCDWebServerMakePosixError(errno); - } - return NO; - } - return YES; -} - -- (BOOL)close:(NSError**)error { - if (close(_file) < 0) { - if (error) { - *error = GCDWebServerMakePosixError(errno); - } - return NO; - } -#ifdef __GCDWEBSERVER_ENABLE_TESTING__ - NSString* creationDateHeader = [self.headers objectForKey:@"X-GCDWebServer-CreationDate"]; - if (creationDateHeader) { - NSDate* date = GCDWebServerParseISO8601(creationDateHeader); - if (!date || ![[NSFileManager defaultManager] setAttributes:@{NSFileCreationDate : date} ofItemAtPath:_temporaryPath error:error]) { - return NO; - } - } - NSString* modifiedDateHeader = [self.headers objectForKey:@"X-GCDWebServer-ModifiedDate"]; - if (modifiedDateHeader) { - NSDate* date = GCDWebServerParseRFC822(modifiedDateHeader); - if (!date || ![[NSFileManager defaultManager] setAttributes:@{NSFileModificationDate : date} ofItemAtPath:_temporaryPath error:error]) { - return NO; - } - } -#endif - return YES; -} - -- (NSString*)description { - NSMutableString* description = [NSMutableString stringWithString:[super description]]; - [description appendFormat:@"\n\n{%@}", _temporaryPath]; - return description; -} - -@end diff --git a/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerMultiPartFormRequest.h b/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerMultiPartFormRequest.h deleted file mode 100644 index cbe838eaa..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerMultiPartFormRequest.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "GCDWebServerRequest.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - * The GCDWebServerMultiPart class is an abstract class that wraps the content - * of a part. - */ -@interface GCDWebServerMultiPart : NSObject - -/** - * Returns the control name retrieved from the part headers. - */ -@property(nonatomic, readonly) NSString* controlName; - -/** - * Returns the content type retrieved from the part headers or "text/plain" - * if not available (per HTTP specifications). - */ -@property(nonatomic, readonly) NSString* contentType; - -/** - * Returns the MIME type component of the content type for the part. - */ -@property(nonatomic, readonly) NSString* mimeType; - -@end - -/** - * The GCDWebServerMultiPartArgument subclass of GCDWebServerMultiPart wraps - * the content of a part as data in memory. - */ -@interface GCDWebServerMultiPartArgument : GCDWebServerMultiPart - -/** - * Returns the data for the part. - */ -@property(nonatomic, readonly) NSData* data; - -/** - * Returns the data for the part interpreted as text. If the content - * type of the part is not a text one, or if an error occurs, nil is returned. - * - * The text encoding used to interpret the data is extracted from the - * "Content-Type" header or defaults to UTF-8. - */ -@property(nonatomic, readonly, nullable) NSString* string; - -@end - -/** - * The GCDWebServerMultiPartFile subclass of GCDWebServerMultiPart wraps - * the content of a part as a file on disk. - */ -@interface GCDWebServerMultiPartFile : GCDWebServerMultiPart - -/** - * Returns the file name retrieved from the part headers. - */ -@property(nonatomic, readonly) NSString* fileName; - -/** - * Returns the path to the temporary file containing the part data. - * - * @warning This temporary file will be automatically deleted when the - * GCDWebServerMultiPartFile is deallocated. If you want to preserve this file, - * you must move it to a different location beforehand. - */ -@property(nonatomic, readonly) NSString* temporaryPath; - -@end - -/** - * The GCDWebServerMultiPartFormRequest subclass of GCDWebServerRequest - * parses the body of the HTTP request as a multipart encoded form. - */ -@interface GCDWebServerMultiPartFormRequest : GCDWebServerRequest - -/** - * Returns the argument parts from the multipart encoded form as - * name / GCDWebServerMultiPartArgument pairs. - */ -@property(nonatomic, readonly) NSArray* arguments; - -/** - * Returns the files parts from the multipart encoded form as - * name / GCDWebServerMultiPartFile pairs. - */ -@property(nonatomic, readonly) NSArray* files; - -/** - * Returns the MIME type for multipart encoded forms - * i.e. "multipart/form-data". - */ -+ (NSString*)mimeType; - -/** - * Returns the first argument for a given control name or nil if not found. - */ -- (nullable GCDWebServerMultiPartArgument*)firstArgumentForControlName:(NSString*)name; - -/** - * Returns the first file for a given control name or nil if not found. - */ -- (nullable GCDWebServerMultiPartFile*)firstFileForControlName:(NSString*)name; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerMultiPartFormRequest.m b/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerMultiPartFormRequest.m deleted file mode 100644 index 7550a021f..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerMultiPartFormRequest.m +++ /dev/null @@ -1,405 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !__has_feature(objc_arc) -#error GCDWebServer requires ARC -#endif - -#import "GCDWebServerPrivate.h" - -#define kMultiPartBufferSize (256 * 1024) - -typedef enum { - kParserState_Undefined = 0, - kParserState_Start, - kParserState_Headers, - kParserState_Content, - kParserState_End -} ParserState; - -@interface GCDWebServerMIMEStreamParser : NSObject -@end - -static NSData* _newlineData = nil; -static NSData* _newlinesData = nil; -static NSData* _dashNewlineData = nil; - -@implementation GCDWebServerMultiPart - -- (instancetype)initWithControlName:(NSString* _Nonnull)name contentType:(NSString* _Nonnull)type { - if ((self = [super init])) { - _controlName = [name copy]; - _contentType = [type copy]; - _mimeType = (NSString*)GCDWebServerTruncateHeaderValue(_contentType); - } - return self; -} - -@end - -@implementation GCDWebServerMultiPartArgument - -- (instancetype)initWithControlName:(NSString* _Nonnull)name contentType:(NSString* _Nonnull)type data:(NSData* _Nonnull)data { - if ((self = [super initWithControlName:name contentType:type])) { - _data = data; - - if ([self.contentType hasPrefix:@"text/"]) { - NSString* charset = GCDWebServerExtractHeaderValueParameter(self.contentType, @"charset"); - _string = [[NSString alloc] initWithData:_data encoding:GCDWebServerStringEncodingFromCharset(charset)]; - } - } - return self; -} - -- (NSString*)description { - return [NSString stringWithFormat:@"<%@ | '%@' | %lu bytes>", [self class], self.mimeType, (unsigned long)_data.length]; -} - -@end - -@implementation GCDWebServerMultiPartFile - -- (instancetype)initWithControlName:(NSString* _Nonnull)name contentType:(NSString* _Nonnull)type fileName:(NSString* _Nonnull)fileName temporaryPath:(NSString* _Nonnull)temporaryPath { - if ((self = [super initWithControlName:name contentType:type])) { - _fileName = [fileName copy]; - _temporaryPath = [temporaryPath copy]; - } - return self; -} - -- (void)dealloc { - unlink([_temporaryPath fileSystemRepresentation]); -} - -- (NSString*)description { - return [NSString stringWithFormat:@"<%@ | '%@' | '%@>'", [self class], self.mimeType, _fileName]; -} - -@end - -@implementation GCDWebServerMIMEStreamParser { - NSData* _boundary; - NSString* _defaultcontrolName; - ParserState _state; - NSMutableData* _data; - NSMutableArray* _arguments; - NSMutableArray* _files; - - NSString* _controlName; - NSString* _fileName; - NSString* _contentType; - NSString* _tmpPath; - int _tmpFile; - GCDWebServerMIMEStreamParser* _subParser; -} - -+ (void)initialize { - if (_newlineData == nil) { - _newlineData = [[NSData alloc] initWithBytes:"\r\n" length:2]; - GWS_DCHECK(_newlineData); - } - if (_newlinesData == nil) { - _newlinesData = [[NSData alloc] initWithBytes:"\r\n\r\n" length:4]; - GWS_DCHECK(_newlinesData); - } - if (_dashNewlineData == nil) { - _dashNewlineData = [[NSData alloc] initWithBytes:"--\r\n" length:4]; - GWS_DCHECK(_dashNewlineData); - } -} - -- (instancetype)initWithBoundary:(NSString* _Nonnull)boundary defaultControlName:(NSString* _Nullable)name arguments:(NSMutableArray* _Nonnull)arguments files:(NSMutableArray* _Nonnull)files { - NSData* data = boundary.length ? [[NSString stringWithFormat:@"--%@", boundary] dataUsingEncoding:NSASCIIStringEncoding] : nil; - if (data == nil) { - GWS_DNOT_REACHED(); - return nil; - } - if ((self = [super init])) { - _boundary = data; - _defaultcontrolName = name; - _arguments = arguments; - _files = files; - _data = [[NSMutableData alloc] initWithCapacity:kMultiPartBufferSize]; - _state = kParserState_Start; - } - return self; -} - -- (void)dealloc { - if (_tmpFile > 0) { - close(_tmpFile); - unlink([_tmpPath fileSystemRepresentation]); - } -} - -// http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2 -- (BOOL)_parseData { - BOOL success = YES; - - if (_state == kParserState_Headers) { - NSRange range = [_data rangeOfData:_newlinesData options:0 range:NSMakeRange(0, _data.length)]; - if (range.location != NSNotFound) { - _controlName = nil; - _fileName = nil; - _contentType = nil; - _tmpPath = nil; - _subParser = nil; - NSString* headers = [[NSString alloc] initWithData:[_data subdataWithRange:NSMakeRange(0, range.location)] encoding:NSUTF8StringEncoding]; - if (headers) { - for (NSString* header in [headers componentsSeparatedByString:@"\r\n"]) { - NSRange subRange = [header rangeOfString:@":"]; - if (subRange.location != NSNotFound) { - NSString* name = [header substringToIndex:subRange.location]; - NSString* value = [[header substringFromIndex:(subRange.location + subRange.length)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; - if ([name caseInsensitiveCompare:@"Content-Type"] == NSOrderedSame) { - _contentType = GCDWebServerNormalizeHeaderValue(value); - } else if ([name caseInsensitiveCompare:@"Content-Disposition"] == NSOrderedSame) { - NSString* contentDisposition = GCDWebServerNormalizeHeaderValue(value); - if ([GCDWebServerTruncateHeaderValue(contentDisposition) isEqualToString:@"form-data"]) { - _controlName = GCDWebServerExtractHeaderValueParameter(contentDisposition, @"name"); - _fileName = GCDWebServerExtractHeaderValueParameter(contentDisposition, @"filename"); - } else if ([GCDWebServerTruncateHeaderValue(contentDisposition) isEqualToString:@"file"]) { - _controlName = _defaultcontrolName; - _fileName = GCDWebServerExtractHeaderValueParameter(contentDisposition, @"filename"); - } - } - } else { - GWS_DNOT_REACHED(); - } - } - if (_contentType == nil) { - _contentType = @"text/plain"; - } - } else { - GWS_LOG_ERROR(@"Failed decoding headers in part of 'multipart/form-data'"); - GWS_DNOT_REACHED(); - } - if (_controlName) { - if ([GCDWebServerTruncateHeaderValue(_contentType) isEqualToString:@"multipart/mixed"]) { - NSString* boundary = GCDWebServerExtractHeaderValueParameter(_contentType, @"boundary"); - _subParser = [[GCDWebServerMIMEStreamParser alloc] initWithBoundary:boundary defaultControlName:_controlName arguments:_arguments files:_files]; - if (_subParser == nil) { - GWS_DNOT_REACHED(); - success = NO; - } - } else if (_fileName) { - NSString* path = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSProcessInfo processInfo] globallyUniqueString]]; - _tmpFile = open([path fileSystemRepresentation], O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (_tmpFile > 0) { - _tmpPath = [path copy]; - } else { - GWS_DNOT_REACHED(); - success = NO; - } - } - } else { - GWS_DNOT_REACHED(); - success = NO; - } - - [_data replaceBytesInRange:NSMakeRange(0, range.location + range.length) withBytes:NULL length:0]; - _state = kParserState_Content; - } - } - - if ((_state == kParserState_Start) || (_state == kParserState_Content)) { - NSRange range = [_data rangeOfData:_boundary options:0 range:NSMakeRange(0, _data.length)]; - if (range.location != NSNotFound) { - NSRange subRange = NSMakeRange(range.location + range.length, _data.length - range.location - range.length); - NSRange subRange1 = [_data rangeOfData:_newlineData options:NSDataSearchAnchored range:subRange]; - NSRange subRange2 = [_data rangeOfData:_dashNewlineData options:NSDataSearchAnchored range:subRange]; - if ((subRange1.location != NSNotFound) || (subRange2.location != NSNotFound)) { - if (_state == kParserState_Content) { - const void* dataBytes = _data.bytes; - NSUInteger dataLength = range.location - 2; - if (_subParser) { - if (![_subParser appendBytes:dataBytes length:(dataLength + 2)] || ![_subParser isAtEnd]) { - GWS_DNOT_REACHED(); - success = NO; - } - _subParser = nil; - } else if (_tmpPath) { - ssize_t result = write(_tmpFile, dataBytes, dataLength); - if (result == (ssize_t)dataLength) { - if (close(_tmpFile) == 0) { - _tmpFile = 0; - GCDWebServerMultiPartFile* file = [[GCDWebServerMultiPartFile alloc] initWithControlName:_controlName contentType:_contentType fileName:_fileName temporaryPath:_tmpPath]; - [_files addObject:file]; - } else { - GWS_DNOT_REACHED(); - success = NO; - } - } else { - GWS_DNOT_REACHED(); - success = NO; - } - _tmpPath = nil; - } else { - NSData* data = [[NSData alloc] initWithBytes:(void*)dataBytes length:dataLength]; - GCDWebServerMultiPartArgument* argument = [[GCDWebServerMultiPartArgument alloc] initWithControlName:_controlName contentType:_contentType data:data]; - [_arguments addObject:argument]; - } - } - - if (subRange1.location != NSNotFound) { - [_data replaceBytesInRange:NSMakeRange(0, subRange1.location + subRange1.length) withBytes:NULL length:0]; - _state = kParserState_Headers; - success = [self _parseData]; - } else { - _state = kParserState_End; - } - } - } else { - NSUInteger margin = 2 * _boundary.length; - if (_data.length > margin) { - NSUInteger length = _data.length - margin; - if (_subParser) { - if ([_subParser appendBytes:_data.bytes length:length]) { - [_data replaceBytesInRange:NSMakeRange(0, length) withBytes:NULL length:0]; - } else { - GWS_DNOT_REACHED(); - success = NO; - } - } else if (_tmpPath) { - ssize_t result = write(_tmpFile, _data.bytes, length); - if (result == (ssize_t)length) { - [_data replaceBytesInRange:NSMakeRange(0, length) withBytes:NULL length:0]; - } else { - GWS_DNOT_REACHED(); - success = NO; - } - } - } - } - } - - return success; -} - -- (BOOL)appendBytes:(const void*)bytes length:(NSUInteger)length { - [_data appendBytes:bytes length:length]; - return [self _parseData]; -} - -- (BOOL)isAtEnd { - return (_state == kParserState_End); -} - -@end - -@interface GCDWebServerMultiPartFormRequest () -@property(nonatomic) NSMutableArray* arguments; -@property(nonatomic) NSMutableArray* files; -@end - -@implementation GCDWebServerMultiPartFormRequest { - GCDWebServerMIMEStreamParser* _parser; -} - -+ (NSString*)mimeType { - return @"multipart/form-data"; -} - -- (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers path:(NSString*)path query:(NSDictionary*)query { - if ((self = [super initWithMethod:method url:url headers:headers path:path query:query])) { - _arguments = [[NSMutableArray alloc] init]; - _files = [[NSMutableArray alloc] init]; - } - return self; -} - -- (BOOL)open:(NSError**)error { - NSString* boundary = GCDWebServerExtractHeaderValueParameter(self.contentType, @"boundary"); - _parser = [[GCDWebServerMIMEStreamParser alloc] initWithBoundary:boundary defaultControlName:nil arguments:_arguments files:_files]; - if (_parser == nil) { - if (error) { - *error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Failed starting to parse multipart form data"}]; - } - return NO; - } - return YES; -} - -- (BOOL)writeData:(NSData*)data error:(NSError**)error { - if (![_parser appendBytes:data.bytes length:data.length]) { - if (error) { - *error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Failed continuing to parse multipart form data"}]; - } - return NO; - } - return YES; -} - -- (BOOL)close:(NSError**)error { - BOOL atEnd = [_parser isAtEnd]; - _parser = nil; - if (!atEnd) { - if (error) { - *error = [NSError errorWithDomain:kGCDWebServerErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Failed finishing to parse multipart form data"}]; - } - return NO; - } - return YES; -} - -- (GCDWebServerMultiPartArgument*)firstArgumentForControlName:(NSString*)name { - for (GCDWebServerMultiPartArgument* argument in _arguments) { - if ([argument.controlName isEqualToString:name]) { - return argument; - } - } - return nil; -} - -- (GCDWebServerMultiPartFile*)firstFileForControlName:(NSString*)name { - for (GCDWebServerMultiPartFile* file in _files) { - if ([file.controlName isEqualToString:name]) { - return file; - } - } - return nil; -} - -- (NSString*)description { - NSMutableString* description = [NSMutableString stringWithString:[super description]]; - if (_arguments.count) { - [description appendString:@"\n"]; - for (GCDWebServerMultiPartArgument* argument in _arguments) { - [description appendFormat:@"\n%@ (%@)\n", argument.controlName, argument.contentType]; - [description appendString:GCDWebServerDescribeData(argument.data, argument.contentType)]; - } - } - if (_files.count) { - [description appendString:@"\n"]; - for (GCDWebServerMultiPartFile* file in _files) { - [description appendFormat:@"\n%@ (%@): %@\n{%@}", file.controlName, file.contentType, file.fileName, file.temporaryPath]; - } - } - return description; -} - -@end diff --git a/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerURLEncodedFormRequest.h b/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerURLEncodedFormRequest.h deleted file mode 100644 index c0168b761..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerURLEncodedFormRequest.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "GCDWebServerDataRequest.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - * The GCDWebServerURLEncodedFormRequest subclass of GCDWebServerRequest - * parses the body of the HTTP request as a URL encoded form using - * GCDWebServerParseURLEncodedForm(). - */ -@interface GCDWebServerURLEncodedFormRequest : GCDWebServerDataRequest - -/** - * Returns the unescaped control names and values for the URL encoded form. - * - * The text encoding used to interpret the data is extracted from the - * "Content-Type" header or defaults to UTF-8. - */ -@property(nonatomic, readonly) NSDictionary* arguments; - -/** - * Returns the MIME type for URL encoded forms - * i.e. "application/x-www-form-urlencoded". - */ -+ (NSString*)mimeType; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerURLEncodedFormRequest.m b/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerURLEncodedFormRequest.m deleted file mode 100644 index d4d89e43e..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Requests/GCDWebServerURLEncodedFormRequest.m +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !__has_feature(objc_arc) -#error GCDWebServer requires ARC -#endif - -#import "GCDWebServerPrivate.h" - -@implementation GCDWebServerURLEncodedFormRequest - -+ (NSString*)mimeType { - return @"application/x-www-form-urlencoded"; -} - -- (BOOL)close:(NSError**)error { - if (![super close:error]) { - return NO; - } - - NSString* charset = GCDWebServerExtractHeaderValueParameter(self.contentType, @"charset"); - NSString* string = [[NSString alloc] initWithData:self.data encoding:GCDWebServerStringEncodingFromCharset(charset)]; - _arguments = GCDWebServerParseURLEncodedForm(string); - return YES; -} - -- (NSString*)description { - NSMutableString* description = [NSMutableString stringWithString:[super description]]; - [description appendString:@"\n"]; - for (NSString* argument in [[_arguments allKeys] sortedArrayUsingSelector:@selector(compare:)]) { - [description appendFormat:@"\n%@ = %@", argument, [_arguments objectForKey:argument]]; - } - return description; -} - -@end diff --git a/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerDataResponse.h b/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerDataResponse.h deleted file mode 100644 index e5121c336..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerDataResponse.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "GCDWebServerResponse.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - * The GCDWebServerDataResponse subclass of GCDWebServerResponse reads the body - * of the HTTP response from memory. - */ -@interface GCDWebServerDataResponse : GCDWebServerResponse -@property(nonatomic, copy) NSString* contentType; // Redeclare as non-null - -/** - * Creates a response with data in memory and a given content type. - */ -+ (instancetype)responseWithData:(NSData*)data contentType:(NSString*)type; - -/** - * This method is the designated initializer for the class. - */ -- (instancetype)initWithData:(NSData*)data contentType:(NSString*)type; - -@end - -@interface GCDWebServerDataResponse (Extensions) - -/** - * Creates a data response from text encoded using UTF-8. - */ -+ (nullable instancetype)responseWithText:(NSString*)text; - -/** - * Creates a data response from HTML encoded using UTF-8. - */ -+ (nullable instancetype)responseWithHTML:(NSString*)html; - -/** - * Creates a data response from an HTML template encoded using UTF-8. - * See -initWithHTMLTemplate:variables: for details. - */ -+ (nullable instancetype)responseWithHTMLTemplate:(NSString*)path variables:(NSDictionary*)variables; - -/** - * Creates a data response from a serialized JSON object and the default - * "application/json" content type. - */ -+ (nullable instancetype)responseWithJSONObject:(id)object; - -/** - * Creates a data response from a serialized JSON object and a custom - * content type. - */ -+ (nullable instancetype)responseWithJSONObject:(id)object contentType:(NSString*)type; - -/** - * Initializes a data response from text encoded using UTF-8. - */ -- (nullable instancetype)initWithText:(NSString*)text; - -/** - * Initializes a data response from HTML encoded using UTF-8. - */ -- (nullable instancetype)initWithHTML:(NSString*)html; - -/** - * Initializes a data response from an HTML template encoded using UTF-8. - * - * All occurences of "%variable%" within the HTML template are replaced with - * their corresponding values. - */ -- (nullable instancetype)initWithHTMLTemplate:(NSString*)path variables:(NSDictionary*)variables; - -/** - * Initializes a data response from a serialized JSON object and the default - * "application/json" content type. - */ -- (nullable instancetype)initWithJSONObject:(id)object; - -/** - * Initializes a data response from a serialized JSON object and a custom - * content type. - */ -- (nullable instancetype)initWithJSONObject:(id)object contentType:(NSString*)type; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerDataResponse.m b/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerDataResponse.m deleted file mode 100644 index 2ea2ce904..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerDataResponse.m +++ /dev/null @@ -1,136 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !__has_feature(objc_arc) -#error GCDWebServer requires ARC -#endif - -#import "GCDWebServerPrivate.h" - -@implementation GCDWebServerDataResponse { - NSData* _data; - BOOL _done; -} - -@dynamic contentType; - -+ (instancetype)responseWithData:(NSData*)data contentType:(NSString*)type { - return [(GCDWebServerDataResponse*)[[self class] alloc] initWithData:data contentType:type]; -} - -- (instancetype)initWithData:(NSData*)data contentType:(NSString*)type { - if ((self = [super init])) { - _data = data; - - self.contentType = type; - self.contentLength = data.length; - } - return self; -} - -- (NSData*)readData:(NSError**)error { - NSData* data; - if (_done) { - data = [NSData data]; - } else { - data = _data; - _done = YES; - } - return data; -} - -- (NSString*)description { - NSMutableString* description = [NSMutableString stringWithString:[super description]]; - [description appendString:@"\n\n"]; - [description appendString:GCDWebServerDescribeData(_data, self.contentType)]; - return description; -} - -@end - -@implementation GCDWebServerDataResponse (Extensions) - -+ (instancetype)responseWithText:(NSString*)text { - return [(GCDWebServerDataResponse*)[self alloc] initWithText:text]; -} - -+ (instancetype)responseWithHTML:(NSString*)html { - return [(GCDWebServerDataResponse*)[self alloc] initWithHTML:html]; -} - -+ (instancetype)responseWithHTMLTemplate:(NSString*)path variables:(NSDictionary*)variables { - return [(GCDWebServerDataResponse*)[self alloc] initWithHTMLTemplate:path variables:variables]; -} - -+ (instancetype)responseWithJSONObject:(id)object { - return [(GCDWebServerDataResponse*)[self alloc] initWithJSONObject:object]; -} - -+ (instancetype)responseWithJSONObject:(id)object contentType:(NSString*)type { - return [(GCDWebServerDataResponse*)[self alloc] initWithJSONObject:object contentType:type]; -} - -- (instancetype)initWithText:(NSString*)text { - NSData* data = [text dataUsingEncoding:NSUTF8StringEncoding]; - if (data == nil) { - GWS_DNOT_REACHED(); - return nil; - } - return [self initWithData:data contentType:@"text/plain; charset=utf-8"]; -} - -- (instancetype)initWithHTML:(NSString*)html { - NSData* data = [html dataUsingEncoding:NSUTF8StringEncoding]; - if (data == nil) { - GWS_DNOT_REACHED(); - return nil; - } - return [self initWithData:data contentType:@"text/html; charset=utf-8"]; -} - -- (instancetype)initWithHTMLTemplate:(NSString*)path variables:(NSDictionary*)variables { - NSMutableString* html = [[NSMutableString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL]; - [variables enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSString* value, BOOL* stop) { - [html replaceOccurrencesOfString:[NSString stringWithFormat:@"%%%@%%", key] withString:value options:0 range:NSMakeRange(0, html.length)]; - }]; - return [self initWithHTML:html]; -} - -- (instancetype)initWithJSONObject:(id)object { - return [self initWithJSONObject:object contentType:@"application/json"]; -} - -- (instancetype)initWithJSONObject:(id)object contentType:(NSString*)type { - NSData* data = [NSJSONSerialization dataWithJSONObject:object options:0 error:NULL]; - if (data == nil) { - GWS_DNOT_REACHED(); - return nil; - } - return [self initWithData:data contentType:type]; -} - -@end diff --git a/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerErrorResponse.h b/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerErrorResponse.h deleted file mode 100644 index 7e10d5bfe..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerErrorResponse.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "GCDWebServerDataResponse.h" -#import "GCDWebServerHTTPStatusCodes.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - * The GCDWebServerDataResponse subclass of GCDWebServerDataResponse generates - * an HTML body from an HTTP status code and an error message. - */ -@interface GCDWebServerErrorResponse : GCDWebServerDataResponse - -/** - * Creates a client error response with the corresponding HTTP status code. - */ -+ (instancetype)responseWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode message:(NSString*)format, ... NS_FORMAT_FUNCTION(2, 3); - -/** - * Creates a server error response with the corresponding HTTP status code. - */ -+ (instancetype)responseWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode message:(NSString*)format, ... NS_FORMAT_FUNCTION(2, 3); - -/** - * Creates a client error response with the corresponding HTTP status code - * and an underlying NSError. - */ -+ (instancetype)responseWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode underlyingError:(nullable NSError*)underlyingError message:(NSString*)format, ... NS_FORMAT_FUNCTION(3, 4); - -/** - * Creates a server error response with the corresponding HTTP status code - * and an underlying NSError. - */ -+ (instancetype)responseWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode underlyingError:(nullable NSError*)underlyingError message:(NSString*)format, ... NS_FORMAT_FUNCTION(3, 4); - -/** - * Initializes a client error response with the corresponding HTTP status code. - */ -- (instancetype)initWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode message:(NSString*)format, ... NS_FORMAT_FUNCTION(2, 3); - -/** - * Initializes a server error response with the corresponding HTTP status code. - */ -- (instancetype)initWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode message:(NSString*)format, ... NS_FORMAT_FUNCTION(2, 3); - -/** - * Initializes a client error response with the corresponding HTTP status code - * and an underlying NSError. - */ -- (instancetype)initWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode underlyingError:(nullable NSError*)underlyingError message:(NSString*)format, ... NS_FORMAT_FUNCTION(3, 4); - -/** - * Initializes a server error response with the corresponding HTTP status code - * and an underlying NSError. - */ -- (instancetype)initWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode underlyingError:(nullable NSError*)underlyingError message:(NSString*)format, ... NS_FORMAT_FUNCTION(3, 4); - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerErrorResponse.m b/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerErrorResponse.m deleted file mode 100644 index ab3788f6b..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerErrorResponse.m +++ /dev/null @@ -1,124 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !__has_feature(objc_arc) -#error GCDWebServer requires ARC -#endif - -#import "GCDWebServerPrivate.h" - -@implementation GCDWebServerErrorResponse - -+ (instancetype)responseWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode message:(NSString*)format, ... { - GWS_DCHECK(((NSInteger)errorCode >= 400) && ((NSInteger)errorCode < 500)); - va_list arguments; - va_start(arguments, format); - GCDWebServerErrorResponse* response = [(GCDWebServerErrorResponse*)[self alloc] initWithStatusCode:errorCode underlyingError:nil messageFormat:format arguments:arguments]; - va_end(arguments); - return response; -} - -+ (instancetype)responseWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode message:(NSString*)format, ... { - GWS_DCHECK(((NSInteger)errorCode >= 500) && ((NSInteger)errorCode < 600)); - va_list arguments; - va_start(arguments, format); - GCDWebServerErrorResponse* response = [(GCDWebServerErrorResponse*)[self alloc] initWithStatusCode:errorCode underlyingError:nil messageFormat:format arguments:arguments]; - va_end(arguments); - return response; -} - -+ (instancetype)responseWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode underlyingError:(NSError*)underlyingError message:(NSString*)format, ... { - GWS_DCHECK(((NSInteger)errorCode >= 400) && ((NSInteger)errorCode < 500)); - va_list arguments; - va_start(arguments, format); - GCDWebServerErrorResponse* response = [(GCDWebServerErrorResponse*)[self alloc] initWithStatusCode:errorCode underlyingError:underlyingError messageFormat:format arguments:arguments]; - va_end(arguments); - return response; -} - -+ (instancetype)responseWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode underlyingError:(NSError*)underlyingError message:(NSString*)format, ... { - GWS_DCHECK(((NSInteger)errorCode >= 500) && ((NSInteger)errorCode < 600)); - va_list arguments; - va_start(arguments, format); - GCDWebServerErrorResponse* response = [(GCDWebServerErrorResponse*)[self alloc] initWithStatusCode:errorCode underlyingError:underlyingError messageFormat:format arguments:arguments]; - va_end(arguments); - return response; -} - -static inline NSString* _EscapeHTMLString(NSString* string) { - return [string stringByReplacingOccurrencesOfString:@"\"" withString:@"""]; -} - -- (instancetype)initWithStatusCode:(NSInteger)statusCode underlyingError:(NSError*)underlyingError messageFormat:(NSString*)format arguments:(va_list)arguments { - NSString* message = [[NSString alloc] initWithFormat:format arguments:arguments]; - NSString* title = [NSString stringWithFormat:@"HTTP Error %i", (int)statusCode]; - NSString* error = underlyingError ? [NSString stringWithFormat:@"[%@] %@ (%li)", underlyingError.domain, _EscapeHTMLString(underlyingError.localizedDescription), (long)underlyingError.code] : @""; - NSString* html = [NSString stringWithFormat:@"%@

%@: %@

%@

", - title, title, _EscapeHTMLString(message), error]; - if ((self = [self initWithHTML:html])) { - self.statusCode = statusCode; - } - return self; -} - -- (instancetype)initWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode message:(NSString*)format, ... { - GWS_DCHECK(((NSInteger)errorCode >= 400) && ((NSInteger)errorCode < 500)); - va_list arguments; - va_start(arguments, format); - self = [self initWithStatusCode:errorCode underlyingError:nil messageFormat:format arguments:arguments]; - va_end(arguments); - return self; -} - -- (instancetype)initWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode message:(NSString*)format, ... { - GWS_DCHECK(((NSInteger)errorCode >= 500) && ((NSInteger)errorCode < 600)); - va_list arguments; - va_start(arguments, format); - self = [self initWithStatusCode:errorCode underlyingError:nil messageFormat:format arguments:arguments]; - va_end(arguments); - return self; -} - -- (instancetype)initWithClientError:(GCDWebServerClientErrorHTTPStatusCode)errorCode underlyingError:(NSError*)underlyingError message:(NSString*)format, ... { - GWS_DCHECK(((NSInteger)errorCode >= 400) && ((NSInteger)errorCode < 500)); - va_list arguments; - va_start(arguments, format); - self = [self initWithStatusCode:errorCode underlyingError:underlyingError messageFormat:format arguments:arguments]; - va_end(arguments); - return self; -} - -- (instancetype)initWithServerError:(GCDWebServerServerErrorHTTPStatusCode)errorCode underlyingError:(NSError*)underlyingError message:(NSString*)format, ... { - GWS_DCHECK(((NSInteger)errorCode >= 500) && ((NSInteger)errorCode < 600)); - va_list arguments; - va_start(arguments, format); - self = [self initWithStatusCode:errorCode underlyingError:underlyingError messageFormat:format arguments:arguments]; - va_end(arguments); - return self; -} - -@end diff --git a/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerFileResponse.h b/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerFileResponse.h deleted file mode 100644 index 78931bc61..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerFileResponse.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "GCDWebServerResponse.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - * The GCDWebServerFileResponse subclass of GCDWebServerResponse reads the body - * of the HTTP response from a file on disk. - * - * It will automatically set the contentType, lastModifiedDate and eTag - * properties of the GCDWebServerResponse according to the file extension and - * metadata. - */ -@interface GCDWebServerFileResponse : GCDWebServerResponse -@property(nonatomic, copy) NSString* contentType; // Redeclare as non-null -@property(nonatomic) NSDate* lastModifiedDate; // Redeclare as non-null -@property(nonatomic, copy) NSString* eTag; // Redeclare as non-null - -/** - * Creates a response with the contents of a file. - */ -+ (nullable instancetype)responseWithFile:(NSString*)path; - -/** - * Creates a response like +responseWithFile: and sets the "Content-Disposition" - * HTTP header for a download if the "attachment" argument is YES. - */ -+ (nullable instancetype)responseWithFile:(NSString*)path isAttachment:(BOOL)attachment; - -/** - * Creates a response like +responseWithFile: but restricts the file contents - * to a specific byte range. - * - * See -initWithFile:byteRange: for details. - */ -+ (nullable instancetype)responseWithFile:(NSString*)path byteRange:(NSRange)range; - -/** - * Creates a response like +responseWithFile:byteRange: and sets the - * "Content-Disposition" HTTP header for a download if the "attachment" - * argument is YES. - */ -+ (nullable instancetype)responseWithFile:(NSString*)path byteRange:(NSRange)range isAttachment:(BOOL)attachment; - -/** - * Initializes a response with the contents of a file. - */ -- (nullable instancetype)initWithFile:(NSString*)path; - -/** - * Initializes a response like +responseWithFile: and sets the - * "Content-Disposition" HTTP header for a download if the "attachment" - * argument is YES. - */ -- (nullable instancetype)initWithFile:(NSString*)path isAttachment:(BOOL)attachment; - -/** - * Initializes a response like -initWithFile: but restricts the file contents - * to a specific byte range. This range should be set to (NSUIntegerMax, 0) for - * the full file, (offset, length) if expressed from the beginning of the file, - * or (NSUIntegerMax, length) if expressed from the end of the file. The "offset" - * and "length" values will be automatically adjusted to be compatible with the - * actual size of the file. - * - * This argument would typically be set to the value of the byteRange property - * of the current GCDWebServerRequest. - */ -- (nullable instancetype)initWithFile:(NSString*)path byteRange:(NSRange)range; - -/** - * This method is the designated initializer for the class. - * - * If MIME type overrides are specified, they allow to customize the built-in - * mapping from extensions to MIME types. Keys of the dictionary must be lowercased - * file extensions without the period, and the values must be the corresponding - * MIME types. - */ -- (nullable instancetype)initWithFile:(NSString*)path byteRange:(NSRange)range isAttachment:(BOOL)attachment mimeTypeOverrides:(nullable NSDictionary*)overrides; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerFileResponse.m b/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerFileResponse.m deleted file mode 100644 index 78233063e..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerFileResponse.m +++ /dev/null @@ -1,185 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !__has_feature(objc_arc) -#error GCDWebServer requires ARC -#endif - -#import - -#import "GCDWebServerPrivate.h" - -#define kFileReadBufferSize (32 * 1024) - -@implementation GCDWebServerFileResponse { - NSString* _path; - NSUInteger _offset; - NSUInteger _size; - int _file; -} - -@dynamic contentType, lastModifiedDate, eTag; - -+ (instancetype)responseWithFile:(NSString*)path { - return [(GCDWebServerFileResponse*)[[self class] alloc] initWithFile:path]; -} - -+ (instancetype)responseWithFile:(NSString*)path isAttachment:(BOOL)attachment { - return [(GCDWebServerFileResponse*)[[self class] alloc] initWithFile:path isAttachment:attachment]; -} - -+ (instancetype)responseWithFile:(NSString*)path byteRange:(NSRange)range { - return [(GCDWebServerFileResponse*)[[self class] alloc] initWithFile:path byteRange:range]; -} - -+ (instancetype)responseWithFile:(NSString*)path byteRange:(NSRange)range isAttachment:(BOOL)attachment { - return [(GCDWebServerFileResponse*)[[self class] alloc] initWithFile:path byteRange:range isAttachment:attachment mimeTypeOverrides:nil]; -} - -- (instancetype)initWithFile:(NSString*)path { - return [self initWithFile:path byteRange:NSMakeRange(NSUIntegerMax, 0) isAttachment:NO mimeTypeOverrides:nil]; -} - -- (instancetype)initWithFile:(NSString*)path isAttachment:(BOOL)attachment { - return [self initWithFile:path byteRange:NSMakeRange(NSUIntegerMax, 0) isAttachment:attachment mimeTypeOverrides:nil]; -} - -- (instancetype)initWithFile:(NSString*)path byteRange:(NSRange)range { - return [self initWithFile:path byteRange:range isAttachment:NO mimeTypeOverrides:nil]; -} - -static inline NSDate* _NSDateFromTimeSpec(const struct timespec* t) { - return [NSDate dateWithTimeIntervalSince1970:((NSTimeInterval)t->tv_sec + (NSTimeInterval)t->tv_nsec / 1000000000.0)]; -} - -- (instancetype)initWithFile:(NSString*)path byteRange:(NSRange)range isAttachment:(BOOL)attachment mimeTypeOverrides:(NSDictionary*)overrides { - struct stat info; - if (lstat([path fileSystemRepresentation], &info) || !(info.st_mode & S_IFREG)) { - GWS_DNOT_REACHED(); - return nil; - } -#ifndef __LP64__ - if (info.st_size >= (off_t)4294967295) { // In 32 bit mode, we can't handle files greater than 4 GiBs (don't use "NSUIntegerMax" here to avoid potential unsigned to signed conversion issues) - GWS_DNOT_REACHED(); - return nil; - } -#endif - NSUInteger fileSize = (NSUInteger)info.st_size; - - BOOL hasByteRange = GCDWebServerIsValidByteRange(range); - if (hasByteRange) { - if (range.location != NSUIntegerMax) { - range.location = MIN(range.location, fileSize); - range.length = MIN(range.length, fileSize - range.location); - } else { - range.length = MIN(range.length, fileSize); - range.location = fileSize - range.length; - } - if (range.length == 0) { - return nil; // TODO: Return 416 status code and "Content-Range: bytes */{file length}" header - } - } else { - range.location = 0; - range.length = fileSize; - } - - if ((self = [super init])) { - _path = [path copy]; - _offset = range.location; - _size = range.length; - if (hasByteRange) { - [self setStatusCode:kGCDWebServerHTTPStatusCode_PartialContent]; - [self setValue:[NSString stringWithFormat:@"bytes %lu-%lu/%lu", (unsigned long)_offset, (unsigned long)(_offset + _size - 1), (unsigned long)fileSize] forAdditionalHeader:@"Content-Range"]; - GWS_LOG_DEBUG(@"Using content bytes range [%lu-%lu] for file \"%@\"", (unsigned long)_offset, (unsigned long)(_offset + _size - 1), path); - } - - if (attachment) { - NSString* fileName = [path lastPathComponent]; - NSData* data = [[fileName stringByReplacingOccurrencesOfString:@"\"" withString:@""] dataUsingEncoding:NSISOLatin1StringEncoding allowLossyConversion:YES]; - NSString* lossyFileName = data ? [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding] : nil; - if (lossyFileName) { - NSString* value = [NSString stringWithFormat:@"attachment; filename=\"%@\"; filename*=UTF-8''%@", lossyFileName, GCDWebServerEscapeURLString(fileName)]; - [self setValue:value forAdditionalHeader:@"Content-Disposition"]; - } else { - GWS_DNOT_REACHED(); - } - } - - self.contentType = GCDWebServerGetMimeTypeForExtension([_path pathExtension], overrides); - self.contentLength = _size; - self.lastModifiedDate = _NSDateFromTimeSpec(&info.st_mtimespec); - self.eTag = [NSString stringWithFormat:@"%llu/%li/%li", info.st_ino, info.st_mtimespec.tv_sec, info.st_mtimespec.tv_nsec]; - } - return self; -} - -- (BOOL)open:(NSError**)error { - _file = open([_path fileSystemRepresentation], O_NOFOLLOW | O_RDONLY); - if (_file <= 0) { - if (error) { - *error = GCDWebServerMakePosixError(errno); - } - return NO; - } - if (lseek(_file, _offset, SEEK_SET) != (off_t)_offset) { - if (error) { - *error = GCDWebServerMakePosixError(errno); - } - close(_file); - return NO; - } - return YES; -} - -- (NSData*)readData:(NSError**)error { - size_t length = MIN((NSUInteger)kFileReadBufferSize, _size); - NSMutableData* data = [[NSMutableData alloc] initWithLength:length]; - ssize_t result = read(_file, data.mutableBytes, length); - if (result < 0) { - if (error) { - *error = GCDWebServerMakePosixError(errno); - } - return nil; - } - if (result > 0) { - [data setLength:result]; - _size -= result; - } - return data; -} - -- (void)close { - close(_file); -} - -- (NSString*)description { - NSMutableString* description = [NSMutableString stringWithString:[super description]]; - [description appendFormat:@"\n\n{%@}", _path]; - return description; -} - -@end diff --git a/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerStreamedResponse.h b/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerStreamedResponse.h deleted file mode 100644 index 211f63038..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerStreamedResponse.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "GCDWebServerResponse.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - * The GCDWebServerStreamBlock is called to stream the data for the HTTP body. - * The block must return either a chunk of data, an empty NSData when done, or - * nil on error and set the "error" argument which is guaranteed to be non-NULL. - */ -typedef NSData* _Nullable (^GCDWebServerStreamBlock)(NSError** error); - -/** - * The GCDWebServerAsyncStreamBlock works like the GCDWebServerStreamBlock - * except the streamed data can be returned at a later time allowing for - * truly asynchronous generation of the data. - * - * The block must call "completionBlock" passing the new chunk of data when ready, - * an empty NSData when done, or nil on error and pass a NSError. - * - * The block cannot call "completionBlock" more than once per invocation. - */ -typedef void (^GCDWebServerAsyncStreamBlock)(GCDWebServerBodyReaderCompletionBlock completionBlock); - -/** - * The GCDWebServerStreamedResponse subclass of GCDWebServerResponse streams - * the body of the HTTP response using a GCD block. - */ -@interface GCDWebServerStreamedResponse : GCDWebServerResponse -@property(nonatomic, copy) NSString* contentType; // Redeclare as non-null - -/** - * Creates a response with streamed data and a given content type. - */ -+ (instancetype)responseWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block; - -/** - * Creates a response with async streamed data and a given content type. - */ -+ (instancetype)responseWithContentType:(NSString*)type asyncStreamBlock:(GCDWebServerAsyncStreamBlock)block; - -/** - * Initializes a response with streamed data and a given content type. - */ -- (instancetype)initWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block; - -/** - * This method is the designated initializer for the class. - */ -- (instancetype)initWithContentType:(NSString*)type asyncStreamBlock:(GCDWebServerAsyncStreamBlock)block; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerStreamedResponse.m b/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerStreamedResponse.m deleted file mode 100644 index c05e91b44..000000000 --- a/Pods/GCDWebServer/GCDWebServer/Responses/GCDWebServerStreamedResponse.m +++ /dev/null @@ -1,76 +0,0 @@ -/* - Copyright (c) 2012-2019, Pierre-Olivier Latour - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !__has_feature(objc_arc) -#error GCDWebServer requires ARC -#endif - -#import "GCDWebServerPrivate.h" - -@implementation GCDWebServerStreamedResponse { - GCDWebServerAsyncStreamBlock _block; -} - -@dynamic contentType; - -+ (instancetype)responseWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block { - return [(GCDWebServerStreamedResponse*)[[self class] alloc] initWithContentType:type streamBlock:block]; -} - -+ (instancetype)responseWithContentType:(NSString*)type asyncStreamBlock:(GCDWebServerAsyncStreamBlock)block { - return [(GCDWebServerStreamedResponse*)[[self class] alloc] initWithContentType:type asyncStreamBlock:block]; -} - -- (instancetype)initWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block { - return [self initWithContentType:type - asyncStreamBlock:^(GCDWebServerBodyReaderCompletionBlock completionBlock) { - NSError* error = nil; - NSData* data = block(&error); - completionBlock(data, error); - }]; -} - -- (instancetype)initWithContentType:(NSString*)type asyncStreamBlock:(GCDWebServerAsyncStreamBlock)block { - if ((self = [super init])) { - _block = [block copy]; - - self.contentType = type; - } - return self; -} - -- (void)asyncReadDataWithCompletion:(GCDWebServerBodyReaderCompletionBlock)block { - _block(block); -} - -- (NSString*)description { - NSMutableString* description = [NSMutableString stringWithString:[super description]]; - [description appendString:@"\n\n"]; - return description; -} - -@end diff --git a/Pods/GCDWebServer/LICENSE b/Pods/GCDWebServer/LICENSE deleted file mode 100644 index 12335de49..000000000 --- a/Pods/GCDWebServer/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2012-2014, Pierre-Olivier Latour -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * The name of Pierre-Olivier Latour may not be used to endorse - or promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PIERRE-OLIVIER LATOUR BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Pods/GCDWebServer/README.md b/Pods/GCDWebServer/README.md deleted file mode 100644 index 7d6aa578b..000000000 --- a/Pods/GCDWebServer/README.md +++ /dev/null @@ -1,469 +0,0 @@ -Overview -======== - -[![Build Status](https://travis-ci.org/swisspol/GCDWebServer.svg?branch=master)](https://travis-ci.org/swisspol/GCDWebServer) -[![Version](http://cocoapod-badges.herokuapp.com/v/GCDWebServer/badge.png)](https://cocoapods.org/pods/GCDWebServer) -[![Platform](http://cocoapod-badges.herokuapp.com/p/GCDWebServer/badge.png)](https://github.com/swisspol/GCDWebServer) -[![License](http://img.shields.io/cocoapods/l/GCDWebServer.svg)](LICENSE) - -GCDWebServer is a modern and lightweight GCD based HTTP 1.1 server designed to be embedded in iOS, macOS & tvOS apps. It was written from scratch with the following goals in mind: -* Elegant and easy to use architecture with only 4 core classes: server, connection, request and response (see "Understanding GCDWebServer's Architecture" below) -* Well designed API with fully documented headers for easy integration and customization -* Entirely built with an event-driven design using [Grand Central Dispatch](http://en.wikipedia.org/wiki/Grand_Central_Dispatch) for best performance and concurrency -* No dependencies on third-party source code -* Available under a friendly [New BSD License](LICENSE) - -Extra built-in features: -* Allow implementation of fully asynchronous handlers of incoming HTTP requests -* Minimize memory usage with disk streaming of large HTTP request or response bodies -* Parser for [web forms](http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4) submitted using "application/x-www-form-urlencoded" or "multipart/form-data" encodings (including file uploads) -* [JSON](http://www.json.org/) parsing and serialization for request and response HTTP bodies -* [Chunked transfer encoding](https://en.wikipedia.org/wiki/Chunked_transfer_encoding) for request and response HTTP bodies -* [HTTP compression](https://en.wikipedia.org/wiki/HTTP_compression) with gzip for request and response HTTP bodies -* [HTTP range](https://en.wikipedia.org/wiki/Byte_serving) support for requests of local files -* [Basic](https://en.wikipedia.org/wiki/Basic_access_authentication) and [Digest Access](https://en.wikipedia.org/wiki/Digest_access_authentication) authentications for password protection -* Automatically handle transitions between foreground, background and suspended modes in iOS apps -* Full support for both IPv4 and IPv6 -* NAT port mapping (IPv4 only) - -Included extensions: -* [GCDWebUploader](GCDWebUploader/GCDWebUploader.h): subclass of ```GCDWebServer``` that implements an interface for uploading and downloading files using a web browser -* [GCDWebDAVServer](GCDWebDAVServer/GCDWebDAVServer.h): subclass of ```GCDWebServer``` that implements a class 1 [WebDAV](https://en.wikipedia.org/wiki/WebDAV) server (with partial class 2 support for macOS Finder) - -What's not supported (but not really required from an embedded HTTP server): -* Keep-alive connections -* HTTPS - -Requirements: -* macOS 10.7 or later (x86_64) -* iOS 8.0 or later (armv7, armv7s or arm64) -* tvOS 9.0 or later (arm64) -* ARC memory management only (if you need MRC support use GCDWebServer 3.1 or earlier) - -Getting Started -=============== - -Download or check out the [latest release](https://github.com/swisspol/GCDWebServer/releases) of GCDWebServer then add the entire "GCDWebServer" subfolder to your Xcode project. If you intend to use one of the extensions like GCDWebDAVServer or GCDWebUploader, add these subfolders as well. Finally link to `libz` (via Target > Build Phases > Link Binary With Libraries) and add `$(SDKROOT)/usr/include/libxml2` to your header search paths (via Target > Build Settings > HEADER_SEARCH_PATHS). - -Alternatively, you can install GCDWebServer using [CocoaPods](http://cocoapods.org/) by simply adding this line to your Podfile: -``` -pod "GCDWebServer", "~> 3.0" -``` -If you want to use GCDWebUploader, use this line instead: -``` -pod "GCDWebServer/WebUploader", "~> 3.0" -``` -Or this line for GCDWebDAVServer: -``` -pod "GCDWebServer/WebDAV", "~> 3.0" -``` - -And finally run `$ pod install`. - -You can also use [Carthage](https://github.com/Carthage/Carthage) by adding this line to your Cartfile (3.2.5 is the first release with Carthage support): -``` -github "swisspol/GCDWebServer" ~> 3.2.5 -``` - -Then run `$ carthage update` and add the generated frameworks to your Xcode projects (see [Carthage instructions](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application)). - -Help & Support -============== - -For help with using GCDWebServer, it's best to ask your question on Stack Overflow with the [`gcdwebserver`](http://stackoverflow.com/questions/tagged/gcdwebserver) tag. For bug reports and enhancement requests you can use [issues](https://github.com/swisspol/GCDWebServer/issues) in this project. - -Be sure to read this entire README first though! - -Hello World -=========== - -These code snippets show how to implement a custom HTTP server that runs on port 8080 and returns a "Hello World" HTML page to any request. Since GCDWebServer uses GCD blocks to handle requests, no subclassing or delegates are needed, which results in very clean code. - -**IMPORTANT:** If not using CocoaPods, be sure to add the `libz` shared system library to the Xcode target for your app. - -**macOS version (command line tool):** -```objectivec -#import "GCDWebServer.h" -#import "GCDWebServerDataResponse.h" - -int main(int argc, const char* argv[]) { - @autoreleasepool { - - // Create server - GCDWebServer* webServer = [[GCDWebServer alloc] init]; - - // Add a handler to respond to GET requests on any URL - [webServer addDefaultHandlerForMethod:@"GET" - requestClass:[GCDWebServerRequest class] - processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { - - return [GCDWebServerDataResponse responseWithHTML:@"

Hello World

"]; - - }]; - - // Use convenience method that runs server on port 8080 - // until SIGINT (Ctrl-C in Terminal) or SIGTERM is received - [webServer runWithPort:8080 bonjourName:nil]; - NSLog(@"Visit %@ in your web browser", webServer.serverURL); - - } - return 0; -} -``` - -**iOS version:** -```objectivec -#import "GCDWebServer.h" -#import "GCDWebServerDataResponse.h" - -@interface AppDelegate : NSObject { - GCDWebServer* _webServer; -} -@end - -@implementation AppDelegate - -- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { - - // Create server - _webServer = [[GCDWebServer alloc] init]; - - // Add a handler to respond to GET requests on any URL - [_webServer addDefaultHandlerForMethod:@"GET" - requestClass:[GCDWebServerRequest class] - processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { - - return [GCDWebServerDataResponse responseWithHTML:@"

Hello World

"]; - - }]; - - // Start server on port 8080 - [_webServer startWithPort:8080 bonjourName:nil]; - NSLog(@"Visit %@ in your web browser", _webServer.serverURL); - - return YES; -} - -@end -``` - -**macOS Swift version (command line tool):** - -***webServer.swift*** -```swift -import Foundation -import GCDWebServer - -func initWebServer() { - - let webServer = GCDWebServer() - - webServer.addDefaultHandler(forMethod: "GET", request: GCDWebServerRequest.self, processBlock: {request in - return GCDWebServerDataResponse(html:"

Hello World

") - - }) - - webServer.start(withPort: 8080, bonjourName: "GCD Web Server") - - print("Visit \(webServer.serverURL) in your web browser") -} -``` - -***WebServer-Bridging-Header.h*** -```objectivec -#import -#import -``` - -Web Based Uploads in iOS Apps -============================= - -GCDWebUploader is a subclass of ```GCDWebServer``` that provides a ready-to-use HTML 5 file uploader & downloader. This lets users upload, download, delete files and create directories from a directory inside your iOS app's sandbox using a clean user interface in their web browser. - -Simply instantiate and run a ```GCDWebUploader``` instance then visit ```http://{YOUR-IOS-DEVICE-IP-ADDRESS}/``` from your web browser: - -```objectivec -#import "GCDWebUploader.h" - -@interface AppDelegate : NSObject { - GCDWebUploader* _webUploader; -} -@end - -@implementation AppDelegate - -- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { - NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; - _webUploader = [[GCDWebUploader alloc] initWithUploadDirectory:documentsPath]; - [_webUploader start]; - NSLog(@"Visit %@ in your web browser", _webUploader.serverURL); - return YES; -} - -@end -``` - -WebDAV Server in iOS Apps -========================= - -GCDWebDAVServer is a subclass of ```GCDWebServer``` that provides a class 1 compliant [WebDAV](https://en.wikipedia.org/wiki/WebDAV) server. This lets users upload, download, delete files and create directories from a directory inside your iOS app's sandbox using any WebDAV client like [Transmit](https://panic.com/transmit/) (Mac), [ForkLift](http://binarynights.com/forklift/) (Mac) or [CyberDuck](http://cyberduck.io/) (Mac / Windows). - -GCDWebDAVServer should also work with the [macOS Finder](http://support.apple.com/kb/PH13859) as it is partially class 2 compliant (but only when the client is the macOS WebDAV implementation). - -Simply instantiate and run a ```GCDWebDAVServer``` instance then connect to ```http://{YOUR-IOS-DEVICE-IP-ADDRESS}/``` using a WebDAV client: - -```objectivec -#import "GCDWebDAVServer.h" - -@interface AppDelegate : NSObject { - GCDWebDAVServer* _davServer; -} -@end - -@implementation AppDelegate - -- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { - NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; - _davServer = [[GCDWebDAVServer alloc] initWithUploadDirectory:documentsPath]; - [_davServer start]; - NSLog(@"Visit %@ in your WebDAV client", _davServer.serverURL); - return YES; -} - -@end -``` - -Serving a Static Website -======================== - -GCDWebServer includes a built-in handler that can recursively serve a directory (it also lets you control how the ["Cache-Control"](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) header should be set): - -**macOS version (command line tool):** -```objectivec -#import "GCDWebServer.h" - -int main(int argc, const char* argv[]) { - @autoreleasepool { - - GCDWebServer* webServer = [[GCDWebServer alloc] init]; - [webServer addGETHandlerForBasePath:@"/" directoryPath:NSHomeDirectory() indexFilename:nil cacheAge:3600 allowRangeRequests:YES]; - [webServer runWithPort:8080]; - - } - return 0; -} -``` - -Using GCDWebServer -================== - -You start by creating an instance of the ```GCDWebServer``` class. Note that you can have multiple web servers running in the same app as long as they listen on different ports. - -Then you add one or more "handlers" to the server: each handler gets a chance to handle an incoming web request and provide a response. Handlers are called in a LIFO queue, so the latest added handler overrides any previously added ones. - -Finally you start the server on a given port. - -Understanding GCDWebServer's Architecture -========================================= - -GCDWebServer's architecture consists of only 4 core classes: -* [GCDWebServer](GCDWebServer/Core/GCDWebServer.h) manages the socket that listens for new HTTP connections and the list of handlers used by the server. -* [GCDWebServerConnection](GCDWebServer/Core/GCDWebServerConnection.h) is instantiated by ```GCDWebServer``` to handle each new HTTP connection. Each instance stays alive until the connection is closed. You cannot use this class directly, but it is exposed so you can subclass it to override some hooks. -* [GCDWebServerRequest](GCDWebServer/Core/GCDWebServerRequest.h) is created by the ```GCDWebServerConnection``` instance after HTTP headers have been received. It wraps the request and handles the HTTP body if any. GCDWebServer comes with [several subclasses](GCDWebServer/Requests) of ```GCDWebServerRequest``` to handle common cases like storing the body in memory or stream it to a file on disk. -* [GCDWebServerResponse](GCDWebServer/Core/GCDWebServerResponse.h) is created by the request handler and wraps the response HTTP headers and optional body. GCDWebServer comes with [several subclasses](GCDWebServer/Responses) of ```GCDWebServerResponse``` to handle common cases like HTML text in memory or streaming a file from disk. - -Implementing Handlers -===================== - -GCDWebServer relies on "handlers" to process incoming web requests and generating responses. Handlers are implemented with GCD blocks which makes it very easy to provide your own. However, they are executed on arbitrary threads within GCD so __special attention must be paid to thread-safety and re-entrancy__. - -Handlers require 2 GCD blocks: -* The ```GCDWebServerMatchBlock``` is called on every handler added to the ```GCDWebServer``` instance whenever a web request has started (i.e. HTTP headers have been received). It is passed the basic info for the web request (HTTP method, URL, headers...) and must decide if it wants to handle it or not. If yes, it must return a new ```GCDWebServerRequest``` instance (see above) created with this info. Otherwise, it simply returns nil. -* The ```GCDWebServerProcessBlock``` or ```GCDWebServerAsyncProcessBlock``` is called after the web request has been fully received and is passed the ```GCDWebServerRequest``` instance created at the previous step. It must return synchronously (if using ```GCDWebServerProcessBlock```) or asynchronously (if using ```GCDWebServerAsyncProcessBlock```) a ```GCDWebServerResponse``` instance (see above) or nil on error, which will result in a 500 HTTP status code returned to the client. It's however recommended to return an instance of [GCDWebServerErrorResponse](GCDWebServer/Responses/GCDWebServerErrorResponse.h) on error so more useful information can be returned to the client. - -Note that most methods on ```GCDWebServer``` to add handlers only require the ```GCDWebServerProcessBlock``` or ```GCDWebServerAsyncProcessBlock``` as they already provide a built-in ```GCDWebServerMatchBlock``` e.g. to match a URL path with a Regex. - -Asynchronous HTTP Responses -=========================== - -New in GCDWebServer 3.0 is the ability to process HTTP requests asynchronously i.e. add handlers to the server which generate their ```GCDWebServerResponse``` asynchronously. This is achieved by adding handlers that use a ```GCDWebServerAsyncProcessBlock``` instead of a ```GCDWebServerProcessBlock```. Here's an example: - -**(Synchronous version)** The handler blocks while generating the HTTP response: -```objectivec -[webServer addDefaultHandlerForMethod:@"GET" - requestClass:[GCDWebServerRequest class] - processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { - - GCDWebServerDataResponse* response = [GCDWebServerDataResponse responseWithHTML:@"

Hello World

"]; - return response; - -}]; -``` - -**(Asynchronous version)** The handler returns immediately and calls back GCDWebServer later with the generated HTTP response: -```objectivec -[webServer addDefaultHandlerForMethod:@"GET" - requestClass:[GCDWebServerRequest class] - asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) { - - // Do some async operation like network access or file I/O (simulated here using dispatch_after()) - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - GCDWebServerDataResponse* response = [GCDWebServerDataResponse responseWithHTML:@"

Hello World

"]; - completionBlock(response); - }); - -}]; -``` - -**(Advanced asynchronous version)** The handler returns immediately a streamed HTTP response which itself generates its contents asynchronously: -```objectivec -[webServer addDefaultHandlerForMethod:@"GET" - requestClass:[GCDWebServerRequest class] - processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { - - NSMutableArray* contents = [NSMutableArray arrayWithObjects:@"

\n", @"Hello World!\n", @"

\n", nil]; // Fake data source we are reading from - GCDWebServerStreamedResponse* response = [GCDWebServerStreamedResponse responseWithContentType:@"text/html" asyncStreamBlock:^(GCDWebServerBodyReaderCompletionBlock completionBlock) { - - // Simulate a delay reading from the fake data source - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - NSString* string = contents.firstObject; - if (string) { - [contents removeObjectAtIndex:0]; - completionBlock([string dataUsingEncoding:NSUTF8StringEncoding], nil); // Generate the 2nd part of the stream data - } else { - completionBlock([NSData data], nil); // Must pass an empty NSData to signal the end of the stream - } - }); - - }]; - return response; - -}]; -``` - -*Note that you can even combine both the asynchronous and advanced asynchronous versions to return asynchronously an asynchronous HTTP response!* - -GCDWebServer & Background Mode for iOS Apps -=========================================== - -When doing networking operations in iOS apps, you must handle carefully [what happens when iOS puts the app in the background](https://developer.apple.com/library/ios/technotes/tn2277/_index.html). Typically you must stop any network servers while the app is in the background and restart them when the app comes back to the foreground. This can become quite complex considering servers might have ongoing connections when they need to be stopped. - -Fortunately, GCDWebServer does all of this automatically for you: -- GCDWebServer begins a [background task](https://developer.apple.com/library/archive/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html) whenever the first HTTP connection is opened and ends it only when the last one is closed. This prevents iOS from suspending the app after it goes in the background, which would immediately kill HTTP connections to the client. - - While the app is in the background, as long as new HTTP connections keep being initiated, the background task will continue to exist and iOS will not suspend the app **for up to 10 minutes** (unless under sudden and unexpected memory pressure). - - If the app is still in the background when the last HTTP connection is closed, GCDWebServer will suspend itself and stop accepting new connections as if you had called ```-stop``` (this behavior can be disabled with the ```GCDWebServerOption_AutomaticallySuspendInBackground``` option). -- If the app goes in the background while no HTTP connections are opened, GCDWebServer will immediately suspend itself and stop accepting new connections as if you had called ```-stop``` (this behavior can be disabled with the ```GCDWebServerOption_AutomaticallySuspendInBackground``` option). -- If the app comes back to the foreground and GCDWebServer had been suspended, it will automatically resume itself and start accepting again new HTTP connections as if you had called ```-start```. - -HTTP connections are often initiated in batches (or bursts), for instance when loading a web page with multiple resources. This makes it difficult to accurately detect when the *very last* HTTP connection has been closed: it's possible 2 consecutive HTTP connections part of the same batch would be separated by a small delay instead of overlapping. It would be bad for the client if GCDWebServer suspended itself right in between. The ```GCDWebServerOption_ConnectedStateCoalescingInterval``` option solves this problem elegantly by forcing GCDWebServer to wait some extra delay before performing any action after the last HTTP connection has been closed, just in case a new HTTP connection is initiated within this delay. - -Logging in GCDWebServer -======================= - -Both for debugging and informational purpose, GCDWebServer logs messages extensively whenever something happens. Furthermore, when building GCDWebServer in "Debug" mode versus "Release" mode, it logs even more information but also performs a number of internal consistency checks. To enable this behavior, define the preprocessor constant ```DEBUG=1``` when compiling GCDWebServer. In Xcode target settings, this can be done by adding ```DEBUG=1``` to the build setting ```GCC_PREPROCESSOR_DEFINITIONS``` when building in "Debug" configuration. Finally, you can also control the logging verbosity at run time by calling ```+[GCDWebServer setLogLevel:]```. - -By default, all messages logged by GCDWebServer are sent to its built-in logging facility, which simply outputs to ```stderr``` (assuming a terminal type device is connected). In order to better integrate with the rest of your app or because of the amount of information logged, you might want to use another logging facility. - -GCDWebServer has automatic support for [XLFacility](https://github.com/swisspol/XLFacility) (by the same author as GCDWebServer and also open-source): if it is in the same Xcode project, GCDWebServer should use it automatically instead of the built-in logging facility (see [GCDWebServerPrivate.h](GCDWebServer/Core/GCDWebServerPrivate.h) for the implementation details). - -It's also possible to use a custom logging facility - see [GCDWebServer.h](GCDWebServer/Core/GCDWebServer.h) for more information. - -Advanced Example 1: Implementing HTTP Redirects -=============================================== - -Here's an example handler that redirects "/" to "/index.html" using the convenience method on ```GCDWebServerResponse``` (it sets the HTTP status code and "Location" header automatically): - -```objectivec -[self addHandlerForMethod:@"GET" - path:@"/" - requestClass:[GCDWebServerRequest class] - processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { - - return [GCDWebServerResponse responseWithRedirect:[NSURL URLWithString:@"index.html" relativeToURL:request.URL] - permanent:NO]; - -}]; -``` - -Advanced Example 2: Implementing Forms -====================================== - -To implement an HTTP form, you need a pair of handlers: -* The GET handler does not expect any body in the HTTP request and therefore uses the ```GCDWebServerRequest``` class. The handler generates a response containing a simple HTML form. -* The POST handler expects the form values to be in the body of the HTTP request and percent-encoded. Fortunately, GCDWebServer provides the request class ```GCDWebServerURLEncodedFormRequest``` which can automatically parse such bodies. The handler simply echoes back the value from the user submitted form. - -```objectivec -[webServer addHandlerForMethod:@"GET" - path:@"/" - requestClass:[GCDWebServerRequest class] - processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { - - NSString* html = @" \ - \ -
\ - Value: \ - \ -
\ - \ - "; - return [GCDWebServerDataResponse responseWithHTML:html]; - -}]; - -[webServer addHandlerForMethod:@"POST" - path:@"/" - requestClass:[GCDWebServerURLEncodedFormRequest class] - processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { - - NSString* value = [[(GCDWebServerURLEncodedFormRequest*)request arguments] objectForKey:@"value"]; - NSString* html = [NSString stringWithFormat:@"

%@

", value]; - return [GCDWebServerDataResponse responseWithHTML:html]; - -}]; -``` - -Advanced Example 3: Serving a Dynamic Website -============================================= - -GCDWebServer provides an extension to the ```GCDWebServerDataResponse``` class that can return HTML content generated from a template and a set of variables (using the format ```%variable%```). It is a very basic template system and is really intended as a starting point to building more advanced template systems by subclassing ```GCDWebServerResponse```. - -Assuming you have a website directory in your app containing HTML template files along with the corresponding CSS, scripts and images, it's pretty easy to turn it into a dynamic website: - -```objectivec -// Get the path to the website directory -NSString* websitePath = [[NSBundle mainBundle] pathForResource:@"Website" ofType:nil]; - -// Add a default handler to serve static files (i.e. anything other than HTML files) -[self addGETHandlerForBasePath:@"/" directoryPath:websitePath indexFilename:nil cacheAge:3600 allowRangeRequests:YES]; - -// Add an override handler for all requests to "*.html" URLs to do the special HTML templatization -[self addHandlerForMethod:@"GET" - pathRegex:@"/.*\.html" - requestClass:[GCDWebServerRequest class] - processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { - - NSDictionary* variables = [NSDictionary dictionaryWithObjectsAndKeys:@"value", @"variable", nil]; - return [GCDWebServerDataResponse responseWithHTMLTemplate:[websitePath stringByAppendingPathComponent:request.path] - variables:variables]; - -}]; - -// Add an override handler to redirect "/" URL to "/index.html" -[self addHandlerForMethod:@"GET" - path:@"/" - requestClass:[GCDWebServerRequest class] - processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) { - - return [GCDWebServerResponse responseWithRedirect:[NSURL URLWithString:@"index.html" relativeToURL:request.URL] - permanent:NO]; - -]; - -``` - -Final Example: File Downloads and Uploads From iOS App -====================================================== - -GCDWebServer was originally written for the [ComicFlow](http://itunes.apple.com/us/app/comicflow/id409290355?mt=8) comic reader app for iPad. It allow users to connect to their iPad with their web browser over WiFi and then upload, download and organize comic files inside the app. - -ComicFlow is [entirely open-source](https://github.com/swisspol/ComicFlow) and you can see how it uses GCDWebServer in the [WebServer.h](https://github.com/swisspol/ComicFlow/blob/master/Classes/WebServer.h) and [WebServer.m](https://github.com/swisspol/ComicFlow/blob/master/Classes/WebServer.m) files. diff --git a/Pods/Headers/Private/BRLOptionParser/BRLOptionParser.h b/Pods/Headers/Private/BRLOptionParser/BRLOptionParser.h deleted file mode 120000 index 155812821..000000000 --- a/Pods/Headers/Private/BRLOptionParser/BRLOptionParser.h +++ /dev/null @@ -1 +0,0 @@ -../../../BRLOptionParser/BRLOptionParser/BRLOptionParser.h \ No newline at end of file diff --git a/Pods/Headers/Public/BRLOptionParser/BRLOptionParser.h b/Pods/Headers/Public/BRLOptionParser/BRLOptionParser.h deleted file mode 120000 index 155812821..000000000 --- a/Pods/Headers/Public/BRLOptionParser/BRLOptionParser.h +++ /dev/null @@ -1 +0,0 @@ -../../../BRLOptionParser/BRLOptionParser/BRLOptionParser.h \ No newline at end of file diff --git a/Pods/MASShortcut/Framework/Model/MASKeyCodes.h b/Pods/MASShortcut/Framework/Model/MASKeyCodes.h deleted file mode 100644 index 4c000b172..000000000 --- a/Pods/MASShortcut/Framework/Model/MASKeyCodes.h +++ /dev/null @@ -1,44 +0,0 @@ -#import -#import -#import "MASKeyMasks.h" - -// These glyphs are missed in Carbon.h -typedef NS_ENUM(unsigned short, kMASShortcutGlyph) { - kMASShortcutGlyphEject = 0x23CF, - kMASShortcutGlyphClear = 0x2715, - kMASShortcutGlyphDeleteLeft = 0x232B, - kMASShortcutGlyphDeleteRight = 0x2326, - kMASShortcutGlyphLeftArrow = 0x2190, - kMASShortcutGlyphRightArrow = 0x2192, - kMASShortcutGlyphUpArrow = 0x2191, - kMASShortcutGlyphDownArrow = 0x2193, - kMASShortcutGlyphEscape = 0x238B, - kMASShortcutGlyphHelp = 0x003F, - kMASShortcutGlyphPageDown = 0x21DF, - kMASShortcutGlyphPageUp = 0x21DE, - kMASShortcutGlyphTabRight = 0x21E5, - kMASShortcutGlyphReturn = 0x2305, - kMASShortcutGlyphReturnR2L = 0x21A9, - kMASShortcutGlyphPadClear = 0x2327, - kMASShortcutGlyphNorthwestArrow = 0x2196, - kMASShortcutGlyphSoutheastArrow = 0x2198, -}; - -NS_INLINE NSString* NSStringFromMASKeyCode(unsigned short ch) -{ - return [NSString stringWithFormat:@"%C", ch]; -} - -NS_INLINE NSUInteger MASPickCocoaModifiers(NSUInteger flags) -{ - return (flags & (NSEventModifierFlagControl | NSEventModifierFlagShift | NSEventModifierFlagOption | NSEventModifierFlagCommand)); -} - -NS_INLINE UInt32 MASCarbonModifiersFromCocoaModifiers(NSUInteger cocoaFlags) -{ - return - (cocoaFlags & NSEventModifierFlagCommand ? cmdKey : 0) - | (cocoaFlags & NSEventModifierFlagOption ? optionKey : 0) - | (cocoaFlags & NSEventModifierFlagControl ? controlKey : 0) - | (cocoaFlags & NSEventModifierFlagShift ? shiftKey : 0); -} diff --git a/Pods/MASShortcut/Framework/Model/MASKeyMasks.h b/Pods/MASShortcut/Framework/Model/MASKeyMasks.h deleted file mode 100644 index 5813c1df5..000000000 --- a/Pods/MASShortcut/Framework/Model/MASKeyMasks.h +++ /dev/null @@ -1,18 +0,0 @@ -#import - -// https://github.com/shpakovski/MASShortcut/issues/99 -// -// Long story short: NSControlKeyMask and friends were replaced with NSEventModifierFlagControl -// and similar in macOS Sierra. The project builds fine & clean, but including MASShortcut in -// a project with deployment target set to 10.12 results in several deprecation warnings because -// of the control masks. Simply replacing the old symbols with the new ones isn’t an option, -// since it breaks the build on older SDKs – in Travis, for example. -// -// It should be safe to remove this whole thing once the 10.12 SDK is ubiquitous. - -#if __MAC_OS_X_VERSION_MAX_ALLOWED < 101200 -#define NSEventModifierFlagCommand NSCommandKeyMask -#define NSEventModifierFlagControl NSControlKeyMask -#define NSEventModifierFlagOption NSAlternateKeyMask -#define NSEventModifierFlagShift NSShiftKeyMask -#endif diff --git a/Pods/MASShortcut/Framework/Model/MASShortcut.h b/Pods/MASShortcut/Framework/Model/MASShortcut.h deleted file mode 100644 index 1b7d76bed..000000000 --- a/Pods/MASShortcut/Framework/Model/MASShortcut.h +++ /dev/null @@ -1,81 +0,0 @@ -#import "MASKeyCodes.h" - -/** - A model class to hold a key combination. - - This class just represents a combination of keys. It does not care if - the combination is valid or can be used as a hotkey, it doesn’t watch - the input system for the shortcut appearance, nor it does access user - defaults. -*/ -@interface MASShortcut : NSObject - -/** - The virtual key code for the keyboard key. - - Hardware independent, same as in `NSEvent`. See `Events.h` in the HIToolbox - framework for a complete list, or Command-click this symbol: `kVK_ANSI_A`. -*/ -@property (nonatomic, readonly) NSInteger keyCode; - -/** - Cocoa keyboard modifier flags. - - Same as in `NSEvent`: `NSCommandKeyMask`, `NSAlternateKeyMask`, etc. -*/ -@property (nonatomic, readonly) NSEventModifierFlags modifierFlags; - -/** - Same as `keyCode`, just a different type. -*/ -@property (nonatomic, readonly) UInt32 carbonKeyCode; - -/** - Carbon modifier flags. - - A bit sum of `cmdKey`, `optionKey`, etc. -*/ -@property (nonatomic, readonly) UInt32 carbonFlags; - -/** - A string representing the “key” part of a shortcut, like the `5` in `⌘5`. - - @warning The value may change depending on the active keyboard layout. - For example for the `^2` keyboard shortcut (`kVK_ANSI_2+NSControlKeyMask` - to be precise) the `keyCodeString` is `2` on the US keyboard, but `ě` when - the Czech keyboard layout is active. See the spec for details. -*/ -@property (nonatomic, readonly) NSString *keyCodeString; - -/** - A key-code string used in key equivalent matching. - - For precise meaning of “key equivalents” see the `keyEquivalent` - property of `NSMenuItem`. Here the string is used to support shortcut - validation (“is the shortcut already taken in this menu?”) and - for display in `NSMenu`. - - The value of this property may differ from `keyCodeString`. For example - the Russian keyboard has a `Г` (Ge) Cyrillic character in place of the - latin `U` key. This means you can create a `^Г` shortcut, but in menus - that’s always displayed as `^U`. So the `keyCodeString` returns `Г` - and `keyCodeStringForKeyEquivalent` returns `U`. -*/ -@property (nonatomic, readonly) NSString *keyCodeStringForKeyEquivalent; - -/** - A string representing the shortcut modifiers, like the `⌘` in `⌘5`. -*/ -@property (nonatomic, readonly) NSString *modifierFlagsString; - -- (instancetype)initWithKeyCode:(NSInteger)code modifierFlags:(NSEventModifierFlags)flags; -+ (instancetype)shortcutWithKeyCode:(NSInteger)code modifierFlags:(NSEventModifierFlags)flags; - -/** - Creates a new shortcut from an `NSEvent` object. - - This is just a convenience initializer that reads the key code and modifiers from an `NSEvent`. -*/ -+ (instancetype)shortcutWithEvent:(NSEvent *)anEvent; - -@end diff --git a/Pods/MASShortcut/Framework/Model/MASShortcut.m b/Pods/MASShortcut/Framework/Model/MASShortcut.m deleted file mode 100644 index 1a029a90b..000000000 --- a/Pods/MASShortcut/Framework/Model/MASShortcut.m +++ /dev/null @@ -1,243 +0,0 @@ -#import "MASShortcut.h" -#import "MASLocalization.h" - -static NSString *const MASShortcutKeyCode = @"KeyCode"; -static NSString *const MASShortcutModifierFlags = @"ModifierFlags"; - -@implementation MASShortcut - -#pragma mark Initialization - -- (instancetype)initWithKeyCode:(NSInteger)code modifierFlags:(NSEventModifierFlags)flags -{ - self = [super init]; - if (self) { - _keyCode = code; - _modifierFlags = MASPickCocoaModifiers(flags); - } - return self; -} - -+ (instancetype)shortcutWithKeyCode:(NSInteger)code modifierFlags:(NSEventModifierFlags)flags -{ - return [[self alloc] initWithKeyCode:code modifierFlags:flags]; -} - -+ (instancetype)shortcutWithEvent:(NSEvent *)event -{ - return [[self alloc] initWithKeyCode:event.keyCode modifierFlags:event.modifierFlags]; -} - -#pragma mark Shortcut Accessors - -- (UInt32)carbonKeyCode -{ - return (self.keyCode == NSNotFound ? 0 : (UInt32)self.keyCode); -} - -- (UInt32)carbonFlags -{ - return MASCarbonModifiersFromCocoaModifiers(self.modifierFlags); -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"%@%@", self.modifierFlagsString, self.keyCodeString]; -} - -- (NSString *)keyCodeStringForKeyEquivalent -{ - NSString *keyCodeString = self.keyCodeString; - - if (keyCodeString.length <= 1) { - return keyCodeString.lowercaseString; - } - - switch (self.keyCode) { - case kVK_F1: return NSStringFromMASKeyCode(NSF1FunctionKey); - case kVK_F2: return NSStringFromMASKeyCode(NSF2FunctionKey); - case kVK_F3: return NSStringFromMASKeyCode(NSF3FunctionKey); - case kVK_F4: return NSStringFromMASKeyCode(NSF4FunctionKey); - case kVK_F5: return NSStringFromMASKeyCode(NSF5FunctionKey); - case kVK_F6: return NSStringFromMASKeyCode(NSF6FunctionKey); - case kVK_F7: return NSStringFromMASKeyCode(NSF7FunctionKey); - case kVK_F8: return NSStringFromMASKeyCode(NSF8FunctionKey); - case kVK_F9: return NSStringFromMASKeyCode(NSF9FunctionKey); - case kVK_F10: return NSStringFromMASKeyCode(NSF10FunctionKey); - case kVK_F11: return NSStringFromMASKeyCode(NSF11FunctionKey); - case kVK_F12: return NSStringFromMASKeyCode(NSF12FunctionKey); - case kVK_F13: return NSStringFromMASKeyCode(NSF13FunctionKey); - case kVK_F14: return NSStringFromMASKeyCode(NSF14FunctionKey); - case kVK_F15: return NSStringFromMASKeyCode(NSF15FunctionKey); - case kVK_F16: return NSStringFromMASKeyCode(NSF16FunctionKey); - case kVK_F17: return NSStringFromMASKeyCode(NSF17FunctionKey); - case kVK_F18: return NSStringFromMASKeyCode(NSF18FunctionKey); - case kVK_F19: return NSStringFromMASKeyCode(NSF19FunctionKey); - case kVK_Space: return NSStringFromMASKeyCode(0x20); - default: return @""; - } -} - -- (NSString *)keyCodeString -{ - // Some key codes don't have an equivalent - switch (self.keyCode) { - case NSNotFound: return @""; - case kVK_F1: return @"F1"; - case kVK_F2: return @"F2"; - case kVK_F3: return @"F3"; - case kVK_F4: return @"F4"; - case kVK_F5: return @"F5"; - case kVK_F6: return @"F6"; - case kVK_F7: return @"F7"; - case kVK_F8: return @"F8"; - case kVK_F9: return @"F9"; - case kVK_F10: return @"F10"; - case kVK_F11: return @"F11"; - case kVK_F12: return @"F12"; - case kVK_F13: return @"F13"; - case kVK_F14: return @"F14"; - case kVK_F15: return @"F15"; - case kVK_F16: return @"F16"; - case kVK_F17: return @"F17"; - case kVK_F18: return @"F18"; - case kVK_F19: return @"F19"; - case kVK_Space: return MASLocalizedString(@"Space", @"Shortcut glyph name for SPACE key"); - case kVK_Escape: return NSStringFromMASKeyCode(kMASShortcutGlyphEscape); - case kVK_Delete: return NSStringFromMASKeyCode(kMASShortcutGlyphDeleteLeft); - case kVK_ForwardDelete: return NSStringFromMASKeyCode(kMASShortcutGlyphDeleteRight); - case kVK_LeftArrow: return NSStringFromMASKeyCode(kMASShortcutGlyphLeftArrow); - case kVK_RightArrow: return NSStringFromMASKeyCode(kMASShortcutGlyphRightArrow); - case kVK_UpArrow: return NSStringFromMASKeyCode(kMASShortcutGlyphUpArrow); - case kVK_DownArrow: return NSStringFromMASKeyCode(kMASShortcutGlyphDownArrow); - case kVK_Help: return NSStringFromMASKeyCode(kMASShortcutGlyphHelp); - case kVK_PageUp: return NSStringFromMASKeyCode(kMASShortcutGlyphPageUp); - case kVK_PageDown: return NSStringFromMASKeyCode(kMASShortcutGlyphPageDown); - case kVK_Tab: return NSStringFromMASKeyCode(kMASShortcutGlyphTabRight); - case kVK_Return: return NSStringFromMASKeyCode(kMASShortcutGlyphReturnR2L); - - // Keypad - case kVK_ANSI_Keypad0: return @"0"; - case kVK_ANSI_Keypad1: return @"1"; - case kVK_ANSI_Keypad2: return @"2"; - case kVK_ANSI_Keypad3: return @"3"; - case kVK_ANSI_Keypad4: return @"4"; - case kVK_ANSI_Keypad5: return @"5"; - case kVK_ANSI_Keypad6: return @"6"; - case kVK_ANSI_Keypad7: return @"7"; - case kVK_ANSI_Keypad8: return @"8"; - case kVK_ANSI_Keypad9: return @"9"; - case kVK_ANSI_KeypadDecimal: return @"."; - case kVK_ANSI_KeypadMultiply: return @"*"; - case kVK_ANSI_KeypadPlus: return @"+"; - case kVK_ANSI_KeypadClear: return NSStringFromMASKeyCode(kMASShortcutGlyphPadClear); - case kVK_ANSI_KeypadDivide: return @"/"; - case kVK_ANSI_KeypadEnter: return NSStringFromMASKeyCode(kMASShortcutGlyphReturn); - case kVK_ANSI_KeypadMinus: return @"-"; - case kVK_ANSI_KeypadEquals: return @"="; - - // Hardcode - case 119: return NSStringFromMASKeyCode(kMASShortcutGlyphSoutheastArrow); - case 115: return NSStringFromMASKeyCode(kMASShortcutGlyphNorthwestArrow); - } - - // Everything else should be printable so look it up in the current ASCII capable keyboard layout - OSStatus error = noErr; - NSString *keystroke = nil; - TISInputSourceRef inputSource = TISCopyCurrentASCIICapableKeyboardLayoutInputSource(); - if (inputSource) { - CFDataRef layoutDataRef = TISGetInputSourceProperty(inputSource, kTISPropertyUnicodeKeyLayoutData); - if (layoutDataRef) { - UCKeyboardLayout *layoutData = (UCKeyboardLayout *)CFDataGetBytePtr(layoutDataRef); - UniCharCount length = 0; - UniChar chars[256] = { 0 }; - UInt32 deadKeyState = 0; - error = UCKeyTranslate(layoutData, (UInt16)self.keyCode, kUCKeyActionDisplay, 0, // No modifiers - LMGetKbdType(), kUCKeyTranslateNoDeadKeysMask, &deadKeyState, - sizeof(chars) / sizeof(UniChar), &length, chars); - keystroke = ((error == noErr) && length ? [NSString stringWithCharacters:chars length:length] : @""); - } - CFRelease(inputSource); - } - - // Validate keystroke - if (keystroke.length) { - static NSMutableCharacterSet *validChars = nil; - if (validChars == nil) { - validChars = [[NSMutableCharacterSet alloc] init]; - [validChars formUnionWithCharacterSet:[NSCharacterSet alphanumericCharacterSet]]; - [validChars formUnionWithCharacterSet:[NSCharacterSet punctuationCharacterSet]]; - [validChars formUnionWithCharacterSet:[NSCharacterSet symbolCharacterSet]]; - } - for (NSUInteger i = 0, length = keystroke.length; i < length; i++) { - if (![validChars characterIsMember:[keystroke characterAtIndex:i]]) { - keystroke = @""; - break; - } - } - } - - // Finally, we've got a shortcut! - return keystroke.uppercaseString; -} - -- (NSString *)modifierFlagsString -{ - unichar chars[4]; - NSUInteger count = 0; - // These are in the same order as the menu manager shows them - if (self.modifierFlags & NSControlKeyMask) chars[count++] = kControlUnicode; - if (self.modifierFlags & NSAlternateKeyMask) chars[count++] = kOptionUnicode; - if (self.modifierFlags & NSShiftKeyMask) chars[count++] = kShiftUnicode; - if (self.modifierFlags & NSCommandKeyMask) chars[count++] = kCommandUnicode; - return (count ? [NSString stringWithCharacters:chars length:count] : @""); -} - -#pragma mark NSObject - -- (BOOL) isEqual: (MASShortcut*) object -{ - return [object isKindOfClass:[self class]] - && (object.keyCode == self.keyCode) - && (object.modifierFlags == self.modifierFlags); -} - -- (NSUInteger) hash -{ - return self.keyCode + self.modifierFlags; -} - -#pragma mark NSCoding - -- (void)encodeWithCoder:(NSCoder *)coder -{ - [coder encodeInteger:(self.keyCode != NSNotFound ? self.keyCode : - 1) forKey:MASShortcutKeyCode]; - [coder encodeInteger:(NSInteger)self.modifierFlags forKey:MASShortcutModifierFlags]; -} - -- (instancetype)initWithCoder:(NSCoder *)decoder -{ - self = [super init]; - if (self) { - NSInteger code = [decoder decodeIntegerForKey:MASShortcutKeyCode]; - _keyCode = (code < 0) ? NSNotFound : code; - _modifierFlags = [decoder decodeIntegerForKey:MASShortcutModifierFlags]; - } - return self; -} - -#pragma mark NSSecureCoding - -+ (BOOL)supportsSecureCoding -{ - return YES; -} - -#pragma mark NSCopying - -- (instancetype) copyWithZone:(NSZone *)zone -{ - return [[self class] shortcutWithKeyCode:_keyCode modifierFlags:_modifierFlags]; -} - -@end diff --git a/Pods/MASShortcut/Framework/Model/MASShortcutValidator.h b/Pods/MASShortcut/Framework/Model/MASShortcutValidator.h deleted file mode 100644 index 95fe8282b..000000000 --- a/Pods/MASShortcut/Framework/Model/MASShortcutValidator.h +++ /dev/null @@ -1,29 +0,0 @@ -#import "MASShortcut.h" - -/** - This class is used by the recording control to tell which shortcuts are acceptable. - - There are two kinds of shortcuts that are not considered acceptable: shortcuts that - are too simple (like single letter keys) and shortcuts that are already used by the - operating system. -*/ -@interface MASShortcutValidator : NSObject - -/** - Set to `YES` if you want to accept Option-something shortcuts. - - `NO` by default, since Option-something shortcuts are often used by system, - for example Option-G will type the © sign. This also applies to Option-Shift - shortcuts – in other words, shortcut recorder will not accept shortcuts like - Option-Shift-K by default. (Again, since Option-Shift-K inserts the Apple - logo sign by default.) -*/ -@property(assign) BOOL allowAnyShortcutWithOptionModifier; - -+ (instancetype) sharedValidator; - -- (BOOL) isShortcutValid: (MASShortcut*) shortcut; -- (BOOL) isShortcut: (MASShortcut*) shortcut alreadyTakenInMenu: (NSMenu*) menu explanation: (NSString**) explanation; -- (BOOL) isShortcutAlreadyTakenBySystem: (MASShortcut*) shortcut explanation: (NSString**) explanation; - -@end diff --git a/Pods/MASShortcut/Framework/Model/MASShortcutValidator.m b/Pods/MASShortcut/Framework/Model/MASShortcutValidator.m deleted file mode 100644 index 01f21b737..000000000 --- a/Pods/MASShortcut/Framework/Model/MASShortcutValidator.m +++ /dev/null @@ -1,112 +0,0 @@ -#import "MASShortcutValidator.h" -#import "MASLocalization.h" - -@implementation MASShortcutValidator - -+ (instancetype) sharedValidator -{ - static dispatch_once_t once; - static MASShortcutValidator *sharedInstance; - dispatch_once(&once, ^{ - sharedInstance = [[self alloc] init]; - }); - return sharedInstance; -} - -- (BOOL) isShortcutValid: (MASShortcut*) shortcut -{ - NSInteger keyCode = [shortcut keyCode]; - NSEventModifierFlags modifiers = [shortcut modifierFlags]; - - // Allow any function key with any combination of modifiers - BOOL includesFunctionKey = ((keyCode == kVK_F1) || (keyCode == kVK_F2) || (keyCode == kVK_F3) || (keyCode == kVK_F4) || - (keyCode == kVK_F5) || (keyCode == kVK_F6) || (keyCode == kVK_F7) || (keyCode == kVK_F8) || - (keyCode == kVK_F9) || (keyCode == kVK_F10) || (keyCode == kVK_F11) || (keyCode == kVK_F12) || - (keyCode == kVK_F13) || (keyCode == kVK_F14) || (keyCode == kVK_F15) || (keyCode == kVK_F16) || - (keyCode == kVK_F17) || (keyCode == kVK_F18) || (keyCode == kVK_F19) || (keyCode == kVK_F20)); - if (includesFunctionKey) return YES; - - // Do not allow any other key without modifiers - BOOL hasModifierFlags = (modifiers > 0); - if (!hasModifierFlags) return NO; - - // Allow any hotkey containing Control or Command modifier - BOOL includesCommand = ((modifiers & NSCommandKeyMask) > 0); - BOOL includesControl = ((modifiers & NSControlKeyMask) > 0); - if (includesCommand || includesControl) return YES; - - // Allow Option key only in selected cases - BOOL includesOption = ((modifiers & NSAlternateKeyMask) > 0); - if (includesOption) { - - // Always allow Option-Space and Option-Escape because they do not have any bind system commands - if ((keyCode == kVK_Space) || (keyCode == kVK_Escape)) return YES; - - // Allow Option modifier with any key even if it will break the system binding - if (_allowAnyShortcutWithOptionModifier) return YES; - } - - // The hotkey does not have any modifiers or violates system bindings - return NO; -} - -- (BOOL) isShortcut: (MASShortcut*) shortcut alreadyTakenInMenu: (NSMenu*) menu explanation: (NSString**) explanation -{ - NSString *keyEquivalent = [shortcut keyCodeStringForKeyEquivalent]; - NSEventModifierFlags flags = [shortcut modifierFlags]; - - for (NSMenuItem *menuItem in menu.itemArray) { - if (menuItem.hasSubmenu && [self isShortcut:shortcut alreadyTakenInMenu:[menuItem submenu] explanation:explanation]) return YES; - - BOOL equalFlags = (MASPickCocoaModifiers(menuItem.keyEquivalentModifierMask) == flags); - BOOL equalHotkeyLowercase = [menuItem.keyEquivalent.lowercaseString isEqualToString:keyEquivalent]; - - // Check if the cases are different, we know ours is lower and that shift is included in our modifiers - // If theirs is capitol, we need to add shift to their modifiers - if (equalHotkeyLowercase && ![menuItem.keyEquivalent isEqualToString:keyEquivalent]) { - equalFlags = (MASPickCocoaModifiers(menuItem.keyEquivalentModifierMask | NSShiftKeyMask) == flags); - } - - if (equalFlags && equalHotkeyLowercase) { - if (explanation) { - *explanation = MASLocalizedString(@"This shortcut cannot be used because it is already used by the menu item ‘%@’.", - @"Message for alert when shortcut is already used"); - *explanation = [NSString stringWithFormat:*explanation, menuItem.title]; - } - return YES; - } - } - return NO; -} - -- (BOOL) isShortcutAlreadyTakenBySystem: (MASShortcut*) shortcut explanation: (NSString**) explanation -{ - CFArrayRef globalHotKeys; - if (CopySymbolicHotKeys(&globalHotKeys) == noErr) { - - // Enumerate all global hotkeys and check if any of them matches current shortcut - for (CFIndex i = 0, count = CFArrayGetCount(globalHotKeys); i < count; i++) { - CFDictionaryRef hotKeyInfo = CFArrayGetValueAtIndex(globalHotKeys, i); - CFNumberRef code = CFDictionaryGetValue(hotKeyInfo, kHISymbolicHotKeyCode); - CFNumberRef flags = CFDictionaryGetValue(hotKeyInfo, kHISymbolicHotKeyModifiers); - CFNumberRef enabled = CFDictionaryGetValue(hotKeyInfo, kHISymbolicHotKeyEnabled); - - if (([(__bridge NSNumber *)code integerValue] == [shortcut keyCode]) && - ([(__bridge NSNumber *)flags unsignedIntegerValue] == [shortcut carbonFlags]) && - ([(__bridge NSNumber *)enabled boolValue])) { - - if (explanation) { - *explanation = MASLocalizedString(@"This combination cannot be used because it is already used by a system-wide " - @"keyboard shortcut.\nIf you really want to use this key combination, most shortcuts " - @"can be changed in the Keyboard & Mouse panel in System Preferences.", - @"Message for alert when shortcut is already used by the system"); - } - return YES; - } - } - CFRelease(globalHotKeys); - } - return [self isShortcut:shortcut alreadyTakenInMenu:[NSApp mainMenu] explanation:explanation]; -} - -@end diff --git a/Pods/MASShortcut/Framework/Monitoring/MASHotKey.h b/Pods/MASShortcut/Framework/Monitoring/MASHotKey.h deleted file mode 100644 index 1d267e423..000000000 --- a/Pods/MASShortcut/Framework/Monitoring/MASHotKey.h +++ /dev/null @@ -1,12 +0,0 @@ -#import "MASShortcut.h" - -extern FourCharCode const MASHotKeySignature; - -@interface MASHotKey : NSObject - -@property(readonly) UInt32 carbonID; -@property(copy) dispatch_block_t action; - -+ (instancetype) registeredHotKeyWithShortcut: (MASShortcut*) shortcut; - -@end diff --git a/Pods/MASShortcut/Framework/Monitoring/MASHotKey.m b/Pods/MASShortcut/Framework/Monitoring/MASHotKey.m deleted file mode 100644 index c5ab74445..000000000 --- a/Pods/MASShortcut/Framework/Monitoring/MASHotKey.m +++ /dev/null @@ -1,44 +0,0 @@ -#import "MASHotKey.h" - -FourCharCode const MASHotKeySignature = 'MASS'; - -@interface MASHotKey () -@property(assign) EventHotKeyRef hotKeyRef; -@property(assign) UInt32 carbonID; -@end - -@implementation MASHotKey - -- (instancetype) initWithShortcut: (MASShortcut*) shortcut -{ - self = [super init]; - - static UInt32 CarbonHotKeyID = 0; - - _carbonID = ++CarbonHotKeyID; - EventHotKeyID hotKeyID = { .signature = MASHotKeySignature, .id = _carbonID }; - - OSStatus status = RegisterEventHotKey([shortcut carbonKeyCode], [shortcut carbonFlags], - hotKeyID, GetEventDispatcherTarget(), 0, &_hotKeyRef); - - if (status != noErr) { - return nil; - } - - return self; -} - -+ (instancetype) registeredHotKeyWithShortcut: (MASShortcut*) shortcut -{ - return [[self alloc] initWithShortcut:shortcut]; -} - -- (void) dealloc -{ - if (_hotKeyRef) { - UnregisterEventHotKey(_hotKeyRef); - _hotKeyRef = NULL; - } -} - -@end diff --git a/Pods/MASShortcut/Framework/Monitoring/MASShortcutMonitor.h b/Pods/MASShortcut/Framework/Monitoring/MASShortcutMonitor.h deleted file mode 100644 index dc3d458fb..000000000 --- a/Pods/MASShortcut/Framework/Monitoring/MASShortcutMonitor.h +++ /dev/null @@ -1,27 +0,0 @@ -#import "MASShortcut.h" - -/** - Executes action when a shortcut is pressed. - - There can only be one instance of this class, otherwise things - will probably not work. (There’s a Carbon event handler inside - and there can only be one Carbon event handler of a given type.) -*/ -@interface MASShortcutMonitor : NSObject - -- (instancetype) init __unavailable; -+ (instancetype) sharedMonitor; - -/** - Register a shortcut along with an action. - - Attempting to insert an already registered shortcut probably won’t work. - It may burn your house or cut your fingers. You have been warned. -*/ -- (BOOL) registerShortcut: (MASShortcut*) shortcut withAction: (dispatch_block_t) action; -- (BOOL) isShortcutRegistered: (MASShortcut*) shortcut; - -- (void) unregisterShortcut: (MASShortcut*) shortcut; -- (void) unregisterAllShortcuts; - -@end diff --git a/Pods/MASShortcut/Framework/Monitoring/MASShortcutMonitor.m b/Pods/MASShortcut/Framework/Monitoring/MASShortcutMonitor.m deleted file mode 100644 index fce802265..000000000 --- a/Pods/MASShortcut/Framework/Monitoring/MASShortcutMonitor.m +++ /dev/null @@ -1,108 +0,0 @@ -#import "MASShortcutMonitor.h" -#import "MASHotKey.h" - -@interface MASShortcutMonitor () -@property(assign) EventHandlerRef eventHandlerRef; -@property(strong) NSMutableDictionary *hotKeys; -@end - -static OSStatus MASCarbonEventCallback(EventHandlerCallRef, EventRef, void*); - -@implementation MASShortcutMonitor - -#pragma mark Initialization - -- (instancetype) init -{ - self = [super init]; - [self setHotKeys:[NSMutableDictionary dictionary]]; - EventTypeSpec hotKeyPressedSpec = { .eventClass = kEventClassKeyboard, .eventKind = kEventHotKeyPressed }; - OSStatus status = InstallEventHandler(GetEventDispatcherTarget(), MASCarbonEventCallback, - 1, &hotKeyPressedSpec, (__bridge void*)self, &_eventHandlerRef); - if (status != noErr) { - return nil; - } - return self; -} - -- (void) dealloc -{ - if (_eventHandlerRef) { - RemoveEventHandler(_eventHandlerRef); - _eventHandlerRef = NULL; - } -} - -+ (instancetype) sharedMonitor -{ - static dispatch_once_t once; - static MASShortcutMonitor *sharedInstance; - dispatch_once(&once, ^{ - sharedInstance = [[self alloc] init]; - }); - return sharedInstance; -} - -#pragma mark Registration - -- (BOOL) registerShortcut: (MASShortcut*) shortcut withAction: (dispatch_block_t) action -{ - MASHotKey *hotKey = [MASHotKey registeredHotKeyWithShortcut:shortcut]; - if (hotKey) { - [hotKey setAction:action]; - [_hotKeys setObject:hotKey forKey:shortcut]; - return YES; - } else { - return NO; - } -} - -- (void) unregisterShortcut: (MASShortcut*) shortcut -{ - if (shortcut) { - [_hotKeys removeObjectForKey:shortcut]; - } -} - -- (void) unregisterAllShortcuts -{ - [_hotKeys removeAllObjects]; -} - -- (BOOL) isShortcutRegistered: (MASShortcut*) shortcut -{ - return !![_hotKeys objectForKey:shortcut]; -} - -#pragma mark Event Handling - -- (void) handleEvent: (EventRef) event -{ - if (GetEventClass(event) != kEventClassKeyboard) { - return; - } - - EventHotKeyID hotKeyID; - OSStatus status = GetEventParameter(event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(hotKeyID), NULL, &hotKeyID); - if (status != noErr || hotKeyID.signature != MASHotKeySignature) { - return; - } - - [_hotKeys enumerateKeysAndObjectsUsingBlock:^(MASShortcut *shortcut, MASHotKey *hotKey, BOOL *stop) { - if (hotKeyID.id == [hotKey carbonID]) { - if ([hotKey action]) { - dispatch_async(dispatch_get_main_queue(), [hotKey action]); - } - *stop = YES; - } - }]; -} - -@end - -static OSStatus MASCarbonEventCallback(EventHandlerCallRef _, EventRef event, void *context) -{ - MASShortcutMonitor *dispatcher = (__bridge id)context; - [dispatcher handleEvent:event]; - return noErr; -} diff --git a/Pods/MASShortcut/Framework/Shortcut.h b/Pods/MASShortcut/Framework/Shortcut.h deleted file mode 100644 index 5a8de8e3a..000000000 --- a/Pods/MASShortcut/Framework/Shortcut.h +++ /dev/null @@ -1,8 +0,0 @@ -#import "MASKeyMasks.h" -#import "MASShortcut.h" -#import "MASShortcutValidator.h" -#import "MASShortcutMonitor.h" -#import "MASShortcutBinder.h" -#import "MASDictionaryTransformer.h" -#import "MASShortcutView.h" -#import "MASShortcutView+Bindings.h" diff --git a/Pods/MASShortcut/Framework/UI/MASLocalization.h b/Pods/MASShortcut/Framework/UI/MASLocalization.h deleted file mode 100644 index 466a9694e..000000000 --- a/Pods/MASShortcut/Framework/UI/MASLocalization.h +++ /dev/null @@ -1,13 +0,0 @@ -/** - Reads a localized string from the framework’s bundle. - - Normally you would use NSLocalizedString to read the localized - strings, but that’s just a shortcut for loading the strings from - the main bundle. And once the framework ends up in an app, the - main bundle will be the app’s bundle and won’t contain our strings. - So we introduced this helper function that makes sure to load the - strings from the framework’s bundle. Please avoid using - NSLocalizedString throughout the framework, it wouldn’t work - properly. -*/ -NSString *MASLocalizedString(NSString *key, NSString *comment); \ No newline at end of file diff --git a/Pods/MASShortcut/Framework/UI/MASLocalization.m b/Pods/MASShortcut/Framework/UI/MASLocalization.m deleted file mode 100644 index 5e119a71c..000000000 --- a/Pods/MASShortcut/Framework/UI/MASLocalization.m +++ /dev/null @@ -1,34 +0,0 @@ -#import "MASLocalization.h" -#import "MASShortcut.h" - -static NSString *const MASLocalizationTableName = @"Localizable"; -static NSString *const MASPlaceholderLocalizationString = @"XXX"; - -// The CocoaPods trickery here is needed because when the code -// is built as a part of CocoaPods, it won’t make a separate framework -// and the Localized.strings file won’t be bundled correctly. -// See https://github.com/shpakovski/MASShortcut/issues/74 -NSString *MASLocalizedString(NSString *key, NSString *comment) { - static NSBundle *localizationBundle = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSBundle *frameworkBundle = [NSBundle bundleForClass:[MASShortcut class]]; - // first we'll check if resources bundle was copied to MASShortcut framework bundle when !use_frameworks option is active - NSURL *cocoaPodsBundleURL = [frameworkBundle URLForResource:@"MASShortcut" withExtension:@"bundle"]; - if (cocoaPodsBundleURL) { - localizationBundle = [NSBundle bundleWithURL: cocoaPodsBundleURL]; - } else { - // trying to fetch cocoapods bundle from main bundle - cocoaPodsBundleURL = [[NSBundle mainBundle] URLForResource: @"MASShortcut" withExtension:@"bundle"]; - if (cocoaPodsBundleURL) { - localizationBundle = [NSBundle bundleWithURL: cocoaPodsBundleURL]; - } else { - // fallback to framework bundle - localizationBundle = frameworkBundle; - } - } - }); - return [localizationBundle localizedStringForKey:key - value:MASPlaceholderLocalizationString - table:MASLocalizationTableName]; -} diff --git a/Pods/MASShortcut/Framework/UI/MASShortcutView+Bindings.h b/Pods/MASShortcut/Framework/UI/MASShortcutView+Bindings.h deleted file mode 100644 index 01b224686..000000000 --- a/Pods/MASShortcut/Framework/UI/MASShortcutView+Bindings.h +++ /dev/null @@ -1,25 +0,0 @@ -#import "MASShortcutView.h" - -/** - A simplified interface to bind the recorder value to user defaults. - - You can bind the `shortcutValue` to user defaults using the standard - `bind:toObject:withKeyPath:options:` call, but since that’s a lot to type - and read, here’s a simpler option. - - Setting the `associatedUserDefaultsKey` binds the view’s shortcut value - to the given user defaults key. You can supply a value transformer to convert - values between user defaults and `MASShortcut`. If you don’t supply - a transformer, the `NSUnarchiveFromDataTransformerName` will be used - automatically. - - Set `associatedUserDefaultsKey` to `nil` to disconnect the binding. -*/ -@interface MASShortcutView (Bindings) - -@property(copy) NSString *associatedUserDefaultsKey; - -- (void) setAssociatedUserDefaultsKey: (NSString*) newKey withTransformer: (NSValueTransformer*) transformer; -- (void) setAssociatedUserDefaultsKey: (NSString*) newKey withTransformerName: (NSString*) transformerName; - -@end diff --git a/Pods/MASShortcut/Framework/UI/MASShortcutView+Bindings.m b/Pods/MASShortcut/Framework/UI/MASShortcutView+Bindings.m deleted file mode 100644 index 54c511154..000000000 --- a/Pods/MASShortcut/Framework/UI/MASShortcutView+Bindings.m +++ /dev/null @@ -1,50 +0,0 @@ -#import "MASShortcutView+Bindings.h" - -@implementation MASShortcutView (Bindings) - -- (NSString*) associatedUserDefaultsKey -{ - NSDictionary* bindingInfo = [self infoForBinding:MASShortcutBinding]; - if (bindingInfo != nil) { - NSString *keyPath = [bindingInfo objectForKey:NSObservedKeyPathKey]; - NSString *key = [keyPath stringByReplacingOccurrencesOfString:@"values." withString:@""]; - return key; - } else { - return nil; - } -} - -- (void) setAssociatedUserDefaultsKey: (NSString*) newKey withTransformer: (NSValueTransformer*) transformer -{ - // Break previous binding if any - NSString *currentKey = [self associatedUserDefaultsKey]; - if (currentKey != nil) { - [self unbind:currentKey]; - } - - // Stop if the new binding is nil - if (newKey == nil) { - return; - } - - NSDictionary *options = transformer ? - @{NSValueTransformerBindingOption:transformer} : - nil; - - [self bind:MASShortcutBinding - toObject:[NSUserDefaultsController sharedUserDefaultsController] - withKeyPath:[@"values." stringByAppendingString:newKey] - options:options]; -} - -- (void) setAssociatedUserDefaultsKey: (NSString*) newKey withTransformerName: (NSString*) transformerName -{ - [self setAssociatedUserDefaultsKey:newKey withTransformer:[NSValueTransformer valueTransformerForName:transformerName]]; -} - -- (void) setAssociatedUserDefaultsKey: (NSString*) newKey -{ - [self setAssociatedUserDefaultsKey:newKey withTransformerName:NSKeyedUnarchiveFromDataTransformerName]; -} - -@end diff --git a/Pods/MASShortcut/Framework/UI/MASShortcutView.h b/Pods/MASShortcut/Framework/UI/MASShortcutView.h deleted file mode 100644 index 75d4eb333..000000000 --- a/Pods/MASShortcut/Framework/UI/MASShortcutView.h +++ /dev/null @@ -1,26 +0,0 @@ -@class MASShortcut, MASShortcutValidator; - -extern NSString *const MASShortcutBinding; - -typedef NS_ENUM(NSInteger, MASShortcutViewStyle) { - MASShortcutViewStyleDefault = 0, // Height = 19 px - MASShortcutViewStyleTexturedRect, // Height = 25 px - MASShortcutViewStyleRounded, // Height = 43 px - MASShortcutViewStyleFlat -}; - -@interface MASShortcutView : NSView - -@property (nonatomic, strong) MASShortcut *shortcutValue; -@property (nonatomic, strong) MASShortcutValidator *shortcutValidator; -@property (nonatomic, getter = isRecording) BOOL recording; -@property (nonatomic, getter = isEnabled) BOOL enabled; -@property (nonatomic, copy) void (^shortcutValueChange)(MASShortcutView *sender); -@property (nonatomic, assign) MASShortcutViewStyle style; - -/// Returns custom class for drawing control. -+ (Class)shortcutCellClass; - -- (void)setAcceptsFirstResponder:(BOOL)value; - -@end diff --git a/Pods/MASShortcut/Framework/UI/MASShortcutView.m b/Pods/MASShortcut/Framework/UI/MASShortcutView.m deleted file mode 100644 index 3a44df42e..000000000 --- a/Pods/MASShortcut/Framework/UI/MASShortcutView.m +++ /dev/null @@ -1,646 +0,0 @@ -#import "MASShortcutView.h" -#import "MASShortcutValidator.h" -#import "MASLocalization.h" - -NSString *const MASShortcutBinding = @"shortcutValue"; - -static const CGFloat MASHintButtonWidth = 23; -static const CGFloat MASButtonFontSize = 11; - -#pragma mark - - -@interface MASShortcutView () // Private accessors - -@property (nonatomic, getter = isHinting) BOOL hinting; -@property (nonatomic, copy) NSString *shortcutPlaceholder; -@property (nonatomic, assign) BOOL showsDeleteButton; - -@end - -#pragma mark - - -@implementation MASShortcutView { - NSButtonCell *_shortcutCell; - NSInteger _shortcutToolTipTag; - NSInteger _hintToolTipTag; - NSTrackingArea *_hintArea; - BOOL _acceptsFirstResponder; -} - -#pragma mark - - -+ (Class)shortcutCellClass -{ - return [NSButtonCell class]; -} - -- (id)initWithFrame:(CGRect)frameRect -{ - self = [super initWithFrame:frameRect]; - if (self) { - [self commonInit]; - } - return self; -} - -- (id)initWithCoder:(NSCoder *)coder -{ - self = [super initWithCoder:coder]; - if (self) { - [self commonInit]; - } - return self; -} - -- (void)commonInit -{ - _shortcutCell = [[[self.class shortcutCellClass] alloc] init]; - _shortcutCell.buttonType = NSPushOnPushOffButton; - _shortcutCell.font = [[NSFontManager sharedFontManager] convertFont:_shortcutCell.font toSize:MASButtonFontSize]; - _shortcutValidator = [MASShortcutValidator sharedValidator]; - _enabled = YES; - _showsDeleteButton = YES; - _acceptsFirstResponder = NO; - [self resetShortcutCellStyle]; -} - -- (void)dealloc -{ - [self activateEventMonitoring:NO]; - [self activateResignObserver:NO]; -} - -#pragma mark - Public accessors - -- (void)setEnabled:(BOOL)flag -{ - if (_enabled != flag) { - _enabled = flag; - [self updateTrackingAreas]; - self.recording = NO; - [self invalidateIntrinsicContentSize]; - [self setNeedsDisplay:YES]; - } -} - -- (void)setStyle:(MASShortcutViewStyle)newStyle -{ - if (_style != newStyle) { - _style = newStyle; - [self resetShortcutCellStyle]; - [self invalidateIntrinsicContentSize]; - [self setNeedsDisplay:YES]; - } -} - -- (void)resetShortcutCellStyle -{ - switch (_style) { - case MASShortcutViewStyleDefault: { - _shortcutCell.bezelStyle = NSRoundRectBezelStyle; - break; - } - case MASShortcutViewStyleTexturedRect: { - _shortcutCell.bezelStyle = NSTexturedRoundedBezelStyle; - break; - } - case MASShortcutViewStyleRounded: { - _shortcutCell.bezelStyle = NSRoundedBezelStyle; - break; - } - case MASShortcutViewStyleFlat: { - self.wantsLayer = YES; - _shortcutCell.backgroundColor = [NSColor clearColor]; - _shortcutCell.bordered = NO; - break; - } - } -} - -- (void)setRecording:(BOOL)flag -{ - // Only one recorder can be active at the moment - static MASShortcutView *currentRecorder = nil; - if (flag && (currentRecorder != self)) { - currentRecorder.recording = NO; - currentRecorder = flag ? self : nil; - } - - // Only enabled view supports recording - if (flag && !self.enabled) return; - - // Only care about changes in state - if (flag == _recording) return; - - _recording = flag; - self.shortcutPlaceholder = nil; - [self resetToolTips]; - [self activateEventMonitoring:_recording]; - [self activateResignObserver:_recording]; - [self invalidateIntrinsicContentSize]; - [self setNeedsDisplay:YES]; - - // Give VoiceOver users feedback on the result. Requires at least 10.9 to run. - // We’re silencing the “tautological compare” warning here so that if someone - // takes the naked source files and compiles them with -Wall, the following - // NSAccessibilityPriorityKey comparison doesn’t cause a warning. See: - // https://github.com/shpakovski/MASShortcut/issues/76 - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wtautological-compare" - if (_recording == NO && (&NSAccessibilityPriorityKey != NULL)) { - NSString* msg = _shortcutValue ? - MASLocalizedString(@"Shortcut set", @"VoiceOver: Shortcut set") : - MASLocalizedString(@"Shortcut cleared", @"VoiceOver: Shortcut cleared"); - NSDictionary *announcementInfo = @{ - NSAccessibilityAnnouncementKey : msg, - NSAccessibilityPriorityKey : @(NSAccessibilityPriorityHigh), - }; - NSAccessibilityPostNotificationWithUserInfo(self, NSAccessibilityAnnouncementRequestedNotification, announcementInfo); - } - #pragma clang diagnostic pop -} - -- (void)setShortcutValue:(MASShortcut *)shortcutValue -{ - _shortcutValue = shortcutValue; - [self resetToolTips]; - [self invalidateIntrinsicContentSize]; - [self setNeedsDisplay:YES]; - [self propagateValue:shortcutValue forBinding:MASShortcutBinding]; - - if (self.shortcutValueChange) { - self.shortcutValueChange(self); - } -} - -- (void)setShortcutPlaceholder:(NSString *)shortcutPlaceholder -{ - _shortcutPlaceholder = shortcutPlaceholder.copy; - [self invalidateIntrinsicContentSize]; - [self setNeedsDisplay:YES]; -} - -#pragma mark - Appearance - -- (BOOL)allowsVibrancy -{ - return YES; -} - -#pragma mark - Drawing - -- (BOOL)isFlipped -{ - return YES; -} - -- (void)drawInRect:(CGRect)frame withTitle:(NSString *)title alignment:(NSTextAlignment)alignment state:(NSInteger)state -{ - _shortcutCell.title = title; - _shortcutCell.alignment = alignment; - _shortcutCell.state = state; - _shortcutCell.enabled = self.enabled; - - switch (_style) { - case MASShortcutViewStyleDefault: { - [_shortcutCell drawWithFrame:frame inView:self]; - break; - } - case MASShortcutViewStyleTexturedRect: { - [_shortcutCell drawWithFrame:CGRectOffset(frame, 0.0, 1.0) inView:self]; - break; - } - case MASShortcutViewStyleRounded: { - [_shortcutCell drawWithFrame:CGRectOffset(frame, 0.0, 1.0) inView:self]; - break; - } - case MASShortcutViewStyleFlat: { - [_shortcutCell drawWithFrame:frame inView:self]; - break; - } - } -} - -- (void)drawRect:(CGRect)dirtyRect -{ - if (self.shortcutValue) { - NSString *buttonTitle; - if (self.recording) { - buttonTitle = NSStringFromMASKeyCode(kMASShortcutGlyphEscape); - } else if (self.showsDeleteButton) { - buttonTitle = NSStringFromMASKeyCode(kMASShortcutGlyphClear); - } - if (buttonTitle != nil) { - [self drawInRect:self.bounds withTitle:buttonTitle alignment:NSRightTextAlignment state:NSOffState]; - } - CGRect shortcutRect; - [self getShortcutRect:&shortcutRect hintRect:NULL]; - NSString *title = (self.recording - ? (_hinting - ? MASLocalizedString(@"Use Old Shortcut", @"Cancel action button for non-empty shortcut in recording state") - : (self.shortcutPlaceholder.length > 0 - ? self.shortcutPlaceholder - : MASLocalizedString(@"Type New Shortcut", @"Non-empty shortcut button in recording state"))) - : _shortcutValue ? _shortcutValue.description : @""); - [self drawInRect:shortcutRect withTitle:title alignment:NSCenterTextAlignment state:self.isRecording ? NSOnState : NSOffState]; - } - else { - if (self.recording) - { - [self drawInRect:self.bounds withTitle:NSStringFromMASKeyCode(kMASShortcutGlyphEscape) alignment:NSRightTextAlignment state:NSOffState]; - - CGRect shortcutRect; - [self getShortcutRect:&shortcutRect hintRect:NULL]; - NSString *title = (_hinting - ? MASLocalizedString(@"Cancel", @"Cancel action button in recording state") - : (self.shortcutPlaceholder.length > 0 - ? self.shortcutPlaceholder - : MASLocalizedString(@"Type Shortcut", @"Empty shortcut button in recording state"))); - [self drawInRect:shortcutRect withTitle:title alignment:NSCenterTextAlignment state:NSOnState]; - } - else - { - [self drawInRect:self.bounds withTitle:MASLocalizedString(@"Record Shortcut", @"Empty shortcut button in normal state") - alignment:NSCenterTextAlignment state:NSOffState]; - } - } -} - - -- (NSSize)intrinsicContentSize -{ - NSSize cellSize = _shortcutCell.cellSize; - - // Use a "fake" value for width. Since determining the actual width requires information - // that is not determined until drawRect: is called, it doesn't seem feasible to properly - // calculate the intrinsic size without refactoring the code. That would give better results, - // however. - - // 120 is an arbitray number that seems to be wide enough for English localization. This - // may need to be adjusted for other locales/languages. - - // NOTE: Simply returning cellSize results in a display that is sometimes correct - // and sometimes not, and changes based on whether the mouse is hovering or not. - return NSMakeSize(120, cellSize.height); -} - - -#pragma mark - Mouse handling - -- (void)getShortcutRect:(CGRect *)shortcutRectRef hintRect:(CGRect *)hintRectRef -{ - CGRect shortcutRect, hintRect; - CGFloat hintButtonWidth = MASHintButtonWidth; - switch (self.style) { - case MASShortcutViewStyleTexturedRect: hintButtonWidth += 2.0; break; - case MASShortcutViewStyleRounded: hintButtonWidth += 3.0; break; - case MASShortcutViewStyleFlat: hintButtonWidth -= 8.0 - (_shortcutCell.font.pointSize - MASButtonFontSize); break; - default: break; - } - CGRectDivide(self.bounds, &hintRect, &shortcutRect, hintButtonWidth, CGRectMaxXEdge); - if (shortcutRectRef) *shortcutRectRef = shortcutRect; - if (hintRectRef) *hintRectRef = hintRect; -} - -- (BOOL)locationInShortcutRect:(CGPoint)location -{ - CGRect shortcutRect; - [self getShortcutRect:&shortcutRect hintRect:NULL]; - return CGRectContainsPoint(shortcutRect, [self convertPoint:location fromView:nil]); -} - -- (BOOL)locationInHintRect:(CGPoint)location -{ - CGRect hintRect; - [self getShortcutRect:NULL hintRect:&hintRect]; - return CGRectContainsPoint(hintRect, [self convertPoint:location fromView:nil]); -} - -- (void)mouseDown:(NSEvent *)event -{ - if (self.enabled) { - if (self.shortcutValue) { - if (self.recording) { - if ([self locationInHintRect:event.locationInWindow]) { - self.recording = NO; - } - } - else { - if ([self locationInShortcutRect:event.locationInWindow]) { - self.recording = YES; - } - else { - self.shortcutValue = nil; - } - } - } - else { - if (self.recording) { - if ([self locationInHintRect:event.locationInWindow]) { - self.recording = NO; - } - } - else { - self.recording = YES; - } - } - } - else { - [super mouseDown:event]; - } -} - -#pragma mark - Handling mouse over - -- (void)updateTrackingAreas -{ - [super updateTrackingAreas]; - - if (_hintArea) { - [self removeTrackingArea:_hintArea]; - _hintArea = nil; - } - - // Forbid hinting if view is disabled - if (!self.enabled) return; - - CGRect hintRect; - [self getShortcutRect:NULL hintRect:&hintRect]; - NSTrackingAreaOptions options = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways | NSTrackingAssumeInside); - _hintArea = [[NSTrackingArea alloc] initWithRect:hintRect options:options owner:self userInfo:nil]; - [self addTrackingArea:_hintArea]; -} - -- (void)setHinting:(BOOL)flag -{ - if (_hinting != flag) { - _hinting = flag; - [self invalidateIntrinsicContentSize]; - [self setNeedsDisplay:YES]; - } -} - -- (void)mouseEntered:(NSEvent *)event -{ - self.hinting = YES; -} - -- (void)mouseExited:(NSEvent *)event -{ - self.hinting = NO; -} - -void *kUserDataShortcut = &kUserDataShortcut; -void *kUserDataHint = &kUserDataHint; - -- (void)resetToolTips -{ - if (_shortcutToolTipTag) { - [self removeToolTip:_shortcutToolTipTag]; - _shortcutToolTipTag = 0; - } - if (_hintToolTipTag) { - [self removeToolTip:_hintToolTipTag]; - _hintToolTipTag = 0; - } - - if ((self.shortcutValue == nil) || self.recording || !self.enabled) return; - - CGRect shortcutRect, hintRect; - [self getShortcutRect:&shortcutRect hintRect:&hintRect]; - _shortcutToolTipTag = [self addToolTipRect:shortcutRect owner:self userData:kUserDataShortcut]; - _hintToolTipTag = [self addToolTipRect:hintRect owner:self userData:kUserDataHint]; -} - -- (NSString *)view:(NSView *)view stringForToolTip:(NSToolTipTag)tag point:(CGPoint)point userData:(void *)data -{ - if (data == kUserDataShortcut) { - return MASLocalizedString(@"Click to record new shortcut", @"Tooltip for non-empty shortcut button"); - } - else if (data == kUserDataHint) { - return MASLocalizedString(@"Delete shortcut", @"Tooltip for hint button near the non-empty shortcut"); - } - return @""; -} - -#pragma mark - Event monitoring - -- (void)activateEventMonitoring:(BOOL)shouldActivate -{ - static BOOL isActive = NO; - if (isActive == shouldActivate) return; - isActive = shouldActivate; - - static id eventMonitor = nil; - if (shouldActivate) { - __unsafe_unretained MASShortcutView *weakSelf = self; - NSEventMask eventMask = (NSKeyDownMask | NSFlagsChangedMask); - eventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^(NSEvent *event) { - - // Create a shortcut from the event - MASShortcut *shortcut = [MASShortcut shortcutWithEvent:event]; - - // Tab key must pass through. - if (shortcut.keyCode == kVK_Tab){ - return event; - } - - // If the shortcut is a plain Delete or Backspace, clear the current shortcut and cancel recording - if (!shortcut.modifierFlags && ((shortcut.keyCode == kVK_Delete) || (shortcut.keyCode == kVK_ForwardDelete))) { - weakSelf.shortcutValue = nil; - weakSelf.recording = NO; - event = nil; - } - - // If the shortcut is a plain Esc, cancel recording - else if (!shortcut.modifierFlags && shortcut.keyCode == kVK_Escape) { - weakSelf.recording = NO; - event = nil; - } - - // If the shortcut is Cmd-W or Cmd-Q, cancel recording and pass the event through - else if ((shortcut.modifierFlags == NSCommandKeyMask) && (shortcut.keyCode == kVK_ANSI_W || shortcut.keyCode == kVK_ANSI_Q)) { - weakSelf.recording = NO; - } - - else { - // Verify possible shortcut - if (shortcut.keyCodeString.length > 0) { - if (!weakSelf.shortcutValidator || [weakSelf.shortcutValidator isShortcutValid:shortcut]) { - // Verify that shortcut is not used - NSString *explanation = nil; - if ([weakSelf.shortcutValidator isShortcutAlreadyTakenBySystem:shortcut explanation:&explanation]) { - // Prevent cancel of recording when Alert window is key - [weakSelf activateResignObserver:NO]; - [weakSelf activateEventMonitoring:NO]; - NSString *format = MASLocalizedString(@"The key combination %@ cannot be used", - @"Title for alert when shortcut is already used"); - NSAlert* alert = [[NSAlert alloc]init]; - alert.alertStyle = NSCriticalAlertStyle; - alert.informativeText = explanation; - alert.messageText = [NSString stringWithFormat:format, shortcut]; - [alert addButtonWithTitle:MASLocalizedString(@"OK", @"Alert button when shortcut is already used")]; - - [alert runModal]; - weakSelf.shortcutPlaceholder = nil; - [weakSelf activateResignObserver:YES]; - [weakSelf activateEventMonitoring:YES]; - } - else { - weakSelf.shortcutValue = shortcut; - weakSelf.recording = NO; - } - } - else { - // Key press with or without SHIFT is not valid input - NSBeep(); - } - } - else { - // User is playing with modifier keys - weakSelf.shortcutPlaceholder = shortcut.modifierFlagsString; - } - event = nil; - } - return event; - }]; - } - else { - [NSEvent removeMonitor:eventMonitor]; - } -} - -- (void)activateResignObserver:(BOOL)shouldActivate -{ - static BOOL isActive = NO; - if (isActive == shouldActivate) return; - isActive = shouldActivate; - - static id observer = nil; - NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; - if (shouldActivate) { - __unsafe_unretained MASShortcutView *weakSelf = self; - observer = [notificationCenter addObserverForName:NSWindowDidResignKeyNotification object:self.window - queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification) { - weakSelf.recording = NO; - }]; - } - else { - [notificationCenter removeObserver:observer]; - } -} - -#pragma mark Bindings - -// http://tomdalling.com/blog/cocoa/implementing-your-own-cocoa-bindings/ --(void) propagateValue:(id)value forBinding:(NSString*)binding -{ - NSParameterAssert(binding != nil); - - //WARNING: bindingInfo contains NSNull, so it must be accounted for - NSDictionary* bindingInfo = [self infoForBinding:binding]; - if(!bindingInfo) - return; //there is no binding - - //apply the value transformer, if one has been set - NSDictionary* bindingOptions = [bindingInfo objectForKey:NSOptionsKey]; - if(bindingOptions){ - NSValueTransformer* transformer = [bindingOptions valueForKey:NSValueTransformerBindingOption]; - if(!transformer || (id)transformer == [NSNull null]){ - NSString* transformerName = [bindingOptions valueForKey:NSValueTransformerNameBindingOption]; - if(transformerName && (id)transformerName != [NSNull null]){ - transformer = [NSValueTransformer valueTransformerForName:transformerName]; - } - } - - if(transformer && (id)transformer != [NSNull null]){ - if([[transformer class] allowsReverseTransformation]){ - value = [transformer reverseTransformedValue:value]; - } else { - NSLog(@"WARNING: binding \"%@\" has value transformer, but it doesn't allow reverse transformations in %s", binding, __PRETTY_FUNCTION__); - } - } - } - - id boundObject = [bindingInfo objectForKey:NSObservedObjectKey]; - if(!boundObject || boundObject == [NSNull null]){ - NSLog(@"ERROR: NSObservedObjectKey was nil for binding \"%@\" in %s", binding, __PRETTY_FUNCTION__); - return; - } - - NSString* boundKeyPath = [bindingInfo objectForKey:NSObservedKeyPathKey]; - if(!boundKeyPath || (id)boundKeyPath == [NSNull null]){ - NSLog(@"ERROR: NSObservedKeyPathKey was nil for binding \"%@\" in %s", binding, __PRETTY_FUNCTION__); - return; - } - - [boundObject setValue:value forKeyPath:boundKeyPath]; -} - -#pragma mark - Accessibility - -- (NSString *)accessibilityHelp -{ - return MASLocalizedString(@"To record a new shortcut, click this button, and then type the" - @" new shortcut, or press delete to clear an existing shortcut.", - @"VoiceOver shortcut help"); -} - -- (NSString *)accessibilityLabel -{ - NSString* title = _shortcutValue.description ?: @"Empty"; - title = [title stringByAppendingFormat:@" %@", MASLocalizedString(@"keyboard shortcut", @"VoiceOver title")]; - return title; -} - -- (BOOL)accessibilityPerformPress -{ - if (self.isRecording == NO) { - self.recording = YES; - return YES; - } - else { - return NO; - } -} - -- (NSString *)accessibilityRole -{ - return NSAccessibilityButtonRole; -} - -- (BOOL)acceptsFirstResponder -{ - return _acceptsFirstResponder; -} - -- (void)setAcceptsFirstResponder:(BOOL)value -{ - _acceptsFirstResponder = value; -} - -- (BOOL)becomeFirstResponder -{ - [self invalidateIntrinsicContentSize]; - [self setNeedsDisplay:YES]; - return [super becomeFirstResponder]; -} - -- (BOOL)resignFirstResponder -{ - [self invalidateIntrinsicContentSize]; - [self setNeedsDisplay:YES]; - return [super resignFirstResponder]; -} - -- (void)drawFocusRingMask -{ - [_shortcutCell drawFocusRingMaskWithFrame:[self bounds] inView:self]; -} - -- (NSRect)focusRingMaskBounds -{ - return [self bounds]; -} - -@end diff --git a/Pods/MASShortcut/Framework/User Defaults Storage/MASDictionaryTransformer.h b/Pods/MASShortcut/Framework/User Defaults Storage/MASDictionaryTransformer.h deleted file mode 100644 index 6e53fd8b0..000000000 --- a/Pods/MASShortcut/Framework/User Defaults Storage/MASDictionaryTransformer.h +++ /dev/null @@ -1,19 +0,0 @@ -extern NSString *const MASDictionaryTransformerName; - -/** - Converts shortcuts for storage in user defaults. - - User defaults can’t stored custom types directly, they have to - be serialized to `NSData` or some other supported type like an - `NSDictionary`. In Cocoa Bindings, the conversion can be done - using value transformers like this one. - - There’s a built-in transformer (`NSKeyedUnarchiveFromDataTransformerName`) - that converts any `NSCoding` types to `NSData`, but with shortcuts - it makes sense to use a dictionary instead – the defaults look better - when inspected with the `defaults` command-line utility and the - format is compatible with an older sortcut library called Shortcut - Recorder. -*/ -@interface MASDictionaryTransformer : NSValueTransformer -@end diff --git a/Pods/MASShortcut/Framework/User Defaults Storage/MASDictionaryTransformer.m b/Pods/MASShortcut/Framework/User Defaults Storage/MASDictionaryTransformer.m deleted file mode 100644 index 9e4c82b4b..000000000 --- a/Pods/MASShortcut/Framework/User Defaults Storage/MASDictionaryTransformer.m +++ /dev/null @@ -1,51 +0,0 @@ -#import "MASDictionaryTransformer.h" -#import "MASShortcut.h" - -NSString *const MASDictionaryTransformerName = @"MASDictionaryTransformer"; - -static NSString *const MASKeyCodeKey = @"keyCode"; -static NSString *const MASModifierFlagsKey = @"modifierFlags"; - -@implementation MASDictionaryTransformer - -+ (BOOL) allowsReverseTransformation -{ - return YES; -} - -// Storing nil values as an empty dictionary lets us differ between -// “not available, use default value” and “explicitly set to none”. -// See http://stackoverflow.com/questions/5540760 for details. -- (NSDictionary*) reverseTransformedValue: (MASShortcut*) shortcut -{ - if (shortcut == nil) { - return [NSDictionary dictionary]; - } else { - return @{ - MASKeyCodeKey: @([shortcut keyCode]), - MASModifierFlagsKey: @([shortcut modifierFlags]) - }; - } -} - -- (MASShortcut*) transformedValue: (NSDictionary*) dictionary -{ - // We have to be defensive here as the value may come from user defaults. - if (![dictionary isKindOfClass:[NSDictionary class]]) { - return nil; - } - - id keyCodeBox = [dictionary objectForKey:MASKeyCodeKey]; - id modifierFlagsBox = [dictionary objectForKey:MASModifierFlagsKey]; - - SEL integerValue = @selector(integerValue); - if (![keyCodeBox respondsToSelector:integerValue] || ![modifierFlagsBox respondsToSelector:integerValue]) { - return nil; - } - - return [MASShortcut - shortcutWithKeyCode:[keyCodeBox integerValue] - modifierFlags:[modifierFlagsBox integerValue]]; -} - -@end diff --git a/Pods/MASShortcut/Framework/User Defaults Storage/MASShortcutBinder.h b/Pods/MASShortcut/Framework/User Defaults Storage/MASShortcutBinder.h deleted file mode 100644 index e7406dee2..000000000 --- a/Pods/MASShortcut/Framework/User Defaults Storage/MASShortcutBinder.h +++ /dev/null @@ -1,67 +0,0 @@ -#import "MASShortcutMonitor.h" - -/** - Binds actions to user defaults keys. - - If you store shortcuts in user defaults (for example by binding - a `MASShortcutView` to user defaults), you can use this class to - connect an action directly to a user defaults key. If the shortcut - stored under the key changes, the action will get automatically - updated to the new one. - - This class is mostly a wrapper around a `MASShortcutMonitor`. It - watches the changes in user defaults and updates the shortcut monitor - accordingly with the new shortcuts. -*/ -@interface MASShortcutBinder : NSObject - -/** - A convenience shared instance. - - You may use it so that you don’t have to manage an instance by hand, - but it’s perfectly fine to allocate and use a separate instance instead. -*/ -+ (instancetype) sharedBinder; - -/** - The underlying shortcut monitor. -*/ -@property(strong) MASShortcutMonitor *shortcutMonitor; - -/** - Binding options customizing the access to user defaults. - - As an example, you can use `NSValueTransformerNameBindingOption` to customize - the storage format used for the shortcuts. By default the shortcuts are converted - from `NSData` (`NSKeyedUnarchiveFromDataTransformerName`). Note that if the - binder is to work with `MASShortcutView`, both object have to use the same storage - format. -*/ -@property(copy) NSDictionary *bindingOptions; - -/** - Binds given action to a shortcut stored under the given defaults key. - - In other words, no matter what shortcut you store under the given key, - pressing it will always trigger the given action. -*/ -- (void) bindShortcutWithDefaultsKey: (NSString*) defaultsKeyName toAction: (dispatch_block_t) action; - -/** - Disconnect the binding between user defaults and action. - - In other words, the shortcut stored under the given key will no longer trigger an action. -*/ -- (void) breakBindingWithDefaultsKey: (NSString*) defaultsKeyName; - -/** - Register default shortcuts in user defaults. - - This is a convenience frontent to `[NSUserDefaults registerDefaults]`. - The dictionary should contain a map of user defaults’ keys to appropriate - keyboard shortcuts. The shortcuts will be transformed according to - `bindingOptions` and registered using `registerDefaults`. -*/ -- (void) registerDefaultShortcuts: (NSDictionary*) defaultShortcuts; - -@end diff --git a/Pods/MASShortcut/Framework/User Defaults Storage/MASShortcutBinder.m b/Pods/MASShortcut/Framework/User Defaults Storage/MASShortcutBinder.m deleted file mode 100644 index 4c0d7f9ae..000000000 --- a/Pods/MASShortcut/Framework/User Defaults Storage/MASShortcutBinder.m +++ /dev/null @@ -1,121 +0,0 @@ -#import "MASShortcutBinder.h" -#import "MASShortcut.h" - -@interface MASShortcutBinder () -@property(strong) NSMutableDictionary *actions; -@property(strong) NSMutableDictionary *shortcuts; -@end - -@implementation MASShortcutBinder - -#pragma mark Initialization - -- (id) init -{ - self = [super init]; - [self setActions:[NSMutableDictionary dictionary]]; - [self setShortcuts:[NSMutableDictionary dictionary]]; - [self setShortcutMonitor:[MASShortcutMonitor sharedMonitor]]; - [self setBindingOptions:@{NSValueTransformerNameBindingOption: NSKeyedUnarchiveFromDataTransformerName}]; - return self; -} - -- (void) dealloc -{ - for (NSString *bindingName in [_actions allKeys]) { - [self unbind:bindingName]; - } -} - -+ (instancetype) sharedBinder -{ - static dispatch_once_t once; - static MASShortcutBinder *sharedInstance; - dispatch_once(&once, ^{ - sharedInstance = [[self alloc] init]; - }); - return sharedInstance; -} - -#pragma mark Registration - -- (void) bindShortcutWithDefaultsKey: (NSString*) defaultsKeyName toAction: (dispatch_block_t) action -{ - NSAssert([defaultsKeyName rangeOfString:@"."].location == NSNotFound, - @"Illegal character in binding name (“.”), please see http://git.io/x5YS."); - NSAssert([defaultsKeyName rangeOfString:@" "].location == NSNotFound, - @"Illegal character in binding name (“ ”), please see http://git.io/x5YS."); - [_actions setObject:[action copy] forKey:defaultsKeyName]; - [self bind:defaultsKeyName - toObject:[NSUserDefaultsController sharedUserDefaultsController] - withKeyPath:[@"values." stringByAppendingString:defaultsKeyName] - options:_bindingOptions]; -} - -- (void) breakBindingWithDefaultsKey: (NSString*) defaultsKeyName -{ - [_shortcutMonitor unregisterShortcut:[_shortcuts objectForKey:defaultsKeyName]]; - [_shortcuts removeObjectForKey:defaultsKeyName]; - [_actions removeObjectForKey:defaultsKeyName]; - [self unbind:defaultsKeyName]; -} - -- (void) registerDefaultShortcuts: (NSDictionary*) defaultShortcuts -{ - NSValueTransformer *transformer = [_bindingOptions valueForKey:NSValueTransformerBindingOption]; - if (transformer == nil) { - NSString *transformerName = [_bindingOptions valueForKey:NSValueTransformerNameBindingOption]; - if (transformerName) { - transformer = [NSValueTransformer valueTransformerForName:transformerName]; - } - } - - NSAssert(transformer != nil, @"Can’t register default shortcuts without a transformer."); - - [defaultShortcuts enumerateKeysAndObjectsUsingBlock:^(NSString *defaultsKey, MASShortcut *shortcut, BOOL *stop) { - id value = [transformer reverseTransformedValue:shortcut]; - [[NSUserDefaults standardUserDefaults] registerDefaults:@{defaultsKey:value}]; - }]; -} - -#pragma mark Bindings - -- (BOOL) isRegisteredAction: (NSString*) name -{ - return !![_actions objectForKey:name]; -} - -- (id) valueForUndefinedKey: (NSString*) key -{ - return [self isRegisteredAction:key] ? - [_shortcuts objectForKey:key] : - [super valueForUndefinedKey:key]; -} - -- (void) setValue: (id) value forUndefinedKey: (NSString*) key -{ - if (![self isRegisteredAction:key]) { - [super setValue:value forUndefinedKey:key]; - return; - } - - MASShortcut *newShortcut = value; - MASShortcut *currentShortcut = [_shortcuts objectForKey:key]; - - // Unbind previous shortcut if any - if (currentShortcut != nil) { - [_shortcutMonitor unregisterShortcut:currentShortcut]; - } - - // Just deleting the old shortcut - if (newShortcut == nil) { - [_shortcuts removeObjectForKey:key]; - return; - } - - // Bind new shortcut - [_shortcuts setObject:newShortcut forKey:key]; - [_shortcutMonitor registerShortcut:newShortcut withAction:[_actions objectForKey:key]]; -} - -@end diff --git a/Pods/MASShortcut/LICENSE b/Pods/MASShortcut/LICENSE deleted file mode 100644 index e7686315f..000000000 --- a/Pods/MASShortcut/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2012-2013, Vadim Shpakovski -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Pods/MASShortcut/README.md b/Pods/MASShortcut/README.md deleted file mode 100644 index d10ba1abe..000000000 --- a/Pods/MASShortcut/README.md +++ /dev/null @@ -1,136 +0,0 @@ -[![Build Status](https://travis-ci.org/shpakovski/MASShortcut.svg?branch=master)](https://travis-ci.org/shpakovski/MASShortcut) -[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) - -# Intro - -Some time ago Cocoa developers used a brilliant framework [ShortcutRecorder](http://wafflesoftware.net/shortcut/) for managing keyboard shortcuts in application preferences. However, it became incompatible with the new plugin architecture of Xcode 4. - -The MASShortcut project introduces a modern API and user interface for recording, storing and using system-wide keyboard shortcuts. - -![Screenshot of the demo project](https://raw.githubusercontent.com/shpakovski/MASShortcut/master/Demo/screenshot.png "This is how the demo looks like") - -Features: - -* Record and display keyboard shortcuts -* Watch for shortcuts and execute actions, system-wide -* A nice, [documented API](http://cocoadocs.org/docsets/MASShortcut/) -* Can be configured to be compatible with Shortcut Recorder -* Can be installed both through CocoaPods and as a Git submodule -* Mac App Store friendly -* Works on OS X 10.10 and up -* Hacking-friendly codebase covered with tests - -Partially done: - -* Accessibility support. There’s some basic accessibility code, testers and feedback welcome. -* Localisation. The English and Czech localization should be complete, there’s basic support for German, French, Spanish, Italian, and Japanese. If you’re a native speaker in one of the mentioned languages, please test the localization and report issues or add missing strings. - -Pull requests welcome :) - -# Installation - -You can use [CocoaPods](http://cocoapods.org/), adding the following line to your Podfile: - - pod 'MASShortcut' - -If you want to stick to the 1.x branch, you can use the version smart match operator: - - pod 'MASShortcut', '~> 1' - -You can also install via [Carthage](https://github.com/Carthage/Carthage), or you can use Git submodules and link against the MASShortcut framework manually. - -To build from the command line, type 'make release'. The framework will be created in a temporary directory and revealed in Finder when the build is complete. - -# Usage - -I hope, it is really easy: - -```objective-c -#import - -// Drop a custom view into XIB, set its class to MASShortcutView -// and its height to 19. If you select another appearance style, -// look up the correct height values in MASShortcutView.h. -@property (nonatomic, weak) IBOutlet MASShortcutView *shortcutView; - -// Pick a preference key to store the shortcut between launches -static NSString *const kPreferenceGlobalShortcut = @"GlobalShortcut"; - -// Associate the shortcut view with user defaults -self.shortcutView.associatedUserDefaultsKey = kPreferenceGlobalShortcut; - -// Associate the preference key with an action -[[MASShortcutBinder sharedBinder] - bindShortcutWithDefaultsKey:kPreferenceGlobalShortcut - toAction:^{ - // Let me know if you find a better or a more convenient API. -}]; -``` - -You can see a real usage example in the Demo target. Enjoy! - -# Shortcut Recorder Compatibility - -By default, MASShortcut uses a different User Defaults storage format incompatible with Shortcut Recorder. But it’s easily possible to change that, so that you can replace Shortcut Recorder with MASShortcut without having to migrate the shortcuts previously stored by your apps. There are two parts of the story: - -If you bind the recorder control (`MASShortcutView`) to User defaults, set the Value Transformer field in the Interface Builder to `MASDictionaryTransformer`. This makes sure the shortcuts are written in the Shortcut Recorder format. - -If you use `MASShortcutBinder` to automatically load shortcuts from User Defaults, set the `bindingOptions` accordingly: - -```objective-c -[[MASShortcutBinder sharedBinder] setBindingOptions:@{NSValueTransformerNameBindingOption:MASDictionaryTransformerName}]; -``` - -This makes sure that the shortcuts in the Shortcut Recorder format are loaded correctly. - -# Notifications - -By registering for KVO notifications from `NSUserDefaultsController`, you can get a callback whenever a user changes the shortcut, allowing you to perform any UI updates, or other code handling tasks. - -This is just as easy to implement: - -```objective-c -// Declare an ivar for key path in the user defaults controller -NSString *_observableKeyPath; - -// Make a global context reference -void *kGlobalShortcutContext = &kGlobalShortcutContext; - -// Implement when loading view -_observableKeyPath = [@"values." stringByAppendingString:kPreferenceGlobalShortcut]; -[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:_observableKeyPath - options:NSKeyValueObservingOptionInitial - context:kGlobalShortcutContext]; - -// Capture the KVO change and do something -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)obj - change:(NSDictionary *)change context:(void *)ctx -{ - if (ctx == kGlobalShortcutContext) { - NSLog(@"Shortcut has changed"); - } - else { - [super observeValueForKeyPath:keyPath ofObject:obj change:change context:ctx]; - } -} - -// Do not forget to remove the observer -[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self - forKeyPath:_observableKeyPath - context:kGlobalShortcutContext]; -``` - -# Using in Swift projects - - 1. Install as a Pod using the latest CocoaPods with Swift support. - 2. Create a bridging header file [using the instructions here](http://swiftalicio.us/2014/11/using-cocoapods-from-swift/) - 3. Your bridging header file should contain the following [two](https://github.com/shpakovski/MASShortcut/issues/36) imports: - -```objective-c -#import -#import -``` - -# Copyright - -MASShortcut is licensed under the 2-clause BSD license. diff --git a/Pods/MASShortcut/Resources/cs.lproj/Localizable.strings b/Pods/MASShortcut/Resources/cs.lproj/Localizable.strings deleted file mode 100644 index afefe2bb0..000000000 --- a/Pods/MASShortcut/Resources/cs.lproj/Localizable.strings +++ /dev/null @@ -1,47 +0,0 @@ -/* Cancel action button in recording state */ -"Cancel" = "Zrušit"; - -/* Tooltip for non-empty shortcut button */ -"Click to record new shortcut" = "Kliknutím nahrajete novou zkratku"; - -/* Tooltip for hint button near the non-empty shortcut */ -"Delete shortcut" = "Smazat zkratku"; - -/* VoiceOver title */ -"keyboard shortcut" = "klávesová zkratka"; - -/* Alert button when shortcut is already used */ -"OK" = "OK"; - -/* Empty shortcut button in normal state */ -"Record Shortcut" = "Nahrát zkratku"; - -/* VoiceOver: Shortcut cleared */ -"Shortcut cleared" = "zkratka smazána"; - -/* VoiceOver: Shortcut set */ -"Shortcut set" = "zkratka nastavena"; - -/* Shortcut glyph name for SPACE key */ -"Space" = "Mezerník"; - -/* Title for alert when shortcut is already used */ -"The key combination %@ cannot be used" = "Kombinace %@ se nedá použít"; - -/* Message for alert when shortcut is already used by the system */ -"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "Tato zkratka se nedá použít, protože už ji obsadil systém.\nKdybyste na ní trvali, většina systémových zkratek se dá přenastavit v Předvolbách systému."; - -/* Message for alert when shortcut is already used */ -"This shortcut cannot be used because it is already used by the menu item ‘%@’." = "Tato zkratka se nedá použít, protože už je použita pro menu (%@)."; - -/* VoiceOver shortcut help */ -"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "Pokud chcete nahrát novou zkratku, stiskněte toto tlačítko a následně vybranou zkratku. Stisknutím Delete vymažete stávající zkratku."; - -/* Non-empty shortcut button in recording state */ -"Type New Shortcut" = "Stiskněte zkratku"; - -/* Empty shortcut button in recording state */ -"Type Shortcut" = "Stiskněte zkratku"; - -/* Cancel action button for non-empty shortcut in recording state */ -"Use Old Shortcut" = "Vrátit se k původní"; diff --git a/Pods/MASShortcut/Resources/de.lproj/Localizable.strings b/Pods/MASShortcut/Resources/de.lproj/Localizable.strings deleted file mode 100644 index 986cdba51..000000000 --- a/Pods/MASShortcut/Resources/de.lproj/Localizable.strings +++ /dev/null @@ -1,47 +0,0 @@ -/* Cancel action button in recording state */ -"Cancel" = "Abbrechen"; - -/* Tooltip for non-empty shortcut button */ -"Click to record new shortcut" = "Klicken um neuen Kurzbefehl aufzunehmen"; - -/* Tooltip for hint button near the non-empty shortcut */ -"Delete shortcut" = "Kurzbefehl Löschen"; - -/* VoiceOver title */ -"keyboard shortcut" = "Kurzbefehl"; - -/* Alert button when shortcut is already used */ -"OK" = "OK"; - -/* Empty shortcut button in normal state */ -"Record Shortcut" = "Kurzbefehl aufnehmen"; - -/* VoiceOver: Shortcut cleared */ -"Shortcut cleared" = "Kurzbefehl gelöscht"; - -/* VoiceOver: Shortcut set */ -"Shortcut set" = "Kurzbefehl gesetzt"; - -/* Shortcut glyph name for SPACE key */ -"Space" = "Leertaste"; - -/* Title for alert when shortcut is already used */ -"The key combination %@ cannot be used" = "Die Tastenkombination %@ kann nicht genutzt werden"; - -/* Message for alert when shortcut is already used by the system */ -"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "Diese Kombination kann nicht genutzt werden, weil sie bereits als systemweiter Kurzbefehl genutzt wird.\nFalls du diese Tastenkombination wirklich benutzen willst, können die meisten Kurzbefehle in den Tastatur Systemeinstellungen geändert werden."; - -/* Message for alert when shortcut is already used */ -"This shortcut cannot be used because it is already used by the menu item ‘%@’." = "Dieser Kurzbefehl kann nicht genutzt werden, weil er bereits vom Menüpunkt „%@“ genutzt wird."; - -/* VoiceOver shortcut help */ -"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "Drücke diesen Button, um einen neuen Kurzbefehl aufzunehmen. Tippe dann den neuen Kurzbefehl oder drücke Löschen, um den aktuellen Kurzbefehl zu löschen."; - -/* Non-empty shortcut button in recording state */ -"Type New Shortcut" = "Neuen eingeben"; - -/* Empty shortcut button in recording state */ -"Type Shortcut" = "Kurzbefehl eingeben"; - -/* Cancel action button for non-empty shortcut in recording state */ -"Use Old Shortcut" = "Alten nutzen"; diff --git a/Pods/MASShortcut/Resources/en.lproj/Localizable.strings b/Pods/MASShortcut/Resources/en.lproj/Localizable.strings deleted file mode 100644 index bfa60a96f..000000000 --- a/Pods/MASShortcut/Resources/en.lproj/Localizable.strings +++ /dev/null @@ -1,47 +0,0 @@ -/* Cancel action button in recording state */ -"Cancel" = "Cancel"; - -/* Tooltip for non-empty shortcut button */ -"Click to record new shortcut" = "Click to record new shortcut"; - -/* Tooltip for hint button near the non-empty shortcut */ -"Delete shortcut" = "Delete shortcut"; - -/* VoiceOver title */ -"keyboard shortcut" = "keyboard shortcut"; - -/* Alert button when shortcut is already used */ -"OK" = "OK"; - -/* Empty shortcut button in normal state */ -"Record Shortcut" = "Record Shortcut"; - -/* VoiceOver: Shortcut cleared */ -"Shortcut cleared" = "Shortcut cleared"; - -/* VoiceOver: Shortcut set */ -"Shortcut set" = "Shortcut set"; - -/* Shortcut glyph name for SPACE key */ -"Space" = "Space"; - -/* Title for alert when shortcut is already used */ -"The key combination %@ cannot be used" = "The key combination %@ cannot be used"; - -/* Message for alert when shortcut is already used by the system */ -"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences."; - -/* Message for alert when shortcut is already used */ -"This shortcut cannot be used because it is already used by the menu item ‘%@’." = "This shortcut cannot be used because it is already used by the menu item ‘%@’."; - -/* VoiceOver shortcut help */ -"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut."; - -/* Non-empty shortcut button in recording state */ -"Type New Shortcut" = "Type New Shortcut"; - -/* Empty shortcut button in recording state */ -"Type Shortcut" = "Type Shortcut"; - -/* Cancel action button for non-empty shortcut in recording state */ -"Use Old Shortcut" = "Use Old Shortcut"; diff --git a/Pods/MASShortcut/Resources/es.lproj/Localizable.strings b/Pods/MASShortcut/Resources/es.lproj/Localizable.strings deleted file mode 100644 index 55362cfec..000000000 --- a/Pods/MASShortcut/Resources/es.lproj/Localizable.strings +++ /dev/null @@ -1,47 +0,0 @@ -/* Cancel action button in recording state */ -"Cancel" = "Cancelar"; - -/* Tooltip for non-empty shortcut button */ -"Click to record new shortcut" = "Haga clic para grabar nuevo atajo"; - -/* Tooltip for hint button near the non-empty shortcut */ -"Delete shortcut" = "Borrar atajo"; - -/* VoiceOver title */ -"keyboard shortcut" = "atajo de teklado"; - -/* Alert button when shortcut is already used */ -"OK" = "OK"; - -/* Empty shortcut button in normal state */ -"Record Shortcut" = "Grabar atajo"; - -/* VoiceOver: Shortcut cleared */ -"Shortcut cleared" = "Atajo borrado"; - -/* VoiceOver: Shortcut set */ -"Shortcut set" = "Atajo creado"; - -/* Shortcut glyph name for SPACE key */ -"Space" = "Espacio"; - -/* Title for alert when shortcut is already used */ -"The key combination %@ cannot be used" = "La combinación de claves %@ no se puede utilizada"; - -/* Message for alert when shortcut is already used by the system */ -"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "Esta combinación no se puede utilizar debido a que ya es en us como atajo del sistema.\nSi realmente desea utilizar esta combinación de teclas, la mayoría de los atajos se puede cambiar en el panel de Teclado y Ratón de Preferencias del Sistema."; - -/* Message for alert when shortcut is already used */ -"This shortcut cannot be used because it is already used by the menu item ‘%@’." = "Este atajo no se puede utilizar debido a que ya es utilizado por el elemento de menú '%@'."; - -/* VoiceOver shortcut help */ -"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "Para grabar un nuevo atajo, haga clic en este botón, a continuar, escriba el nuevo atajo, o pulse borrar para qutar un atajo existente."; - -/* Non-empty shortcut button in recording state */ -"Type New Shortcut" = "Escribir atajo"; - -/* Empty shortcut button in recording state */ -"Type Shortcut" = "Escribir atajo"; - -/* Cancel action button for non-empty shortcut in recording state */ -"Use Old Shortcut" = "Usa atajo anterior"; \ No newline at end of file diff --git a/Pods/MASShortcut/Resources/fr.lproj/Localizable.strings b/Pods/MASShortcut/Resources/fr.lproj/Localizable.strings deleted file mode 100644 index 003dbacf2..000000000 --- a/Pods/MASShortcut/Resources/fr.lproj/Localizable.strings +++ /dev/null @@ -1,47 +0,0 @@ -/* Cancel action button in recording state */ -"Cancel" = "Annuler"; - -/* Tooltip for non-empty shortcut button */ -"Click to record new shortcut" = "Cliquez pour enregistrer le raccourci"; - -/* Tooltip for hint button near the non-empty shortcut */ -"Delete shortcut" = "Supprimer le raccourci"; - -/* VoiceOver title */ -"keyboard shortcut" = "raccourci clavier"; - -/* Alert button when shortcut is already used */ -"OK" = "OK"; - -/* Empty shortcut button in normal state */ -"Record Shortcut" = "Enregistrer le raccourci"; - -/* VoiceOver: Shortcut cleared */ -"Shortcut cleared" = "Raccourci supprimé"; - -/* VoiceOver: Shortcut set */ -"Shortcut set" = "Raccourci configuré"; - -/* Shortcut glyph name for SPACE key */ -"Space" = "Espace"; - -/* Title for alert when shortcut is already used */ -"The key combination %@ cannot be used" = "La combinaison %@ ne peut être utilisée"; - -/* Message for alert when shortcut is already used by the system */ -"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "Cette combinaison de touches ne peut être utilisée parce qu’elle est réservée pour un raccourci du système.\nSi vous désirez l’utiliser, la plupart des raccourcis peuvent être modifiés dans l’onglet Clavier, dans Préférences Système."; - -/* Message for alert when shortcut is already used */ -"This shortcut cannot be used because it is already used by the menu item ‘%@’." = "Ce raccourci ne peut être utilisé parce qu’il est déjà utilisé par le point de menu «%@»."; - -/* VoiceOver shortcut help */ -"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "Pour enregistrer un nouveau raccourci, cliquez sur ce bouton et tapez le nouveau raccourci, ou bien, tapez sur «Supprimer» pour supprimer le raccourci configuré."; - -/* Non-empty shortcut button in recording state */ -"Type New Shortcut" = "Saisir un raccourci"; - -/* Empty shortcut button in recording state */ -"Type Shortcut" = "Saisir un raccourci"; - -/* Cancel action button for non-empty shortcut in recording state */ -"Use Old Shortcut" = "Revenir au raccourci précédent"; diff --git a/Pods/MASShortcut/Resources/it.lproj/Localizable.strings b/Pods/MASShortcut/Resources/it.lproj/Localizable.strings deleted file mode 100644 index 53ec56087..000000000 --- a/Pods/MASShortcut/Resources/it.lproj/Localizable.strings +++ /dev/null @@ -1,47 +0,0 @@ -/* Cancel action button in recording state */ -"Cancel" = "Annulla"; - -/* Tooltip for non-empty shortcut button */ -"Click to record new shortcut" = "Cliccare per registrare una nuova combinazione"; - -/* Tooltip for hint button near the non-empty shortcut */ -"Delete shortcut" = "Cancella scorciatoia"; - -/* VoiceOver title */ -"keyboard shortcut" = "Scorciatoia da tastiera"; - -/* Alert button when shortcut is already used */ -"OK" = "OK"; - -/* Empty shortcut button in normal state */ -"Record Shortcut" = "Registra scorciatoia"; - -/* VoiceOver: Shortcut cleared */ -"Shortcut cleared" = "Scorciatoia rimossa"; - -/* VoiceOver: Shortcut set */ -"Shortcut set" = "Scorciatoia impostata"; - -/* Shortcut glyph name for SPACE key */ -"Space" = "Spazio"; - -/* Title for alert when shortcut is already used */ -"The key combination %@ cannot be used" = "Questa combinazione %@ di tasti non può essere usata"; - -/* Message for alert when shortcut is already used by the system */ -"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "Questa combinazione di tasti non può essere usata perchè è già usata da una scorciatoia da tastiera a livello di Sistema.\nSe volete davvero usare questa combinazione di tasti, la maggior parte delle scorciatoie possono essere cambiate nel pannello Tastiera e Mouse delle Preferenze di Sistema."; - -/* Message for alert when shortcut is already used */ -"This shortcut cannot be used because it is already used by the menu item ‘%@’." = "Questa combinazione di tasti non può essere usata perchè è già usata dalla voce di menù ‘%@’."; - -/* VoiceOver shortcut help */ -"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "Per registrare una nuova scorciatoia, cliccare su questo pulsante e poi inserire la muova scorciatoia o premere cancella per resettare una scorciatoia esistente."; - -/* Non-empty shortcut button in recording state */ -"Type New Shortcut" = "Digita nuova"; - -/* Empty shortcut button in recording state */ -"Type Shortcut" = "Digita scorciatoia"; - -/* Cancel action button for non-empty shortcut in recording state */ -"Use Old Shortcut" = "Usare vecchia"; diff --git a/Pods/MASShortcut/Resources/ja.lproj/Localizable.strings b/Pods/MASShortcut/Resources/ja.lproj/Localizable.strings deleted file mode 100644 index dec08eb38..000000000 --- a/Pods/MASShortcut/Resources/ja.lproj/Localizable.strings +++ /dev/null @@ -1,47 +0,0 @@ -/* Cancel action button in recording state */ -"Cancel" = "キャンセルする"; - -/* Tooltip for non-empty shortcut button */ -"Click to record new shortcut" = "クリックしてショートカットを入力"; - -/* Tooltip for hint button near the non-empty shortcut */ -"Delete shortcut" = "ショートカットを削除"; - -/* VoiceOver title */ -"keyboard shortcut" = "キーボードショートカット"; - -/* Alert button when shortcut is already used */ -"OK" = "OK"; - -/* Empty shortcut button in normal state */ -"Record Shortcut" = "ショートカットを入力"; - -/* VoiceOver: Shortcut cleared */ -"Shortcut cleared" = "ショートカットが削除されました"; - -/* VoiceOver: Shortcut set */ -"Shortcut set" = "ショートカットが設定されました"; - -/* Shortcut glyph name for SPACE key */ -"Space" = "スペース"; - -/* Title for alert when shortcut is already used */ -"The key combination %@ cannot be used" = "%@ はショートカットに設定できません"; - -/* Message for alert when shortcut is already used by the system */ -"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "このショートカットは、システム全体で使用されているショートカットのため、設定することができません。\nもしこのショートカットを使用したい場合、「システム環境設定」の「キーボード」、「マウス」のパネルから既に設定されているショートカットを変更してください。"; - -/* Message for alert when shortcut is already used */ -"This shortcut cannot be used because it is already used by the menu item ‘%@’." = "このショートカットは、メニュー操作の「%@」で使われているため、設定できません。"; - -/* VoiceOver shortcut help */ -"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "このボタンをクリックし、ショートカットを入力すると、新しいショートカットが設定されます。また、削除ボタンをおすと、ショートカットが削除されます。"; - -/* Non-empty shortcut button in recording state */ -"Type New Shortcut" = "ショートカットを入力"; - -/* Empty shortcut button in recording state */ -"Type Shortcut" = "ショートカットを入力"; - -/* Cancel action button for non-empty shortcut in recording state */ -"Use Old Shortcut" = "古いショートカットを使用"; diff --git a/Pods/MASShortcut/Resources/ko.lproj/Localizable.strings b/Pods/MASShortcut/Resources/ko.lproj/Localizable.strings deleted file mode 100644 index 41c079648..000000000 --- a/Pods/MASShortcut/Resources/ko.lproj/Localizable.strings +++ /dev/null @@ -1,47 +0,0 @@ -/* Cancel action button in recording state */ -"Cancel" = "취소"; - -/* Tooltip for non-empty shortcut button */ -"Click to record new shortcut" = "클릭해 단축 키를 입력"; - -/* Tooltip for hint button near the non-empty shortcut */ -"Delete shortcut" = "단축키 삭제"; - -/* VoiceOver title */ -"keyboard shortcut" = "키보드 단축키"; - -/* Alert button when shortcut is already used */ -"OK" = "좋아"; - -/* Empty shortcut button in normal state */ -"Record Shortcut" = "단축키 입력"; - -/* VoiceOver: Shortcut cleared */ -"Shortcut cleared" = "단축키 삭제됨"; - -/* VoiceOver: Shortcut set */ -"Shortcut set" = "단축키 설정됨"; - -/* Shortcut glyph name for SPACE key */ -"Space" = "스페이스 바"; - -/* Title for alert when shortcut is already used */ -"The key combination %@ cannot be used" = "%@ 단축키로 설정할 수 없습니다"; - -/* Message for alert when shortcut is already used by the system */ -"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "이 결합은 시스템 전체에서 사용 때문에 단축키로 설정 할 수 없습니다.\n단축키를 사용하고 싶으면 시스템 환경 설정의 키보드, 마우스 패널에서 이미 설정되어있는 단축키를 변경하십시오."; - -/* Message for alert when shortcut is already used */ -"This shortcut cannot be used because it is already used by the menu item ‘%@’." = "이 단축키는 ‘%@’ 메뉴 아이템에 사용되고 있기 때문에 설정할 수 없습니다."; - -/* VoiceOver shortcut help */ -"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "이 버튼을 클릭하고 단축키를 입력하면 새로운 단축키가 설정됩니다. 또한 삭제 버튼을 누르면 단축키가 삭제됩니다."; - -/* Non-empty shortcut button in recording state */ -"Type New Shortcut" = "새 단축키 입력"; - -/* Empty shortcut button in recording state */ -"Type Shortcut" = "단축키 입력"; - -/* Cancel action button for non-empty shortcut in recording state */ -"Use Old Shortcut" = "오래된 단축키를 사용"; diff --git a/Pods/MASShortcut/Resources/nl.lproj/Localizable.strings b/Pods/MASShortcut/Resources/nl.lproj/Localizable.strings deleted file mode 100644 index 06f78176c..000000000 --- a/Pods/MASShortcut/Resources/nl.lproj/Localizable.strings +++ /dev/null @@ -1,47 +0,0 @@ -/* Cancel action button in recording state */ -"Cancel" = "Verbreken"; - -/* Tooltip for non-empty shortcut button */ -"Click to record new shortcut" = "Druk om een nieuwe sneltoets in te voeren"; - -/* Tooltip for hint button near the non-empty shortcut */ -"Delete shortcut" = "Verwijder sneltoets"; - -/* VoiceOver title */ -"keyboard shortcut" = "sneltoets"; - -/* Alert button when shortcut is already used */ -"OK" = "OK"; - -/* Empty shortcut button in normal state */ -"Record Shortcut" = "Sneltoets opnemen"; - -/* VoiceOver: Shortcut cleared */ -"Shortcut cleared" = "Sneltoets verwijderd"; - -/* VoiceOver: Shortcut set */ -"Shortcut set" = "Sneltoets zetten"; - -/* Shortcut glyph name for SPACE key */ -"Space" = "Spatie"; - -/* Title for alert when shortcut is already used */ -"The key combination %@ cannot be used" = "De sneltoetsencombinatie kan niet worden gebruikt"; - -/* Message for alert when shortcut is already used by the system */ -"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "Deze combinatie kan niet worden gebruikt want hij wordt al gebruikt door een systeembreed sneltoets.\nAls je deze combinatie echt wilt gebruiken, kun je de meeste sneltoetsen binnen Toetsenbordinstellingen veranderen."; - -/* Message for alert when shortcut is already used */ -"This shortcut cannot be used because it is already used by the menu item ‘%@’." = "Deze sneltoets kan niet worden gebruikt want hij wordt al gebruikt door het menu item ‘%@’."; - -/* VoiceOver shortcut help */ -"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "Om nieuwe sneltoets op te nemen, druk op deze knop, en voer een nieuwe sneltoets in, of druk op verwijder om bestaande sneltoets te verwijderen."; - -/* Non-empty shortcut button in recording state */ -"Type New Shortcut" = "Voer Nieuwe Sneltoets in"; - -/* Empty shortcut button in recording state */ -"Type Shortcut" = "Voer Sneltoets in"; - -/* Cancel action button for non-empty shortcut in recording state */ -"Use Old Shortcut" = "Gebruik Oude Sneltoets"; \ No newline at end of file diff --git a/Pods/MASShortcut/Resources/pl.lproj/Localizable.strings b/Pods/MASShortcut/Resources/pl.lproj/Localizable.strings deleted file mode 100644 index fffe334cf..000000000 --- a/Pods/MASShortcut/Resources/pl.lproj/Localizable.strings +++ /dev/null @@ -1,47 +0,0 @@ -/* Cancel action button in recording state */ -"Cancel" = "Anuluj"; - -/* Tooltip for non-empty shortcut button */ -"Click to record new shortcut" = "Kliknij, by ustawić nowy skrót"; - -/* Tooltip for hint button near the non-empty shortcut */ -"Delete shortcut" = "Usuń skrót"; - -/* VoiceOver title */ -"keyboard shortcut" = "skrót klawiszowy"; - -/* Alert button when shortcut is already used */ -"OK" = "OK"; - -/* Empty shortcut button in normal state */ -"Record Shortcut" = "Utwórz skrót"; - -/* VoiceOver: Shortcut cleared */ -"Shortcut cleared" = "Skrót usunięty"; - -/* VoiceOver: Shortcut set */ -"Shortcut set" = "Skrót ustawiony"; - -/* Shortcut glyph name for SPACE key */ -"Space" = "Spacja"; - -/* Title for alert when shortcut is already used */ -"The key combination %@ cannot be used" = "Nie można użyć kombinacji klawiszy %@"; - -/* Message for alert when shortcut is already used by the system */ -"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "Nie można użyć tej kombinacji, ponieważ jest już zajęta przez skrót systemowy.\nMożesz to zmienić w panelu Klawiatura w Preferencjach systemowych."; - -/* Message for alert when shortcut is already used */ -"This shortcut cannot be used because it is already used by the menu item ‘%@’." = "Ten skrót nie może być użyty, ponieważ w menu ma już przypisaną funkcję ‘%@’."; - -/* VoiceOver shortcut help */ -"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "Aby ustawić nowy skrót, użyj tego przycisku, a następnie wpisz nowy skrót albo naciśnij klawisz delete, by usunąć istniejący skrót"; - -/* Non-empty shortcut button in recording state */ -"Type New Shortcut" = "Wpisz nowy skrót"; - -/* Empty shortcut button in recording state */ -"Type Shortcut" = "Wpisz skrót"; - -/* Cancel action button for non-empty shortcut in recording state */ -"Use Old Shortcut" = "Użyj starego skrótu"; \ No newline at end of file diff --git a/Pods/MASShortcut/Resources/pt.lproj/Localizable.strings b/Pods/MASShortcut/Resources/pt.lproj/Localizable.strings deleted file mode 100644 index 0d4dfde19..000000000 --- a/Pods/MASShortcut/Resources/pt.lproj/Localizable.strings +++ /dev/null @@ -1,47 +0,0 @@ -/* Cancel action button in recording state */ -"Cancel" = "Cancelar"; - -/* Tooltip for non-empty shortcut button */ -"Click to record new shortcut" ="Clique para gravar o atalho"; - -/* Tooltip for hint button near the non-empty shortcut */ -"Delete shortcut" = "Apagar atalho"; - -/* VoiceOver title */ -"keyboard shortcut" = "atalho de teclado"; - -/* Alert button when shortcut is already used */ -"OK" = "OK"; - -/* Empty shortcut button in normal state */ -"Record Shortcut" = "Gravar Atalho"; - -/* VoiceOver: Shortcut cleared */ -"Shortcut cleared" = "Atalho limpo"; - -/* VoiceOver: Shortcut set */ -"Shortcut set" = "Atalho definido"; - -/* Shortcut glyph name for SPACE key */ -"Space" = "Espaço"; - -/* Title for alert when shortcut is already used */ -"The key combination %@ cannot be used" = "A combinação de teclas “%@” não pode ser usada"; - -/* Message for alert when shortcut is already used by the system */ -"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "Esta combinação não pode ser usada porque ela já é usada por um atalho global do sistema.\nA maioria dos atalhos pode ser alterada no painel Teclado das Preferências do Sistema, caso realmente deseje usar esta combinação."; - -/* Message for alert when shortcut is already used */ -"This shortcut cannot be used because it is already used by the menu item ‘%@’." = "Este atalho não pode ser usado porque ele já é usado pelo item de menu “%@”."; - -/* VoiceOver shortcut help */ -"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "Para gravar um atalho novo, clique neste botão e digite o novo atalho ou pressione apagar para limpar um atalho existente."; - -/* Non-empty shortcut button in recording state */ -"Type New Shortcut" = "Digite o atalho"; - -/* Empty shortcut button in recording state */ -"Type Shortcut" = "Digite o atalho"; - -/* Cancel action button for non-empty shortcut in recording state */ -"Use Old Shortcut" = "Usar atalho antigo"; diff --git a/Pods/MASShortcut/Resources/ru.lproj/Localizable.strings b/Pods/MASShortcut/Resources/ru.lproj/Localizable.strings deleted file mode 100644 index 36c52080c..000000000 --- a/Pods/MASShortcut/Resources/ru.lproj/Localizable.strings +++ /dev/null @@ -1,47 +0,0 @@ -/* Cancel action button in recording state */ -"Cancel" = "Отмена"; - -/* Tooltip for non-empty shortcut button */ -"Click to record new shortcut" = "Нажмите для записи сочетания клавиш"; - -/* Tooltip for hint button near the non-empty shortcut */ -"Delete shortcut" = "Удалить горячую клавишу"; - -/* VoiceOver title */ -"keyboard shortcut" = "сочетание клавиш"; - -/* Alert button when shortcut is already used */ -"OK" = "ОК"; - -/* Empty shortcut button in normal state */ -"Record Shortcut" = "Ввести сочетание"; - -/* VoiceOver: Shortcut cleared */ -"Shortcut cleared" = "Сочетание клавиш удалено"; - -/* VoiceOver: Shortcut set */ -"Shortcut set" = "Сочетание клавиш назначено"; - -/* Shortcut glyph name for SPACE key */ -"Space" = "Пробел"; - -/* Title for alert when shortcut is already used */ -"The key combination %@ cannot be used" = "Нельзя использовать сочетание клавиш %@"; - -/* Message for alert when shortcut is already used by the system */ -"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "Нельзя использовать это сочетание клавиш, потому что оно уже используется в системе.\n Если вы хотите использовать это сочетание, измените существующее системное сочетание клавиш через панель Клавиатура в Cистемных настройках."; - -/* Message for alert when shortcut is already used */ -"This shortcut cannot be used because it is already used by the menu item ‘%@’." = "Нельзя использовать это сочетание, потому что оно уже связано с элементом ‘%@’."; - -/* VoiceOver shortcut help */ -"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "Чтобы назначить новое сочетание клавиш, нажмите эту кнопку и введите новое сочетание, или нажмите \"Удалить\", чтобы удалить действующее сочетание клавиш."; - -/* Non-empty shortcut button in recording state */ -"Type New Shortcut" = "Введите сочетание"; - -/* Empty shortcut button in recording state */ -"Type Shortcut" = "Введите сочетание"; - -/* Cancel action button for non-empty shortcut in recording state */ -"Use Old Shortcut" = "Вернуть старое"; \ No newline at end of file diff --git a/Pods/MASShortcut/Resources/sv.lproj/Localizable.strings b/Pods/MASShortcut/Resources/sv.lproj/Localizable.strings deleted file mode 100644 index e8bb31da5..000000000 --- a/Pods/MASShortcut/Resources/sv.lproj/Localizable.strings +++ /dev/null @@ -1,47 +0,0 @@ -/* Cancel action button in recording state */ -"Cancel" = "Avbryt"; - -/* Tooltip for non-empty shortcut button */ -"Click to record new shortcut" = "Klicka för att registrera ny kortkommando"; - -/* Tooltip for hint button near the non-empty shortcut */ -"Delete shortcut" = "Ta bort en kortkommando"; - -/* VoiceOver title */ -"keyboard shortcut" = "Tangentbordskortkommando"; - -/* Alert button when shortcut is already used */ -"OK" = "OK"; - -/* Empty shortcut button in normal state */ -"Record Shortcut" = "Registrera kortkommando"; - -/* VoiceOver: Shortcut cleared */ -"Shortcut cleared" = "Kortkommando rensas"; - -/* VoiceOver: Shortcut set */ -"Shortcut set" = "Kortkommando uppsättning"; - -/* Shortcut glyph name for SPACE key */ -"Space" = "Utrymme"; - -/* Title for alert when shortcut is already used */ -"The key combination %@ cannot be used" = "Tangentkombinationen %@ kan inte användas"; - -/* Message for alert when shortcut is already used by the system */ -"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "Den här kombinationen kan inte användas eftersom den redan används som en tangentbordskortkommando. Om du verkligen vill använda den här tangentkombinationen kan de flesta genvägar ändras under Tangentbord & Mus i Systeminställningar."; - -/* Message for alert when shortcut is already used */ -"This shortcut cannot be used because it is already used by the menu item ‘%@’." = "Denna kortkommando kan inte användas eftersom det redan används av ett menyalternativ ‘%@’."; - -/* VoiceOver shortcut help */ -"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "För att registrera en ny kortkommando, klicka på den här knappen och skriv sedan in den nya kortkommando, eller tryck på radera för att rensa en befintlig kortkommando."; - -/* Non-empty shortcut button in recording state */ -"Type New Shortcut" = "Skriv Ny Kortkommando"; - -/* Empty shortcut button in recording state */ -"Type Shortcut" = "Skriv Kortkommando"; - -/* Cancel action button for non-empty shortcut in recording state */ -"Use Old Shortcut" = "Använd Gammal Kortkommando"; diff --git a/Pods/MASShortcut/Resources/zh-Hans.lproj/Localizable.strings b/Pods/MASShortcut/Resources/zh-Hans.lproj/Localizable.strings deleted file mode 100644 index d383cc96c..000000000 --- a/Pods/MASShortcut/Resources/zh-Hans.lproj/Localizable.strings +++ /dev/null @@ -1,47 +0,0 @@ -/* Cancel action button in recording state */ -"Cancel" = "取消"; - -/* Tooltip for non-empty shortcut button */ -"Click to record new shortcut" = "点击以记录新快捷键"; - -/* Tooltip for hint button near the non-empty shortcut */ -"Delete shortcut" = "删除快捷键"; - -/* VoiceOver title */ -"keyboard shortcut" = "键盘快捷键"; - -/* Alert button when shortcut is already used */ -"OK" = "好"; - -/* Empty shortcut button in normal state */ -"Record Shortcut" = "记录快捷键"; - -/* VoiceOver: Shortcut cleared */ -"Shortcut cleared" = "快捷键已清除"; - -/* VoiceOver: Shortcut set */ -"Shortcut set" = "快捷键已设置"; - -/* Shortcut glyph name for SPACE key */ -"Space" = "空格键"; - -/* Title for alert when shortcut is already used */ -"The key combination %@ cannot be used" = "按键组合“%@”无法使用"; - -/* Message for alert when shortcut is already used by the system */ -"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "当前按键组合无法使用,因为它已经用作其他系统全局快捷键。\n如果您真的想使用这个按键组合,大部分系统全局快捷键能在“系统偏好设置”里的“键盘”和“鼠标”面板中重设。"; - -/* Message for alert when shortcut is already used */ -"This shortcut cannot be used because it is already used by the menu item ‘%@’." = "当前快捷键无法使用,因为它已用作菜单项“%@”的快捷键。"; - -/* VoiceOver shortcut help */ -"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "若要记录新的快捷键,单击此按钮,然后键入新的快捷键,或者按“delete键”删除已经存在的快捷键。"; - -/* Non-empty shortcut button in recording state */ -"Type New Shortcut" = "键入新快捷键"; - -/* Empty shortcut button in recording state */ -"Type Shortcut" = "键入快捷键"; - -/* Cancel action button for non-empty shortcut in recording state */ -"Use Old Shortcut" = "还原快捷键"; diff --git a/Pods/MASShortcut/Resources/zh-Hant.lproj/Localizable.strings b/Pods/MASShortcut/Resources/zh-Hant.lproj/Localizable.strings deleted file mode 100644 index 28a765cb0..000000000 --- a/Pods/MASShortcut/Resources/zh-Hant.lproj/Localizable.strings +++ /dev/null @@ -1,47 +0,0 @@ -/* Cancel action button in recording state */ -"Cancel" = "取消"; - -/* Tooltip for non-empty shortcut button */ -"Click to record new shortcut" = "點選以記錄新快捷鍵"; - -/* Tooltip for hint button near the non-empty shortcut */ -"Delete shortcut" = "刪除快捷鍵"; - -/* VoiceOver title */ -"keyboard shortcut" = "鍵盤快捷鍵"; - -/* Alert button when shortcut is already used */ -"OK" = "好"; - -/* Empty shortcut button in normal state */ -"Record Shortcut" = "記錄快捷鍵"; - -/* VoiceOver: Shortcut cleared */ -"Shortcut cleared" = "快捷鍵已清除"; - -/* VoiceOver: Shortcut set */ -"Shortcut set" = "快捷鍵已設定"; - -/* Shortcut glyph name for SPACE key */ -"Space" = "空格鍵"; - -/* Title for alert when shortcut is already used */ -"The key combination %@ cannot be used" = "按鍵組合“%@”無法使用"; - -/* Message for alert when shortcut is already used by the system */ -"This combination cannot be used because it is already used by a system-wide keyboard shortcut.\nIf you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences." = "當前按鍵組合無法使用,因為它已經用作其他系統全局快捷鍵。\n如果您真的想使用這個按鍵組合,大部分系統全局快捷鍵能在“系統偏好設定”裡的“鍵盤”和“滑鼠”面板中重設。"; - -/* Message for alert when shortcut is already used */ -"This shortcut cannot be used because it is already used by the menu item ‘%@’." = "當前快捷鍵無法使用,因為它已用作選單項“%@”的快捷鍵。"; - -/* VoiceOver shortcut help */ -"To record a new shortcut, click this button, and then type the new shortcut, or press delete to clear an existing shortcut." = "若要記錄新的快捷鍵,單擊此按鈕,然後鍵入新的快捷鍵,或者按“delete鍵”刪除已經存在的快捷鍵。"; - -/* Non-empty shortcut button in recording state */ -"Type New Shortcut" = "鍵入新快捷鍵"; - -/* Empty shortcut button in recording state */ -"Type Shortcut" = "鍵入快捷鍵"; - -/* Cancel action button for non-empty shortcut in recording state */ -"Use Old Shortcut" = "還原快捷鍵"; diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock deleted file mode 100644 index ba9ec4fe5..000000000 --- a/Pods/Manifest.lock +++ /dev/null @@ -1,44 +0,0 @@ -PODS: - - Alamofire (5.4.3) - - BRLOptionParser (0.3.1) - - GCDWebServer (3.5.4): - - GCDWebServer/Core (= 3.5.4) - - GCDWebServer/Core (3.5.4) - - MASShortcut (2.4.0) - - RxCocoa (6.2.0): - - RxRelay (= 6.2.0) - - RxSwift (= 6.2.0) - - RxRelay (6.2.0): - - RxSwift (= 6.2.0) - - RxSwift (6.2.0) - -DEPENDENCIES: - - Alamofire (~> 5.4.3) - - BRLOptionParser (~> 0.3.1) - - GCDWebServer (~> 3.0) - - MASShortcut (~> 2) - - RxCocoa (~> 6.2.0) - - RxSwift (~> 6.2.0) - -SPEC REPOS: - trunk: - - Alamofire - - BRLOptionParser - - GCDWebServer - - MASShortcut - - RxCocoa - - RxRelay - - RxSwift - -SPEC CHECKSUMS: - Alamofire: e447a2774a40c996748296fa2c55112fdbbc42f9 - BRLOptionParser: a03256a8ff003ca1f5376c55f55f210e085a3958 - GCDWebServer: 2c156a56c8226e2d5c0c3f208a3621ccffbe3ce4 - MASShortcut: d9e4909e878661cc42877cc9d6efbe638273ab57 - RxCocoa: 4baf94bb35f2c0ab31bc0cb9f1900155f646ba42 - RxRelay: e72dbfd157807478401ef1982e1c61c945c94b2f - RxSwift: d356ab7bee873611322f134c5f9ef379fa183d8f - -PODFILE CHECKSUM: 5e6ee339e4466d456309238c104e8625cd1e3e41 - -COCOAPODS: 1.10.1 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj deleted file mode 100644 index f49790919..000000000 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ /dev/null @@ -1,3522 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 013BAC24F7AC722E59517CB110A9E685 /* HTTPMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 403ABCCF5634DCD99A376EAA601F828E /* HTTPMethod.swift */; }; - 017170EB9F2450569816AB0FF2E6D541 /* CombineLatest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF5FCDE3BD3C3E02C0A0B3D529BF6982 /* CombineLatest.swift */; }; - 022F83EC88B467A88CBB491D7C98FA7E /* UITabBar+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21F927D22EA76A49C54C44827DD1CE5A /* UITabBar+Rx.swift */; }; - 02AEF100BA92B652E6E48EF58B479533 /* en.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 4A797B2A249C56CB61DB60A3FEA31FD2 /* en.lproj */; }; - 037CEEDED76C75AB19A6A015D66C1322 /* RxCollectionViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9215F3DCBD2FE1BDADCEF5D05219A48 /* RxCollectionViewDelegateProxy.swift */; }; - 06185F389644D5BD1C84259027C533D5 /* UICollectionView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = D49EC557FA27872611535147AB5D700C /* UICollectionView+Rx.swift */; }; - 0722A6B0D2DE0B9620F5C9659CB679D8 /* Debounce.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A2C23CF743A94075196D7A4F419F5A4 /* Debounce.swift */; }; - 07326CA68F757A1C82495BB52A92BD5C /* CompositeDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BE91EC45C71C190D532DC351F5E724D /* CompositeDisposable.swift */; }; - 080F0457EB8E6A9F2841FB0D77AEEF42 /* RxCollectionViewDataSourcePrefetchingProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78275DA82CA025902C1D6FAF39BC9403 /* RxCollectionViewDataSourcePrefetchingProxy.swift */; }; - 08FE05B1BA0A6D9CE971027E0480350A /* AnonymousDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EB8536183BE6472CDCC5817172688EF /* AnonymousDisposable.swift */; }; - 091B8980E4EFE8B81548A8B0369DF1F7 /* UIPickerView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 608BE9EFB078FCC2348EF2782C265D92 /* UIPickerView+Rx.swift */; }; - 0A1849775CF90D514963187D3A771CF8 /* Combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F78589C2F1DDF07DF58CD22F6835B19 /* Combine.swift */; }; - 0A20A09C199A4692A8EA72497B3D504A /* Catch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CD2535A24AA927A5965AF73264678A3 /* Catch.swift */; }; - 0A4DF5D6FC29A34C999E1ECBB53C696B /* RxMutableBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 530CEAEC9F4BC5F2EC9C9534779927A3 /* RxMutableBox.swift */; }; - 0A8A30C3BF493120607DD0157A560065 /* ObserveOn.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD39BD9C1B852EC7AC7CD7D77D1E606F /* ObserveOn.swift */; }; - 0A900DF17E3B64F08AF673E9A0DDD697 /* OperationQueue+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26DA8062B81F764A6EEA6168DF6337AB /* OperationQueue+Alamofire.swift */; }; - 0CA982442C8027B672202D753260BAC9 /* RxSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 77B5C856C653A9586105526C4341767A /* RxSwift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 0D8B936D823A959DDE9005A1C1D89487 /* Disposables.swift in Sources */ = {isa = PBXBuildFile; fileRef = CECC6752E3DD709B29A4ED0461B7BF82 /* Disposables.swift */; }; - 0E7C902AB09DA1CA05D07D36BD55C73E /* Enumerated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31234D4C5E912BD05D37874E7E89A233 /* Enumerated.swift */; }; - 0EEDE530AD4098CC0660A78E2852DA6A /* MASKeyMasks.h in Headers */ = {isa = PBXBuildFile; fileRef = 867FD5BBBCAC1E98FE144867305F8FEF /* MASKeyMasks.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 0FB5F248B62BC1F0113E53461E807AE5 /* SubjectType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44D9E4509154BFFEBEA9AEA0C935EC9E /* SubjectType.swift */; }; - 0FE468D23725DEF3BB913C80A61F9B1B /* RxPickerViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 961D7CAE484B6E4929A7BE5B048D29B5 /* RxPickerViewDataSourceType.swift */; }; - 10993D369AADB3E2BCA4E966DE514C09 /* SchedulerServices+Emulation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0791E5EB9ADBB88CEE0BCD83DA9502C /* SchedulerServices+Emulation.swift */; }; - 109ADA4349083858A198CA863E457E37 /* DisposeBag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F2EB184269284B56190B6EE5A7E5CC3 /* DisposeBag.swift */; }; - 11B06B47E4CB24A05B1299D730643803 /* ObservableType+PrimitiveSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AA3BEB86C50C2AAE9CCEDB0171CFC56 /* ObservableType+PrimitiveSequence.swift */; }; - 1208E81DA8B532D0646D627B50290EB6 /* AFError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D8A09F0F8EDB0B1A568AA29A33D62EA /* AFError.swift */; }; - 128376A37733CDCD9870A39DE261904E /* UISearchController+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8ED0DC48A18FD32A95BE8B28D715172C /* UISearchController+Rx.swift */; }; - 12DF0C4E73CEC6118673050B236C7799 /* MASKeyCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 73327356D8055C270C5AFBAEE0D202DD /* MASKeyCodes.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 12E8D9F9C1A9B4FC7669C18954BC4798 /* ControlEvent+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C0E4BDE3E30AF8C9062AFAD9C3AEA28 /* ControlEvent+Driver.swift */; }; - 14403B39AC36562E41D4768CCF3540B1 /* CombineLatest+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC41D63AA5F0A525ACB78573334AB97C /* CombineLatest+arity.swift */; }; - 14C185529F30494F6B6F0DFA9AEDDC05 /* TakeLast.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73118DDBDD8A625213B479BD40C4B9CE /* TakeLast.swift */; }; - 14E31D647AFA8F0FBE3793EF61872247 /* ScheduledItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19FF8B675AE7A3F0AB7CDE7C48E8082A /* ScheduledItemType.swift */; }; - 16C263170733039596369C8D4F89077A /* InfiniteSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC8F5BC5CABB65CCD832B9821F532DBD /* InfiniteSequence.swift */; }; - 19D605A3233499828FB6B790869F3E9C /* NetworkReachabilityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5102E62600D264D29633030E490AAE6 /* NetworkReachabilityManager.swift */; }; - 1A630AD9EFDB068A1544BD51CA5E99B7 /* Dematerialize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 080201197B517655700BD33F44B1A602 /* Dematerialize.swift */; }; - 1AECEBA213A2C9E6EC56C2C1358849E4 /* MASShortcut.m in Sources */ = {isa = PBXBuildFile; fileRef = 7A4A724DBFF9C1C260A76A4B104F3B1E /* MASShortcut.m */; }; - 1B341070BA8EB97021BE7C152639CBF5 /* VirtualTimeScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A2828DE92C9CEECE9FB19F2EE763305 /* VirtualTimeScheduler.swift */; }; - 1C0A940E6D4FD420BEC04B9F16914D71 /* RecursiveLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11DD125BCF1FDD4E34715800EC2F295F /* RecursiveLock.swift */; }; - 1C11628696BD0C889E0A4FC6CA4B6922 /* GCDWebServer-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A0680C8640FDF225CF2A27A4204628 /* GCDWebServer-dummy.m */; }; - 1D5606C6BD48C543FA0DB2C82B8791B7 /* GCDWebServer-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = B400BB6631F1C9F8534BE1CEF160097E /* GCDWebServer-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1DF080CB9D37CB063C6FEC09BBF8F238 /* Timer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F893DD80BE166F23DB8567A0940B0FEE /* Timer.swift */; }; - 1EC23A9ACE471AAE845CE9ACD4588932 /* Infallible+Zip+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2FFFF24B3AC3570742D7F2CCF2FE3C5 /* Infallible+Zip+arity.swift */; }; - 1ECDFBCA376564682426B5D8AC70393C /* RxTableViewDataSourceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADC06A8D8266504D3FD0F38F5F1A87AD /* RxTableViewDataSourceProxy.swift */; }; - 1FAEB66513E2610FE37D99FDD8F9E46D /* GCDWebServerStreamedResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = AE4742C0047EC328BE64C1DF6D868CEF /* GCDWebServerStreamedResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1FDEA9EB6CAF8FB09C98CEBE607DCFB6 /* SectionedViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4177B545582D09C0D653414E6353741 /* SectionedViewDataSourceType.swift */; }; - 212EDC48B68107BEA9247F3464CE696E /* StringEncoding+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8305C9D0B89A4CE30258C61DDD5A342 /* StringEncoding+Alamofire.swift */; }; - 218C14EAE5AA31C30314AE0289B732A0 /* Protected.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D1B54DDFE366EA8E657D1CFA2A5349 /* Protected.swift */; }; - 221F057199246D7709DD91C950746B7B /* GCDWebServerMultiPartFormRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C1C25377D5ADEBBE1E5B44FD42F2BF8 /* GCDWebServerMultiPartFormRequest.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 2375AD3B88ECB4A1C01F9F70DCFB05E7 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 718741562429DAE6AA6DC455ED6883D4 /* Errors.swift */; }; - 239AC2D5500F4E4FB04BC341A1335DF7 /* SerialDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DAFFC9484B606CC3A8583B2085B7957 /* SerialDisposable.swift */; }; - 23CF55A9FA514BDCA0B46320D4ED5DEC /* RxCocoa.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1816E3DFE7F11350A74B0C1F878F7FC /* RxCocoa.swift */; }; - 2453CFD81C667B99753FF8354AA82C60 /* HistoricalScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DA5F27AAEF9B366933CB017942EFAA8 /* HistoricalScheduler.swift */; }; - 262C2E49711CEA356F7C2031AE074C8A /* RecursiveScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40FC23633FFFBBD0FA165FB284958F8C /* RecursiveScheduler.swift */; }; - 262EBFD1844224838811BD9E1726CD73 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA187A944BB7C96464B1E79E6D12F90F /* AppKit.framework */; }; - 26900F59621365F9EF08DB37C7E07C06 /* RxScrollViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B58732AA1AF7EA39B29A8BE85721F26 /* RxScrollViewDelegateProxy.swift */; }; - 27C5636F69D717D7745A0235D715E4FB /* Platform.Linux.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FF704B43D944C2399606B76A430F1A6 /* Platform.Linux.swift */; }; - 27E59A11A2743B0595CDE3A08675EAE1 /* DispatchQueue+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41ADA85A38ECDBBD122B707DA599E641 /* DispatchQueue+Alamofire.swift */; }; - 2862DA4097D964B745862F00BB45759D /* KVORepresentable+Swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EB5DBBABE4FD6FFF0223AC1BC4674DB /* KVORepresentable+Swift.swift */; }; - 2B540E502B0EE71D93636BA94B9F0817 /* Zip+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABD89974F6EA342767735D559995D3FA /* Zip+arity.swift */; }; - 2BD53F1C421E9938A099F3F45C84FBAD /* Platform.Linux.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2586C5A6499D4E9A6B62C1CF5804DE66 /* Platform.Linux.swift */; }; - 2C8A055494092F137EDB2E3BDCA74DFC /* Maybe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5219820998BC7D8238F0F05F90A3D96F /* Maybe.swift */; }; - 2CD9AC66F1727C363449C4072DA57F89 /* ObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4338C646A92E1539E9BED963FC618602 /* ObservableType.swift */; }; - 2D890B63806F7465912098B60052B092 /* SerialDispatchQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 408AEB2CFB972D5D82E41BB027E6686C /* SerialDispatchQueueScheduler.swift */; }; - 2E0722133679D5C422D0EC5ACB8B23A1 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE6672D913C4CDAB5BAC161BDC483A67 /* Cocoa.framework */; }; - 2F835E1CFB72A43AC17728C6105B9635 /* SharedSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F401550E51DCC5F5746B99EC564065B /* SharedSequence.swift */; }; - 2FD49578803778A2F094C0B21FEE332C /* Cancelable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8565AD8EBB9A4E532AF93D887B586876 /* Cancelable.swift */; }; - 30536C64EAA45BE64894B48D74144B1E /* DispatchQueue+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29E3014CE53E3127CCD38149E2060C76 /* DispatchQueue+Extensions.swift */; }; - 313170D278E51360492948E6BB704EA7 /* ru.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 9A3F0ED147035005ABA4D679F9E36A7B /* ru.lproj */; }; - 3212BC4884F26AE9244A7548691A0CE0 /* Delay.swift in Sources */ = {isa = PBXBuildFile; fileRef = D570E112B81800B30A1165D0BC68DB8A /* Delay.swift */; }; - 325A6428E460396F0B0CB9B6FE10EEC4 /* it.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 321FC2ED515952B66BACDB8CAC130EB4 /* it.lproj */; }; - 332D9AE4473773687AA9155EF16A80D8 /* MASHotKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 8937D9E4BB1CD1D979DFF21019B4D814 /* MASHotKey.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 34C033CDDD8217EE4221E9BDFFC23086 /* MainScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98B151536C20EA366FDBE99C5A8BB7A5 /* MainScheduler.swift */; }; - 3596F8FDA81BECFE1B05B50500447638 /* KVORepresentable+CoreGraphics.swift in Sources */ = {isa = PBXBuildFile; fileRef = C70C13D2EC9B57E48D64BD7ABC49F9D6 /* KVORepresentable+CoreGraphics.swift */; }; - 35A428176550E4AA2BB98CDDEE2AFF99 /* Signal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E4505859B317DCDCC426973F6C7153D /* Signal.swift */; }; - 3685E20BBC5AFEA3BC80FE12732AB269 /* GCDWebServerResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = C40D7DCF882E3A5609EDE1602335E721 /* GCDWebServerResponse.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 36DED9F6B7737F022FB0B01ECE2BB88E /* GCDWebServerFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 0555618E1BBA944D30E358F0700CDD8B /* GCDWebServerFunctions.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 381FF05F8B4F611EE9C2FDBE4457BB89 /* SessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7045A3758C33721435A4135DBC6A8AA /* SessionDelegate.swift */; }; - 38A45D6FD7DCA41AC0C9CD58EDBB57CB /* UITextView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4BB8686A6F85698D8AC03A77D188340 /* UITextView+Rx.swift */; }; - 39988540E9F936FE5085117BB8F32FAC /* PriorityQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3A89F3DBB03CFC012C901EB6D452A3B /* PriorityQueue.swift */; }; - 3AB06F4DB0A01BA8F6662D0EDC495981 /* InvocableScheduledItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F97D53A26324CAC07AB16E21B963CF9A /* InvocableScheduledItem.swift */; }; - 3BAE1C06A091DFA7A91F93BD40BD41B9 /* Throttle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 127B3965CEBAEBFB395F0D10B7C255FB /* Throttle.swift */; }; - 3BBEC4A24B60E2276CBC26E555F64F41 /* GCDWebServerDataResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = AB7765E1848A0449B3E3267F17DDE12E /* GCDWebServerDataResponse.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 3D8428BE717C8E76FA50C1D8B93561EE /* DisposeBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04A3FEA575D65278CDB553AA231A0CF6 /* DisposeBase.swift */; }; - 3E2FF4CBA1E2C3A36060CB61A25F80F7 /* BRLOptionParser-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1389D4639C0D9038BA081FA8DC1CD646 /* BRLOptionParser-dummy.m */; }; - 3E6A74677BA3612A449B323631B44559 /* ObservableType+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C713517A8C0251C9EEB925D43C63A544 /* ObservableType+Extensions.swift */; }; - 42DBD7750A47DE5273041BDEE8850195 /* Multicast.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD90405BE5311F3F3A8CFCFABCCF3560 /* Multicast.swift */; }; - 4319C0B97542219FCA256B790FE90C1C /* es.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 4504CA755CE81F89F9F165BF93126D21 /* es.lproj */; }; - 432B3CB444984CCCFB4EF37E2D762F05 /* Observable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 636937DE6DA6CE01D7E94282A16BC9D9 /* Observable.swift */; }; - 43BC914A79B9230DA50C9D476DE5114D /* WKWebView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDCA53BCCEFF4720A955F8202537A982 /* WKWebView+Rx.swift */; }; - 4407E13BF761D53607A7B419BE64458B /* TextInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DBE368EA1C6F7EBE80E08054C9BC6AE /* TextInput.swift */; }; - 440BDCF5820801BC8A6D740C48EEAB8E /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B23D7AFD516825208E6CE9B362989DB /* Queue.swift */; }; - 447B98FAB75F9B738B72DA92A3C581D6 /* RxPickerViewDataSourceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC44E7C397DF9B77CEF6F5C86EFCE92A /* RxPickerViewDataSourceProxy.swift */; }; - 44C45DEC66DB1FBBA5F850E79057DC13 /* TakeWithPredicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6327835932D3C270A640C0C76A860EB8 /* TakeWithPredicate.swift */; }; - 44D30DA4840EF46F1C4BCEA6179AAE60 /* ElementAt.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA23B9C3D142FEFFA05E4F37B1A976AE /* ElementAt.swift */; }; - 45B8CC1C61E7A0BB28CFA8CE7C12FEBC /* MultipartFormData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7453403FEE25F56521DBB8A39EA0204 /* MultipartFormData.swift */; }; - 4673A5004D211FA68BB8506B9A323034 /* Sink.swift in Sources */ = {isa = PBXBuildFile; fileRef = B304846A96173EC0E0631D07751C0893 /* Sink.swift */; }; - 4728113A1BA4AE948E1B2FB610A473B4 /* Repeat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45BF55923F2D3657D9D5420E606B641F /* Repeat.swift */; }; - 47E487EF80C53073DBFE5F5FD6BCFF0E /* AsyncSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD07F15ADFC693A5C730840EA2B42015 /* AsyncSubject.swift */; }; - 47FDBBBD2704901588C3A7C56BBC502D /* ServerTrustEvaluation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90E9219489B97BDFE17BA3231CC465FC /* ServerTrustEvaluation.swift */; }; - 4892C3EBD345FAE187A5E15D7FA19CBE /* GCDWebServerFileRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 962EFFE0B39AFE334DBCAF81B4DBFE56 /* GCDWebServerFileRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4940AB8BC3936DEBDC02BF49FE5E97A1 /* GCDWebServerFileRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 392538EA12C4E3008D6EF1ABB226B3BF /* GCDWebServerFileRequest.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 4953376F75EEA98570C65CFC41E0A154 /* RxSearchControllerDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 474547C10494F37402A98A0BFC7E6288 /* RxSearchControllerDelegateProxy.swift */; }; - 4A33F1A7BD2AD1F318E081E17B0AA80F /* InvocableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 200825C8579BF340304A9767D679EC35 /* InvocableType.swift */; }; - 4AEC050FA7D5ED52FDA9DF50EA3560DF /* ParameterEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7ED9E80778846168B6F3F867C04F6AA /* ParameterEncoder.swift */; }; - 4B9CC90686F274845EBBB82F230C11EE /* Infallible+Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF4A8984BD7018149BDA495C7EA5FE28 /* Infallible+Operators.swift */; }; - 4BEC411F5B170048C65D315C87832600 /* AsyncLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52626495FA7375A2A4753E3EC16FB26C /* AsyncLock.swift */; }; - 4BF6073DF04E6CD2C3BD8D2C552D7E65 /* UISlider+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 466B399C2E7FFAA61B709F2AB447ECDF /* UISlider+Rx.swift */; }; - 4C3A9F4F5A688009D660C0FA5E5D81BB /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE6672D913C4CDAB5BAC161BDC483A67 /* Cocoa.framework */; }; - 4C6CC049B53AF49050AD6428C5B50AB0 /* NopDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6B674A528A68BF8E6AB4A5F747B05B8 /* NopDisposable.swift */; }; - 4C88ED296D3687C973B0472D047CE3E8 /* SchedulerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 111E9F3F4997D0ACA2E0BCDAF269904C /* SchedulerType.swift */; }; - 4D15DB973A043E9B4A47B724738A2A5F /* MASShortcut.h in Headers */ = {isa = PBXBuildFile; fileRef = A2B9727C5385989526550D8E1AC4649A /* MASShortcut.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4D6504A580F9D6278452D19FD3DD35BC /* PublishRelay.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA7211C3393B6E1ED0E57C4CCF5F5005 /* PublishRelay.swift */; }; - 4E095DE808150F9350BB9CB3C99A37B2 /* _RXObjCRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = 638797412ABBF2F7725016AF4B056309 /* _RXObjCRuntime.m */; }; - 4EC10410410410FF3A33C6015FD5927D /* ShareReplayScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72D91E08E6C75E1F0DBACD4FF3CA2F55 /* ShareReplayScope.swift */; }; - 516E4177ED65653EA9DAADBA3CF3FBED /* OperationQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4C66DE7DB1A4B525929AEF699AC3CE /* OperationQueueScheduler.swift */; }; - 519260344D4291AA4C1CEAD7711B1489 /* Deferred.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33BBD4B03778E41A59C1A3F64AAB876C /* Deferred.swift */; }; - 51B830516D57359FAB42031193E47CB1 /* RxCollectionViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0D1BF03B3F26978B85F2E44EBE18FC1 /* RxCollectionViewDataSourceType.swift */; }; - 5263ED302CD55D6C365476F9B20AD5D1 /* MASShortcutMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 24121C8FA3C10947BE50901868F9198A /* MASShortcutMonitor.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 52CB53A7C3EF4BD88F73996450B73AA7 /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44775F4816D20EB134F1DBAB43BE0B3A /* Filter.swift */; }; - 535519D2B25D1784AA6D6A9BDE60C759 /* Switch.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4786526A5AD085C95AC191C7253C591 /* Switch.swift */; }; - 543010884F5B7C1F2920A0DF33A3A9D1 /* SynchronizedUnsubscribeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FA62A0165A7A8D001536C62FD5E2392 /* SynchronizedUnsubscribeType.swift */; }; - 54FFBD61CC8FA5DD12646A7FFAAFE425 /* RxRelay-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DDC82F5641636881356BF49166C8DF3 /* RxRelay-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 563C41694A1B06EF34752E894297D3FA /* MASShortcut-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B668707F7C66384A3BB8BC4FE3F41E6 /* MASShortcut-dummy.m */; }; - 58D3BBBF801B54CC74FAAC0374F1948D /* NSTextStorage+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = E35662841C2AAA3188CD9ADFDC38880F /* NSTextStorage+Rx.swift */; }; - 5989329B01C0737EFDB490C5A771FDC2 /* GCDWebServerURLEncodedFormRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = DC40BD5F1E0BFED23CB5A6AE57FA4443 /* GCDWebServerURLEncodedFormRequest.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 5BF5F916582D2EE625A9F0F32ECE709A /* MASShortcut-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 930EB20F00FF48CAF9B19505BC219504 /* MASShortcut-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5CDF229542C4FC347E9D1DFDBAC8B230 /* Scan.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32777B9FE68F64D911474F7B7595C94C /* Scan.swift */; }; - 5E3681E1F77D4A9B58F332348935EE8C /* Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2096522151041770121528F182B6F42D /* Range.swift */; }; - 5F7CE7907DC769D3E61980B80D20A275 /* Concat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C7F789300668AEDFA53AEA1392C48B /* Concat.swift */; }; - 601A69113478A1336ADA98C7658D2355 /* Take.swift in Sources */ = {isa = PBXBuildFile; fileRef = 273C90965AA81CCFE4CDA40530425746 /* Take.swift */; }; - 60FBA126D0D250DE50F4DD26041E4A9C /* RxTableViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D418B4DEE726BA9D5A912D8F1FBF0888 /* RxTableViewDataSourceType.swift */; }; - 611ACC0E723AF0E572160BC75133A9E6 /* UIGestureRecognizer+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87FAE60EB40AC65B2E5000C6B82DFEB /* UIGestureRecognizer+Rx.swift */; }; - 62DF258CA1EA9A41A99B93052A72DAB0 /* _RXDelegateProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6AD4414199F479D544CBF1FFF3FB45E4 /* _RXDelegateProxy.m */; }; - 63257249A72693C87BF365F343DA1D36 /* ko.lproj in Resources */ = {isa = PBXBuildFile; fileRef = A254689F2908346AD7387F063C24B41A /* ko.lproj */; }; - 63CE2D43072C461D8DE926F0B9EC2E97 /* RxPickerViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22D41ECF1E34CC3D83A32F7896831100 /* RxPickerViewDelegateProxy.swift */; }; - 64F43894B4404E7BDE27A5C8BE96E0AE /* Completable+AndThen.swift in Sources */ = {isa = PBXBuildFile; fileRef = A111C3B36368413B50627674BB48E859 /* Completable+AndThen.swift */; }; - 652118C36365C28E76826357E309EADE /* Infallible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370A313E34AF66CB8D7437ABDC3FB7F8 /* Infallible.swift */; }; - 6546D728B69398F93B506845141EBD61 /* EventMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E0CDE6403F2AF9E108FF190F90FA9FF /* EventMonitor.swift */; }; - 65EA84D8C4EA09B4455BC6C221D2A940 /* Pods-ShadowsocksX-NGTests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 72A57876EDEB24ADDFE06DD482CE250C /* Pods-ShadowsocksX-NGTests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 66207468882614FB8CE9896DC4250F13 /* Infallible+Create.swift in Sources */ = {isa = PBXBuildFile; fileRef = 161437331F54761E08F028DD14CDC21E /* Infallible+Create.swift */; }; - 665FBE569EDC9AF24C721F6B9C7241EC /* MASShortcutBinder.h in Headers */ = {isa = PBXBuildFile; fileRef = A18A7F7794D2CC58900E95F6644D63E8 /* MASShortcutBinder.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 666EC5C8356E6D4448A2FE7BEE77AD88 /* RedirectHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A32434EC299FDE302FFF9F31EB8735D0 /* RedirectHandler.swift */; }; - 66B26C6CAE737EC21F4BA1F1851B69C5 /* Result+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD2C25316E1BF4F3230E3412417481E6 /* Result+Alamofire.swift */; }; - 6809229B402FC6C91774DA8664AD4F2F /* GCDWebServerRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = A4395BE2A0C53A82170A01602870453A /* GCDWebServerRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 695A83FEFDFE24858DDC37BD64DBBA33 /* Binder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4412635C50524157DDF38FA0CB197F4A /* Binder.swift */; }; - 69D750E3DAB2F11E37761A204A145883 /* Timeout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 661DD8158386E15481E17DE6E2FA1882 /* Timeout.swift */; }; - 6A2F2216A64E4B4E0FD6215A2F5E692D /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE6672D913C4CDAB5BAC161BDC483A67 /* Cocoa.framework */; }; - 6A3972E7F1ACA4CEE36E0AA3B2BA34FB /* Reactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C0FB7A81FC88101C56EABF826BD78F5 /* Reactive.swift */; }; - 6A5300346FF40392C6A4B5908AA9C027 /* RxCocoaObjCRuntimeError+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F666DF6A38D74980DF6F191509F4971 /* RxCocoaObjCRuntimeError+Extensions.swift */; }; - 6AE407A4FB6C3D6ADD862CC6E3067A17 /* Session.swift in Sources */ = {isa = PBXBuildFile; fileRef = 996DFC2DB5C2F37F0E623EB885F5DEB5 /* Session.swift */; }; - 6B105A67121436E162ADE05A682BEA71 /* Amb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CB05B6D60934D955FE0D75C2339A114 /* Amb.swift */; }; - 6BDF6DD0C73F197EC93643F477997B40 /* UISearchBar+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2888FA81FD2BE4D3B068BCE4AFDC9A93 /* UISearchBar+Rx.swift */; }; - 6C08F6A77889651626583100F560153D /* RequestTaskMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF8D2E7C64775F0DD477127B5EC2E0AB /* RequestTaskMap.swift */; }; - 6C1064F34CFE15C3DB0E923D9D170E0C /* UIBarButtonItem+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB340F626B32E3AF98F1E13658FB46E2 /* UIBarButtonItem+Rx.swift */; }; - 6CA2AE8DA8D630D83FAED6FC2F081967 /* HistoricalSchedulerTimeConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38A0B431980745BE7A67D566D79E240A /* HistoricalSchedulerTimeConverter.swift */; }; - 6CD3A3F8ABC5FCE23D15CE6823840010 /* RxTabBarControllerDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39D9FF9E1CBB62DA6FC1910AA45EB039 /* RxTabBarControllerDelegateProxy.swift */; }; - 6CDC5000511AB1CF616FEBB8A856AE58 /* Bag+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCCC3232579F890A62A86540F6600BE6 /* Bag+Rx.swift */; }; - 6D5BDAE5D8D991B874AD4D7FF2EA7C8C /* Lock.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA0A6C3DB39AD5C25FF5B1A9F554E228 /* Lock.swift */; }; - 6E54F64E8DA73F4B0B46C216F9F93F63 /* RequestInterceptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80B5C55F7279E38D15E19E9DEDDEDE7B /* RequestInterceptor.swift */; }; - 6E75ECF4BDC7AF83E3151274539DFF93 /* DispatchQueue+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C96F1CEB77C6CB8A9D2A7682406E7AE9 /* DispatchQueue+Extensions.swift */; }; - 6FD62C6E23DE07DF1291500FEFC19354 /* BehaviorRelay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D796FDCC7398C88D7B835BD89700D56 /* BehaviorRelay.swift */; }; - 70359E1C7BAA76860EA35A607CCC4309 /* DelegateProxyType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB7AE66363DEA0FFF31BA0AD1EB9340 /* DelegateProxyType.swift */; }; - 7094648D68C944D337CE86C10F8EEB04 /* zh-Hans.lproj in Resources */ = {isa = PBXBuildFile; fileRef = B2BCE49AE180E28B89BBBE037DF32A2F /* zh-Hans.lproj */; }; - 72E6FED1FBFB7D269B435A3802528AA1 /* MASShortcutValidator.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E796A67AE756E845646324A31731334 /* MASShortcutValidator.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 72EC2712926E6D28B52360D9AC41668F /* AlamofireExtended.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19AA7CC35C97B4BDF08E2E5CE20955E0 /* AlamofireExtended.swift */; }; - 73E48515343BD4E57358BAD9F3B2F590 /* Platform.Darwin.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAABDBC186233AEF9876B5A4F009C8B8 /* Platform.Darwin.swift */; }; - 741E51A8D9DE26331ABB938B3BD5751A /* AddRef.swift in Sources */ = {isa = PBXBuildFile; fileRef = 494FD3BF9675BD2ADCE4731FED65B5FF /* AddRef.swift */; }; - 75917BCA0645283EC7D9CC3ADEE6DB4F /* BehaviorRelay+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98EF0EFA057CC202BD041F55B091661A /* BehaviorRelay+Driver.swift */; }; - 77093BBAB8F2F51540322CB14BD2C178 /* BehaviorSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1177638C48D2FB13DDFB46A70CD35D /* BehaviorSubject.swift */; }; - 77260113D5ADF7B45DAE46C549580AFD /* UIRefreshControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 506B13C445D67D7231C25641361EE5A1 /* UIRefreshControl+Rx.swift */; }; - 774C726DE2716860799DAEAD0B801A94 /* Reduce.swift in Sources */ = {isa = PBXBuildFile; fileRef = D894FDA92A29CEECD7D1E50C263F1777 /* Reduce.swift */; }; - 7813074001D6CD69B3A1EBAF59379E58 /* Observable+Bind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A18EEA4857408358F9A8E6ED8AF8829 /* Observable+Bind.swift */; }; - 786C836C43BD6428332A4001EE13816F /* RecursiveLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5554F4E6979C7DDD1E00F81CB94D474D /* RecursiveLock.swift */; }; - 7885432DE1DDE9F2A4607033B2808E5B /* GroupBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47EB7F9271D4EAE5B4A31D5D0194BECC /* GroupBy.swift */; }; - 7B0FB5B7BF42B15FDF1FCE073D8C4C21 /* AsSingle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8D247C19100F15D54BFF5D93804C65E /* AsSingle.swift */; }; - 7B99EC9A5D3CF7B6DE0330773143F15F /* ObserverType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B00E954AA2FCFDF5ACDEC8CD8C6941E /* ObserverType.swift */; }; - 7BD242803D2ADF6E50A27C3542C8695D /* NSSlider+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5874107EF4581DA493B60BBCFE422D1C /* NSSlider+Rx.swift */; }; - 7BFBC9F9818BC849C72D672D6B6E4B75 /* RxNavigationControllerDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52DFCC55A239674DEF17871D293D227C /* RxNavigationControllerDelegateProxy.swift */; }; - 7CF0187F571D299FE14788318D720152 /* StartWith.swift in Sources */ = {isa = PBXBuildFile; fileRef = 864BF009AFF7BFF4D8B68869FC885957 /* StartWith.swift */; }; - 7D3DD4A8BB36733BA15868F7FB8C56CE /* Alamofire-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 10E99E50E2994DB7AD9AEBDEF1A2F72B /* Alamofire-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 7D5AE7E56AC7636F1D00076095F57745 /* GCDWebServerConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D0B40D5A184825074ECC549693CAF02 /* GCDWebServerConnection.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 7E8BC075464E9C355B763973CA6C08D2 /* UINavigationController+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D742A8B753D54115AD3C6D293B64276 /* UINavigationController+Rx.swift */; }; - 805003984E8CFD3375B935DC772A7BF3 /* MASShortcutView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7C73921B2C710D3814A33EF328D04D20 /* MASShortcutView.m */; }; - 809C371060C874FBEF8FECDF197D74E3 /* sv.lproj in Resources */ = {isa = PBXBuildFile; fileRef = FDF7D102C3DA0493A530D68E569DA7CF /* sv.lproj */; }; - 80C7348602C99C09226B1241C02D4754 /* MASShortcutView.h in Headers */ = {isa = PBXBuildFile; fileRef = A2EEB1D58595D58C5DC8978116BE0648 /* MASShortcutView.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 815908B08BEA64FC0E5641D046D43CB6 /* RxCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 7EB9FE74C8220E21EC9A5A77098E9152 /* RxCocoa.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 82764E2E2DA3FD699FC5B659ED35D9AE /* pt.lproj in Resources */ = {isa = PBXBuildFile; fileRef = FAB6166D07AACCBF2B4A5FFC66F22602 /* pt.lproj */; }; - 830F06C3D23016D62112E4BA1C22A766 /* LockOwnerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 683395CCE980D15405934DC5E2BCD682 /* LockOwnerType.swift */; }; - 8314F89A5274810933307BC20E85D3B0 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE6672D913C4CDAB5BAC161BDC483A67 /* Cocoa.framework */; }; - 83470A9EFB9948DED806CC1D1233D21C /* Skip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07B4CEF97C27B2FE6205EE1D720BFB39 /* Skip.swift */; }; - 844134211AB7B26FACFFF74B58B81C02 /* UIButton+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17F9F190DDBE93E38A56D8405CBFA664 /* UIButton+Rx.swift */; }; - 8450D728709DB935952A5A59650DB926 /* MASDictionaryTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = 353B178196A1B3A383089B3D1006F66A /* MASDictionaryTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 84E576015933A4F6F431759174C62956 /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4764F518EAB30C5EA82C03A5607ED7AF /* Error.swift */; }; - 85CD565FB8198B084806FE075B268AB5 /* NSObject+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C119A4F639217703B4B382419AF9D4EF /* NSObject+Rx.swift */; }; - 872E07F59296D07A405BAB9C36936AC8 /* DelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB63C0EAF763E45BC31AAB9802F87995 /* DelegateProxy.swift */; }; - 8819CBF35F9919DFC3C17016DF3ACE46 /* UIApplication+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C78EDD95C0B56A70BE237D148A1726CA /* UIApplication+Rx.swift */; }; - 88665F16CDF39BC2A50C6619169E6EDF /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 62F5D09616527A0713F24DF416BEC64F /* Carbon.framework */; }; - 88F5FF298C4C3D2CDCA5EB7B0BE2B52C /* GCDWebServerResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 89066EEDE0D03A9B328DADDC9344CC13 /* GCDWebServerResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 896AD4C4865ECEA0A8344B54BBA3B9E1 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE6672D913C4CDAB5BAC161BDC483A67 /* Cocoa.framework */; }; - 8AA937910F87915DE700CAB6C868689E /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEEC0450A3B1A48A304AE8BF1DC03429 /* Notifications.swift */; }; - 8B67845A8F56DF49F8B22B1BB63C5E10 /* VirtualTimeConverterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4673D1BC54F57F490E2D3352F6BA1B73 /* VirtualTimeConverterType.swift */; }; - 8B7EEE0E899778DA279E64E26E38FB30 /* RxTextViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 531091EE9FF408558B83A1E053360F67 /* RxTextViewDelegateProxy.swift */; }; - 8BEDC2C0D907FBB47A65EE0E01DE2A59 /* GCDWebServerDataRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 36E9C273C636D7A0C559787BD1FABA68 /* GCDWebServerDataRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8CE605907DC8FA1F2E4751F939A4E604 /* UIControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C1FFDE936B5B805CB094F77E95A88FC /* UIControl+Rx.swift */; }; - 8EB4272CE33A59083F0DC9746C0F71D0 /* RxSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = F0007682E9947D6BFA4DA24D30F6CBF2 /* RxSwift-dummy.m */; }; - 8EEA6795ED2806C80FBE6A00B615CB76 /* PriorityQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = D96D37A7C37C05D7DEEAE9B3944CC4DD /* PriorityQueue.swift */; }; - 8F66042610AE99F62D17E50EF0C83B0D /* Never.swift in Sources */ = {isa = PBXBuildFile; fileRef = F961756C2E9DE7614DBA1271483EB245 /* Never.swift */; }; - 901D8E9CC22C5E7FDB218557EBBB3559 /* GCDWebServerDataResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = C21721CAB3BC76F0D7582BD636DB821D /* GCDWebServerDataResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 90429156F020B4490158F6686EEFCB02 /* Date+Dispatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11E6B29B9CB879F29AFEBD980D3AFBF /* Date+Dispatch.swift */; }; - 90B5B048AE70F82175F8A3DB72EF601E /* Buffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE717EAC81EE595FC7AE3C1A3C6D06A6 /* Buffer.swift */; }; - 911448B2EDA2FF880108F77642797A88 /* ResponseSerialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48CB9D3553F121F84DBB750A8FBE0F3D /* ResponseSerialization.swift */; }; - 9131DD9E2CB7420C156461E56835AE6E /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFD92A4EF88D0A6B34E86A6A7CE2436D /* RxSwift.framework */; }; - 9141315B460BE4CD3030B62BE7692B73 /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 960C49C6C3C5E2554CA3CD8EB86B61AC /* Queue.swift */; }; - 91B837CE0DCD8EDB300FCDFFA1279162 /* HTTPHeaders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3425B3045259FEA3A238D183DEEE520B /* HTTPHeaders.swift */; }; - 91C85BAD47B39F365F260E74AB24693D /* zh-Hant.lproj in Resources */ = {isa = PBXBuildFile; fileRef = B5D8A52DE9A6385138A6D20CB5527DDB /* zh-Hant.lproj */; }; - 9281E701873CD72C35440865226A1A8B /* Pods-ShadowsocksX-NGTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1C10AA3C311345DB3616BCE827B69C55 /* Pods-ShadowsocksX-NGTests-dummy.m */; }; - 934592C980EE09EEE5F4B5074C6A56D8 /* PublishRelay+Signal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 758B67811993E4C5163D7637EDBB6CFD /* PublishRelay+Signal.swift */; }; - 9360BB098EFD18F90BA16149E8EF8A34 /* Merge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CA0D236EFCE9E4E77F9A2B2A0AF3FC4 /* Merge.swift */; }; - 9389C4BF3F440F2503FFEB8BBC8975C8 /* ja.lproj in Resources */ = {isa = PBXBuildFile; fileRef = B1F34EB08D07E2AF230CDA30F361889D /* ja.lproj */; }; - 953EC9012B7246D01EA866100FAEA023 /* RxPickerViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F979292485788BE53E5871123C74EB10 /* RxPickerViewAdapter.swift */; }; - 96E6F7A2D012051B29BC9147340E5117 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE6672D913C4CDAB5BAC161BDC483A67 /* Cocoa.framework */; }; - 9806F1246774ADD50F50D3F1624EB0EB /* UITabBarController+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D4701E49CFDE5F411CDFD316EDD3C70 /* UITabBarController+Rx.swift */; }; - 99210D61FFF596695086F3E51D893204 /* ControlProperty+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97D6BD38BB9E0F241C3C82A118E7F253 /* ControlProperty+Driver.swift */; }; - 999CAB83E4F6D824DF56B2B755C0B588 /* _RXKVOObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = A14B9E97BE00B01372727FA8DA9B10A3 /* _RXKVOObserver.m */; }; - 99ABB4C207FE146C78313E8A9A581FD6 /* GCDWebServerFileResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 5BC543740C092C697A08396093A0F7BD /* GCDWebServerFileResponse.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - 99E2AEBB5C39DB1661C5C03DDAA451EC /* Infallible+CombineLatest+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40573DCBFB24CA15F7D6C33B5C73162F /* Infallible+CombineLatest+arity.swift */; }; - 9A1CDAE2E9AFFFDBC654855D4A8C6D36 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 817D9055D7659CAC86800D119F65E0F4 /* CFNetwork.framework */; }; - 9AA31D499392F8C3E63FE70C8DE816ED /* RxCocoaRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = 95F05E167015F6A202D2BEB9437AE766 /* RxCocoaRuntime.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9AC6705C60E05CAB6115BA7603BDC0F6 /* Bag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B98DA4C08DC1A12B2789714C6CDEFFA /* Bag.swift */; }; - 9B1D8A7798D8A6F518FC9AF9725431D0 /* URLConvertible+URLRequestConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE6768B8A7BED83ED5C93BB3439EFFEF /* URLConvertible+URLRequestConvertible.swift */; }; - 9C3D3F75523B1B1BB4B3051C01F8F6FE /* Zip+Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3677CB82C594C5820F17431AA45C5C87 /* Zip+Collection.swift */; }; - 9D05E77AB8415BB11EC5C5FB6FD62276 /* UITextField+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 877FA6BB936631CD8F2CA0DFFF6EFC9C /* UITextField+Rx.swift */; }; - 9D5CD154B7C49DA0BCBFF996CA9A6E62 /* RetryWhen.swift in Sources */ = {isa = PBXBuildFile; fileRef = AADC2D51259367D2BB2C73816E5A35CD /* RetryWhen.swift */; }; - 9E9A7DA26421695F48AA96DA35B813B4 /* RxTableViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B1AE9FCFABDD97172220DFDFE618E5 /* RxTableViewDelegateProxy.swift */; }; - 9F77A1FFC61AF7C54E88B7436893C91B /* DistinctUntilChanged.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3949A4BE0C4C31915E5A812146DB23B9 /* DistinctUntilChanged.swift */; }; - 9F794FB773B632DAC0416008A8EC3F45 /* ScheduledDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0D4493458E5817BA46B4318626487F6 /* ScheduledDisposable.swift */; }; - 9FC8EA2F7B3939D69D1469F9046B166A /* Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = 855607DC318E2CF3120B3C70565140A0 /* Window.swift */; }; - 9FED70D1E1FBFB80E974E999EF732258 /* RetryPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B85D80911EDFC7DD402EBEB3A05169A /* RetryPolicy.swift */; }; - A0F9BB688F14F5B350A388BA60C184A0 /* ObservableConvertibleType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4618A8C418D70264404BBAF10EE3A1F4 /* ObservableConvertibleType.swift */; }; - A1CB4107AB9FDEC58E3A7C0C14B4AB79 /* UIDatePicker+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46A83A815027A06FB7A8AB2CEDF56368 /* UIDatePicker+Rx.swift */; }; - A24E8834A85F99EF471C495AD4EFACAB /* RxRelay.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FBD8075FDD277652161C8676E945DE6A /* RxRelay.framework */; }; - A2526FE80C9370555D66A0A33EA22E44 /* NotificationCenter+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE18F7CA6E337EA48867C7D92143B6F9 /* NotificationCenter+Rx.swift */; }; - A2F246B7FCDC421BE6098866AA1509C9 /* MASShortcutView+Bindings.m in Sources */ = {isa = PBXBuildFile; fileRef = 7C471325C18D493A8244DEB1563B18B6 /* MASShortcutView+Bindings.m */; }; - A34F81BE4A40B0C6EF378FBB8F240C66 /* _RXObjCRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = 6985BD62945B0A86382437BC1758C282 /* _RXObjCRuntime.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A3D78B5A2E0E6B987B021DA58CA55BEB /* PublishSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE18557905075BFBE5AFBE3A0D9287F4 /* PublishSubject.swift */; }; - A4CE525F7E6904D7D244727C90DBDBE2 /* Sample.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBC071EBDAC90F82FF4D25D024A5AACF /* Sample.swift */; }; - A525A6AE79BA19A9BDEA467D31477916 /* NSTextField+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C81F8C45A4C248E266304541A86B5A8 /* NSTextField+Rx.swift */; }; - A5BE980B95C08EDFEBEC17E0433A4A2E /* RxTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B37E46EBF28CB6542B58754F09D8AAA /* RxTarget.swift */; }; - A5DC2335899B03F0130A9C739319C92A /* SwitchIfEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = A20673B8CBA1827BCAE8A9CDEAF0CDC5 /* SwitchIfEmpty.swift */; }; - A6652D3942752A05ED133DB77C955216 /* DelaySubscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AE4AAE5FF0F7FEDE2C8D5FB08A1AE4F /* DelaySubscription.swift */; }; - A7A81BFC5D65FDB665AC19E78D4F21B6 /* ToArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314A2DB247EA6781CE45C5C146496327 /* ToArray.swift */; }; - A8DBBA1BD18472113BBE931A3F949659 /* Infallible+Bind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36C45F96BE0AE01F3BB2C90370A73616 /* Infallible+Bind.swift */; }; - A8EEAAF6FACD8832BE7E4A6331ED57E4 /* ControlEvent+Signal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C3A35E7DD83A1437478608A9F2EF44C /* ControlEvent+Signal.swift */; }; - A9AFA432B293A80CF9B1ABD1285A4705 /* AtomicInt.swift in Sources */ = {isa = PBXBuildFile; fileRef = A269EEED1FC8BFDA5FCB004DC335F5C8 /* AtomicInt.swift */; }; - A9DD82DFCFA49DC81169D82415DE7B94 /* Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = D54CB24891D5C94C81CAED6F6D1D4FAB /* Rx.swift */; }; - A9DFF7177D374AF79EEAD9F34B66569A /* NSButton+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DFC3F4E49698472F1AA8DE21B1BD0F2 /* NSButton+Rx.swift */; }; - A9E6EFE85136C81C4AD5BF1CC1B990FD /* BinaryDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FEFD09344E88FFE590FC0A7146C0D32 /* BinaryDisposable.swift */; }; - AA5CBA43C0BF98751988A758EB180BA6 /* ScheduledItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8663196F6A9678BFC77A8E46F8666C75 /* ScheduledItem.swift */; }; - AB83592C5AA99079DA59151D2ACDFBE2 /* ObservableConvertibleType+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = E14C791F6C2C8320DE732C78C55306A1 /* ObservableConvertibleType+Driver.swift */; }; - ABA85887A41495358C83CE3F3030EDEA /* CachedResponseHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32EC506B43DB4AE47634A8AEE18D9E8C /* CachedResponseHandler.swift */; }; - ABDF69C30364D8B9BDFDA8D82A797396 /* ConcurrentDispatchQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB051CDFBF3B30AA181F5BF12F48FD3A /* ConcurrentDispatchQueueScheduler.swift */; }; - AC9540D461C3407AB049AEDB94B82375 /* _RXDelegateProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 30E50B8D09D21C042020DA82FA315C59 /* _RXDelegateProxy.h */; settings = {ATTRIBUTES = (Public, ); }; }; - ADF86969180231C97A14929F02866A1E /* DefaultIfEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = C798C591985DFD0B008AAEEBF78EF979 /* DefaultIfEmpty.swift */; }; - AE143D6485273A676FF9FBF637EE32B3 /* Create.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ED0602BE820AA0F7B2D99CBFED4C1F0 /* Create.swift */; }; - AEA40BB1875D2E7B7DCB5E63E672033B /* UITableView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E7C258B34B55C44CAA679574F0B5E1 /* UITableView+Rx.swift */; }; - AECCE1EAA0757255BC4D722A53202DB0 /* GCDWebServer.h in Headers */ = {isa = PBXBuildFile; fileRef = C771BA2A255CC372CD2AB83291BD3E1C /* GCDWebServer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AED84FBEE9189CFC8A946DDC2BFCB2BE /* _RX.m in Sources */ = {isa = PBXBuildFile; fileRef = 74E6FB11E3F38127740B54FF3C72D1EF /* _RX.m */; }; - B1501E5B044C314A7E3E08D5172CE6C4 /* MASLocalization.m in Sources */ = {isa = PBXBuildFile; fileRef = 46DA81F6288F2733B7F27CCDE97EA2C4 /* MASLocalization.m */; }; - B21C782362344F1FBCA4C5792EC1DED4 /* PrimitiveSequence+Zip+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8C417EB740CAC7F2602C6D8880E7737 /* PrimitiveSequence+Zip+arity.swift */; }; - B2246BF06902F6B9264919F779968CCB /* RxTableViewDataSourcePrefetchingProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C15539256AFFEE061C9DE9660B995B25 /* RxTableViewDataSourcePrefetchingProxy.swift */; }; - B261ED81ABD31C88EAC460E27E453FAE /* NSTextView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5800B274C19C06FB1CA12AC039704852 /* NSTextView+Rx.swift */; }; - B28F09A584B9F1BBF2EFD17B072A5CE1 /* UIStepper+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B2134E06DD0F0E19694ADD2E46E9EF0 /* UIStepper+Rx.swift */; }; - B3C0F4C71E972214529455424C69E544 /* GroupedObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFD30F9BBDEB87F6ADD6C3AAF8DE6E30 /* GroupedObservable.swift */; }; - B3E529B0C5581EFBE667B478A97681F6 /* Pods-ShadowsocksX-NG-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = D60357581333E7EC56952E31B2991366 /* Pods-ShadowsocksX-NG-dummy.m */; }; - B47372436C56EE24B909DE97D5005A64 /* GCDWebServerFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = DD31B6D267ADAB9B30F51F821C60554A /* GCDWebServerFunctions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B4E0DA5CB21C859040F39077A2731701 /* ImmediateSchedulerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DF9FA6B1D40855A99145762147C1690 /* ImmediateSchedulerType.swift */; }; - B59F717CE3CD531818EAFE88FBB454AA /* InfiniteSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB62C29E42A50AB4AA5C6DED19DA376D /* InfiniteSequence.swift */; }; - B6634C3C7216D0A7B063174C16BA1922 /* PrimitiveSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 280A80C3BD890370005C094FC4C3DC12 /* PrimitiveSequence.swift */; }; - B7B31CEFFD225FE0DE33DA0CAAFB46BB /* AnonymousObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 636D1EE61F0E0E367F486461F8E0DF54 /* AnonymousObserver.swift */; }; - B82E2164A69C0D6D3A21B76EFF96F083 /* SharedSequence+Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = D18636DE7B757847E9D7B9E45CA10DE2 /* SharedSequence+Operators.swift */; }; - B8B7E2AC4972978F6894F9C22936CA42 /* Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E698A2854CB4D9E919B55523EB57D1A /* Driver.swift */; }; - B90A504C57627AFCC56F0608D321FB31 /* nl.lproj in Resources */ = {isa = PBXBuildFile; fileRef = A94A0417121D2C31F7167E4A79EC5313 /* nl.lproj */; }; - B936FB1A1779B971BCE58D1CFB84036B /* SingleAssignmentDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCF992D22D15D6CF73AF4D310FEE871C /* SingleAssignmentDisposable.swift */; }; - B9C2804D9E9FD66CF22595DBFED0DC79 /* SubscribeOn.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17A8B6DADE1F343EA5319D5964E84B71 /* SubscribeOn.swift */; }; - BAB6CF7AB28DA0D4BCBC2CF5F53D51AE /* UIScrollView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 441E899D371A5638D8CBD0A21A8CCA61 /* UIScrollView+Rx.swift */; }; - BAC5C3D7F895C6A95B5EA70D1C4BB998 /* DispatchQueueConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 222E861679233A0833D6C2F8079146E7 /* DispatchQueueConfiguration.swift */; }; - BACB203DEE570915EDEC3E701158A173 /* AsMaybe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D680C4252D37F732EE2D1BB9AB911DA /* AsMaybe.swift */; }; - BB15F798287F7447B78B4D49522030C4 /* SwiftSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BC06E9EC97DF3F5E3AB732D978BD66B /* SwiftSupport.swift */; }; - BB322452A0B606428489BA2B2F6D3715 /* NSControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAFFAAB92EFEC042FEE2F851EF9C6CC0 /* NSControl+Rx.swift */; }; - BC03F491551F314E102DEB2F96110609 /* ObservableConvertibleType+Signal.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DCF3854C69F5239CE7E89C1FCFAA51 /* ObservableConvertibleType+Signal.swift */; }; - BC184A6D6502B7B4B308496F5172E4FE /* SynchronizedOnType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95A61E2BD71E9AE873207EFE8994362B /* SynchronizedOnType.swift */; }; - BD379AB5D6DF4FF97EF15732D9635186 /* GCDWebServerURLEncodedFormRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 97319F4B64360DC3D794BD7B57BC9936 /* GCDWebServerURLEncodedFormRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; - BD386D2A7F6652D62B9E75803D3AAD3B /* Bag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2BDFA1D8F5CB80DCE3773C11691B223D /* Bag.swift */; }; - BEF81EB8E8A3FB2B8519CDF1C6DEDA1E /* CombineLatest+Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68D133622632E3F0C62D1F74D188EA7E /* CombineLatest+Collection.swift */; }; - BF1EB892BE3CF9CDFA0DAC7F9392435C /* GCDWebServerRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = D4E3DADB00C8898A4A01F4DF1034F96C /* GCDWebServerRequest.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - C09F690FF2734763D8D2838B0BA14B0F /* RxCocoa-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C0551E43C5CE2E6F3BD09C18890BFD /* RxCocoa-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C0ACE318CA3576826A53026F9C253E0B /* RefCountDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B97E5FCD7744551B43A8C353FD79E774 /* RefCountDisposable.swift */; }; - C0E1B20534F498B9891E956388D79209 /* NSView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4028B836251B6DD18772CF35047686A /* NSView+Rx.swift */; }; - C0EA3A392A5229080E52F9FDF969FDC8 /* Completable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AE63CBE5D3B0C2D25184C45E1B8C885 /* Completable.swift */; }; - C1C5B050B55C15103ABC81769551A283 /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D09EFC8E8E0DD0BACEB39FA20E08331 /* Response.swift */; }; - C1F1DB6A9CBDE584D09BA1613AAD4F9D /* Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E656BCAB89EA23EC58A161ACF0DAE68 /* Alamofire.swift */; }; - C33311F020C5777D0CB7E0F61E4FED8D /* Shortcut.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B9491CF676F85A85C4F0987D38F9051 /* Shortcut.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C341FC8944C28CCA39FB9AC4B0F23763 /* GCDWebServerHTTPStatusCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 57BEC3094A7FB642608645E131DA83D4 /* GCDWebServerHTTPStatusCodes.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C3D17F4F92CD46A4285A92D1FD6AA4B1 /* fr.lproj in Resources */ = {isa = PBXBuildFile; fileRef = B68B5F9FDDB0D41979766C1D549A8780 /* fr.lproj */; }; - C4CD2007BF8F2B0B5125A85B1C43AD24 /* ReplayRelay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 485A8E801F2DA21AB5D16808AE1B4887 /* ReplayRelay.swift */; }; - C60C9B7447C5D9555611004E27093043 /* SharedSequence+Operators+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87A94DCCD78781BAE448DEA818B26DE4 /* SharedSequence+Operators+arity.swift */; }; - C6D5A4B4028B2C43380C9FA58BD5C8CA /* Alamofire-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 06A09DBC68AE0A93F94442D71EBF343F /* Alamofire-dummy.m */; }; - C7A325790D6CB1C3545FE9E688545C56 /* BooleanDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0C023ECBE853C3AFE12E6702B6D1CD /* BooleanDisposable.swift */; }; - C81FF014587AC7E1A51D4F3F2C6F72EA /* ReplaySubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96D93775EA307729314581C5C539C487 /* ReplaySubject.swift */; }; - C83DA2E174587856EBBAAA1763F6D483 /* _RXKVOObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A33670952794CBD825EC26F1A98DBF /* _RXKVOObserver.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C8422B20017685DE0D693EC679FF8BF6 /* KVORepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F202B17AB2C7DC4FEC3F1CF2B5FD57 /* KVORepresentable.swift */; }; - CA391E5CE794FA6D964DC2DFC8B8E109 /* NSObject+Rx+KVORepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B00813C768C553C089DAF0C1900799B /* NSObject+Rx+KVORepresentable.swift */; }; - CC9F7F2B397CCCC5397750D0B139E373 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29BFF21F894144F23E9F778185A1EBC4 /* Utils.swift */; }; - CCE2D9FB50D6084FD48013ED3474F992 /* Optional.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5158C591583049B150EC9F57DC2FA656 /* Optional.swift */; }; - CD782D1189ADBAA42D087B87D53838A0 /* GCDWebServerDataRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DFEE31FDCAA3B9A85119C45EE5BF376 /* GCDWebServerDataRequest.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - CE622A228B2F310835326CCF0B83F031 /* SynchronizedDisposeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3623071AC720B9C13DD1043F7052A73 /* SynchronizedDisposeType.swift */; }; - CEA50BEC377AEE2AAA9DB5B71DEA418C /* BRLOptionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 31F9576864749334961DE762B01B777C /* BRLOptionParser.h */; settings = {ATTRIBUTES = (Project, ); }; }; - D03F1F02DE8606E6057D57866611BEBF /* MultipartUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CF5ADA01C91A2DF993314D6CC9C63D3 /* MultipartUpload.swift */; }; - D0B9EA4DC98653D58DEAE9629A2F0285 /* SkipUntil.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1D0AF20D0BF5465039BB88836A959B6 /* SkipUntil.swift */; }; - D0C4275AF3346D1C08B187D04D9606F2 /* Platform.Darwin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E801F2049749D5BA709EAE3A2028661 /* Platform.Darwin.swift */; }; - D13BDCB5C86CD4018E19F1DA207BA61A /* CurrentThreadScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C793DFE7002D416E900642C76CEEBD75 /* CurrentThreadScheduler.swift */; }; - D14066FAE94E304798E43651E5886D13 /* ParameterEncoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF8CD0A416163A50B72AAF4B0C4A124 /* ParameterEncoding.swift */; }; - D21D80287E6B1C56E0BE86B1E3F08249 /* Decode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D99DA86D8CBFFCB2E7FD40BC42568F3 /* Decode.swift */; }; - D251A0235B97F9217D50C5A1C7C5F311 /* URLSession+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB5B580FE6B602D602E607C7BC7C470 /* URLSession+Rx.swift */; }; - D260B45339932BAA56D7024048E2D155 /* GCDWebServerConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 1410700BFA8AF785CCF9919941F9930C /* GCDWebServerConnection.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - D31FC7FDD450C4CDD633ECBAD27C6221 /* URLEncodedFormEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D0A2A589A608DD00CA24C86BCD46E62 /* URLEncodedFormEncoder.swift */; }; - D33C1AD2E019F48235F734A00CE7C24C /* GCDWebServerFileResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 77E73C4E3CAF9AD8FAE2EA9130D6A37E /* GCDWebServerFileResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D37A995029438A503B62B1D2ACFE9247 /* MASShortcut.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 230F8208BE63C052A548A7D41A1158B2 /* MASShortcut.bundle */; }; - D557532ED179C1F26074DCD602EF357D /* cs.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 18B45BFB16E63DDF1AFB6C167D70D1C2 /* cs.lproj */; }; - D574A95C82CDFCC40442A4C5A20645D9 /* Single.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3E96B8BC40FDC92B51E51B50F126573 /* Single.swift */; }; - D57542063237724C1CA2962EAC1764C7 /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 172B845C32EEB48FD9EF1A11CC432D51 /* Sequence.swift */; }; - D597C1B3CBDE4896A022E9422A4F4874 /* Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 555231B7293881D7D76CA80C82AABA2B /* Debug.swift */; }; - D5E020763D69E9336EB398ACD48FEBB0 /* GCDWebServerErrorResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 199E49652A8B30754D25980910F956E1 /* GCDWebServerErrorResponse.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - D5EAAFB6FAD77A8F0699345149BA3CBB /* URLRequest+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47291D90953698297410B0C37E619402 /* URLRequest+Alamofire.swift */; }; - D6389E438CF72863B7F4832592B60428 /* Empty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D8FEBF2028BCC7758A666F2A35989A /* Empty.swift */; }; - D661EA5F16B11BEE347BAE35961A3AD2 /* TailRecursiveSink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 558A95B0EAE7FAFDFCC334A1E9277C19 /* TailRecursiveSink.swift */; }; - D9884F11DD4FAA059A45CBBBC68E090F /* RxCollectionViewReactiveArrayDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = B25AD05D537735CCA21E1986D98F830E /* RxCollectionViewReactiveArrayDataSource.swift */; }; - DAB6B67BBE65A9ECA898A563CACF442A /* RxWKNavigationDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AC418FEB3CC60F42D6A18E6151C871A /* RxWKNavigationDelegateProxy.swift */; }; - DADE159BB4CF9E438FC5DEF80822A710 /* MASHotKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BE4993AB90D97D332E61EB54E0C3C9A /* MASHotKey.m */; }; - DBFA45EBB79E16D7B6780CDA789B0D08 /* SkipWhile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 904A920F44C4C4A18874A6A62A3ED759 /* SkipWhile.swift */; }; - DC627AFC5B585686898B014184AFCABD /* AuthenticationInterceptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E101994FDA2210D6CD7972A656C511F /* AuthenticationInterceptor.swift */; }; - DC708FA8C70373D522CB885D4451F3D0 /* RxTabBarDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D1DACD1512DCFE82BC525C443DA8A5 /* RxTabBarDelegateProxy.swift */; }; - DCC8DE3CDC74A5E38864303C8C2404EF /* ObserverBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE8BA32B7F7B571C37D44747CBB93955 /* ObserverBase.swift */; }; - DD24A504D1BB91B71B67B4A93A92F1DA /* ConcurrentMainScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A126CA25C01C17FEF1E4B62108855349 /* ConcurrentMainScheduler.swift */; }; - DD7EC76A4EB8C3A1741CD5B77B57E0A4 /* UISwitch+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3622945DEBFCB14514027A236BDFC74C /* UISwitch+Rx.swift */; }; - DDA573352B48255CA674E8BB62C306C6 /* Using.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE3AAA7586F734974B628C45E2310229 /* Using.swift */; }; - DE76073247081964D8DA688F13021B62 /* UISegmentedControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = E39E7221D0BA332CC5AC5DD0A7C16C92 /* UISegmentedControl+Rx.swift */; }; - DF3FD63D6A37C12FDB09B8CA5AE80AC3 /* GCDWebServerPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 10F2E7253B70490BD80C987E65C522AC /* GCDWebServerPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; - E03556E8EC8DA4FF0DE3ED6F86BD7C51 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE6672D913C4CDAB5BAC161BDC483A67 /* Cocoa.framework */; }; - E06F7DEDC12A706F1AA7067CA7D58BD8 /* Disposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8369906FA14B85B8271089FAAA1E4694 /* Disposable.swift */; }; - E0AF255AB2AFA980F44645355BB7828C /* _RX.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BAD385D5CDC39C1AE6584A123D2DFC4 /* _RX.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E1AD1FE46FE8F693F913FEC190210A59 /* RxCocoa-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4752AFB18B745CA95D95FB7457EAA1C4 /* RxCocoa-dummy.m */; }; - E26E725D6366FA3AE20B95802F54C4B6 /* WithUnretained.swift in Sources */ = {isa = PBXBuildFile; fileRef = 897003218412D0C779A54DAAD7D2A4EE /* WithUnretained.swift */; }; - E3EE570AEF6808660B0542591285D354 /* RxRelay-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1718F5B8FAF3CE57AE64B5F53589493F /* RxRelay-dummy.m */; }; - E46EB73E26A44700E41C3CD2F1E847FD /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CE7CD3C7A16D2E9341BBBAB18D5D8DC /* Event.swift */; }; - E52E9DB2E0EB574ED157EB478E60D13D /* Pods-proxy_conf_helper-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 8752D17209EE8AAD7681107D6444113F /* Pods-proxy_conf_helper-dummy.m */; }; - E5A162C30F57D3A21BD9D74BC97E782E /* First.swift in Sources */ = {isa = PBXBuildFile; fileRef = 543DFE92FBC6235F6826EF38928A7C08 /* First.swift */; }; - E5F1157CAB86D8C0C166874A6E826739 /* Materialize.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4618B5826B29CA49F53BD36B1570602 /* Materialize.swift */; }; - E5F3CF900C793B92F327E2F4BDF8A8AB /* MASLocalization.h in Headers */ = {isa = PBXBuildFile; fileRef = 82A2597C8D9860F95F40565C0631A47D /* MASLocalization.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E8064C59B797763270D65097B4CD075B /* ObservableConvertibleType+SharedSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFAC6355D5B0FD94083A74B4602AF9D2 /* ObservableConvertibleType+SharedSequence.swift */; }; - E816A86AE437A96B389D73C115778CFA /* NSObject+Rx+RawRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9EBFDB861299F7DC1241C7FCFF00DD /* NSObject+Rx+RawRepresentable.swift */; }; - E83CDC839BC5CA753A57BE04CB66F85D /* ConnectableObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2505B197F74151D018080608E6576C6C /* ConnectableObservableType.swift */; }; - E84DB9453D7F43DCEC20FDFB5F1CDFD6 /* RxSearchBarDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 345AE1A0C847584A14AD381D5E476AB9 /* RxSearchBarDelegateProxy.swift */; }; - E9B95D42F4510C79E2D8A8CFA251CD49 /* GCDWebServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 55F5FEB17D952CAA64A6B7DE90D7E47D /* GCDWebServer.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - E9C69CBF2B72EC9A5031BA6FF30BC251 /* Generate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 886072F083033D493924A8BE652713ED /* Generate.swift */; }; - E9FD5789C7C4946FC504E7C679BDD156 /* ControlProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5878F666B9410A53C5BBE1778D1B2CCE /* ControlProperty.swift */; }; - EA82A6A287EA96119DF03722AB2F25B8 /* Just.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1467E6A8A0A5B978108FDFC868000E /* Just.swift */; }; - EB8C4B9D8DFF39ECFE8538B73F5717F7 /* CompactMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6415209F9685A39C6C1018082155EA5 /* CompactMap.swift */; }; - EC388029B45DC677A2412CF1617E4DF1 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EF91750DCDE73B687E4BA164856BE224 /* SystemConfiguration.framework */; }; - ED82861E104428E8C3FA8D1B2618C875 /* Producer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FDB60114950AF3BF06EF9DA0AF9E5AC /* Producer.swift */; }; - EDC93BD7B9262119AE145E4C7A9D0212 /* Request.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9029CBEE1EB8EBFDFCC3F55CEC98E088 /* Request.swift */; }; - EDD85DAC7DC88B01D5A2C20969416C9B /* BRLOptionParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 68C9C3CF6142E1B32695BC562ECAC427 /* BRLOptionParser.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - F01A39BF2122BF11990A88015EF45A48 /* Pods-ShadowsocksX-NG-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = CD95085BFAA31431686824B236DB9319 /* Pods-ShadowsocksX-NG-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F07EC9B60B1FB76D9F64FE2BC62A87DF /* MASShortcutView+Bindings.h in Headers */ = {isa = PBXBuildFile; fileRef = B5AEEDAA3124911175E2336A08227588 /* MASShortcutView+Bindings.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F0F3224FF592F9BA2A044A2FC2BD4CCD /* Validation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 151A22449BAFE60147DA302082A00FA1 /* Validation.swift */; }; - F186B25E38062738E07F219D0289CBFA /* ItemEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 684F8C697CD894D0F5680EE542AC32E9 /* ItemEvents.swift */; }; - F1A73AB066B6EC8C012F4044B542568D /* Map.swift in Sources */ = {isa = PBXBuildFile; fileRef = 494A67061DAFFD52534BC4699A8DF637 /* Map.swift */; }; - F1F7AF19C5D50FB5BCD1D357FB9A5946 /* Do.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E5F518C62FDAA5A762312C37D1CB101 /* Do.swift */; }; - F2AB55CF962B7EBDE26DD970C282CEDE /* RxTableViewReactiveArrayDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = B265FABD755D21851D1C166921BB4A24 /* RxTableViewReactiveArrayDataSource.swift */; }; - F44EF6685A8C029EAC293DE9FADC3794 /* ControlTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DA6A1DA8589C7192C8BFDBC3F4A9913 /* ControlTarget.swift */; }; - F45717BF2118BB61C328A1F67CFE9238 /* Driver+Subscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F46244A2FF95EF2B228E2F76529358 /* Driver+Subscription.swift */; }; - F4C5E42370FEF310E72D2A8DAD2993FB /* pl.lproj in Resources */ = {isa = PBXBuildFile; fileRef = EE873D31D9227598B067D9426D366009 /* pl.lproj */; }; - F515F0E56CBF807E49797455E495074C /* MASShortcutMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = 605C26B2F1FFA16F0E85E33F5CC526EC /* MASShortcutMonitor.m */; }; - F5C3C227785D45C44F1FA8157EF99C71 /* GCDWebServerErrorResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 9EE8B6717B73CE07A9FAC17FFCB1BA91 /* GCDWebServerErrorResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F5E8D9EC4166B35C084791CAEFF2404C /* WithLatestFrom.swift in Sources */ = {isa = PBXBuildFile; fileRef = A49E3489F755F888C3405824694827BF /* WithLatestFrom.swift */; }; - F621486B5084C21DA2498C0FC6A85E02 /* AnyObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840A431555445FF451B4B74E7A8DDCF4 /* AnyObserver.swift */; }; - F654788A27A296CD2C1F104B4C897EF0 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE6672D913C4CDAB5BAC161BDC483A67 /* Cocoa.framework */; }; - F6F5712CC3ED7DD4D51BA12747FCDE6E /* MASDictionaryTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = F6460C30C5328ED85A1103897C8CB63C /* MASDictionaryTransformer.m */; }; - F70EF854395CDE981A8336E4FF0310FE /* URLSessionConfiguration+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FE5C08C0F9F63C9A7D2B71EF9F0864 /* URLSessionConfiguration+Alamofire.swift */; }; - F71DB74D923AB8F40A88103BDC5ABFA6 /* RxTextStorageDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B33DD3F11E0587A32ECE709173E4EF /* RxTextStorageDelegateProxy.swift */; }; - F7DAD2EF3F86BC40F7D4F2EE49362418 /* GCDWebServerStreamedResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = DAE48A7C993FBD43A674E228A900457B /* GCDWebServerStreamedResponse.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; - F89A75BE493264635F9977B0A9233617 /* ObservableConvertibleType+Infallible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 834EB5666F2D27EDBD25C600C80DF7CE /* ObservableConvertibleType+Infallible.swift */; }; - F8C1D484E959F9ADD96E9CD2F3B045B0 /* Observable+Bind.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8976DA3C1E5870E7B74F26E219A9885 /* Observable+Bind.swift */; }; - F8EC0962127455A9E5ABEA1B2D0C91D7 /* UIActivityIndicatorView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89A41E2A66DF6A8547AFAB72FE74B6A2 /* UIActivityIndicatorView+Rx.swift */; }; - F9872C7244CA7C80D5E402B3922DB009 /* SchedulerType+SharedSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53EB3CB0FCC5ABA4F18B576E6BA4EB1F /* SchedulerType+SharedSequence.swift */; }; - F9C743AF2433172C84F9365D8DE8CBF3 /* MASShortcutValidator.m in Sources */ = {isa = PBXBuildFile; fileRef = 726DEA3A84065F8E12FDE5617447B366 /* MASShortcutValidator.m */; }; - FA547DB169BA1CB0759702BA51F1C52E /* SubscriptionDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAFB048690381EFB0893639F33D3C764 /* SubscriptionDisposable.swift */; }; - FAEF22DB65A2C18EAF044623FF4ECA43 /* SingleAsync.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2B10B3F59B2394712B672A72C5827F0 /* SingleAsync.swift */; }; - FB3AD79C536DC201CED66150778FA691 /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFD92A4EF88D0A6B34E86A6A7CE2436D /* RxSwift.framework */; }; - FB425C8625656D7AE2AFD1F8A78713B0 /* MASShortcutBinder.m in Sources */ = {isa = PBXBuildFile; fileRef = 46002374E8C8C6F2127C7C9A6DFEF743 /* MASShortcutBinder.m */; }; - FC22B1E68007E6AC40CC8DF2DF5E0AB6 /* Zip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA0DBB3C5358A6E4EF0C16145BB0F7E /* Zip.swift */; }; - FCBF7F9DA53A194F0653EE7E00B57BC8 /* GCDWebServerMultiPartFormRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = D157799A728D6FFED669C62E86BABD73 /* GCDWebServerMultiPartFormRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; - FD397CD62192F67DF9C2088CC5EBE409 /* ControlEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38724BD70D1712C03FA9B7A4C417144D /* ControlEvent.swift */; }; - FDEBCA25E0674ADFB66FA6256FF6486F /* RxCollectionViewDataSourceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5BD2C8DB205D16490D3804A6CAB6C50 /* RxCollectionViewDataSourceProxy.swift */; }; - FF36522388E5964B78AD72A59721AADC /* de.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 8F90CD66F125C28F8983AFCFA7DF6607 /* de.lproj */; }; - FFF63A18CD673B6821ED19EB164316C9 /* Signal+Subscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12318B6E6BA8040BCC422023A5ABEF27 /* Signal+Subscription.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 1CA90026A2A030CD980CB1E78050B63A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4622BFEF3DC16E8BD15EEFC30D4D0084; - remoteInfo = RxRelay; - }; - 290D7A27821274F88F50BA4027E877B0 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 00F92A6698B766C4479D7B608F28D680; - remoteInfo = BRLOptionParser; - }; - 3A3C6F9E9E958812D1FF93C9737FE5B1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = EA9EA43B3B503823EE36C60D9C8A865F; - remoteInfo = RxSwift; - }; - 3DE69038DEBF7AC72F345377CCA1A457 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 73C37A16ECCEAD845651DCDEE95675BE; - remoteInfo = "MASShortcut-MASShortcut"; - }; - 6C21C08D1A9E4A42298C1E83946EFBF6 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = EAAA1AD3A8A1B59AB91319EE40752C6D; - remoteInfo = Alamofire; - }; - 7569E9B350638EBD714C781E38F158A8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = E9FDECF69808DB0491D4B4C08CF920DC; - remoteInfo = "Pods-ShadowsocksX-NG"; - }; - 809667767BFFB7D46B762AD5F006A069 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = EA9EA43B3B503823EE36C60D9C8A865F; - remoteInfo = RxSwift; - }; - 93C581FCCE9BCA693063DEB0CB18943C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4622BFEF3DC16E8BD15EEFC30D4D0084; - remoteInfo = RxRelay; - }; - 95ED7E1E76F66FF2AFA473A3D49F574E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = EA9EA43B3B503823EE36C60D9C8A865F; - remoteInfo = RxSwift; - }; - A5DE8E8EE1A9A5D27FEA05AD1FF38C1E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 7AD0C6DCDC9CEC8A3C7C10C7FEE07BE6; - remoteInfo = RxCocoa; - }; - B0B5FA86CABF29A7785405416D374CDA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 2B2B481A164695722839BD581D442457; - remoteInfo = MASShortcut; - }; - E627335D42AC0ADFBA7B40BFD314B204 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = AD904F32069787EFB2DFFE05EB82F5BD; - remoteInfo = GCDWebServer; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 04A3FEA575D65278CDB553AA231A0CF6 /* DisposeBase.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DisposeBase.swift; path = RxSwift/Disposables/DisposeBase.swift; sourceTree = ""; }; - 0555618E1BBA944D30E358F0700CDD8B /* GCDWebServerFunctions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GCDWebServerFunctions.m; path = GCDWebServer/Core/GCDWebServerFunctions.m; sourceTree = ""; }; - 06A09DBC68AE0A93F94442D71EBF343F /* Alamofire-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Alamofire-dummy.m"; sourceTree = ""; }; - 07B4CEF97C27B2FE6205EE1D720BFB39 /* Skip.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Skip.swift; path = RxSwift/Observables/Skip.swift; sourceTree = ""; }; - 080201197B517655700BD33F44B1A602 /* Dematerialize.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Dematerialize.swift; path = RxSwift/Observables/Dematerialize.swift; sourceTree = ""; }; - 09A0680C8640FDF225CF2A27A4204628 /* GCDWebServer-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "GCDWebServer-dummy.m"; sourceTree = ""; }; - 0A18EEA4857408358F9A8E6ED8AF8829 /* Observable+Bind.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Observable+Bind.swift"; path = "RxRelay/Observable+Bind.swift"; sourceTree = ""; }; - 0B98DA4C08DC1A12B2789714C6CDEFFA /* Bag.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Bag.swift; path = Platform/DataStructures/Bag.swift; sourceTree = ""; }; - 0BC06E9EC97DF3F5E3AB732D978BD66B /* SwiftSupport.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwiftSupport.swift; path = RxSwift/SwiftSupport/SwiftSupport.swift; sourceTree = ""; }; - 0C0FB7A81FC88101C56EABF826BD78F5 /* Reactive.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Reactive.swift; path = RxSwift/Reactive.swift; sourceTree = ""; }; - 0C1C25377D5ADEBBE1E5B44FD42F2BF8 /* GCDWebServerMultiPartFormRequest.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GCDWebServerMultiPartFormRequest.m; path = GCDWebServer/Requests/GCDWebServerMultiPartFormRequest.m; sourceTree = ""; }; - 0CB05B6D60934D955FE0D75C2339A114 /* Amb.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Amb.swift; path = RxSwift/Observables/Amb.swift; sourceTree = ""; }; - 0D09EFC8E8E0DD0BACEB39FA20E08331 /* Response.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Response.swift; path = Source/Response.swift; sourceTree = ""; }; - 0E5F518C62FDAA5A762312C37D1CB101 /* Do.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Do.swift; path = RxSwift/Observables/Do.swift; sourceTree = ""; }; - 0F2EB184269284B56190B6EE5A7E5CC3 /* DisposeBag.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DisposeBag.swift; path = RxSwift/Disposables/DisposeBag.swift; sourceTree = ""; }; - 10E99E50E2994DB7AD9AEBDEF1A2F72B /* Alamofire-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Alamofire-umbrella.h"; sourceTree = ""; }; - 10F2E7253B70490BD80C987E65C522AC /* GCDWebServerPrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCDWebServerPrivate.h; path = GCDWebServer/Core/GCDWebServerPrivate.h; sourceTree = ""; }; - 111E9F3F4997D0ACA2E0BCDAF269904C /* SchedulerType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SchedulerType.swift; path = RxSwift/SchedulerType.swift; sourceTree = ""; }; - 11DD125BCF1FDD4E34715800EC2F295F /* RecursiveLock.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RecursiveLock.swift; path = Platform/RecursiveLock.swift; sourceTree = ""; }; - 11F97CBA2FD3653262BC227DD1340D90 /* Pods-proxy_conf_helper-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-proxy_conf_helper-acknowledgements.plist"; sourceTree = ""; }; - 12318B6E6BA8040BCC422023A5ABEF27 /* Signal+Subscription.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Signal+Subscription.swift"; path = "RxCocoa/Traits/Signal/Signal+Subscription.swift"; sourceTree = ""; }; - 127B3965CEBAEBFB395F0D10B7C255FB /* Throttle.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Throttle.swift; path = RxSwift/Observables/Throttle.swift; sourceTree = ""; }; - 1389D4639C0D9038BA081FA8DC1CD646 /* BRLOptionParser-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "BRLOptionParser-dummy.m"; sourceTree = ""; }; - 1410700BFA8AF785CCF9919941F9930C /* GCDWebServerConnection.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GCDWebServerConnection.m; path = GCDWebServer/Core/GCDWebServerConnection.m; sourceTree = ""; }; - 151A22449BAFE60147DA302082A00FA1 /* Validation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Validation.swift; path = Source/Validation.swift; sourceTree = ""; }; - 161437331F54761E08F028DD14CDC21E /* Infallible+Create.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Infallible+Create.swift"; path = "RxSwift/Traits/Infallible/Infallible+Create.swift"; sourceTree = ""; }; - 1718F5B8FAF3CE57AE64B5F53589493F /* RxRelay-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "RxRelay-dummy.m"; sourceTree = ""; }; - 172B845C32EEB48FD9EF1A11CC432D51 /* Sequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Sequence.swift; path = RxSwift/Observables/Sequence.swift; sourceTree = ""; }; - 17A8B6DADE1F343EA5319D5964E84B71 /* SubscribeOn.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SubscribeOn.swift; path = RxSwift/Observables/SubscribeOn.swift; sourceTree = ""; }; - 17F9F190DDBE93E38A56D8405CBFA664 /* UIButton+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIButton+Rx.swift"; path = "RxCocoa/iOS/UIButton+Rx.swift"; sourceTree = ""; }; - 18B45BFB16E63DDF1AFB6C167D70D1C2 /* cs.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = cs.lproj; path = Resources/cs.lproj; sourceTree = ""; }; - 196DA983244F60766BA272090829A16E /* Pods-ShadowsocksX-NGTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ShadowsocksX-NGTests.debug.xcconfig"; sourceTree = ""; }; - 199E49652A8B30754D25980910F956E1 /* GCDWebServerErrorResponse.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GCDWebServerErrorResponse.m; path = GCDWebServer/Responses/GCDWebServerErrorResponse.m; sourceTree = ""; }; - 19AA7CC35C97B4BDF08E2E5CE20955E0 /* AlamofireExtended.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AlamofireExtended.swift; path = Source/AlamofireExtended.swift; sourceTree = ""; }; - 19FF8B675AE7A3F0AB7CDE7C48E8082A /* ScheduledItemType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ScheduledItemType.swift; path = RxSwift/Schedulers/Internal/ScheduledItemType.swift; sourceTree = ""; }; - 1A2C716EE769E98BF094D14B243A42C2 /* Alamofire-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Alamofire-prefix.pch"; sourceTree = ""; }; - 1AA3BEB86C50C2AAE9CCEDB0171CFC56 /* ObservableType+PrimitiveSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ObservableType+PrimitiveSequence.swift"; path = "RxSwift/Traits/PrimitiveSequence/ObservableType+PrimitiveSequence.swift"; sourceTree = ""; }; - 1B2134E06DD0F0E19694ADD2E46E9EF0 /* UIStepper+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIStepper+Rx.swift"; path = "RxCocoa/iOS/UIStepper+Rx.swift"; sourceTree = ""; }; - 1C10AA3C311345DB3616BCE827B69C55 /* Pods-ShadowsocksX-NGTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-ShadowsocksX-NGTests-dummy.m"; sourceTree = ""; }; - 1CD2535A24AA927A5965AF73264678A3 /* Catch.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Catch.swift; path = RxSwift/Observables/Catch.swift; sourceTree = ""; }; - 1DBE368EA1C6F7EBE80E08054C9BC6AE /* TextInput.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TextInput.swift; path = RxCocoa/Common/TextInput.swift; sourceTree = ""; }; - 1EA29F7E0E65B6A9619DB77448844EC1 /* Pods-ShadowsocksX-NG.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-ShadowsocksX-NG.modulemap"; sourceTree = ""; }; - 1EB8536183BE6472CDCC5817172688EF /* AnonymousDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnonymousDisposable.swift; path = RxSwift/Disposables/AnonymousDisposable.swift; sourceTree = ""; }; - 1FA62A0165A7A8D001536C62FD5E2392 /* SynchronizedUnsubscribeType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SynchronizedUnsubscribeType.swift; path = RxSwift/Concurrency/SynchronizedUnsubscribeType.swift; sourceTree = ""; }; - 200825C8579BF340304A9767D679EC35 /* InvocableType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InvocableType.swift; path = RxSwift/Schedulers/Internal/InvocableType.swift; sourceTree = ""; }; - 2094BFBE78A2839B3C673A3E450C77FC /* GCDWebServer.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GCDWebServer.release.xcconfig; sourceTree = ""; }; - 2096522151041770121528F182B6F42D /* Range.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Range.swift; path = RxSwift/Observables/Range.swift; sourceTree = ""; }; - 21F927D22EA76A49C54C44827DD1CE5A /* UITabBar+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UITabBar+Rx.swift"; path = "RxCocoa/iOS/UITabBar+Rx.swift"; sourceTree = ""; }; - 222E861679233A0833D6C2F8079146E7 /* DispatchQueueConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DispatchQueueConfiguration.swift; path = RxSwift/Schedulers/Internal/DispatchQueueConfiguration.swift; sourceTree = ""; }; - 22ADD736785A6DE33628551E25AC889A /* Pods-ShadowsocksX-NGTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-ShadowsocksX-NGTests-acknowledgements.markdown"; sourceTree = ""; }; - 22D41ECF1E34CC3D83A32F7896831100 /* RxPickerViewDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxPickerViewDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxPickerViewDelegateProxy.swift; sourceTree = ""; }; - 230F8208BE63C052A548A7D41A1158B2 /* MASShortcut.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MASShortcut.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; - 24121C8FA3C10947BE50901868F9198A /* MASShortcutMonitor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcutMonitor.h; path = Framework/Monitoring/MASShortcutMonitor.h; sourceTree = ""; }; - 2505B197F74151D018080608E6576C6C /* ConnectableObservableType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConnectableObservableType.swift; path = RxSwift/ConnectableObservableType.swift; sourceTree = ""; }; - 2586C5A6499D4E9A6B62C1CF5804DE66 /* Platform.Linux.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Platform.Linux.swift; path = Platform/Platform.Linux.swift; sourceTree = ""; }; - 26A8810424438A12E7ADBFB3E068C658 /* MASShortcut.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MASShortcut.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 26DA8062B81F764A6EEA6168DF6337AB /* OperationQueue+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "OperationQueue+Alamofire.swift"; path = "Source/OperationQueue+Alamofire.swift"; sourceTree = ""; }; - 273C90965AA81CCFE4CDA40530425746 /* Take.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Take.swift; path = RxSwift/Observables/Take.swift; sourceTree = ""; }; - 280A80C3BD890370005C094FC4C3DC12 /* PrimitiveSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PrimitiveSequence.swift; path = RxSwift/Traits/PrimitiveSequence/PrimitiveSequence.swift; sourceTree = ""; }; - 2888FA81FD2BE4D3B068BCE4AFDC9A93 /* UISearchBar+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UISearchBar+Rx.swift"; path = "RxCocoa/iOS/UISearchBar+Rx.swift"; sourceTree = ""; }; - 28F6CED61832E1CE6BA74AA90F7E45EE /* RxSwift.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RxSwift.release.xcconfig; sourceTree = ""; }; - 29BFF21F894144F23E9F778185A1EBC4 /* Utils.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Utils.swift; path = RxRelay/Utils.swift; sourceTree = ""; }; - 29E3014CE53E3127CCD38149E2060C76 /* DispatchQueue+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DispatchQueue+Extensions.swift"; path = "Platform/DispatchQueue+Extensions.swift"; sourceTree = ""; }; - 2A11F032AFA3310A3EEE63E67481B01E /* Pods-ShadowsocksX-NG-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-ShadowsocksX-NG-frameworks.sh"; sourceTree = ""; }; - 2AE63CBE5D3B0C2D25184C45E1B8C885 /* Completable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Completable.swift; path = RxSwift/Traits/PrimitiveSequence/Completable.swift; sourceTree = ""; }; - 2BDFA1D8F5CB80DCE3773C11691B223D /* Bag.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Bag.swift; path = Platform/DataStructures/Bag.swift; sourceTree = ""; }; - 2C81F8C45A4C248E266304541A86B5A8 /* NSTextField+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSTextField+Rx.swift"; path = "RxCocoa/macOS/NSTextField+Rx.swift"; sourceTree = ""; }; - 2CFE9D0E45288EBBAF865D7685C2B983 /* Pods-ShadowsocksX-NGTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-ShadowsocksX-NGTests-acknowledgements.plist"; sourceTree = ""; }; - 2DDC82F5641636881356BF49166C8DF3 /* RxRelay-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxRelay-umbrella.h"; sourceTree = ""; }; - 2E101994FDA2210D6CD7972A656C511F /* AuthenticationInterceptor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AuthenticationInterceptor.swift; path = Source/AuthenticationInterceptor.swift; sourceTree = ""; }; - 2E656BCAB89EA23EC58A161ACF0DAE68 /* Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Alamofire.swift; path = Source/Alamofire.swift; sourceTree = ""; }; - 2F138B6C28378A801D2186B22E1E6224 /* RxCocoa.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RxCocoa.debug.xcconfig; sourceTree = ""; }; - 2FEFD09344E88FFE590FC0A7146C0D32 /* BinaryDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BinaryDisposable.swift; path = RxSwift/Disposables/BinaryDisposable.swift; sourceTree = ""; }; - 30E50B8D09D21C042020DA82FA315C59 /* _RXDelegateProxy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _RXDelegateProxy.h; path = RxCocoa/Runtime/include/_RXDelegateProxy.h; sourceTree = ""; }; - 31234D4C5E912BD05D37874E7E89A233 /* Enumerated.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Enumerated.swift; path = RxSwift/Observables/Enumerated.swift; sourceTree = ""; }; - 314A2DB247EA6781CE45C5C146496327 /* ToArray.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ToArray.swift; path = RxSwift/Observables/ToArray.swift; sourceTree = ""; }; - 31F9576864749334961DE762B01B777C /* BRLOptionParser.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BRLOptionParser.h; path = BRLOptionParser/BRLOptionParser.h; sourceTree = ""; }; - 321FC2ED515952B66BACDB8CAC130EB4 /* it.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = it.lproj; path = Resources/it.lproj; sourceTree = ""; }; - 32777B9FE68F64D911474F7B7595C94C /* Scan.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Scan.swift; path = RxSwift/Observables/Scan.swift; sourceTree = ""; }; - 32EC506B43DB4AE47634A8AEE18D9E8C /* CachedResponseHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CachedResponseHandler.swift; path = Source/CachedResponseHandler.swift; sourceTree = ""; }; - 336A70440B171C2C6AEE66F83620273A /* Alamofire.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Alamofire.modulemap; sourceTree = ""; }; - 33BBD4B03778E41A59C1A3F64AAB876C /* Deferred.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Deferred.swift; path = RxSwift/Observables/Deferred.swift; sourceTree = ""; }; - 3425B3045259FEA3A238D183DEEE520B /* HTTPHeaders.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTPHeaders.swift; path = Source/HTTPHeaders.swift; sourceTree = ""; }; - 345AE1A0C847584A14AD381D5E476AB9 /* RxSearchBarDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxSearchBarDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxSearchBarDelegateProxy.swift; sourceTree = ""; }; - 353B178196A1B3A383089B3D1006F66A /* MASDictionaryTransformer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASDictionaryTransformer.h; path = "Framework/User Defaults Storage/MASDictionaryTransformer.h"; sourceTree = ""; }; - 3622945DEBFCB14514027A236BDFC74C /* UISwitch+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UISwitch+Rx.swift"; path = "RxCocoa/iOS/UISwitch+Rx.swift"; sourceTree = ""; }; - 3677CB82C594C5820F17431AA45C5C87 /* Zip+Collection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Zip+Collection.swift"; path = "RxSwift/Observables/Zip+Collection.swift"; sourceTree = ""; }; - 3685B6DE4DF41097400DA11AA41A500B /* RxSwift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxSwift-prefix.pch"; sourceTree = ""; }; - 36C45F96BE0AE01F3BB2C90370A73616 /* Infallible+Bind.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Infallible+Bind.swift"; path = "RxCocoa/Common/Infallible+Bind.swift"; sourceTree = ""; }; - 36E9C273C636D7A0C559787BD1FABA68 /* GCDWebServerDataRequest.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCDWebServerDataRequest.h; path = GCDWebServer/Requests/GCDWebServerDataRequest.h; sourceTree = ""; }; - 370A313E34AF66CB8D7437ABDC3FB7F8 /* Infallible.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Infallible.swift; path = RxSwift/Traits/Infallible/Infallible.swift; sourceTree = ""; }; - 38724BD70D1712C03FA9B7A4C417144D /* ControlEvent.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ControlEvent.swift; path = RxCocoa/Traits/ControlEvent.swift; sourceTree = ""; }; - 38A0B431980745BE7A67D566D79E240A /* HistoricalSchedulerTimeConverter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HistoricalSchedulerTimeConverter.swift; path = RxSwift/Schedulers/HistoricalSchedulerTimeConverter.swift; sourceTree = ""; }; - 38A6B331CD11EA3ADC9BE7CFD5DE99DA /* RxRelay.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = RxRelay.modulemap; sourceTree = ""; }; - 392538EA12C4E3008D6EF1ABB226B3BF /* GCDWebServerFileRequest.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GCDWebServerFileRequest.m; path = GCDWebServer/Requests/GCDWebServerFileRequest.m; sourceTree = ""; }; - 3949A4BE0C4C31915E5A812146DB23B9 /* DistinctUntilChanged.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DistinctUntilChanged.swift; path = RxSwift/Observables/DistinctUntilChanged.swift; sourceTree = ""; }; - 39D9FF9E1CBB62DA6FC1910AA45EB039 /* RxTabBarControllerDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTabBarControllerDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxTabBarControllerDelegateProxy.swift; sourceTree = ""; }; - 3AC418FEB3CC60F42D6A18E6151C871A /* RxWKNavigationDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxWKNavigationDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxWKNavigationDelegateProxy.swift; sourceTree = ""; }; - 3B85D80911EDFC7DD402EBEB3A05169A /* RetryPolicy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RetryPolicy.swift; path = Source/RetryPolicy.swift; sourceTree = ""; }; - 3BAD385D5CDC39C1AE6584A123D2DFC4 /* _RX.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _RX.h; path = RxCocoa/Runtime/include/_RX.h; sourceTree = ""; }; - 3BE91EC45C71C190D532DC351F5E724D /* CompositeDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CompositeDisposable.swift; path = RxSwift/Disposables/CompositeDisposable.swift; sourceTree = ""; }; - 3ED0602BE820AA0F7B2D99CBFED4C1F0 /* Create.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Create.swift; path = RxSwift/Observables/Create.swift; sourceTree = ""; }; - 403ABCCF5634DCD99A376EAA601F828E /* HTTPMethod.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HTTPMethod.swift; path = Source/HTTPMethod.swift; sourceTree = ""; }; - 40573DCBFB24CA15F7D6C33B5C73162F /* Infallible+CombineLatest+arity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Infallible+CombineLatest+arity.swift"; path = "RxSwift/Traits/Infallible/Infallible+CombineLatest+arity.swift"; sourceTree = ""; }; - 408AEB2CFB972D5D82E41BB027E6686C /* SerialDispatchQueueScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SerialDispatchQueueScheduler.swift; path = RxSwift/Schedulers/SerialDispatchQueueScheduler.swift; sourceTree = ""; }; - 40FC23633FFFBBD0FA165FB284958F8C /* RecursiveScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RecursiveScheduler.swift; path = RxSwift/Schedulers/RecursiveScheduler.swift; sourceTree = ""; }; - 41ADA85A38ECDBBD122B707DA599E641 /* DispatchQueue+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DispatchQueue+Alamofire.swift"; path = "Source/DispatchQueue+Alamofire.swift"; sourceTree = ""; }; - 4338C646A92E1539E9BED963FC618602 /* ObservableType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObservableType.swift; path = RxSwift/ObservableType.swift; sourceTree = ""; }; - 43D1B54DDFE366EA8E657D1CFA2A5349 /* Protected.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Protected.swift; path = Source/Protected.swift; sourceTree = ""; }; - 4412635C50524157DDF38FA0CB197F4A /* Binder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Binder.swift; path = RxSwift/Binder.swift; sourceTree = ""; }; - 441E899D371A5638D8CBD0A21A8CCA61 /* UIScrollView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIScrollView+Rx.swift"; path = "RxCocoa/iOS/UIScrollView+Rx.swift"; sourceTree = ""; }; - 44775F4816D20EB134F1DBAB43BE0B3A /* Filter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Filter.swift; path = RxSwift/Observables/Filter.swift; sourceTree = ""; }; - 44D9E4509154BFFEBEA9AEA0C935EC9E /* SubjectType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SubjectType.swift; path = RxSwift/Subjects/SubjectType.swift; sourceTree = ""; }; - 4504CA755CE81F89F9F165BF93126D21 /* es.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = es.lproj; path = Resources/es.lproj; sourceTree = ""; }; - 45BF55923F2D3657D9D5420E606B641F /* Repeat.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Repeat.swift; path = RxSwift/Observables/Repeat.swift; sourceTree = ""; }; - 46002374E8C8C6F2127C7C9A6DFEF743 /* MASShortcutBinder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcutBinder.m; path = "Framework/User Defaults Storage/MASShortcutBinder.m"; sourceTree = ""; }; - 4618A8C418D70264404BBAF10EE3A1F4 /* ObservableConvertibleType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObservableConvertibleType.swift; path = RxSwift/ObservableConvertibleType.swift; sourceTree = ""; }; - 466B399C2E7FFAA61B709F2AB447ECDF /* UISlider+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UISlider+Rx.swift"; path = "RxCocoa/iOS/UISlider+Rx.swift"; sourceTree = ""; }; - 4673D1BC54F57F490E2D3352F6BA1B73 /* VirtualTimeConverterType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = VirtualTimeConverterType.swift; path = RxSwift/Schedulers/VirtualTimeConverterType.swift; sourceTree = ""; }; - 46A83A815027A06FB7A8AB2CEDF56368 /* UIDatePicker+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIDatePicker+Rx.swift"; path = "RxCocoa/iOS/UIDatePicker+Rx.swift"; sourceTree = ""; }; - 46DA81F6288F2733B7F27CCDE97EA2C4 /* MASLocalization.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASLocalization.m; path = Framework/UI/MASLocalization.m; sourceTree = ""; }; - 47291D90953698297410B0C37E619402 /* URLRequest+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URLRequest+Alamofire.swift"; path = "Source/URLRequest+Alamofire.swift"; sourceTree = ""; }; - 474547C10494F37402A98A0BFC7E6288 /* RxSearchControllerDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxSearchControllerDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxSearchControllerDelegateProxy.swift; sourceTree = ""; }; - 4752AFB18B745CA95D95FB7457EAA1C4 /* RxCocoa-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "RxCocoa-dummy.m"; sourceTree = ""; }; - 4764F518EAB30C5EA82C03A5607ED7AF /* Error.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Error.swift; path = RxSwift/Observables/Error.swift; sourceTree = ""; }; - 47EB7F9271D4EAE5B4A31D5D0194BECC /* GroupBy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GroupBy.swift; path = RxSwift/Observables/GroupBy.swift; sourceTree = ""; }; - 485A8E801F2DA21AB5D16808AE1B4887 /* ReplayRelay.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ReplayRelay.swift; path = RxRelay/ReplayRelay.swift; sourceTree = ""; }; - 48CB9D3553F121F84DBB750A8FBE0F3D /* ResponseSerialization.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ResponseSerialization.swift; path = Source/ResponseSerialization.swift; sourceTree = ""; }; - 4946CBDE2CD13F181402416264EBF61D /* RxSwift-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "RxSwift-Info.plist"; sourceTree = ""; }; - 494A67061DAFFD52534BC4699A8DF637 /* Map.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Map.swift; path = RxSwift/Observables/Map.swift; sourceTree = ""; }; - 494FD3BF9675BD2ADCE4731FED65B5FF /* AddRef.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AddRef.swift; path = RxSwift/Observables/AddRef.swift; sourceTree = ""; }; - 4A70BE8C07BCE9C6D6F47AC73225C959 /* Pods-proxy_conf_helper.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-proxy_conf_helper.release.xcconfig"; sourceTree = ""; }; - 4A797B2A249C56CB61DB60A3FEA31FD2 /* en.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = en.lproj; path = Resources/en.lproj; sourceTree = ""; }; - 4C0E4BDE3E30AF8C9062AFAD9C3AEA28 /* ControlEvent+Driver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ControlEvent+Driver.swift"; path = "RxCocoa/Traits/Driver/ControlEvent+Driver.swift"; sourceTree = ""; }; - 4C9EBFDB861299F7DC1241C7FCFF00DD /* NSObject+Rx+RawRepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSObject+Rx+RawRepresentable.swift"; path = "RxCocoa/Foundation/NSObject+Rx+RawRepresentable.swift"; sourceTree = ""; }; - 4E0CDE6403F2AF9E108FF190F90FA9FF /* EventMonitor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EventMonitor.swift; path = Source/EventMonitor.swift; sourceTree = ""; }; - 4F401550E51DCC5F5746B99EC564065B /* SharedSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SharedSequence.swift; path = RxCocoa/Traits/SharedSequence/SharedSequence.swift; sourceTree = ""; }; - 4FDB60114950AF3BF06EF9DA0AF9E5AC /* Producer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Producer.swift; path = RxSwift/Observables/Producer.swift; sourceTree = ""; }; - 4FF704B43D944C2399606B76A430F1A6 /* Platform.Linux.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Platform.Linux.swift; path = Platform/Platform.Linux.swift; sourceTree = ""; }; - 506B13C445D67D7231C25641361EE5A1 /* UIRefreshControl+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIRefreshControl+Rx.swift"; path = "RxCocoa/iOS/UIRefreshControl+Rx.swift"; sourceTree = ""; }; - 5158C591583049B150EC9F57DC2FA656 /* Optional.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Optional.swift; path = RxSwift/Observables/Optional.swift; sourceTree = ""; }; - 51E7C258B34B55C44CAA679574F0B5E1 /* UITableView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UITableView+Rx.swift"; path = "RxCocoa/iOS/UITableView+Rx.swift"; sourceTree = ""; }; - 5219820998BC7D8238F0F05F90A3D96F /* Maybe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Maybe.swift; path = RxSwift/Traits/PrimitiveSequence/Maybe.swift; sourceTree = ""; }; - 52626495FA7375A2A4753E3EC16FB26C /* AsyncLock.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AsyncLock.swift; path = RxSwift/Concurrency/AsyncLock.swift; sourceTree = ""; }; - 52786C2AA26607ED32FA242D407DEC3D /* RxRelay-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "RxRelay-Info.plist"; sourceTree = ""; }; - 52DFCC55A239674DEF17871D293D227C /* RxNavigationControllerDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxNavigationControllerDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxNavigationControllerDelegateProxy.swift; sourceTree = ""; }; - 530CEAEC9F4BC5F2EC9C9534779927A3 /* RxMutableBox.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxMutableBox.swift; path = RxSwift/RxMutableBox.swift; sourceTree = ""; }; - 531091EE9FF408558B83A1E053360F67 /* RxTextViewDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTextViewDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxTextViewDelegateProxy.swift; sourceTree = ""; }; - 53EB3CB0FCC5ABA4F18B576E6BA4EB1F /* SchedulerType+SharedSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "SchedulerType+SharedSequence.swift"; path = "RxCocoa/Traits/SharedSequence/SchedulerType+SharedSequence.swift"; sourceTree = ""; }; - 543DFE92FBC6235F6826EF38928A7C08 /* First.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = First.swift; path = RxSwift/Observables/First.swift; sourceTree = ""; }; - 54F202B17AB2C7DC4FEC3F1CF2B5FD57 /* KVORepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KVORepresentable.swift; path = RxCocoa/Foundation/KVORepresentable.swift; sourceTree = ""; }; - 555231B7293881D7D76CA80C82AABA2B /* Debug.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Debug.swift; path = RxSwift/Observables/Debug.swift; sourceTree = ""; }; - 5554F4E6979C7DDD1E00F81CB94D474D /* RecursiveLock.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RecursiveLock.swift; path = Platform/RecursiveLock.swift; sourceTree = ""; }; - 558A95B0EAE7FAFDFCC334A1E9277C19 /* TailRecursiveSink.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TailRecursiveSink.swift; path = RxSwift/Observers/TailRecursiveSink.swift; sourceTree = ""; }; - 55F5FEB17D952CAA64A6B7DE90D7E47D /* GCDWebServer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GCDWebServer.m; path = GCDWebServer/Core/GCDWebServer.m; sourceTree = ""; }; - 57BEC3094A7FB642608645E131DA83D4 /* GCDWebServerHTTPStatusCodes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCDWebServerHTTPStatusCodes.h; path = GCDWebServer/Core/GCDWebServerHTTPStatusCodes.h; sourceTree = ""; }; - 5800B274C19C06FB1CA12AC039704852 /* NSTextView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSTextView+Rx.swift"; path = "RxCocoa/macOS/NSTextView+Rx.swift"; sourceTree = ""; }; - 5874107EF4581DA493B60BBCFE422D1C /* NSSlider+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSSlider+Rx.swift"; path = "RxCocoa/macOS/NSSlider+Rx.swift"; sourceTree = ""; }; - 5878F666B9410A53C5BBE1778D1B2CCE /* ControlProperty.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ControlProperty.swift; path = RxCocoa/Traits/ControlProperty.swift; sourceTree = ""; }; - 5BC543740C092C697A08396093A0F7BD /* GCDWebServerFileResponse.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GCDWebServerFileResponse.m; path = GCDWebServer/Responses/GCDWebServerFileResponse.m; sourceTree = ""; }; - 5C0C485AB4EA81F3E9128F65E9AC66CA /* Pods-ShadowsocksX-NGTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ShadowsocksX-NGTests.release.xcconfig"; sourceTree = ""; }; - 5CA0D236EFCE9E4E77F9A2B2A0AF3FC4 /* Merge.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Merge.swift; path = RxSwift/Observables/Merge.swift; sourceTree = ""; }; - 5CE7CD3C7A16D2E9341BBBAB18D5D8DC /* Event.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Event.swift; path = RxSwift/Event.swift; sourceTree = ""; }; - 5D0A2A589A608DD00CA24C86BCD46E62 /* URLEncodedFormEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = URLEncodedFormEncoder.swift; path = Source/URLEncodedFormEncoder.swift; sourceTree = ""; }; - 5D797E9A5C5782CE845840781FA1CC81 /* Alamofire.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Alamofire.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 5D99DA86D8CBFFCB2E7FD40BC42568F3 /* Decode.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Decode.swift; path = RxSwift/Observables/Decode.swift; sourceTree = ""; }; - 5DA6A1DA8589C7192C8BFDBC3F4A9913 /* ControlTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ControlTarget.swift; path = RxCocoa/Common/ControlTarget.swift; sourceTree = ""; }; - 5E698A2854CB4D9E919B55523EB57D1A /* Driver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Driver.swift; path = RxCocoa/Traits/Driver/Driver.swift; sourceTree = ""; }; - 5EE446AD8C625612BFF0E37E4419E0FD /* BRLOptionParser.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = BRLOptionParser.debug.xcconfig; sourceTree = ""; }; - 605C26B2F1FFA16F0E85E33F5CC526EC /* MASShortcutMonitor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcutMonitor.m; path = Framework/Monitoring/MASShortcutMonitor.m; sourceTree = ""; }; - 608BE9EFB078FCC2348EF2782C265D92 /* UIPickerView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIPickerView+Rx.swift"; path = "RxCocoa/iOS/UIPickerView+Rx.swift"; sourceTree = ""; }; - 61C23DB60A84900CD4BDA2F5EE2A0865 /* libPods-proxy_conf_helper.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-proxy_conf_helper.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 62F5D09616527A0713F24DF416BEC64F /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/Carbon.framework; sourceTree = DEVELOPER_DIR; }; - 6327835932D3C270A640C0C76A860EB8 /* TakeWithPredicate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TakeWithPredicate.swift; path = RxSwift/Observables/TakeWithPredicate.swift; sourceTree = ""; }; - 636937DE6DA6CE01D7E94282A16BC9D9 /* Observable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Observable.swift; path = RxSwift/Observable.swift; sourceTree = ""; }; - 636D1EE61F0E0E367F486461F8E0DF54 /* AnonymousObserver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnonymousObserver.swift; path = RxSwift/Observers/AnonymousObserver.swift; sourceTree = ""; }; - 638797412ABBF2F7725016AF4B056309 /* _RXObjCRuntime.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = _RXObjCRuntime.m; path = RxCocoa/Runtime/_RXObjCRuntime.m; sourceTree = ""; }; - 65D8FEBF2028BCC7758A666F2A35989A /* Empty.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Empty.swift; path = RxSwift/Observables/Empty.swift; sourceTree = ""; }; - 661DD8158386E15481E17DE6E2FA1882 /* Timeout.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Timeout.swift; path = RxSwift/Observables/Timeout.swift; sourceTree = ""; }; - 66C7F789300668AEDFA53AEA1392C48B /* Concat.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Concat.swift; path = RxSwift/Observables/Concat.swift; sourceTree = ""; }; - 66D1DACD1512DCFE82BC525C443DA8A5 /* RxTabBarDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTabBarDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxTabBarDelegateProxy.swift; sourceTree = ""; }; - 683395CCE980D15405934DC5E2BCD682 /* LockOwnerType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LockOwnerType.swift; path = RxSwift/Concurrency/LockOwnerType.swift; sourceTree = ""; }; - 684F8C697CD894D0F5680EE542AC32E9 /* ItemEvents.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ItemEvents.swift; path = RxCocoa/iOS/Events/ItemEvents.swift; sourceTree = ""; }; - 68C9C3CF6142E1B32695BC562ECAC427 /* BRLOptionParser.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = BRLOptionParser.m; path = BRLOptionParser/BRLOptionParser.m; sourceTree = ""; }; - 68D133622632E3F0C62D1F74D188EA7E /* CombineLatest+Collection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "CombineLatest+Collection.swift"; path = "RxSwift/Observables/CombineLatest+Collection.swift"; sourceTree = ""; }; - 6985BD62945B0A86382437BC1758C282 /* _RXObjCRuntime.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _RXObjCRuntime.h; path = RxCocoa/Runtime/include/_RXObjCRuntime.h; sourceTree = ""; }; - 6A2828DE92C9CEECE9FB19F2EE763305 /* VirtualTimeScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = VirtualTimeScheduler.swift; path = RxSwift/Schedulers/VirtualTimeScheduler.swift; sourceTree = ""; }; - 6AD4414199F479D544CBF1FFF3FB45E4 /* _RXDelegateProxy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = _RXDelegateProxy.m; path = RxCocoa/Runtime/_RXDelegateProxy.m; sourceTree = ""; }; - 6B37E46EBF28CB6542B58754F09D8AAA /* RxTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTarget.swift; path = RxCocoa/Common/RxTarget.swift; sourceTree = ""; }; - 6B668707F7C66384A3BB8BC4FE3F41E6 /* MASShortcut-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "MASShortcut-dummy.m"; sourceTree = ""; }; - 6B9491CF676F85A85C4F0987D38F9051 /* Shortcut.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Shortcut.h; path = Framework/Shortcut.h; sourceTree = ""; }; - 6D0B40D5A184825074ECC549693CAF02 /* GCDWebServerConnection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCDWebServerConnection.h; path = GCDWebServer/Core/GCDWebServerConnection.h; sourceTree = ""; }; - 6D742A8B753D54115AD3C6D293B64276 /* UINavigationController+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UINavigationController+Rx.swift"; path = "RxCocoa/iOS/UINavigationController+Rx.swift"; sourceTree = ""; }; - 6D8A09F0F8EDB0B1A568AA29A33D62EA /* AFError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AFError.swift; path = Source/AFError.swift; sourceTree = ""; }; - 6DA5F27AAEF9B366933CB017942EFAA8 /* HistoricalScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HistoricalScheduler.swift; path = RxSwift/Schedulers/HistoricalScheduler.swift; sourceTree = ""; }; - 6DAFFC9484B606CC3A8583B2085B7957 /* SerialDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SerialDisposable.swift; path = RxSwift/Disposables/SerialDisposable.swift; sourceTree = ""; }; - 6DFC3F4E49698472F1AA8DE21B1BD0F2 /* NSButton+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSButton+Rx.swift"; path = "RxCocoa/macOS/NSButton+Rx.swift"; sourceTree = ""; }; - 6EB5DBBABE4FD6FFF0223AC1BC4674DB /* KVORepresentable+Swift.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "KVORepresentable+Swift.swift"; path = "RxCocoa/Foundation/KVORepresentable+Swift.swift"; sourceTree = ""; }; - 70C291AA3C3CEE619534F472C4F04882 /* MASShortcut.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MASShortcut.debug.xcconfig; sourceTree = ""; }; - 718741562429DAE6AA6DC455ED6883D4 /* Errors.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Errors.swift; path = RxSwift/Errors.swift; sourceTree = ""; }; - 726DEA3A84065F8E12FDE5617447B366 /* MASShortcutValidator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcutValidator.m; path = Framework/Model/MASShortcutValidator.m; sourceTree = ""; }; - 72A57876EDEB24ADDFE06DD482CE250C /* Pods-ShadowsocksX-NGTests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-ShadowsocksX-NGTests-umbrella.h"; sourceTree = ""; }; - 72D91E08E6C75E1F0DBACD4FF3CA2F55 /* ShareReplayScope.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ShareReplayScope.swift; path = RxSwift/Observables/ShareReplayScope.swift; sourceTree = ""; }; - 73118DDBDD8A625213B479BD40C4B9CE /* TakeLast.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TakeLast.swift; path = RxSwift/Observables/TakeLast.swift; sourceTree = ""; }; - 73327356D8055C270C5AFBAEE0D202DD /* MASKeyCodes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASKeyCodes.h; path = Framework/Model/MASKeyCodes.h; sourceTree = ""; }; - 74656C1BF53AED56A45CDA8600A787D1 /* Pods-proxy_conf_helper-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-proxy_conf_helper-acknowledgements.markdown"; sourceTree = ""; }; - 74E6FB11E3F38127740B54FF3C72D1EF /* _RX.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = _RX.m; path = RxCocoa/Runtime/_RX.m; sourceTree = ""; }; - 758B67811993E4C5163D7637EDBB6CFD /* PublishRelay+Signal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "PublishRelay+Signal.swift"; path = "RxCocoa/Traits/Signal/PublishRelay+Signal.swift"; sourceTree = ""; }; - 75EA425CE2A4DBDDEB580C7303DD2454 /* Alamofire.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Alamofire.debug.xcconfig; sourceTree = ""; }; - 7720FEFA630547FDE17C156840E36CC6 /* MASShortcut-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MASShortcut-prefix.pch"; sourceTree = ""; }; - 77B5C856C653A9586105526C4341767A /* RxSwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxSwift-umbrella.h"; sourceTree = ""; }; - 77E73C4E3CAF9AD8FAE2EA9130D6A37E /* GCDWebServerFileResponse.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCDWebServerFileResponse.h; path = GCDWebServer/Responses/GCDWebServerFileResponse.h; sourceTree = ""; }; - 78275DA82CA025902C1D6FAF39BC9403 /* RxCollectionViewDataSourcePrefetchingProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxCollectionViewDataSourcePrefetchingProxy.swift; path = RxCocoa/iOS/Proxies/RxCollectionViewDataSourcePrefetchingProxy.swift; sourceTree = ""; }; - 7A4A724DBFF9C1C260A76A4B104F3B1E /* MASShortcut.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcut.m; path = Framework/Model/MASShortcut.m; sourceTree = ""; }; - 7B00813C768C553C089DAF0C1900799B /* NSObject+Rx+KVORepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSObject+Rx+KVORepresentable.swift"; path = "RxCocoa/Foundation/NSObject+Rx+KVORepresentable.swift"; sourceTree = ""; }; - 7B00E954AA2FCFDF5ACDEC8CD8C6941E /* ObserverType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObserverType.swift; path = RxSwift/ObserverType.swift; sourceTree = ""; }; - 7B58732AA1AF7EA39B29A8BE85721F26 /* RxScrollViewDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxScrollViewDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxScrollViewDelegateProxy.swift; sourceTree = ""; }; - 7BE4993AB90D97D332E61EB54E0C3C9A /* MASHotKey.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASHotKey.m; path = Framework/Monitoring/MASHotKey.m; sourceTree = ""; }; - 7C471325C18D493A8244DEB1563B18B6 /* MASShortcutView+Bindings.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "MASShortcutView+Bindings.m"; path = "Framework/UI/MASShortcutView+Bindings.m"; sourceTree = ""; }; - 7C73921B2C710D3814A33EF328D04D20 /* MASShortcutView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcutView.m; path = Framework/UI/MASShortcutView.m; sourceTree = ""; }; - 7D680C4252D37F732EE2D1BB9AB911DA /* AsMaybe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AsMaybe.swift; path = RxSwift/Observables/AsMaybe.swift; sourceTree = ""; }; - 7DF9FA6B1D40855A99145762147C1690 /* ImmediateSchedulerType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImmediateSchedulerType.swift; path = RxSwift/ImmediateSchedulerType.swift; sourceTree = ""; }; - 7DFEE31FDCAA3B9A85119C45EE5BF376 /* GCDWebServerDataRequest.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GCDWebServerDataRequest.m; path = GCDWebServer/Requests/GCDWebServerDataRequest.m; sourceTree = ""; }; - 7EB9FE74C8220E21EC9A5A77098E9152 /* RxCocoa.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RxCocoa.h; path = RxCocoa/RxCocoa.h; sourceTree = ""; }; - 809C5FAB588354C9BA37DC3EAB8CB45C /* RxSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RxSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 80B5C55F7279E38D15E19E9DEDDEDE7B /* RequestInterceptor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestInterceptor.swift; path = Source/RequestInterceptor.swift; sourceTree = ""; }; - 817D9055D7659CAC86800D119F65E0F4 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/CFNetwork.framework; sourceTree = DEVELOPER_DIR; }; - 82A2597C8D9860F95F40565C0631A47D /* MASLocalization.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASLocalization.h; path = Framework/UI/MASLocalization.h; sourceTree = ""; }; - 834EB5666F2D27EDBD25C600C80DF7CE /* ObservableConvertibleType+Infallible.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ObservableConvertibleType+Infallible.swift"; path = "RxSwift/Traits/Infallible/ObservableConvertibleType+Infallible.swift"; sourceTree = ""; }; - 8369906FA14B85B8271089FAAA1E4694 /* Disposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Disposable.swift; path = RxSwift/Disposable.swift; sourceTree = ""; }; - 83899FE1EDE6090C8B2F4703A7895330 /* Pods-ShadowsocksX-NGTests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-ShadowsocksX-NGTests.modulemap"; sourceTree = ""; }; - 83FE5C08C0F9F63C9A7D2B71EF9F0864 /* URLSessionConfiguration+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URLSessionConfiguration+Alamofire.swift"; path = "Source/URLSessionConfiguration+Alamofire.swift"; sourceTree = ""; }; - 840A431555445FF451B4B74E7A8DDCF4 /* AnyObserver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnyObserver.swift; path = RxSwift/AnyObserver.swift; sourceTree = ""; }; - 848DD5BA5CA758D1F00A7F6F947019EB /* Alamofire.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Alamofire.release.xcconfig; sourceTree = ""; }; - 855607DC318E2CF3120B3C70565140A0 /* Window.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Window.swift; path = RxSwift/Observables/Window.swift; sourceTree = ""; }; - 8565AD8EBB9A4E532AF93D887B586876 /* Cancelable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Cancelable.swift; path = RxSwift/Cancelable.swift; sourceTree = ""; }; - 864BF009AFF7BFF4D8B68869FC885957 /* StartWith.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StartWith.swift; path = RxSwift/Observables/StartWith.swift; sourceTree = ""; }; - 8663196F6A9678BFC77A8E46F8666C75 /* ScheduledItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ScheduledItem.swift; path = RxSwift/Schedulers/Internal/ScheduledItem.swift; sourceTree = ""; }; - 866C21955F27EBD7A49148F5E63A6E7E /* libBRLOptionParser.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libBRLOptionParser.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 867FD5BBBCAC1E98FE144867305F8FEF /* MASKeyMasks.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASKeyMasks.h; path = Framework/Model/MASKeyMasks.h; sourceTree = ""; }; - 8752D17209EE8AAD7681107D6444113F /* Pods-proxy_conf_helper-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-proxy_conf_helper-dummy.m"; sourceTree = ""; }; - 877FA6BB936631CD8F2CA0DFFF6EFC9C /* UITextField+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UITextField+Rx.swift"; path = "RxCocoa/iOS/UITextField+Rx.swift"; sourceTree = ""; }; - 87A94DCCD78781BAE448DEA818B26DE4 /* SharedSequence+Operators+arity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "SharedSequence+Operators+arity.swift"; path = "RxCocoa/Traits/SharedSequence/SharedSequence+Operators+arity.swift"; sourceTree = ""; }; - 886072F083033D493924A8BE652713ED /* Generate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Generate.swift; path = RxSwift/Observables/Generate.swift; sourceTree = ""; }; - 89066EEDE0D03A9B328DADDC9344CC13 /* GCDWebServerResponse.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCDWebServerResponse.h; path = GCDWebServer/Core/GCDWebServerResponse.h; sourceTree = ""; }; - 8937D9E4BB1CD1D979DFF21019B4D814 /* MASHotKey.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASHotKey.h; path = Framework/Monitoring/MASHotKey.h; sourceTree = ""; }; - 897003218412D0C779A54DAAD7D2A4EE /* WithUnretained.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WithUnretained.swift; path = RxSwift/Observables/WithUnretained.swift; sourceTree = ""; }; - 89A41E2A66DF6A8547AFAB72FE74B6A2 /* UIActivityIndicatorView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIActivityIndicatorView+Rx.swift"; path = "RxCocoa/iOS/UIActivityIndicatorView+Rx.swift"; sourceTree = ""; }; - 8A2C23CF743A94075196D7A4F419F5A4 /* Debounce.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Debounce.swift; path = RxSwift/Observables/Debounce.swift; sourceTree = ""; }; - 8AE4AAE5FF0F7FEDE2C8D5FB08A1AE4F /* DelaySubscription.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DelaySubscription.swift; path = RxSwift/Observables/DelaySubscription.swift; sourceTree = ""; }; - 8C1810C471075F4E78D93E645BD7F63B /* MASShortcut.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = MASShortcut.modulemap; sourceTree = ""; }; - 8D796FDCC7398C88D7B835BD89700D56 /* BehaviorRelay.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BehaviorRelay.swift; path = RxRelay/BehaviorRelay.swift; sourceTree = ""; }; - 8E4505859B317DCDCC426973F6C7153D /* Signal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Signal.swift; path = RxCocoa/Traits/Signal/Signal.swift; sourceTree = ""; }; - 8E796A67AE756E845646324A31731334 /* MASShortcutValidator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcutValidator.h; path = Framework/Model/MASShortcutValidator.h; sourceTree = ""; }; - 8E801F2049749D5BA709EAE3A2028661 /* Platform.Darwin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Platform.Darwin.swift; path = Platform/Platform.Darwin.swift; sourceTree = ""; }; - 8ED0DC48A18FD32A95BE8B28D715172C /* UISearchController+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UISearchController+Rx.swift"; path = "RxCocoa/iOS/UISearchController+Rx.swift"; sourceTree = ""; }; - 8F90CD66F125C28F8983AFCFA7DF6607 /* de.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = de.lproj; path = Resources/de.lproj; sourceTree = ""; }; - 9029CBEE1EB8EBFDFCC3F55CEC98E088 /* Request.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Request.swift; path = Source/Request.swift; sourceTree = ""; }; - 904A920F44C4C4A18874A6A62A3ED759 /* SkipWhile.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SkipWhile.swift; path = RxSwift/Observables/SkipWhile.swift; sourceTree = ""; }; - 90E9219489B97BDFE17BA3231CC465FC /* ServerTrustEvaluation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerTrustEvaluation.swift; path = Source/ServerTrustEvaluation.swift; sourceTree = ""; }; - 92B4BB091693150E5B1FCC6987683C6F /* Pods-ShadowsocksX-NG.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ShadowsocksX-NG.release.xcconfig"; sourceTree = ""; }; - 930EB20F00FF48CAF9B19505BC219504 /* MASShortcut-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MASShortcut-umbrella.h"; sourceTree = ""; }; - 95A61E2BD71E9AE873207EFE8994362B /* SynchronizedOnType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SynchronizedOnType.swift; path = RxSwift/Concurrency/SynchronizedOnType.swift; sourceTree = ""; }; - 95B33DD3F11E0587A32ECE709173E4EF /* RxTextStorageDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTextStorageDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxTextStorageDelegateProxy.swift; sourceTree = ""; }; - 95F05E167015F6A202D2BEB9437AE766 /* RxCocoaRuntime.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RxCocoaRuntime.h; path = RxCocoa/Runtime/include/RxCocoaRuntime.h; sourceTree = ""; }; - 960C49C6C3C5E2554CA3CD8EB86B61AC /* Queue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Queue.swift; path = Platform/DataStructures/Queue.swift; sourceTree = ""; }; - 961D7CAE484B6E4929A7BE5B048D29B5 /* RxPickerViewDataSourceType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxPickerViewDataSourceType.swift; path = RxCocoa/iOS/Protocols/RxPickerViewDataSourceType.swift; sourceTree = ""; }; - 962EFFE0B39AFE334DBCAF81B4DBFE56 /* GCDWebServerFileRequest.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCDWebServerFileRequest.h; path = GCDWebServer/Requests/GCDWebServerFileRequest.h; sourceTree = ""; }; - 96C80DBAD0A8D59912E005E60636A935 /* Pods-ShadowsocksX-NG-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-ShadowsocksX-NG-Info.plist"; sourceTree = ""; }; - 96D93775EA307729314581C5C539C487 /* ReplaySubject.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ReplaySubject.swift; path = RxSwift/Subjects/ReplaySubject.swift; sourceTree = ""; }; - 97319F4B64360DC3D794BD7B57BC9936 /* GCDWebServerURLEncodedFormRequest.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCDWebServerURLEncodedFormRequest.h; path = GCDWebServer/Requests/GCDWebServerURLEncodedFormRequest.h; sourceTree = ""; }; - 97D6BD38BB9E0F241C3C82A118E7F253 /* ControlProperty+Driver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ControlProperty+Driver.swift"; path = "RxCocoa/Traits/Driver/ControlProperty+Driver.swift"; sourceTree = ""; }; - 98B151536C20EA366FDBE99C5A8BB7A5 /* MainScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MainScheduler.swift; path = RxSwift/Schedulers/MainScheduler.swift; sourceTree = ""; }; - 98EF0EFA057CC202BD041F55B091661A /* BehaviorRelay+Driver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "BehaviorRelay+Driver.swift"; path = "RxCocoa/Traits/Driver/BehaviorRelay+Driver.swift"; sourceTree = ""; }; - 996DFC2DB5C2F37F0E623EB885F5DEB5 /* Session.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Session.swift; path = Source/Session.swift; sourceTree = ""; }; - 9A3F0ED147035005ABA4D679F9E36A7B /* ru.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = ru.lproj; path = Resources/ru.lproj; sourceTree = ""; }; - 9A71B9958F30759ED2645E0DF9ADF314 /* Pods-ShadowsocksX-NG.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-ShadowsocksX-NG.debug.xcconfig"; sourceTree = ""; }; - 9B23D7AFD516825208E6CE9B362989DB /* Queue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Queue.swift; path = Platform/DataStructures/Queue.swift; sourceTree = ""; }; - 9C1FFDE936B5B805CB094F77E95A88FC /* UIControl+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIControl+Rx.swift"; path = "RxCocoa/iOS/UIControl+Rx.swift"; sourceTree = ""; }; - 9C3A35E7DD83A1437478608A9F2EF44C /* ControlEvent+Signal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ControlEvent+Signal.swift"; path = "RxCocoa/Traits/Signal/ControlEvent+Signal.swift"; sourceTree = ""; }; - 9CF5ADA01C91A2DF993314D6CC9C63D3 /* MultipartUpload.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MultipartUpload.swift; path = Source/MultipartUpload.swift; sourceTree = ""; }; - 9D407239EE1987EFBB2A7EB11F70BFCF /* BRLOptionParser-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "BRLOptionParser-prefix.pch"; sourceTree = ""; }; - 9D4701E49CFDE5F411CDFD316EDD3C70 /* UITabBarController+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UITabBarController+Rx.swift"; path = "RxCocoa/iOS/UITabBarController+Rx.swift"; sourceTree = ""; }; - 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; - 9EE8B6717B73CE07A9FAC17FFCB1BA91 /* GCDWebServerErrorResponse.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCDWebServerErrorResponse.h; path = GCDWebServer/Responses/GCDWebServerErrorResponse.h; sourceTree = ""; }; - 9EF2C4A08C5514586AFFBB5AE22A99ED /* ResourceBundle-MASShortcut-MASShortcut-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-MASShortcut-MASShortcut-Info.plist"; sourceTree = ""; }; - 9F666DF6A38D74980DF6F191509F4971 /* RxCocoaObjCRuntimeError+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "RxCocoaObjCRuntimeError+Extensions.swift"; path = "RxCocoa/Common/RxCocoaObjCRuntimeError+Extensions.swift"; sourceTree = ""; }; - 9F78589C2F1DDF07DF58CD22F6835B19 /* Combine.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Combine.swift; path = Source/Combine.swift; sourceTree = ""; }; - 9FA0DBB3C5358A6E4EF0C16145BB0F7E /* Zip.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Zip.swift; path = RxSwift/Observables/Zip.swift; sourceTree = ""; }; - A01C872DE26A61BFEF081FC71E72A0D0 /* RxRelay-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxRelay-prefix.pch"; sourceTree = ""; }; - A0791E5EB9ADBB88CEE0BCD83DA9502C /* SchedulerServices+Emulation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "SchedulerServices+Emulation.swift"; path = "RxSwift/Schedulers/SchedulerServices+Emulation.swift"; sourceTree = ""; }; - A111C3B36368413B50627674BB48E859 /* Completable+AndThen.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Completable+AndThen.swift"; path = "RxSwift/Traits/PrimitiveSequence/Completable+AndThen.swift"; sourceTree = ""; }; - A126CA25C01C17FEF1E4B62108855349 /* ConcurrentMainScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConcurrentMainScheduler.swift; path = RxSwift/Schedulers/ConcurrentMainScheduler.swift; sourceTree = ""; }; - A14B9E97BE00B01372727FA8DA9B10A3 /* _RXKVOObserver.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = _RXKVOObserver.m; path = RxCocoa/Runtime/_RXKVOObserver.m; sourceTree = ""; }; - A18A7F7794D2CC58900E95F6644D63E8 /* MASShortcutBinder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcutBinder.h; path = "Framework/User Defaults Storage/MASShortcutBinder.h"; sourceTree = ""; }; - A1D0AF20D0BF5465039BB88836A959B6 /* SkipUntil.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SkipUntil.swift; path = RxSwift/Observables/SkipUntil.swift; sourceTree = ""; }; - A20673B8CBA1827BCAE8A9CDEAF0CDC5 /* SwitchIfEmpty.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwitchIfEmpty.swift; path = RxSwift/Observables/SwitchIfEmpty.swift; sourceTree = ""; }; - A254689F2908346AD7387F063C24B41A /* ko.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = ko.lproj; path = Resources/ko.lproj; sourceTree = ""; }; - A269EEED1FC8BFDA5FCB004DC335F5C8 /* AtomicInt.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AtomicInt.swift; path = Platform/AtomicInt.swift; sourceTree = ""; }; - A2738BBB0867C27512A99A3C9DBB2F1E /* GCDWebServer-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "GCDWebServer-Info.plist"; sourceTree = ""; }; - A2B10B3F59B2394712B672A72C5827F0 /* SingleAsync.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SingleAsync.swift; path = RxSwift/Observables/SingleAsync.swift; sourceTree = ""; }; - A2B9727C5385989526550D8E1AC4649A /* MASShortcut.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcut.h; path = Framework/Model/MASShortcut.h; sourceTree = ""; }; - A2EEB1D58595D58C5DC8978116BE0648 /* MASShortcutView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcutView.h; path = Framework/UI/MASShortcutView.h; sourceTree = ""; }; - A2FFFF24B3AC3570742D7F2CCF2FE3C5 /* Infallible+Zip+arity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Infallible+Zip+arity.swift"; path = "RxSwift/Traits/Infallible/Infallible+Zip+arity.swift"; sourceTree = ""; }; - A32434EC299FDE302FFF9F31EB8735D0 /* RedirectHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RedirectHandler.swift; path = Source/RedirectHandler.swift; sourceTree = ""; }; - A3A89F3DBB03CFC012C901EB6D452A3B /* PriorityQueue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PriorityQueue.swift; path = Platform/DataStructures/PriorityQueue.swift; sourceTree = ""; }; - A3E96B8BC40FDC92B51E51B50F126573 /* Single.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Single.swift; path = RxSwift/Traits/PrimitiveSequence/Single.swift; sourceTree = ""; }; - A4177B545582D09C0D653414E6353741 /* SectionedViewDataSourceType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SectionedViewDataSourceType.swift; path = RxCocoa/Common/SectionedViewDataSourceType.swift; sourceTree = ""; }; - A4395BE2A0C53A82170A01602870453A /* GCDWebServerRequest.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCDWebServerRequest.h; path = GCDWebServer/Core/GCDWebServerRequest.h; sourceTree = ""; }; - A49E3489F755F888C3405824694827BF /* WithLatestFrom.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WithLatestFrom.swift; path = RxSwift/Observables/WithLatestFrom.swift; sourceTree = ""; }; - A4BB8686A6F85698D8AC03A77D188340 /* UITextView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UITextView+Rx.swift"; path = "RxCocoa/iOS/UITextView+Rx.swift"; sourceTree = ""; }; - A6415209F9685A39C6C1018082155EA5 /* CompactMap.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CompactMap.swift; path = RxSwift/Observables/CompactMap.swift; sourceTree = ""; }; - A8A33670952794CBD825EC26F1A98DBF /* _RXKVOObserver.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _RXKVOObserver.h; path = RxCocoa/Runtime/include/_RXKVOObserver.h; sourceTree = ""; }; - A8C417EB740CAC7F2602C6D8880E7737 /* PrimitiveSequence+Zip+arity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "PrimitiveSequence+Zip+arity.swift"; path = "RxSwift/Traits/PrimitiveSequence/PrimitiveSequence+Zip+arity.swift"; sourceTree = ""; }; - A907FA326D15CD08847B63032F80EB64 /* Pods-ShadowsocksX-NG-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-ShadowsocksX-NG-acknowledgements.markdown"; sourceTree = ""; }; - A94A0417121D2C31F7167E4A79EC5313 /* nl.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = nl.lproj; path = Resources/nl.lproj; sourceTree = ""; }; - AADC2D51259367D2BB2C73816E5A35CD /* RetryWhen.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RetryWhen.swift; path = RxSwift/Observables/RetryWhen.swift; sourceTree = ""; }; - AAFFAAB92EFEC042FEE2F851EF9C6CC0 /* NSControl+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSControl+Rx.swift"; path = "RxCocoa/macOS/NSControl+Rx.swift"; sourceTree = ""; }; - AB7765E1848A0449B3E3267F17DDE12E /* GCDWebServerDataResponse.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GCDWebServerDataResponse.m; path = GCDWebServer/Responses/GCDWebServerDataResponse.m; sourceTree = ""; }; - ABD89974F6EA342767735D559995D3FA /* Zip+arity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Zip+arity.swift"; path = "RxSwift/Observables/Zip+arity.swift"; sourceTree = ""; }; - AC4C66DE7DB1A4B525929AEF699AC3CE /* OperationQueueScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = OperationQueueScheduler.swift; path = RxSwift/Schedulers/OperationQueueScheduler.swift; sourceTree = ""; }; - ADC06A8D8266504D3FD0F38F5F1A87AD /* RxTableViewDataSourceProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTableViewDataSourceProxy.swift; path = RxCocoa/iOS/Proxies/RxTableViewDataSourceProxy.swift; sourceTree = ""; }; - AE4742C0047EC328BE64C1DF6D868CEF /* GCDWebServerStreamedResponse.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCDWebServerStreamedResponse.h; path = GCDWebServer/Responses/GCDWebServerStreamedResponse.h; sourceTree = ""; }; - AE6768B8A7BED83ED5C93BB3439EFFEF /* URLConvertible+URLRequestConvertible.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URLConvertible+URLRequestConvertible.swift"; path = "Source/URLConvertible+URLRequestConvertible.swift"; sourceTree = ""; }; - AF22EDE51D4C2AF18359CE03247D06F1 /* RxCocoa.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RxCocoa.release.xcconfig; sourceTree = ""; }; - B1816E3DFE7F11350A74B0C1F878F7FC /* RxCocoa.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxCocoa.swift; path = RxCocoa/RxCocoa.swift; sourceTree = ""; }; - B1F34EB08D07E2AF230CDA30F361889D /* ja.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = ja.lproj; path = Resources/ja.lproj; sourceTree = ""; }; - B25AD05D537735CCA21E1986D98F830E /* RxCollectionViewReactiveArrayDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxCollectionViewReactiveArrayDataSource.swift; path = RxCocoa/iOS/DataSources/RxCollectionViewReactiveArrayDataSource.swift; sourceTree = ""; }; - B265FABD755D21851D1C166921BB4A24 /* RxTableViewReactiveArrayDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTableViewReactiveArrayDataSource.swift; path = RxCocoa/iOS/DataSources/RxTableViewReactiveArrayDataSource.swift; sourceTree = ""; }; - B2BCE49AE180E28B89BBBE037DF32A2F /* zh-Hans.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "zh-Hans.lproj"; path = "Resources/zh-Hans.lproj"; sourceTree = ""; }; - B304846A96173EC0E0631D07751C0893 /* Sink.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Sink.swift; path = RxSwift/Observables/Sink.swift; sourceTree = ""; }; - B400BB6631F1C9F8534BE1CEF160097E /* GCDWebServer-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GCDWebServer-umbrella.h"; sourceTree = ""; }; - B5AEEDAA3124911175E2336A08227588 /* MASShortcutView+Bindings.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "MASShortcutView+Bindings.h"; path = "Framework/UI/MASShortcutView+Bindings.h"; sourceTree = ""; }; - B5B1AE9FCFABDD97172220DFDFE618E5 /* RxTableViewDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTableViewDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxTableViewDelegateProxy.swift; sourceTree = ""; }; - B5D8A52DE9A6385138A6D20CB5527DDB /* zh-Hant.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = "zh-Hant.lproj"; path = "Resources/zh-Hant.lproj"; sourceTree = ""; }; - B68B5F9FDDB0D41979766C1D549A8780 /* fr.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = fr.lproj; path = Resources/fr.lproj; sourceTree = ""; }; - B68C1052A3B51DBCF7D960F898AAFA95 /* GCDWebServer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = GCDWebServer.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - B7045A3758C33721435A4135DBC6A8AA /* SessionDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDelegate.swift; path = Source/SessionDelegate.swift; sourceTree = ""; }; - B797965188D07FBBF91BA7F69EC21D39 /* Pods-ShadowsocksX-NGTests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-ShadowsocksX-NGTests-Info.plist"; sourceTree = ""; }; - B81749D1C6130BC14B2386B76041124F /* GCDWebServer.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GCDWebServer.debug.xcconfig; sourceTree = ""; }; - B8D247C19100F15D54BFF5D93804C65E /* AsSingle.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AsSingle.swift; path = RxSwift/Observables/AsSingle.swift; sourceTree = ""; }; - B9215F3DCBD2FE1BDADCEF5D05219A48 /* RxCollectionViewDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxCollectionViewDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxCollectionViewDelegateProxy.swift; sourceTree = ""; }; - B97E5FCD7744551B43A8C353FD79E774 /* RefCountDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RefCountDisposable.swift; path = RxSwift/Disposables/RefCountDisposable.swift; sourceTree = ""; }; - BB1177638C48D2FB13DDFB46A70CD35D /* BehaviorSubject.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BehaviorSubject.swift; path = RxSwift/Subjects/BehaviorSubject.swift; sourceTree = ""; }; - BB63C0EAF763E45BC31AAB9802F87995 /* DelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DelegateProxy.swift; path = RxCocoa/Common/DelegateProxy.swift; sourceTree = ""; }; - BC41D63AA5F0A525ACB78573334AB97C /* CombineLatest+arity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "CombineLatest+arity.swift"; path = "RxSwift/Observables/CombineLatest+arity.swift"; sourceTree = ""; }; - BC432FD48A5932251F1CAFBC4BF74894 /* RxCocoa.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RxCocoa.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - BE717EAC81EE595FC7AE3C1A3C6D06A6 /* Buffer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Buffer.swift; path = RxSwift/Observables/Buffer.swift; sourceTree = ""; }; - BEEC0450A3B1A48A304AE8BF1DC03429 /* Notifications.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Notifications.swift; path = Source/Notifications.swift; sourceTree = ""; }; - BF07A24C96313F878506258234883CC8 /* GCDWebServer-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GCDWebServer-prefix.pch"; sourceTree = ""; }; - BF25DE5F0433D7BA7D6F91A5F113542A /* RxRelay.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RxRelay.debug.xcconfig; sourceTree = ""; }; - BFD92A4EF88D0A6B34E86A6A7CE2436D /* RxSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RxSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C0D1BF03B3F26978B85F2E44EBE18FC1 /* RxCollectionViewDataSourceType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxCollectionViewDataSourceType.swift; path = RxCocoa/iOS/Protocols/RxCollectionViewDataSourceType.swift; sourceTree = ""; }; - C119A4F639217703B4B382419AF9D4EF /* NSObject+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSObject+Rx.swift"; path = "RxCocoa/Foundation/NSObject+Rx.swift"; sourceTree = ""; }; - C15539256AFFEE061C9DE9660B995B25 /* RxTableViewDataSourcePrefetchingProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTableViewDataSourcePrefetchingProxy.swift; path = RxCocoa/iOS/Proxies/RxTableViewDataSourcePrefetchingProxy.swift; sourceTree = ""; }; - C21721CAB3BC76F0D7582BD636DB821D /* GCDWebServerDataResponse.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCDWebServerDataResponse.h; path = GCDWebServer/Responses/GCDWebServerDataResponse.h; sourceTree = ""; }; - C3B6C103B3C3936D11BF01C71C0EE380 /* BRLOptionParser.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = BRLOptionParser.release.xcconfig; sourceTree = ""; }; - C3DCF3854C69F5239CE7E89C1FCFAA51 /* ObservableConvertibleType+Signal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ObservableConvertibleType+Signal.swift"; path = "RxCocoa/Traits/Signal/ObservableConvertibleType+Signal.swift"; sourceTree = ""; }; - C4028B836251B6DD18772CF35047686A /* NSView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSView+Rx.swift"; path = "RxCocoa/macOS/NSView+Rx.swift"; sourceTree = ""; }; - C40D7DCF882E3A5609EDE1602335E721 /* GCDWebServerResponse.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GCDWebServerResponse.m; path = GCDWebServer/Core/GCDWebServerResponse.m; sourceTree = ""; }; - C535813B1010A4B0BEBADE15AD42DC2E /* MASShortcut-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "MASShortcut-Info.plist"; sourceTree = ""; }; - C5BD2C8DB205D16490D3804A6CAB6C50 /* RxCollectionViewDataSourceProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxCollectionViewDataSourceProxy.swift; path = RxCocoa/iOS/Proxies/RxCollectionViewDataSourceProxy.swift; sourceTree = ""; }; - C70C13D2EC9B57E48D64BD7ABC49F9D6 /* KVORepresentable+CoreGraphics.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "KVORepresentable+CoreGraphics.swift"; path = "RxCocoa/Foundation/KVORepresentable+CoreGraphics.swift"; sourceTree = ""; }; - C713517A8C0251C9EEB925D43C63A544 /* ObservableType+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ObservableType+Extensions.swift"; path = "RxSwift/ObservableType+Extensions.swift"; sourceTree = ""; }; - C771BA2A255CC372CD2AB83291BD3E1C /* GCDWebServer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCDWebServer.h; path = GCDWebServer/Core/GCDWebServer.h; sourceTree = ""; }; - C78EDD95C0B56A70BE237D148A1726CA /* UIApplication+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIApplication+Rx.swift"; path = "RxCocoa/iOS/UIApplication+Rx.swift"; sourceTree = ""; }; - C793DFE7002D416E900642C76CEEBD75 /* CurrentThreadScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CurrentThreadScheduler.swift; path = RxSwift/Schedulers/CurrentThreadScheduler.swift; sourceTree = ""; }; - C798C591985DFD0B008AAEEBF78EF979 /* DefaultIfEmpty.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DefaultIfEmpty.swift; path = RxSwift/Observables/DefaultIfEmpty.swift; sourceTree = ""; }; - C8305C9D0B89A4CE30258C61DDD5A342 /* StringEncoding+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "StringEncoding+Alamofire.swift"; path = "Source/StringEncoding+Alamofire.swift"; sourceTree = ""; }; - C96F1CEB77C6CB8A9D2A7682406E7AE9 /* DispatchQueue+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DispatchQueue+Extensions.swift"; path = "Platform/DispatchQueue+Extensions.swift"; sourceTree = ""; }; - CA0A6C3DB39AD5C25FF5B1A9F554E228 /* Lock.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Lock.swift; path = RxSwift/Concurrency/Lock.swift; sourceTree = ""; }; - CA7211C3393B6E1ED0E57C4CCF5F5005 /* PublishRelay.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PublishRelay.swift; path = RxRelay/PublishRelay.swift; sourceTree = ""; }; - CB340F626B32E3AF98F1E13658FB46E2 /* UIBarButtonItem+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIBarButtonItem+Rx.swift"; path = "RxCocoa/iOS/UIBarButtonItem+Rx.swift"; sourceTree = ""; }; - CCCC3232579F890A62A86540F6600BE6 /* Bag+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Bag+Rx.swift"; path = "RxSwift/Extensions/Bag+Rx.swift"; sourceTree = ""; }; - CD2C25316E1BF4F3230E3412417481E6 /* Result+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Result+Alamofire.swift"; path = "Source/Result+Alamofire.swift"; sourceTree = ""; }; - CD90405BE5311F3F3A8CFCFABCCF3560 /* Multicast.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Multicast.swift; path = RxSwift/Observables/Multicast.swift; sourceTree = ""; }; - CD95085BFAA31431686824B236DB9319 /* Pods-ShadowsocksX-NG-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-ShadowsocksX-NG-umbrella.h"; sourceTree = ""; }; - CE8BA32B7F7B571C37D44747CBB93955 /* ObserverBase.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObserverBase.swift; path = RxSwift/Observers/ObserverBase.swift; sourceTree = ""; }; - CECC6752E3DD709B29A4ED0461B7BF82 /* Disposables.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Disposables.swift; path = RxSwift/Disposables/Disposables.swift; sourceTree = ""; }; - D157799A728D6FFED669C62E86BABD73 /* GCDWebServerMultiPartFormRequest.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCDWebServerMultiPartFormRequest.h; path = GCDWebServer/Requests/GCDWebServerMultiPartFormRequest.h; sourceTree = ""; }; - D18636DE7B757847E9D7B9E45CA10DE2 /* SharedSequence+Operators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "SharedSequence+Operators.swift"; path = "RxCocoa/Traits/SharedSequence/SharedSequence+Operators.swift"; sourceTree = ""; }; - D231BAD0830AAA293F76CB7428ADA704 /* MASShortcut.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MASShortcut.release.xcconfig; sourceTree = ""; }; - D418B4DEE726BA9D5A912D8F1FBF0888 /* RxTableViewDataSourceType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTableViewDataSourceType.swift; path = RxCocoa/iOS/Protocols/RxTableViewDataSourceType.swift; sourceTree = ""; }; - D48183AD5F98D081078429EF56451DFF /* Pods_ShadowsocksX_NGTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ShadowsocksX_NGTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - D49EC557FA27872611535147AB5D700C /* UICollectionView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UICollectionView+Rx.swift"; path = "RxCocoa/iOS/UICollectionView+Rx.swift"; sourceTree = ""; }; - D4E3DADB00C8898A4A01F4DF1034F96C /* GCDWebServerRequest.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GCDWebServerRequest.m; path = GCDWebServer/Core/GCDWebServerRequest.m; sourceTree = ""; }; - D54CB24891D5C94C81CAED6F6D1D4FAB /* Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Rx.swift; path = RxSwift/Rx.swift; sourceTree = ""; }; - D570E112B81800B30A1165D0BC68DB8A /* Delay.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Delay.swift; path = RxSwift/Observables/Delay.swift; sourceTree = ""; }; - D60357581333E7EC56952E31B2991366 /* Pods-ShadowsocksX-NG-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-ShadowsocksX-NG-dummy.m"; sourceTree = ""; }; - D64C89D84E4BDDCF85E57BDA0153F0B1 /* RxSwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = RxSwift.modulemap; sourceTree = ""; }; - D70A973E907BDE134197952FF14301CE /* RxRelay.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RxRelay.release.xcconfig; sourceTree = ""; }; - D7453403FEE25F56521DBB8A39EA0204 /* MultipartFormData.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MultipartFormData.swift; path = Source/MultipartFormData.swift; sourceTree = ""; }; - D7ED9E80778846168B6F3F867C04F6AA /* ParameterEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ParameterEncoder.swift; path = Source/ParameterEncoder.swift; sourceTree = ""; }; - D7F46244A2FF95EF2B228E2F76529358 /* Driver+Subscription.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Driver+Subscription.swift"; path = "RxCocoa/Traits/Driver/Driver+Subscription.swift"; sourceTree = ""; }; - D87FAE60EB40AC65B2E5000C6B82DFEB /* UIGestureRecognizer+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIGestureRecognizer+Rx.swift"; path = "RxCocoa/iOS/UIGestureRecognizer+Rx.swift"; sourceTree = ""; }; - D894FDA92A29CEECD7D1E50C263F1777 /* Reduce.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Reduce.swift; path = RxSwift/Observables/Reduce.swift; sourceTree = ""; }; - D896F6A68919914B3302027C15449A1D /* Pods_ShadowsocksX_NG.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ShadowsocksX_NG.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - D8C88B0B7BFE785BC9B00D1C53FDC003 /* Pods-proxy_conf_helper.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-proxy_conf_helper.debug.xcconfig"; sourceTree = ""; }; - D96D37A7C37C05D7DEEAE9B3944CC4DD /* PriorityQueue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PriorityQueue.swift; path = Platform/DataStructures/PriorityQueue.swift; sourceTree = ""; }; - DA23B9C3D142FEFFA05E4F37B1A976AE /* ElementAt.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ElementAt.swift; path = RxSwift/Observables/ElementAt.swift; sourceTree = ""; }; - DAE48A7C993FBD43A674E228A900457B /* GCDWebServerStreamedResponse.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GCDWebServerStreamedResponse.m; path = GCDWebServer/Responses/GCDWebServerStreamedResponse.m; sourceTree = ""; }; - DAFB048690381EFB0893639F33D3C764 /* SubscriptionDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SubscriptionDisposable.swift; path = RxSwift/Disposables/SubscriptionDisposable.swift; sourceTree = ""; }; - DB051CDFBF3B30AA181F5BF12F48FD3A /* ConcurrentDispatchQueueScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConcurrentDispatchQueueScheduler.swift; path = RxSwift/Schedulers/ConcurrentDispatchQueueScheduler.swift; sourceTree = ""; }; - DBB7AE66363DEA0FFF31BA0AD1EB9340 /* DelegateProxyType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DelegateProxyType.swift; path = RxCocoa/Common/DelegateProxyType.swift; sourceTree = ""; }; - DC40BD5F1E0BFED23CB5A6AE57FA4443 /* GCDWebServerURLEncodedFormRequest.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GCDWebServerURLEncodedFormRequest.m; path = GCDWebServer/Requests/GCDWebServerURLEncodedFormRequest.m; sourceTree = ""; }; - DD31B6D267ADAB9B30F51F821C60554A /* GCDWebServerFunctions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GCDWebServerFunctions.h; path = GCDWebServer/Core/GCDWebServerFunctions.h; sourceTree = ""; }; - DE18F7CA6E337EA48867C7D92143B6F9 /* NotificationCenter+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NotificationCenter+Rx.swift"; path = "RxCocoa/Foundation/NotificationCenter+Rx.swift"; sourceTree = ""; }; - DE719264DC0248D1CA1E5F7821C8381D /* RxCocoa-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxCocoa-prefix.pch"; sourceTree = ""; }; - DFA75B434E18E0DA5F6DEB758B437261 /* GCDWebServer.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = GCDWebServer.modulemap; sourceTree = ""; }; - DFAC6355D5B0FD94083A74B4602AF9D2 /* ObservableConvertibleType+SharedSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ObservableConvertibleType+SharedSequence.swift"; path = "RxCocoa/Traits/SharedSequence/ObservableConvertibleType+SharedSequence.swift"; sourceTree = ""; }; - E14C791F6C2C8320DE732C78C55306A1 /* ObservableConvertibleType+Driver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ObservableConvertibleType+Driver.swift"; path = "RxCocoa/Traits/Driver/ObservableConvertibleType+Driver.swift"; sourceTree = ""; }; - E35662841C2AAA3188CD9ADFDC38880F /* NSTextStorage+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSTextStorage+Rx.swift"; path = "RxCocoa/iOS/NSTextStorage+Rx.swift"; sourceTree = ""; }; - E39E7221D0BA332CC5AC5DD0A7C16C92 /* UISegmentedControl+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UISegmentedControl+Rx.swift"; path = "RxCocoa/iOS/UISegmentedControl+Rx.swift"; sourceTree = ""; }; - E4618B5826B29CA49F53BD36B1570602 /* Materialize.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Materialize.swift; path = RxSwift/Observables/Materialize.swift; sourceTree = ""; }; - E4C0551E43C5CE2E6F3BD09C18890BFD /* RxCocoa-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxCocoa-umbrella.h"; sourceTree = ""; }; - E5635498728E3B4005A42A385330D7CC /* RxCocoa-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "RxCocoa-Info.plist"; sourceTree = ""; }; - E6B674A528A68BF8E6AB4A5F747B05B8 /* NopDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NopDisposable.swift; path = RxSwift/Disposables/NopDisposable.swift; sourceTree = ""; }; - E8976DA3C1E5870E7B74F26E219A9885 /* Observable+Bind.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Observable+Bind.swift"; path = "RxCocoa/Common/Observable+Bind.swift"; sourceTree = ""; }; - EA0C023ECBE853C3AFE12E6702B6D1CD /* BooleanDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BooleanDisposable.swift; path = RxSwift/Disposables/BooleanDisposable.swift; sourceTree = ""; }; - EA187A944BB7C96464B1E79E6D12F90F /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/AppKit.framework; sourceTree = DEVELOPER_DIR; }; - EAB5B580FE6B602D602E607C7BC7C470 /* URLSession+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "URLSession+Rx.swift"; path = "RxCocoa/Foundation/URLSession+Rx.swift"; sourceTree = ""; }; - EB62C29E42A50AB4AA5C6DED19DA376D /* InfiniteSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InfiniteSequence.swift; path = Platform/DataStructures/InfiniteSequence.swift; sourceTree = ""; }; - EBC071EBDAC90F82FF4D25D024A5AACF /* Sample.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Sample.swift; path = RxSwift/Observables/Sample.swift; sourceTree = ""; }; - EC44E7C397DF9B77CEF6F5C86EFCE92A /* RxPickerViewDataSourceProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxPickerViewDataSourceProxy.swift; path = RxCocoa/iOS/Proxies/RxPickerViewDataSourceProxy.swift; sourceTree = ""; }; - EC8F5BC5CABB65CCD832B9821F532DBD /* InfiniteSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InfiniteSequence.swift; path = Platform/DataStructures/InfiniteSequence.swift; sourceTree = ""; }; - ECF8CD0A416163A50B72AAF4B0C4A124 /* ParameterEncoding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ParameterEncoding.swift; path = Source/ParameterEncoding.swift; sourceTree = ""; }; - EE6672D913C4CDAB5BAC161BDC483A67 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; }; - EE873D31D9227598B067D9426D366009 /* pl.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = pl.lproj; path = Resources/pl.lproj; sourceTree = ""; }; - EF4A8984BD7018149BDA495C7EA5FE28 /* Infallible+Operators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Infallible+Operators.swift"; path = "RxSwift/Traits/Infallible/Infallible+Operators.swift"; sourceTree = ""; }; - EF8D2E7C64775F0DD477127B5EC2E0AB /* RequestTaskMap.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestTaskMap.swift; path = Source/RequestTaskMap.swift; sourceTree = ""; }; - EF91750DCDE73B687E4BA164856BE224 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/SystemConfiguration.framework; sourceTree = DEVELOPER_DIR; }; - EFD30F9BBDEB87F6ADD6C3AAF8DE6E30 /* GroupedObservable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GroupedObservable.swift; path = RxSwift/GroupedObservable.swift; sourceTree = ""; }; - F0007682E9947D6BFA4DA24D30F6CBF2 /* RxSwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "RxSwift-dummy.m"; sourceTree = ""; }; - F0D4493458E5817BA46B4318626487F6 /* ScheduledDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ScheduledDisposable.swift; path = RxSwift/Disposables/ScheduledDisposable.swift; sourceTree = ""; }; - F11E6B29B9CB879F29AFEBD980D3AFBF /* Date+Dispatch.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Date+Dispatch.swift"; path = "RxSwift/Date+Dispatch.swift"; sourceTree = ""; }; - F17C7E34E699CD1435A12B207C1A125D /* RxCocoa.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = RxCocoa.modulemap; sourceTree = ""; }; - F3623071AC720B9C13DD1043F7052A73 /* SynchronizedDisposeType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SynchronizedDisposeType.swift; path = RxSwift/Concurrency/SynchronizedDisposeType.swift; sourceTree = ""; }; - F4786526A5AD085C95AC191C7253C591 /* Switch.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Switch.swift; path = RxSwift/Observables/Switch.swift; sourceTree = ""; }; - F5102E62600D264D29633030E490AAE6 /* NetworkReachabilityManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NetworkReachabilityManager.swift; path = Source/NetworkReachabilityManager.swift; sourceTree = ""; }; - F57A5448A0A790BED406AB47ED75D7B1 /* Alamofire-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Alamofire-Info.plist"; sourceTree = ""; }; - F6460C30C5328ED85A1103897C8CB63C /* MASDictionaryTransformer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASDictionaryTransformer.m; path = "Framework/User Defaults Storage/MASDictionaryTransformer.m"; sourceTree = ""; }; - F893DD80BE166F23DB8567A0940B0FEE /* Timer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Timer.swift; path = RxSwift/Observables/Timer.swift; sourceTree = ""; }; - F961756C2E9DE7614DBA1271483EB245 /* Never.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Never.swift; path = RxSwift/Observables/Never.swift; sourceTree = ""; }; - F979292485788BE53E5871123C74EB10 /* RxPickerViewAdapter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxPickerViewAdapter.swift; path = RxCocoa/iOS/DataSources/RxPickerViewAdapter.swift; sourceTree = ""; }; - F97D53A26324CAC07AB16E21B963CF9A /* InvocableScheduledItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InvocableScheduledItem.swift; path = RxSwift/Schedulers/Internal/InvocableScheduledItem.swift; sourceTree = ""; }; - FA1467E6A8A0A5B978108FDFC868000E /* Just.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Just.swift; path = RxSwift/Observables/Just.swift; sourceTree = ""; }; - FAABDBC186233AEF9876B5A4F009C8B8 /* Platform.Darwin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Platform.Darwin.swift; path = Platform/Platform.Darwin.swift; sourceTree = ""; }; - FAB6166D07AACCBF2B4A5FFC66F22602 /* pt.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = pt.lproj; path = Resources/pt.lproj; sourceTree = ""; }; - FB50A95F3BC6DC12244F2B76ABEBB9BD /* Pods-ShadowsocksX-NG-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-ShadowsocksX-NG-acknowledgements.plist"; sourceTree = ""; }; - FBD8075FDD277652161C8676E945DE6A /* RxRelay.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RxRelay.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - FCF992D22D15D6CF73AF4D310FEE871C /* SingleAssignmentDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SingleAssignmentDisposable.swift; path = RxSwift/Disposables/SingleAssignmentDisposable.swift; sourceTree = ""; }; - FD07F15ADFC693A5C730840EA2B42015 /* AsyncSubject.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AsyncSubject.swift; path = RxSwift/Subjects/AsyncSubject.swift; sourceTree = ""; }; - FD39BD9C1B852EC7AC7CD7D77D1E606F /* ObserveOn.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObserveOn.swift; path = RxSwift/Observables/ObserveOn.swift; sourceTree = ""; }; - FDCA53BCCEFF4720A955F8202537A982 /* WKWebView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "WKWebView+Rx.swift"; path = "RxCocoa/iOS/WKWebView+Rx.swift"; sourceTree = ""; }; - FDF7D102C3DA0493A530D68E569DA7CF /* sv.lproj */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder; name = sv.lproj; path = Resources/sv.lproj; sourceTree = ""; }; - FE18557905075BFBE5AFBE3A0D9287F4 /* PublishSubject.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PublishSubject.swift; path = RxSwift/Subjects/PublishSubject.swift; sourceTree = ""; }; - FE3AAA7586F734974B628C45E2310229 /* Using.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Using.swift; path = RxSwift/Observables/Using.swift; sourceTree = ""; }; - FE6138E84780096ADB31F55549931FC6 /* RxSwift.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RxSwift.debug.xcconfig; sourceTree = ""; }; - FF5FCDE3BD3C3E02C0A0B3D529BF6982 /* CombineLatest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CombineLatest.swift; path = RxSwift/Observables/CombineLatest.swift; sourceTree = ""; }; - FF8B264DFE802855D5D67E7CDDABFC3C /* RxRelay.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RxRelay.framework; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 1514A9A36FD5740CCE236AFAF1DAC5C6 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 44ABA0E4566A87964594C3AB0F7D2048 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 6E9985F3EEB339730D49B3D0181E6029 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 2E0722133679D5C422D0EC5ACB8B23A1 /* Cocoa.framework in Frameworks */, - A24E8834A85F99EF471C495AD4EFACAB /* RxRelay.framework in Frameworks */, - 9131DD9E2CB7420C156461E56835AE6E /* RxSwift.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 7B690F32F695B6718D43BA3D3544C78C /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 8314F89A5274810933307BC20E85D3B0 /* Cocoa.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B3C5909F9901CF3F5237F1832E214556 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6A2F2216A64E4B4E0FD6215A2F5E692D /* Cocoa.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - BA30161BB5D2E74710CBABFCC20E409F /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - F654788A27A296CD2C1F104B4C897EF0 /* Cocoa.framework in Frameworks */, - FB3AD79C536DC201CED66150778FA691 /* RxSwift.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - C2D4774AB2F0BFB25B60914F66C457AC /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - E03556E8EC8DA4FF0DE3ED6F86BD7C51 /* Cocoa.framework in Frameworks */, - EC388029B45DC677A2412CF1617E4DF1 /* SystemConfiguration.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DA3A32D96D94A82A8FFE804468C37DB4 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 262EBFD1844224838811BD9E1726CD73 /* AppKit.framework in Frameworks */, - 88665F16CDF39BC2A50C6619169E6EDF /* Carbon.framework in Frameworks */, - 96E6F7A2D012051B29BC9147340E5117 /* Cocoa.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - E4B8CC1E36A98FF4D8BDAC84442F0DCE /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 9A1CDAE2E9AFFFDBC654855D4A8C6D36 /* CFNetwork.framework in Frameworks */, - 4C3A9F4F5A688009D660C0FA5E5D81BB /* Cocoa.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - EE0D52842751CED2CD0BD2633A30FEA4 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F4AB20C615B7CE4E912D4031FF0A52C8 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 896AD4C4865ECEA0A8344B54BBA3B9E1 /* Cocoa.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 016ECA8DBDA1E03C02AE6CE07B9C7B28 /* Pods-ShadowsocksX-NGTests */ = { - isa = PBXGroup; - children = ( - 83899FE1EDE6090C8B2F4703A7895330 /* Pods-ShadowsocksX-NGTests.modulemap */, - 22ADD736785A6DE33628551E25AC889A /* Pods-ShadowsocksX-NGTests-acknowledgements.markdown */, - 2CFE9D0E45288EBBAF865D7685C2B983 /* Pods-ShadowsocksX-NGTests-acknowledgements.plist */, - 1C10AA3C311345DB3616BCE827B69C55 /* Pods-ShadowsocksX-NGTests-dummy.m */, - B797965188D07FBBF91BA7F69EC21D39 /* Pods-ShadowsocksX-NGTests-Info.plist */, - 72A57876EDEB24ADDFE06DD482CE250C /* Pods-ShadowsocksX-NGTests-umbrella.h */, - 196DA983244F60766BA272090829A16E /* Pods-ShadowsocksX-NGTests.debug.xcconfig */, - 5C0C485AB4EA81F3E9128F65E9AC66CA /* Pods-ShadowsocksX-NGTests.release.xcconfig */, - ); - name = "Pods-ShadowsocksX-NGTests"; - path = "Target Support Files/Pods-ShadowsocksX-NGTests"; - sourceTree = ""; - }; - 0AE53B8F7176B22FFD63627F9D926CAF /* Support Files */ = { - isa = PBXGroup; - children = ( - 336A70440B171C2C6AEE66F83620273A /* Alamofire.modulemap */, - 06A09DBC68AE0A93F94442D71EBF343F /* Alamofire-dummy.m */, - F57A5448A0A790BED406AB47ED75D7B1 /* Alamofire-Info.plist */, - 1A2C716EE769E98BF094D14B243A42C2 /* Alamofire-prefix.pch */, - 10E99E50E2994DB7AD9AEBDEF1A2F72B /* Alamofire-umbrella.h */, - 75EA425CE2A4DBDDEB580C7303DD2454 /* Alamofire.debug.xcconfig */, - 848DD5BA5CA758D1F00A7F6F947019EB /* Alamofire.release.xcconfig */, - ); - name = "Support Files"; - path = "../Target Support Files/Alamofire"; - sourceTree = ""; - }; - 14F38608C29A913E1DD0D624DE663510 /* Pods */ = { - isa = PBXGroup; - children = ( - 2FBE37D8419906C6110EC34FC53F14BE /* Alamofire */, - D20BAD07D23FBA7AA269B9FA80FE8BF3 /* BRLOptionParser */, - 25954B3ABFDB5497C48E76FDE256C24A /* GCDWebServer */, - D71126DFC6989B0EEE224402B0C7852C /* MASShortcut */, - AF01C03E9E6BF3B668D35EEF202AD7A0 /* RxCocoa */, - 6B3DE0B21DFC168E060A8E9C9EC74C3A /* RxRelay */, - 62066982AA2FE77C183DF3046C898E34 /* RxSwift */, - ); - name = Pods; - sourceTree = ""; - }; - 165807E7BFFB1F57C0BA71AD827D588F /* Support Files */ = { - isa = PBXGroup; - children = ( - 1389D4639C0D9038BA081FA8DC1CD646 /* BRLOptionParser-dummy.m */, - 9D407239EE1987EFBB2A7EB11F70BFCF /* BRLOptionParser-prefix.pch */, - 5EE446AD8C625612BFF0E37E4419E0FD /* BRLOptionParser.debug.xcconfig */, - C3B6C103B3C3936D11BF01C71C0EE380 /* BRLOptionParser.release.xcconfig */, - ); - name = "Support Files"; - path = "../Target Support Files/BRLOptionParser"; - sourceTree = ""; - }; - 25954B3ABFDB5497C48E76FDE256C24A /* GCDWebServer */ = { - isa = PBXGroup; - children = ( - 7D5BF41D87EA0E33C1D9986ADA4BDA51 /* Core */, - F7E043D77B41FA3B6662AD3E792046E8 /* Support Files */, - ); - path = GCDWebServer; - sourceTree = ""; - }; - 2FBE37D8419906C6110EC34FC53F14BE /* Alamofire */ = { - isa = PBXGroup; - children = ( - 6D8A09F0F8EDB0B1A568AA29A33D62EA /* AFError.swift */, - 2E656BCAB89EA23EC58A161ACF0DAE68 /* Alamofire.swift */, - 19AA7CC35C97B4BDF08E2E5CE20955E0 /* AlamofireExtended.swift */, - 2E101994FDA2210D6CD7972A656C511F /* AuthenticationInterceptor.swift */, - 32EC506B43DB4AE47634A8AEE18D9E8C /* CachedResponseHandler.swift */, - 9F78589C2F1DDF07DF58CD22F6835B19 /* Combine.swift */, - 41ADA85A38ECDBBD122B707DA599E641 /* DispatchQueue+Alamofire.swift */, - 4E0CDE6403F2AF9E108FF190F90FA9FF /* EventMonitor.swift */, - 3425B3045259FEA3A238D183DEEE520B /* HTTPHeaders.swift */, - 403ABCCF5634DCD99A376EAA601F828E /* HTTPMethod.swift */, - D7453403FEE25F56521DBB8A39EA0204 /* MultipartFormData.swift */, - 9CF5ADA01C91A2DF993314D6CC9C63D3 /* MultipartUpload.swift */, - F5102E62600D264D29633030E490AAE6 /* NetworkReachabilityManager.swift */, - BEEC0450A3B1A48A304AE8BF1DC03429 /* Notifications.swift */, - 26DA8062B81F764A6EEA6168DF6337AB /* OperationQueue+Alamofire.swift */, - D7ED9E80778846168B6F3F867C04F6AA /* ParameterEncoder.swift */, - ECF8CD0A416163A50B72AAF4B0C4A124 /* ParameterEncoding.swift */, - 43D1B54DDFE366EA8E657D1CFA2A5349 /* Protected.swift */, - A32434EC299FDE302FFF9F31EB8735D0 /* RedirectHandler.swift */, - 9029CBEE1EB8EBFDFCC3F55CEC98E088 /* Request.swift */, - 80B5C55F7279E38D15E19E9DEDDEDE7B /* RequestInterceptor.swift */, - EF8D2E7C64775F0DD477127B5EC2E0AB /* RequestTaskMap.swift */, - 0D09EFC8E8E0DD0BACEB39FA20E08331 /* Response.swift */, - 48CB9D3553F121F84DBB750A8FBE0F3D /* ResponseSerialization.swift */, - CD2C25316E1BF4F3230E3412417481E6 /* Result+Alamofire.swift */, - 3B85D80911EDFC7DD402EBEB3A05169A /* RetryPolicy.swift */, - 90E9219489B97BDFE17BA3231CC465FC /* ServerTrustEvaluation.swift */, - 996DFC2DB5C2F37F0E623EB885F5DEB5 /* Session.swift */, - B7045A3758C33721435A4135DBC6A8AA /* SessionDelegate.swift */, - C8305C9D0B89A4CE30258C61DDD5A342 /* StringEncoding+Alamofire.swift */, - AE6768B8A7BED83ED5C93BB3439EFFEF /* URLConvertible+URLRequestConvertible.swift */, - 5D0A2A589A608DD00CA24C86BCD46E62 /* URLEncodedFormEncoder.swift */, - 47291D90953698297410B0C37E619402 /* URLRequest+Alamofire.swift */, - 83FE5C08C0F9F63C9A7D2B71EF9F0864 /* URLSessionConfiguration+Alamofire.swift */, - 151A22449BAFE60147DA302082A00FA1 /* Validation.swift */, - 0AE53B8F7176B22FFD63627F9D926CAF /* Support Files */, - ); - path = Alamofire; - sourceTree = ""; - }; - 493933EC245DE8B9BF6A90C4A901306A /* Targets Support Files */ = { - isa = PBXGroup; - children = ( - A1DDAA49ED6DA408AC4F6220754154E6 /* Pods-proxy_conf_helper */, - B364CCC64531E6C6BC03A50131504939 /* Pods-ShadowsocksX-NG */, - 016ECA8DBDA1E03C02AE6CE07B9C7B28 /* Pods-ShadowsocksX-NGTests */, - ); - name = "Targets Support Files"; - sourceTree = ""; - }; - 4AE2520FB25EC7AF2FA83B8E69D00ED0 /* Support Files */ = { - isa = PBXGroup; - children = ( - 8C1810C471075F4E78D93E645BD7F63B /* MASShortcut.modulemap */, - 6B668707F7C66384A3BB8BC4FE3F41E6 /* MASShortcut-dummy.m */, - C535813B1010A4B0BEBADE15AD42DC2E /* MASShortcut-Info.plist */, - 7720FEFA630547FDE17C156840E36CC6 /* MASShortcut-prefix.pch */, - 930EB20F00FF48CAF9B19505BC219504 /* MASShortcut-umbrella.h */, - 70C291AA3C3CEE619534F472C4F04882 /* MASShortcut.debug.xcconfig */, - D231BAD0830AAA293F76CB7428ADA704 /* MASShortcut.release.xcconfig */, - 9EF2C4A08C5514586AFFBB5AE22A99ED /* ResourceBundle-MASShortcut-MASShortcut-Info.plist */, - ); - name = "Support Files"; - path = "../Target Support Files/MASShortcut"; - sourceTree = ""; - }; - 4C712514E3CDE5A583F0DA94CB23FB65 /* Frameworks */ = { - isa = PBXGroup; - children = ( - FBD8075FDD277652161C8676E945DE6A /* RxRelay.framework */, - BFD92A4EF88D0A6B34E86A6A7CE2436D /* RxSwift.framework */, - EE196A86A60DA3C09134F038D0679871 /* OS X */, - ); - name = Frameworks; - sourceTree = ""; - }; - 5E0AA8A2AD4F95EB8CD37C35E2FC5D26 /* Support Files */ = { - isa = PBXGroup; - children = ( - D64C89D84E4BDDCF85E57BDA0153F0B1 /* RxSwift.modulemap */, - F0007682E9947D6BFA4DA24D30F6CBF2 /* RxSwift-dummy.m */, - 4946CBDE2CD13F181402416264EBF61D /* RxSwift-Info.plist */, - 3685B6DE4DF41097400DA11AA41A500B /* RxSwift-prefix.pch */, - 77B5C856C653A9586105526C4341767A /* RxSwift-umbrella.h */, - FE6138E84780096ADB31F55549931FC6 /* RxSwift.debug.xcconfig */, - 28F6CED61832E1CE6BA74AA90F7E45EE /* RxSwift.release.xcconfig */, - ); - name = "Support Files"; - path = "../Target Support Files/RxSwift"; - sourceTree = ""; - }; - 5E93897366D3A44BA737EB9FE037DDB1 /* Support Files */ = { - isa = PBXGroup; - children = ( - F17C7E34E699CD1435A12B207C1A125D /* RxCocoa.modulemap */, - 4752AFB18B745CA95D95FB7457EAA1C4 /* RxCocoa-dummy.m */, - E5635498728E3B4005A42A385330D7CC /* RxCocoa-Info.plist */, - DE719264DC0248D1CA1E5F7821C8381D /* RxCocoa-prefix.pch */, - E4C0551E43C5CE2E6F3BD09C18890BFD /* RxCocoa-umbrella.h */, - 2F138B6C28378A801D2186B22E1E6224 /* RxCocoa.debug.xcconfig */, - AF22EDE51D4C2AF18359CE03247D06F1 /* RxCocoa.release.xcconfig */, - ); - name = "Support Files"; - path = "../Target Support Files/RxCocoa"; - sourceTree = ""; - }; - 62066982AA2FE77C183DF3046C898E34 /* RxSwift */ = { - isa = PBXGroup; - children = ( - 494FD3BF9675BD2ADCE4731FED65B5FF /* AddRef.swift */, - 0CB05B6D60934D955FE0D75C2339A114 /* Amb.swift */, - 1EB8536183BE6472CDCC5817172688EF /* AnonymousDisposable.swift */, - 636D1EE61F0E0E367F486461F8E0DF54 /* AnonymousObserver.swift */, - 840A431555445FF451B4B74E7A8DDCF4 /* AnyObserver.swift */, - 7D680C4252D37F732EE2D1BB9AB911DA /* AsMaybe.swift */, - B8D247C19100F15D54BFF5D93804C65E /* AsSingle.swift */, - 52626495FA7375A2A4753E3EC16FB26C /* AsyncLock.swift */, - FD07F15ADFC693A5C730840EA2B42015 /* AsyncSubject.swift */, - A269EEED1FC8BFDA5FCB004DC335F5C8 /* AtomicInt.swift */, - 0B98DA4C08DC1A12B2789714C6CDEFFA /* Bag.swift */, - CCCC3232579F890A62A86540F6600BE6 /* Bag+Rx.swift */, - BB1177638C48D2FB13DDFB46A70CD35D /* BehaviorSubject.swift */, - 2FEFD09344E88FFE590FC0A7146C0D32 /* BinaryDisposable.swift */, - 4412635C50524157DDF38FA0CB197F4A /* Binder.swift */, - EA0C023ECBE853C3AFE12E6702B6D1CD /* BooleanDisposable.swift */, - BE717EAC81EE595FC7AE3C1A3C6D06A6 /* Buffer.swift */, - 8565AD8EBB9A4E532AF93D887B586876 /* Cancelable.swift */, - 1CD2535A24AA927A5965AF73264678A3 /* Catch.swift */, - FF5FCDE3BD3C3E02C0A0B3D529BF6982 /* CombineLatest.swift */, - BC41D63AA5F0A525ACB78573334AB97C /* CombineLatest+arity.swift */, - 68D133622632E3F0C62D1F74D188EA7E /* CombineLatest+Collection.swift */, - A6415209F9685A39C6C1018082155EA5 /* CompactMap.swift */, - 2AE63CBE5D3B0C2D25184C45E1B8C885 /* Completable.swift */, - A111C3B36368413B50627674BB48E859 /* Completable+AndThen.swift */, - 3BE91EC45C71C190D532DC351F5E724D /* CompositeDisposable.swift */, - 66C7F789300668AEDFA53AEA1392C48B /* Concat.swift */, - DB051CDFBF3B30AA181F5BF12F48FD3A /* ConcurrentDispatchQueueScheduler.swift */, - A126CA25C01C17FEF1E4B62108855349 /* ConcurrentMainScheduler.swift */, - 2505B197F74151D018080608E6576C6C /* ConnectableObservableType.swift */, - 3ED0602BE820AA0F7B2D99CBFED4C1F0 /* Create.swift */, - C793DFE7002D416E900642C76CEEBD75 /* CurrentThreadScheduler.swift */, - F11E6B29B9CB879F29AFEBD980D3AFBF /* Date+Dispatch.swift */, - 8A2C23CF743A94075196D7A4F419F5A4 /* Debounce.swift */, - 555231B7293881D7D76CA80C82AABA2B /* Debug.swift */, - 5D99DA86D8CBFFCB2E7FD40BC42568F3 /* Decode.swift */, - C798C591985DFD0B008AAEEBF78EF979 /* DefaultIfEmpty.swift */, - 33BBD4B03778E41A59C1A3F64AAB876C /* Deferred.swift */, - D570E112B81800B30A1165D0BC68DB8A /* Delay.swift */, - 8AE4AAE5FF0F7FEDE2C8D5FB08A1AE4F /* DelaySubscription.swift */, - 080201197B517655700BD33F44B1A602 /* Dematerialize.swift */, - C96F1CEB77C6CB8A9D2A7682406E7AE9 /* DispatchQueue+Extensions.swift */, - 222E861679233A0833D6C2F8079146E7 /* DispatchQueueConfiguration.swift */, - 8369906FA14B85B8271089FAAA1E4694 /* Disposable.swift */, - CECC6752E3DD709B29A4ED0461B7BF82 /* Disposables.swift */, - 0F2EB184269284B56190B6EE5A7E5CC3 /* DisposeBag.swift */, - 04A3FEA575D65278CDB553AA231A0CF6 /* DisposeBase.swift */, - 3949A4BE0C4C31915E5A812146DB23B9 /* DistinctUntilChanged.swift */, - 0E5F518C62FDAA5A762312C37D1CB101 /* Do.swift */, - DA23B9C3D142FEFFA05E4F37B1A976AE /* ElementAt.swift */, - 65D8FEBF2028BCC7758A666F2A35989A /* Empty.swift */, - 31234D4C5E912BD05D37874E7E89A233 /* Enumerated.swift */, - 4764F518EAB30C5EA82C03A5607ED7AF /* Error.swift */, - 718741562429DAE6AA6DC455ED6883D4 /* Errors.swift */, - 5CE7CD3C7A16D2E9341BBBAB18D5D8DC /* Event.swift */, - 44775F4816D20EB134F1DBAB43BE0B3A /* Filter.swift */, - 543DFE92FBC6235F6826EF38928A7C08 /* First.swift */, - 886072F083033D493924A8BE652713ED /* Generate.swift */, - 47EB7F9271D4EAE5B4A31D5D0194BECC /* GroupBy.swift */, - EFD30F9BBDEB87F6ADD6C3AAF8DE6E30 /* GroupedObservable.swift */, - 6DA5F27AAEF9B366933CB017942EFAA8 /* HistoricalScheduler.swift */, - 38A0B431980745BE7A67D566D79E240A /* HistoricalSchedulerTimeConverter.swift */, - 7DF9FA6B1D40855A99145762147C1690 /* ImmediateSchedulerType.swift */, - 370A313E34AF66CB8D7437ABDC3FB7F8 /* Infallible.swift */, - 40573DCBFB24CA15F7D6C33B5C73162F /* Infallible+CombineLatest+arity.swift */, - 161437331F54761E08F028DD14CDC21E /* Infallible+Create.swift */, - EF4A8984BD7018149BDA495C7EA5FE28 /* Infallible+Operators.swift */, - A2FFFF24B3AC3570742D7F2CCF2FE3C5 /* Infallible+Zip+arity.swift */, - EB62C29E42A50AB4AA5C6DED19DA376D /* InfiniteSequence.swift */, - F97D53A26324CAC07AB16E21B963CF9A /* InvocableScheduledItem.swift */, - 200825C8579BF340304A9767D679EC35 /* InvocableType.swift */, - FA1467E6A8A0A5B978108FDFC868000E /* Just.swift */, - CA0A6C3DB39AD5C25FF5B1A9F554E228 /* Lock.swift */, - 683395CCE980D15405934DC5E2BCD682 /* LockOwnerType.swift */, - 98B151536C20EA366FDBE99C5A8BB7A5 /* MainScheduler.swift */, - 494A67061DAFFD52534BC4699A8DF637 /* Map.swift */, - E4618B5826B29CA49F53BD36B1570602 /* Materialize.swift */, - 5219820998BC7D8238F0F05F90A3D96F /* Maybe.swift */, - 5CA0D236EFCE9E4E77F9A2B2A0AF3FC4 /* Merge.swift */, - CD90405BE5311F3F3A8CFCFABCCF3560 /* Multicast.swift */, - F961756C2E9DE7614DBA1271483EB245 /* Never.swift */, - E6B674A528A68BF8E6AB4A5F747B05B8 /* NopDisposable.swift */, - 636937DE6DA6CE01D7E94282A16BC9D9 /* Observable.swift */, - 4618A8C418D70264404BBAF10EE3A1F4 /* ObservableConvertibleType.swift */, - 834EB5666F2D27EDBD25C600C80DF7CE /* ObservableConvertibleType+Infallible.swift */, - 4338C646A92E1539E9BED963FC618602 /* ObservableType.swift */, - C713517A8C0251C9EEB925D43C63A544 /* ObservableType+Extensions.swift */, - 1AA3BEB86C50C2AAE9CCEDB0171CFC56 /* ObservableType+PrimitiveSequence.swift */, - FD39BD9C1B852EC7AC7CD7D77D1E606F /* ObserveOn.swift */, - CE8BA32B7F7B571C37D44747CBB93955 /* ObserverBase.swift */, - 7B00E954AA2FCFDF5ACDEC8CD8C6941E /* ObserverType.swift */, - AC4C66DE7DB1A4B525929AEF699AC3CE /* OperationQueueScheduler.swift */, - 5158C591583049B150EC9F57DC2FA656 /* Optional.swift */, - FAABDBC186233AEF9876B5A4F009C8B8 /* Platform.Darwin.swift */, - 4FF704B43D944C2399606B76A430F1A6 /* Platform.Linux.swift */, - 280A80C3BD890370005C094FC4C3DC12 /* PrimitiveSequence.swift */, - A8C417EB740CAC7F2602C6D8880E7737 /* PrimitiveSequence+Zip+arity.swift */, - D96D37A7C37C05D7DEEAE9B3944CC4DD /* PriorityQueue.swift */, - 4FDB60114950AF3BF06EF9DA0AF9E5AC /* Producer.swift */, - FE18557905075BFBE5AFBE3A0D9287F4 /* PublishSubject.swift */, - 960C49C6C3C5E2554CA3CD8EB86B61AC /* Queue.swift */, - 2096522151041770121528F182B6F42D /* Range.swift */, - 0C0FB7A81FC88101C56EABF826BD78F5 /* Reactive.swift */, - 11DD125BCF1FDD4E34715800EC2F295F /* RecursiveLock.swift */, - 40FC23633FFFBBD0FA165FB284958F8C /* RecursiveScheduler.swift */, - D894FDA92A29CEECD7D1E50C263F1777 /* Reduce.swift */, - B97E5FCD7744551B43A8C353FD79E774 /* RefCountDisposable.swift */, - 45BF55923F2D3657D9D5420E606B641F /* Repeat.swift */, - 96D93775EA307729314581C5C539C487 /* ReplaySubject.swift */, - AADC2D51259367D2BB2C73816E5A35CD /* RetryWhen.swift */, - D54CB24891D5C94C81CAED6F6D1D4FAB /* Rx.swift */, - 530CEAEC9F4BC5F2EC9C9534779927A3 /* RxMutableBox.swift */, - EBC071EBDAC90F82FF4D25D024A5AACF /* Sample.swift */, - 32777B9FE68F64D911474F7B7595C94C /* Scan.swift */, - F0D4493458E5817BA46B4318626487F6 /* ScheduledDisposable.swift */, - 8663196F6A9678BFC77A8E46F8666C75 /* ScheduledItem.swift */, - 19FF8B675AE7A3F0AB7CDE7C48E8082A /* ScheduledItemType.swift */, - A0791E5EB9ADBB88CEE0BCD83DA9502C /* SchedulerServices+Emulation.swift */, - 111E9F3F4997D0ACA2E0BCDAF269904C /* SchedulerType.swift */, - 172B845C32EEB48FD9EF1A11CC432D51 /* Sequence.swift */, - 408AEB2CFB972D5D82E41BB027E6686C /* SerialDispatchQueueScheduler.swift */, - 6DAFFC9484B606CC3A8583B2085B7957 /* SerialDisposable.swift */, - 72D91E08E6C75E1F0DBACD4FF3CA2F55 /* ShareReplayScope.swift */, - A3E96B8BC40FDC92B51E51B50F126573 /* Single.swift */, - FCF992D22D15D6CF73AF4D310FEE871C /* SingleAssignmentDisposable.swift */, - A2B10B3F59B2394712B672A72C5827F0 /* SingleAsync.swift */, - B304846A96173EC0E0631D07751C0893 /* Sink.swift */, - 07B4CEF97C27B2FE6205EE1D720BFB39 /* Skip.swift */, - A1D0AF20D0BF5465039BB88836A959B6 /* SkipUntil.swift */, - 904A920F44C4C4A18874A6A62A3ED759 /* SkipWhile.swift */, - 864BF009AFF7BFF4D8B68869FC885957 /* StartWith.swift */, - 44D9E4509154BFFEBEA9AEA0C935EC9E /* SubjectType.swift */, - 17A8B6DADE1F343EA5319D5964E84B71 /* SubscribeOn.swift */, - DAFB048690381EFB0893639F33D3C764 /* SubscriptionDisposable.swift */, - 0BC06E9EC97DF3F5E3AB732D978BD66B /* SwiftSupport.swift */, - F4786526A5AD085C95AC191C7253C591 /* Switch.swift */, - A20673B8CBA1827BCAE8A9CDEAF0CDC5 /* SwitchIfEmpty.swift */, - F3623071AC720B9C13DD1043F7052A73 /* SynchronizedDisposeType.swift */, - 95A61E2BD71E9AE873207EFE8994362B /* SynchronizedOnType.swift */, - 1FA62A0165A7A8D001536C62FD5E2392 /* SynchronizedUnsubscribeType.swift */, - 558A95B0EAE7FAFDFCC334A1E9277C19 /* TailRecursiveSink.swift */, - 273C90965AA81CCFE4CDA40530425746 /* Take.swift */, - 73118DDBDD8A625213B479BD40C4B9CE /* TakeLast.swift */, - 6327835932D3C270A640C0C76A860EB8 /* TakeWithPredicate.swift */, - 127B3965CEBAEBFB395F0D10B7C255FB /* Throttle.swift */, - 661DD8158386E15481E17DE6E2FA1882 /* Timeout.swift */, - F893DD80BE166F23DB8567A0940B0FEE /* Timer.swift */, - 314A2DB247EA6781CE45C5C146496327 /* ToArray.swift */, - FE3AAA7586F734974B628C45E2310229 /* Using.swift */, - 4673D1BC54F57F490E2D3352F6BA1B73 /* VirtualTimeConverterType.swift */, - 6A2828DE92C9CEECE9FB19F2EE763305 /* VirtualTimeScheduler.swift */, - 855607DC318E2CF3120B3C70565140A0 /* Window.swift */, - A49E3489F755F888C3405824694827BF /* WithLatestFrom.swift */, - 897003218412D0C779A54DAAD7D2A4EE /* WithUnretained.swift */, - 9FA0DBB3C5358A6E4EF0C16145BB0F7E /* Zip.swift */, - ABD89974F6EA342767735D559995D3FA /* Zip+arity.swift */, - 3677CB82C594C5820F17431AA45C5C87 /* Zip+Collection.swift */, - 5E0AA8A2AD4F95EB8CD37C35E2FC5D26 /* Support Files */, - ); - path = RxSwift; - sourceTree = ""; - }; - 6B3DE0B21DFC168E060A8E9C9EC74C3A /* RxRelay */ = { - isa = PBXGroup; - children = ( - 8D796FDCC7398C88D7B835BD89700D56 /* BehaviorRelay.swift */, - 0A18EEA4857408358F9A8E6ED8AF8829 /* Observable+Bind.swift */, - CA7211C3393B6E1ED0E57C4CCF5F5005 /* PublishRelay.swift */, - 485A8E801F2DA21AB5D16808AE1B4887 /* ReplayRelay.swift */, - 29BFF21F894144F23E9F778185A1EBC4 /* Utils.swift */, - E9E177E10E9704C8136B4410D7F621DB /* Support Files */, - ); - path = RxRelay; - sourceTree = ""; - }; - 7D5BF41D87EA0E33C1D9986ADA4BDA51 /* Core */ = { - isa = PBXGroup; - children = ( - C771BA2A255CC372CD2AB83291BD3E1C /* GCDWebServer.h */, - 55F5FEB17D952CAA64A6B7DE90D7E47D /* GCDWebServer.m */, - 6D0B40D5A184825074ECC549693CAF02 /* GCDWebServerConnection.h */, - 1410700BFA8AF785CCF9919941F9930C /* GCDWebServerConnection.m */, - 36E9C273C636D7A0C559787BD1FABA68 /* GCDWebServerDataRequest.h */, - 7DFEE31FDCAA3B9A85119C45EE5BF376 /* GCDWebServerDataRequest.m */, - C21721CAB3BC76F0D7582BD636DB821D /* GCDWebServerDataResponse.h */, - AB7765E1848A0449B3E3267F17DDE12E /* GCDWebServerDataResponse.m */, - 9EE8B6717B73CE07A9FAC17FFCB1BA91 /* GCDWebServerErrorResponse.h */, - 199E49652A8B30754D25980910F956E1 /* GCDWebServerErrorResponse.m */, - 962EFFE0B39AFE334DBCAF81B4DBFE56 /* GCDWebServerFileRequest.h */, - 392538EA12C4E3008D6EF1ABB226B3BF /* GCDWebServerFileRequest.m */, - 77E73C4E3CAF9AD8FAE2EA9130D6A37E /* GCDWebServerFileResponse.h */, - 5BC543740C092C697A08396093A0F7BD /* GCDWebServerFileResponse.m */, - DD31B6D267ADAB9B30F51F821C60554A /* GCDWebServerFunctions.h */, - 0555618E1BBA944D30E358F0700CDD8B /* GCDWebServerFunctions.m */, - 57BEC3094A7FB642608645E131DA83D4 /* GCDWebServerHTTPStatusCodes.h */, - D157799A728D6FFED669C62E86BABD73 /* GCDWebServerMultiPartFormRequest.h */, - 0C1C25377D5ADEBBE1E5B44FD42F2BF8 /* GCDWebServerMultiPartFormRequest.m */, - 10F2E7253B70490BD80C987E65C522AC /* GCDWebServerPrivate.h */, - A4395BE2A0C53A82170A01602870453A /* GCDWebServerRequest.h */, - D4E3DADB00C8898A4A01F4DF1034F96C /* GCDWebServerRequest.m */, - 89066EEDE0D03A9B328DADDC9344CC13 /* GCDWebServerResponse.h */, - C40D7DCF882E3A5609EDE1602335E721 /* GCDWebServerResponse.m */, - AE4742C0047EC328BE64C1DF6D868CEF /* GCDWebServerStreamedResponse.h */, - DAE48A7C993FBD43A674E228A900457B /* GCDWebServerStreamedResponse.m */, - 97319F4B64360DC3D794BD7B57BC9936 /* GCDWebServerURLEncodedFormRequest.h */, - DC40BD5F1E0BFED23CB5A6AE57FA4443 /* GCDWebServerURLEncodedFormRequest.m */, - ); - name = Core; - sourceTree = ""; - }; - 9D9694B208E8690D485FD95D4A4C8CAA /* Resources */ = { - isa = PBXGroup; - children = ( - 18B45BFB16E63DDF1AFB6C167D70D1C2 /* cs.lproj */, - 8F90CD66F125C28F8983AFCFA7DF6607 /* de.lproj */, - 4A797B2A249C56CB61DB60A3FEA31FD2 /* en.lproj */, - 4504CA755CE81F89F9F165BF93126D21 /* es.lproj */, - B68B5F9FDDB0D41979766C1D549A8780 /* fr.lproj */, - 321FC2ED515952B66BACDB8CAC130EB4 /* it.lproj */, - B1F34EB08D07E2AF230CDA30F361889D /* ja.lproj */, - A254689F2908346AD7387F063C24B41A /* ko.lproj */, - A94A0417121D2C31F7167E4A79EC5313 /* nl.lproj */, - EE873D31D9227598B067D9426D366009 /* pl.lproj */, - FAB6166D07AACCBF2B4A5FFC66F22602 /* pt.lproj */, - 9A3F0ED147035005ABA4D679F9E36A7B /* ru.lproj */, - FDF7D102C3DA0493A530D68E569DA7CF /* sv.lproj */, - B2BCE49AE180E28B89BBBE037DF32A2F /* zh-Hans.lproj */, - B5D8A52DE9A6385138A6D20CB5527DDB /* zh-Hant.lproj */, - ); - name = Resources; - sourceTree = ""; - }; - A1DDAA49ED6DA408AC4F6220754154E6 /* Pods-proxy_conf_helper */ = { - isa = PBXGroup; - children = ( - 74656C1BF53AED56A45CDA8600A787D1 /* Pods-proxy_conf_helper-acknowledgements.markdown */, - 11F97CBA2FD3653262BC227DD1340D90 /* Pods-proxy_conf_helper-acknowledgements.plist */, - 8752D17209EE8AAD7681107D6444113F /* Pods-proxy_conf_helper-dummy.m */, - D8C88B0B7BFE785BC9B00D1C53FDC003 /* Pods-proxy_conf_helper.debug.xcconfig */, - 4A70BE8C07BCE9C6D6F47AC73225C959 /* Pods-proxy_conf_helper.release.xcconfig */, - ); - name = "Pods-proxy_conf_helper"; - path = "Target Support Files/Pods-proxy_conf_helper"; - sourceTree = ""; - }; - AF01C03E9E6BF3B668D35EEF202AD7A0 /* RxCocoa */ = { - isa = PBXGroup; - children = ( - 3BAD385D5CDC39C1AE6584A123D2DFC4 /* _RX.h */, - 74E6FB11E3F38127740B54FF3C72D1EF /* _RX.m */, - 30E50B8D09D21C042020DA82FA315C59 /* _RXDelegateProxy.h */, - 6AD4414199F479D544CBF1FFF3FB45E4 /* _RXDelegateProxy.m */, - A8A33670952794CBD825EC26F1A98DBF /* _RXKVOObserver.h */, - A14B9E97BE00B01372727FA8DA9B10A3 /* _RXKVOObserver.m */, - 6985BD62945B0A86382437BC1758C282 /* _RXObjCRuntime.h */, - 638797412ABBF2F7725016AF4B056309 /* _RXObjCRuntime.m */, - 2BDFA1D8F5CB80DCE3773C11691B223D /* Bag.swift */, - 98EF0EFA057CC202BD041F55B091661A /* BehaviorRelay+Driver.swift */, - 38724BD70D1712C03FA9B7A4C417144D /* ControlEvent.swift */, - 4C0E4BDE3E30AF8C9062AFAD9C3AEA28 /* ControlEvent+Driver.swift */, - 9C3A35E7DD83A1437478608A9F2EF44C /* ControlEvent+Signal.swift */, - 5878F666B9410A53C5BBE1778D1B2CCE /* ControlProperty.swift */, - 97D6BD38BB9E0F241C3C82A118E7F253 /* ControlProperty+Driver.swift */, - 5DA6A1DA8589C7192C8BFDBC3F4A9913 /* ControlTarget.swift */, - BB63C0EAF763E45BC31AAB9802F87995 /* DelegateProxy.swift */, - DBB7AE66363DEA0FFF31BA0AD1EB9340 /* DelegateProxyType.swift */, - 29E3014CE53E3127CCD38149E2060C76 /* DispatchQueue+Extensions.swift */, - 5E698A2854CB4D9E919B55523EB57D1A /* Driver.swift */, - D7F46244A2FF95EF2B228E2F76529358 /* Driver+Subscription.swift */, - 36C45F96BE0AE01F3BB2C90370A73616 /* Infallible+Bind.swift */, - EC8F5BC5CABB65CCD832B9821F532DBD /* InfiniteSequence.swift */, - 684F8C697CD894D0F5680EE542AC32E9 /* ItemEvents.swift */, - 54F202B17AB2C7DC4FEC3F1CF2B5FD57 /* KVORepresentable.swift */, - C70C13D2EC9B57E48D64BD7ABC49F9D6 /* KVORepresentable+CoreGraphics.swift */, - 6EB5DBBABE4FD6FFF0223AC1BC4674DB /* KVORepresentable+Swift.swift */, - DE18F7CA6E337EA48867C7D92143B6F9 /* NotificationCenter+Rx.swift */, - 6DFC3F4E49698472F1AA8DE21B1BD0F2 /* NSButton+Rx.swift */, - AAFFAAB92EFEC042FEE2F851EF9C6CC0 /* NSControl+Rx.swift */, - C119A4F639217703B4B382419AF9D4EF /* NSObject+Rx.swift */, - 7B00813C768C553C089DAF0C1900799B /* NSObject+Rx+KVORepresentable.swift */, - 4C9EBFDB861299F7DC1241C7FCFF00DD /* NSObject+Rx+RawRepresentable.swift */, - 5874107EF4581DA493B60BBCFE422D1C /* NSSlider+Rx.swift */, - 2C81F8C45A4C248E266304541A86B5A8 /* NSTextField+Rx.swift */, - E35662841C2AAA3188CD9ADFDC38880F /* NSTextStorage+Rx.swift */, - 5800B274C19C06FB1CA12AC039704852 /* NSTextView+Rx.swift */, - C4028B836251B6DD18772CF35047686A /* NSView+Rx.swift */, - E8976DA3C1E5870E7B74F26E219A9885 /* Observable+Bind.swift */, - E14C791F6C2C8320DE732C78C55306A1 /* ObservableConvertibleType+Driver.swift */, - DFAC6355D5B0FD94083A74B4602AF9D2 /* ObservableConvertibleType+SharedSequence.swift */, - C3DCF3854C69F5239CE7E89C1FCFAA51 /* ObservableConvertibleType+Signal.swift */, - 8E801F2049749D5BA709EAE3A2028661 /* Platform.Darwin.swift */, - 2586C5A6499D4E9A6B62C1CF5804DE66 /* Platform.Linux.swift */, - A3A89F3DBB03CFC012C901EB6D452A3B /* PriorityQueue.swift */, - 758B67811993E4C5163D7637EDBB6CFD /* PublishRelay+Signal.swift */, - 9B23D7AFD516825208E6CE9B362989DB /* Queue.swift */, - 5554F4E6979C7DDD1E00F81CB94D474D /* RecursiveLock.swift */, - 7EB9FE74C8220E21EC9A5A77098E9152 /* RxCocoa.h */, - B1816E3DFE7F11350A74B0C1F878F7FC /* RxCocoa.swift */, - 9F666DF6A38D74980DF6F191509F4971 /* RxCocoaObjCRuntimeError+Extensions.swift */, - 95F05E167015F6A202D2BEB9437AE766 /* RxCocoaRuntime.h */, - 78275DA82CA025902C1D6FAF39BC9403 /* RxCollectionViewDataSourcePrefetchingProxy.swift */, - C5BD2C8DB205D16490D3804A6CAB6C50 /* RxCollectionViewDataSourceProxy.swift */, - C0D1BF03B3F26978B85F2E44EBE18FC1 /* RxCollectionViewDataSourceType.swift */, - B9215F3DCBD2FE1BDADCEF5D05219A48 /* RxCollectionViewDelegateProxy.swift */, - B25AD05D537735CCA21E1986D98F830E /* RxCollectionViewReactiveArrayDataSource.swift */, - 52DFCC55A239674DEF17871D293D227C /* RxNavigationControllerDelegateProxy.swift */, - F979292485788BE53E5871123C74EB10 /* RxPickerViewAdapter.swift */, - EC44E7C397DF9B77CEF6F5C86EFCE92A /* RxPickerViewDataSourceProxy.swift */, - 961D7CAE484B6E4929A7BE5B048D29B5 /* RxPickerViewDataSourceType.swift */, - 22D41ECF1E34CC3D83A32F7896831100 /* RxPickerViewDelegateProxy.swift */, - 7B58732AA1AF7EA39B29A8BE85721F26 /* RxScrollViewDelegateProxy.swift */, - 345AE1A0C847584A14AD381D5E476AB9 /* RxSearchBarDelegateProxy.swift */, - 474547C10494F37402A98A0BFC7E6288 /* RxSearchControllerDelegateProxy.swift */, - 39D9FF9E1CBB62DA6FC1910AA45EB039 /* RxTabBarControllerDelegateProxy.swift */, - 66D1DACD1512DCFE82BC525C443DA8A5 /* RxTabBarDelegateProxy.swift */, - C15539256AFFEE061C9DE9660B995B25 /* RxTableViewDataSourcePrefetchingProxy.swift */, - ADC06A8D8266504D3FD0F38F5F1A87AD /* RxTableViewDataSourceProxy.swift */, - D418B4DEE726BA9D5A912D8F1FBF0888 /* RxTableViewDataSourceType.swift */, - B5B1AE9FCFABDD97172220DFDFE618E5 /* RxTableViewDelegateProxy.swift */, - B265FABD755D21851D1C166921BB4A24 /* RxTableViewReactiveArrayDataSource.swift */, - 6B37E46EBF28CB6542B58754F09D8AAA /* RxTarget.swift */, - 95B33DD3F11E0587A32ECE709173E4EF /* RxTextStorageDelegateProxy.swift */, - 531091EE9FF408558B83A1E053360F67 /* RxTextViewDelegateProxy.swift */, - 3AC418FEB3CC60F42D6A18E6151C871A /* RxWKNavigationDelegateProxy.swift */, - 53EB3CB0FCC5ABA4F18B576E6BA4EB1F /* SchedulerType+SharedSequence.swift */, - A4177B545582D09C0D653414E6353741 /* SectionedViewDataSourceType.swift */, - 4F401550E51DCC5F5746B99EC564065B /* SharedSequence.swift */, - D18636DE7B757847E9D7B9E45CA10DE2 /* SharedSequence+Operators.swift */, - 87A94DCCD78781BAE448DEA818B26DE4 /* SharedSequence+Operators+arity.swift */, - 8E4505859B317DCDCC426973F6C7153D /* Signal.swift */, - 12318B6E6BA8040BCC422023A5ABEF27 /* Signal+Subscription.swift */, - 1DBE368EA1C6F7EBE80E08054C9BC6AE /* TextInput.swift */, - 89A41E2A66DF6A8547AFAB72FE74B6A2 /* UIActivityIndicatorView+Rx.swift */, - C78EDD95C0B56A70BE237D148A1726CA /* UIApplication+Rx.swift */, - CB340F626B32E3AF98F1E13658FB46E2 /* UIBarButtonItem+Rx.swift */, - 17F9F190DDBE93E38A56D8405CBFA664 /* UIButton+Rx.swift */, - D49EC557FA27872611535147AB5D700C /* UICollectionView+Rx.swift */, - 9C1FFDE936B5B805CB094F77E95A88FC /* UIControl+Rx.swift */, - 46A83A815027A06FB7A8AB2CEDF56368 /* UIDatePicker+Rx.swift */, - D87FAE60EB40AC65B2E5000C6B82DFEB /* UIGestureRecognizer+Rx.swift */, - 6D742A8B753D54115AD3C6D293B64276 /* UINavigationController+Rx.swift */, - 608BE9EFB078FCC2348EF2782C265D92 /* UIPickerView+Rx.swift */, - 506B13C445D67D7231C25641361EE5A1 /* UIRefreshControl+Rx.swift */, - 441E899D371A5638D8CBD0A21A8CCA61 /* UIScrollView+Rx.swift */, - 2888FA81FD2BE4D3B068BCE4AFDC9A93 /* UISearchBar+Rx.swift */, - 8ED0DC48A18FD32A95BE8B28D715172C /* UISearchController+Rx.swift */, - E39E7221D0BA332CC5AC5DD0A7C16C92 /* UISegmentedControl+Rx.swift */, - 466B399C2E7FFAA61B709F2AB447ECDF /* UISlider+Rx.swift */, - 1B2134E06DD0F0E19694ADD2E46E9EF0 /* UIStepper+Rx.swift */, - 3622945DEBFCB14514027A236BDFC74C /* UISwitch+Rx.swift */, - 21F927D22EA76A49C54C44827DD1CE5A /* UITabBar+Rx.swift */, - 9D4701E49CFDE5F411CDFD316EDD3C70 /* UITabBarController+Rx.swift */, - 51E7C258B34B55C44CAA679574F0B5E1 /* UITableView+Rx.swift */, - 877FA6BB936631CD8F2CA0DFFF6EFC9C /* UITextField+Rx.swift */, - A4BB8686A6F85698D8AC03A77D188340 /* UITextView+Rx.swift */, - EAB5B580FE6B602D602E607C7BC7C470 /* URLSession+Rx.swift */, - FDCA53BCCEFF4720A955F8202537A982 /* WKWebView+Rx.swift */, - 5E93897366D3A44BA737EB9FE037DDB1 /* Support Files */, - ); - path = RxCocoa; - sourceTree = ""; - }; - B364CCC64531E6C6BC03A50131504939 /* Pods-ShadowsocksX-NG */ = { - isa = PBXGroup; - children = ( - 1EA29F7E0E65B6A9619DB77448844EC1 /* Pods-ShadowsocksX-NG.modulemap */, - A907FA326D15CD08847B63032F80EB64 /* Pods-ShadowsocksX-NG-acknowledgements.markdown */, - FB50A95F3BC6DC12244F2B76ABEBB9BD /* Pods-ShadowsocksX-NG-acknowledgements.plist */, - D60357581333E7EC56952E31B2991366 /* Pods-ShadowsocksX-NG-dummy.m */, - 2A11F032AFA3310A3EEE63E67481B01E /* Pods-ShadowsocksX-NG-frameworks.sh */, - 96C80DBAD0A8D59912E005E60636A935 /* Pods-ShadowsocksX-NG-Info.plist */, - CD95085BFAA31431686824B236DB9319 /* Pods-ShadowsocksX-NG-umbrella.h */, - 9A71B9958F30759ED2645E0DF9ADF314 /* Pods-ShadowsocksX-NG.debug.xcconfig */, - 92B4BB091693150E5B1FCC6987683C6F /* Pods-ShadowsocksX-NG.release.xcconfig */, - ); - name = "Pods-ShadowsocksX-NG"; - path = "Target Support Files/Pods-ShadowsocksX-NG"; - sourceTree = ""; - }; - CF1408CF629C7361332E53B88F7BD30C = { - isa = PBXGroup; - children = ( - 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, - 4C712514E3CDE5A583F0DA94CB23FB65 /* Frameworks */, - 14F38608C29A913E1DD0D624DE663510 /* Pods */, - E786B58AC38A5957ED28E1C47257C01E /* Products */, - 493933EC245DE8B9BF6A90C4A901306A /* Targets Support Files */, - ); - sourceTree = ""; - }; - D20BAD07D23FBA7AA269B9FA80FE8BF3 /* BRLOptionParser */ = { - isa = PBXGroup; - children = ( - 31F9576864749334961DE762B01B777C /* BRLOptionParser.h */, - 68C9C3CF6142E1B32695BC562ECAC427 /* BRLOptionParser.m */, - 165807E7BFFB1F57C0BA71AD827D588F /* Support Files */, - ); - path = BRLOptionParser; - sourceTree = ""; - }; - D71126DFC6989B0EEE224402B0C7852C /* MASShortcut */ = { - isa = PBXGroup; - children = ( - 353B178196A1B3A383089B3D1006F66A /* MASDictionaryTransformer.h */, - F6460C30C5328ED85A1103897C8CB63C /* MASDictionaryTransformer.m */, - 8937D9E4BB1CD1D979DFF21019B4D814 /* MASHotKey.h */, - 7BE4993AB90D97D332E61EB54E0C3C9A /* MASHotKey.m */, - 73327356D8055C270C5AFBAEE0D202DD /* MASKeyCodes.h */, - 867FD5BBBCAC1E98FE144867305F8FEF /* MASKeyMasks.h */, - 82A2597C8D9860F95F40565C0631A47D /* MASLocalization.h */, - 46DA81F6288F2733B7F27CCDE97EA2C4 /* MASLocalization.m */, - A2B9727C5385989526550D8E1AC4649A /* MASShortcut.h */, - 7A4A724DBFF9C1C260A76A4B104F3B1E /* MASShortcut.m */, - A18A7F7794D2CC58900E95F6644D63E8 /* MASShortcutBinder.h */, - 46002374E8C8C6F2127C7C9A6DFEF743 /* MASShortcutBinder.m */, - 24121C8FA3C10947BE50901868F9198A /* MASShortcutMonitor.h */, - 605C26B2F1FFA16F0E85E33F5CC526EC /* MASShortcutMonitor.m */, - 8E796A67AE756E845646324A31731334 /* MASShortcutValidator.h */, - 726DEA3A84065F8E12FDE5617447B366 /* MASShortcutValidator.m */, - A2EEB1D58595D58C5DC8978116BE0648 /* MASShortcutView.h */, - 7C73921B2C710D3814A33EF328D04D20 /* MASShortcutView.m */, - B5AEEDAA3124911175E2336A08227588 /* MASShortcutView+Bindings.h */, - 7C471325C18D493A8244DEB1563B18B6 /* MASShortcutView+Bindings.m */, - 6B9491CF676F85A85C4F0987D38F9051 /* Shortcut.h */, - 9D9694B208E8690D485FD95D4A4C8CAA /* Resources */, - 4AE2520FB25EC7AF2FA83B8E69D00ED0 /* Support Files */, - ); - path = MASShortcut; - sourceTree = ""; - }; - E786B58AC38A5957ED28E1C47257C01E /* Products */ = { - isa = PBXGroup; - children = ( - 5D797E9A5C5782CE845840781FA1CC81 /* Alamofire.framework */, - B68C1052A3B51DBCF7D960F898AAFA95 /* GCDWebServer.framework */, - 866C21955F27EBD7A49148F5E63A6E7E /* libBRLOptionParser.a */, - 61C23DB60A84900CD4BDA2F5EE2A0865 /* libPods-proxy_conf_helper.a */, - 230F8208BE63C052A548A7D41A1158B2 /* MASShortcut.bundle */, - 26A8810424438A12E7ADBFB3E068C658 /* MASShortcut.framework */, - D896F6A68919914B3302027C15449A1D /* Pods_ShadowsocksX_NG.framework */, - D48183AD5F98D081078429EF56451DFF /* Pods_ShadowsocksX_NGTests.framework */, - BC432FD48A5932251F1CAFBC4BF74894 /* RxCocoa.framework */, - FF8B264DFE802855D5D67E7CDDABFC3C /* RxRelay.framework */, - 809C5FAB588354C9BA37DC3EAB8CB45C /* RxSwift.framework */, - ); - name = Products; - sourceTree = ""; - }; - E9E177E10E9704C8136B4410D7F621DB /* Support Files */ = { - isa = PBXGroup; - children = ( - 38A6B331CD11EA3ADC9BE7CFD5DE99DA /* RxRelay.modulemap */, - 1718F5B8FAF3CE57AE64B5F53589493F /* RxRelay-dummy.m */, - 52786C2AA26607ED32FA242D407DEC3D /* RxRelay-Info.plist */, - A01C872DE26A61BFEF081FC71E72A0D0 /* RxRelay-prefix.pch */, - 2DDC82F5641636881356BF49166C8DF3 /* RxRelay-umbrella.h */, - BF25DE5F0433D7BA7D6F91A5F113542A /* RxRelay.debug.xcconfig */, - D70A973E907BDE134197952FF14301CE /* RxRelay.release.xcconfig */, - ); - name = "Support Files"; - path = "../Target Support Files/RxRelay"; - sourceTree = ""; - }; - EE196A86A60DA3C09134F038D0679871 /* OS X */ = { - isa = PBXGroup; - children = ( - EA187A944BB7C96464B1E79E6D12F90F /* AppKit.framework */, - 62F5D09616527A0713F24DF416BEC64F /* Carbon.framework */, - 817D9055D7659CAC86800D119F65E0F4 /* CFNetwork.framework */, - EE6672D913C4CDAB5BAC161BDC483A67 /* Cocoa.framework */, - EF91750DCDE73B687E4BA164856BE224 /* SystemConfiguration.framework */, - ); - name = "OS X"; - sourceTree = ""; - }; - F7E043D77B41FA3B6662AD3E792046E8 /* Support Files */ = { - isa = PBXGroup; - children = ( - DFA75B434E18E0DA5F6DEB758B437261 /* GCDWebServer.modulemap */, - 09A0680C8640FDF225CF2A27A4204628 /* GCDWebServer-dummy.m */, - A2738BBB0867C27512A99A3C9DBB2F1E /* GCDWebServer-Info.plist */, - BF07A24C96313F878506258234883CC8 /* GCDWebServer-prefix.pch */, - B400BB6631F1C9F8534BE1CEF160097E /* GCDWebServer-umbrella.h */, - B81749D1C6130BC14B2386B76041124F /* GCDWebServer.debug.xcconfig */, - 2094BFBE78A2839B3C673A3E450C77FC /* GCDWebServer.release.xcconfig */, - ); - name = "Support Files"; - path = "../Target Support Files/GCDWebServer"; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 00CE41EA22C241610DE8C8369C5F8DCC /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 65EA84D8C4EA09B4455BC6C221D2A940 /* Pods-ShadowsocksX-NGTests-umbrella.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 4066ADE1EACF598A77B29ECDD1BC4736 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 0CA982442C8027B672202D753260BAC9 /* RxSwift-umbrella.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 578CC080DFCED687B046D6BDE4585CCB /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 54FFBD61CC8FA5DD12646A7FFAAFE425 /* RxRelay-umbrella.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5C92B9BF5BDADA4C1E469E82F4E59CC5 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 8450D728709DB935952A5A59650DB926 /* MASDictionaryTransformer.h in Headers */, - 332D9AE4473773687AA9155EF16A80D8 /* MASHotKey.h in Headers */, - 12DF0C4E73CEC6118673050B236C7799 /* MASKeyCodes.h in Headers */, - 0EEDE530AD4098CC0660A78E2852DA6A /* MASKeyMasks.h in Headers */, - E5F3CF900C793B92F327E2F4BDF8A8AB /* MASLocalization.h in Headers */, - 5BF5F916582D2EE625A9F0F32ECE709A /* MASShortcut-umbrella.h in Headers */, - 4D15DB973A043E9B4A47B724738A2A5F /* MASShortcut.h in Headers */, - 665FBE569EDC9AF24C721F6B9C7241EC /* MASShortcutBinder.h in Headers */, - 5263ED302CD55D6C365476F9B20AD5D1 /* MASShortcutMonitor.h in Headers */, - 72E6FED1FBFB7D269B435A3802528AA1 /* MASShortcutValidator.h in Headers */, - F07EC9B60B1FB76D9F64FE2BC62A87DF /* MASShortcutView+Bindings.h in Headers */, - 80C7348602C99C09226B1241C02D4754 /* MASShortcutView.h in Headers */, - C33311F020C5777D0CB7E0F61E4FED8D /* Shortcut.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 6584631C190AE58FF259F0472DDC1232 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 6D5EE38D1C1016BBF38E27BDF0AE819C /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - CEA50BEC377AEE2AAA9DB5B71DEA418C /* BRLOptionParser.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 6E03461CB76B22AB26BB407943C2763E /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - E0AF255AB2AFA980F44645355BB7828C /* _RX.h in Headers */, - AC9540D461C3407AB049AEDB94B82375 /* _RXDelegateProxy.h in Headers */, - C83DA2E174587856EBBAAA1763F6D483 /* _RXKVOObserver.h in Headers */, - A34F81BE4A40B0C6EF378FBB8F240C66 /* _RXObjCRuntime.h in Headers */, - C09F690FF2734763D8D2838B0BA14B0F /* RxCocoa-umbrella.h in Headers */, - 815908B08BEA64FC0E5641D046D43CB6 /* RxCocoa.h in Headers */, - 9AA31D499392F8C3E63FE70C8DE816ED /* RxCocoaRuntime.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8070B01910C64B9AFD0DB550EDE38D6B /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 7D3DD4A8BB36733BA15868F7FB8C56CE /* Alamofire-umbrella.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8AC5AA6FFC615596F505AD8BD785D837 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 1D5606C6BD48C543FA0DB2C82B8791B7 /* GCDWebServer-umbrella.h in Headers */, - AECCE1EAA0757255BC4D722A53202DB0 /* GCDWebServer.h in Headers */, - 7D5AE7E56AC7636F1D00076095F57745 /* GCDWebServerConnection.h in Headers */, - 8BEDC2C0D907FBB47A65EE0E01DE2A59 /* GCDWebServerDataRequest.h in Headers */, - 901D8E9CC22C5E7FDB218557EBBB3559 /* GCDWebServerDataResponse.h in Headers */, - F5C3C227785D45C44F1FA8157EF99C71 /* GCDWebServerErrorResponse.h in Headers */, - 4892C3EBD345FAE187A5E15D7FA19CBE /* GCDWebServerFileRequest.h in Headers */, - D33C1AD2E019F48235F734A00CE7C24C /* GCDWebServerFileResponse.h in Headers */, - B47372436C56EE24B909DE97D5005A64 /* GCDWebServerFunctions.h in Headers */, - C341FC8944C28CCA39FB9AC4B0F23763 /* GCDWebServerHTTPStatusCodes.h in Headers */, - FCBF7F9DA53A194F0653EE7E00B57BC8 /* GCDWebServerMultiPartFormRequest.h in Headers */, - DF3FD63D6A37C12FDB09B8CA5AE80AC3 /* GCDWebServerPrivate.h in Headers */, - 6809229B402FC6C91774DA8664AD4F2F /* GCDWebServerRequest.h in Headers */, - 88F5FF298C4C3D2CDCA5EB7B0BE2B52C /* GCDWebServerResponse.h in Headers */, - 1FAEB66513E2610FE37D99FDD8F9E46D /* GCDWebServerStreamedResponse.h in Headers */, - BD379AB5D6DF4FF97EF15732D9635186 /* GCDWebServerURLEncodedFormRequest.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - E23D293CACB5C453B56EBB9A0CC37588 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - F01A39BF2122BF11990A88015EF45A48 /* Pods-ShadowsocksX-NG-umbrella.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 00F92A6698B766C4479D7B608F28D680 /* BRLOptionParser */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6D442598AC59E49374231C4242255CA3 /* Build configuration list for PBXNativeTarget "BRLOptionParser" */; - buildPhases = ( - 6D5EE38D1C1016BBF38E27BDF0AE819C /* Headers */, - DFF2B5F26ABB5074146BB93EA5DBE095 /* Sources */, - EE0D52842751CED2CD0BD2633A30FEA4 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = BRLOptionParser; - productName = BRLOptionParser; - productReference = 866C21955F27EBD7A49148F5E63A6E7E /* libBRLOptionParser.a */; - productType = "com.apple.product-type.library.static"; - }; - 2B2B481A164695722839BD581D442457 /* MASShortcut */ = { - isa = PBXNativeTarget; - buildConfigurationList = E888D466E966B416D89BA302F582A3F5 /* Build configuration list for PBXNativeTarget "MASShortcut" */; - buildPhases = ( - 5C92B9BF5BDADA4C1E469E82F4E59CC5 /* Headers */, - 7A815F2E1A9D4EFD8C4C4BD6D7DC1BCA /* Sources */, - DA3A32D96D94A82A8FFE804468C37DB4 /* Frameworks */, - E8A034F83F762D640CA494BF8161ED87 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 53637CA92B734D4013B9F99E7AAA9808 /* PBXTargetDependency */, - ); - name = MASShortcut; - productName = MASShortcut; - productReference = 26A8810424438A12E7ADBFB3E068C658 /* MASShortcut.framework */; - productType = "com.apple.product-type.framework"; - }; - 2E91F9FD8B0C7DA58DD330CBF2096926 /* Pods-ShadowsocksX-NGTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 84B5ECA69733DA3FEDC652649E6E42C5 /* Build configuration list for PBXNativeTarget "Pods-ShadowsocksX-NGTests" */; - buildPhases = ( - 00CE41EA22C241610DE8C8369C5F8DCC /* Headers */, - F0A91985F4DA9728630FB9ABC81A8CC1 /* Sources */, - F4AB20C615B7CE4E912D4031FF0A52C8 /* Frameworks */, - 8FA2F274BF94CAE07E4B856B3E2F5D77 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - FF103DE3A0523E2D55DE3D845DD9F0E2 /* PBXTargetDependency */, - ); - name = "Pods-ShadowsocksX-NGTests"; - productName = "Pods-ShadowsocksX-NGTests"; - productReference = D48183AD5F98D081078429EF56451DFF /* Pods_ShadowsocksX_NGTests.framework */; - productType = "com.apple.product-type.framework"; - }; - 4622BFEF3DC16E8BD15EEFC30D4D0084 /* RxRelay */ = { - isa = PBXNativeTarget; - buildConfigurationList = 3797157A80385C2407F752CEE1BFEB21 /* Build configuration list for PBXNativeTarget "RxRelay" */; - buildPhases = ( - 578CC080DFCED687B046D6BDE4585CCB /* Headers */, - FEE82C527A384A55B52EF357FAA16C22 /* Sources */, - BA30161BB5D2E74710CBABFCC20E409F /* Frameworks */, - A151D550DD2C543F68445FDB753EF8EF /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 232E22686FEEB70180F984222B39F949 /* PBXTargetDependency */, - ); - name = RxRelay; - productName = RxRelay; - productReference = FF8B264DFE802855D5D67E7CDDABFC3C /* RxRelay.framework */; - productType = "com.apple.product-type.framework"; - }; - 73C37A16ECCEAD845651DCDEE95675BE /* MASShortcut-MASShortcut */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1C26E77821938498151B66E4B3FAFDB5 /* Build configuration list for PBXNativeTarget "MASShortcut-MASShortcut" */; - buildPhases = ( - 3DC69F9E1AADA4EC8478D34D6CE9F516 /* Sources */, - 1514A9A36FD5740CCE236AFAF1DAC5C6 /* Frameworks */, - B729EA1E27F34F10BAEB7F33DC42599A /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "MASShortcut-MASShortcut"; - productName = "MASShortcut-MASShortcut"; - productReference = 230F8208BE63C052A548A7D41A1158B2 /* MASShortcut.bundle */; - productType = "com.apple.product-type.bundle"; - }; - 7AD0C6DCDC9CEC8A3C7C10C7FEE07BE6 /* RxCocoa */ = { - isa = PBXNativeTarget; - buildConfigurationList = ABE56D8D3781109924A96BB7837ED223 /* Build configuration list for PBXNativeTarget "RxCocoa" */; - buildPhases = ( - 6E03461CB76B22AB26BB407943C2763E /* Headers */, - CCF785ECCCE66AF314E3E51FEE3B8E42 /* Sources */, - 6E9985F3EEB339730D49B3D0181E6029 /* Frameworks */, - EE0DFE66B52C1DA23E421D65B412E5CC /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 16E7E2DB71489A3B3A809EE95AF55896 /* PBXTargetDependency */, - F1208697A3C80B8117E54FA1B0E859B1 /* PBXTargetDependency */, - ); - name = RxCocoa; - productName = RxCocoa; - productReference = BC432FD48A5932251F1CAFBC4BF74894 /* RxCocoa.framework */; - productType = "com.apple.product-type.framework"; - }; - 9155E0B9A1C6F689BA4B61F3B690FDA1 /* Pods-proxy_conf_helper */ = { - isa = PBXNativeTarget; - buildConfigurationList = 0D501A92E69AF80E7786DD9C0D172BEC /* Build configuration list for PBXNativeTarget "Pods-proxy_conf_helper" */; - buildPhases = ( - 6584631C190AE58FF259F0472DDC1232 /* Headers */, - 19D1B24F4E402839324A4B4FE36492FB /* Sources */, - 44ABA0E4566A87964594C3AB0F7D2048 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 79DC5AF6E7C88EC75AD6D91A9FF3E011 /* PBXTargetDependency */, - ); - name = "Pods-proxy_conf_helper"; - productName = "Pods-proxy_conf_helper"; - productReference = 61C23DB60A84900CD4BDA2F5EE2A0865 /* libPods-proxy_conf_helper.a */; - productType = "com.apple.product-type.library.static"; - }; - AD904F32069787EFB2DFFE05EB82F5BD /* GCDWebServer */ = { - isa = PBXNativeTarget; - buildConfigurationList = 690C9430B03B92419AFA4555712EC873 /* Build configuration list for PBXNativeTarget "GCDWebServer" */; - buildPhases = ( - 8AC5AA6FFC615596F505AD8BD785D837 /* Headers */, - A169CD366B0A64342FFF6E09CEC61622 /* Sources */, - C2D4774AB2F0BFB25B60914F66C457AC /* Frameworks */, - AE499806FA299FC184E575472A14EE39 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = GCDWebServer; - productName = GCDWebServer; - productReference = B68C1052A3B51DBCF7D960F898AAFA95 /* GCDWebServer.framework */; - productType = "com.apple.product-type.framework"; - }; - E9FDECF69808DB0491D4B4C08CF920DC /* Pods-ShadowsocksX-NG */ = { - isa = PBXNativeTarget; - buildConfigurationList = 975822F53DB5EF99EE2C5EA67BC503C9 /* Build configuration list for PBXNativeTarget "Pods-ShadowsocksX-NG" */; - buildPhases = ( - E23D293CACB5C453B56EBB9A0CC37588 /* Headers */, - 53C1A57011F61182535EA4555B7EE67A /* Sources */, - 7B690F32F695B6718D43BA3D3544C78C /* Frameworks */, - E61A0FC1D432BA45188126B9155D697E /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 18247C9B740C16AA1A1F647B7676E673 /* PBXTargetDependency */, - D38F26CBE0B158CB00FD29413295EBDB /* PBXTargetDependency */, - B2D17789138C47D21E16F60C47053226 /* PBXTargetDependency */, - 41031387B219D54FF7673356F1696E11 /* PBXTargetDependency */, - 7DABF5696F48F5C2D50C0A3DE25289EE /* PBXTargetDependency */, - 0403456DEA90C0614E5AFBAE92D06199 /* PBXTargetDependency */, - ); - name = "Pods-ShadowsocksX-NG"; - productName = "Pods-ShadowsocksX-NG"; - productReference = D896F6A68919914B3302027C15449A1D /* Pods_ShadowsocksX_NG.framework */; - productType = "com.apple.product-type.framework"; - }; - EA9EA43B3B503823EE36C60D9C8A865F /* RxSwift */ = { - isa = PBXNativeTarget; - buildConfigurationList = 6331D6AD3A4489B8CBA44A44D38FD80A /* Build configuration list for PBXNativeTarget "RxSwift" */; - buildPhases = ( - 4066ADE1EACF598A77B29ECDD1BC4736 /* Headers */, - 17A2675A401E7A47A2A85F5E0DE8CFFB /* Sources */, - B3C5909F9901CF3F5237F1832E214556 /* Frameworks */, - 046A991884442073662E8396D30686EE /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = RxSwift; - productName = RxSwift; - productReference = 809C5FAB588354C9BA37DC3EAB8CB45C /* RxSwift.framework */; - productType = "com.apple.product-type.framework"; - }; - EAAA1AD3A8A1B59AB91319EE40752C6D /* Alamofire */ = { - isa = PBXNativeTarget; - buildConfigurationList = 78E219AC01CD5AFED663C9AB28280801 /* Build configuration list for PBXNativeTarget "Alamofire" */; - buildPhases = ( - 8070B01910C64B9AFD0DB550EDE38D6B /* Headers */, - 2C8326877F6A9617C2FBE9BD15D95B59 /* Sources */, - E4B8CC1E36A98FF4D8BDAC84442F0DCE /* Frameworks */, - 9BCA7D105D531AE5DAF34FB86A2E623A /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Alamofire; - productName = Alamofire; - productReference = 5D797E9A5C5782CE845840781FA1CC81 /* Alamofire.framework */; - productType = "com.apple.product-type.framework"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - BFDFE7DC352907FC980B868725387E98 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 1100; - LastUpgradeCheck = 1250; - }; - buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = CF1408CF629C7361332E53B88F7BD30C; - productRefGroup = E786B58AC38A5957ED28E1C47257C01E /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - EAAA1AD3A8A1B59AB91319EE40752C6D /* Alamofire */, - 00F92A6698B766C4479D7B608F28D680 /* BRLOptionParser */, - AD904F32069787EFB2DFFE05EB82F5BD /* GCDWebServer */, - 2B2B481A164695722839BD581D442457 /* MASShortcut */, - 73C37A16ECCEAD845651DCDEE95675BE /* MASShortcut-MASShortcut */, - 9155E0B9A1C6F689BA4B61F3B690FDA1 /* Pods-proxy_conf_helper */, - E9FDECF69808DB0491D4B4C08CF920DC /* Pods-ShadowsocksX-NG */, - 2E91F9FD8B0C7DA58DD330CBF2096926 /* Pods-ShadowsocksX-NGTests */, - 7AD0C6DCDC9CEC8A3C7C10C7FEE07BE6 /* RxCocoa */, - 4622BFEF3DC16E8BD15EEFC30D4D0084 /* RxRelay */, - EA9EA43B3B503823EE36C60D9C8A865F /* RxSwift */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 046A991884442073662E8396D30686EE /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8FA2F274BF94CAE07E4B856B3E2F5D77 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 9BCA7D105D531AE5DAF34FB86A2E623A /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A151D550DD2C543F68445FDB753EF8EF /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - AE499806FA299FC184E575472A14EE39 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B729EA1E27F34F10BAEB7F33DC42599A /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D557532ED179C1F26074DCD602EF357D /* cs.lproj in Resources */, - FF36522388E5964B78AD72A59721AADC /* de.lproj in Resources */, - 02AEF100BA92B652E6E48EF58B479533 /* en.lproj in Resources */, - 4319C0B97542219FCA256B790FE90C1C /* es.lproj in Resources */, - C3D17F4F92CD46A4285A92D1FD6AA4B1 /* fr.lproj in Resources */, - 325A6428E460396F0B0CB9B6FE10EEC4 /* it.lproj in Resources */, - 9389C4BF3F440F2503FFEB8BBC8975C8 /* ja.lproj in Resources */, - 63257249A72693C87BF365F343DA1D36 /* ko.lproj in Resources */, - B90A504C57627AFCC56F0608D321FB31 /* nl.lproj in Resources */, - F4C5E42370FEF310E72D2A8DAD2993FB /* pl.lproj in Resources */, - 82764E2E2DA3FD699FC5B659ED35D9AE /* pt.lproj in Resources */, - 313170D278E51360492948E6BB704EA7 /* ru.lproj in Resources */, - 809C371060C874FBEF8FECDF197D74E3 /* sv.lproj in Resources */, - 7094648D68C944D337CE86C10F8EEB04 /* zh-Hans.lproj in Resources */, - 91C85BAD47B39F365F260E74AB24693D /* zh-Hant.lproj in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - E61A0FC1D432BA45188126B9155D697E /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - E8A034F83F762D640CA494BF8161ED87 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D37A995029438A503B62B1D2ACFE9247 /* MASShortcut.bundle in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - EE0DFE66B52C1DA23E421D65B412E5CC /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 17A2675A401E7A47A2A85F5E0DE8CFFB /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 741E51A8D9DE26331ABB938B3BD5751A /* AddRef.swift in Sources */, - 6B105A67121436E162ADE05A682BEA71 /* Amb.swift in Sources */, - 08FE05B1BA0A6D9CE971027E0480350A /* AnonymousDisposable.swift in Sources */, - B7B31CEFFD225FE0DE33DA0CAAFB46BB /* AnonymousObserver.swift in Sources */, - F621486B5084C21DA2498C0FC6A85E02 /* AnyObserver.swift in Sources */, - BACB203DEE570915EDEC3E701158A173 /* AsMaybe.swift in Sources */, - 7B0FB5B7BF42B15FDF1FCE073D8C4C21 /* AsSingle.swift in Sources */, - 4BEC411F5B170048C65D315C87832600 /* AsyncLock.swift in Sources */, - 47E487EF80C53073DBFE5F5FD6BCFF0E /* AsyncSubject.swift in Sources */, - A9AFA432B293A80CF9B1ABD1285A4705 /* AtomicInt.swift in Sources */, - 6CDC5000511AB1CF616FEBB8A856AE58 /* Bag+Rx.swift in Sources */, - 9AC6705C60E05CAB6115BA7603BDC0F6 /* Bag.swift in Sources */, - 77093BBAB8F2F51540322CB14BD2C178 /* BehaviorSubject.swift in Sources */, - A9E6EFE85136C81C4AD5BF1CC1B990FD /* BinaryDisposable.swift in Sources */, - 695A83FEFDFE24858DDC37BD64DBBA33 /* Binder.swift in Sources */, - C7A325790D6CB1C3545FE9E688545C56 /* BooleanDisposable.swift in Sources */, - 90B5B048AE70F82175F8A3DB72EF601E /* Buffer.swift in Sources */, - 2FD49578803778A2F094C0B21FEE332C /* Cancelable.swift in Sources */, - 0A20A09C199A4692A8EA72497B3D504A /* Catch.swift in Sources */, - 14403B39AC36562E41D4768CCF3540B1 /* CombineLatest+arity.swift in Sources */, - BEF81EB8E8A3FB2B8519CDF1C6DEDA1E /* CombineLatest+Collection.swift in Sources */, - 017170EB9F2450569816AB0FF2E6D541 /* CombineLatest.swift in Sources */, - EB8C4B9D8DFF39ECFE8538B73F5717F7 /* CompactMap.swift in Sources */, - 64F43894B4404E7BDE27A5C8BE96E0AE /* Completable+AndThen.swift in Sources */, - C0EA3A392A5229080E52F9FDF969FDC8 /* Completable.swift in Sources */, - 07326CA68F757A1C82495BB52A92BD5C /* CompositeDisposable.swift in Sources */, - 5F7CE7907DC769D3E61980B80D20A275 /* Concat.swift in Sources */, - ABDF69C30364D8B9BDFDA8D82A797396 /* ConcurrentDispatchQueueScheduler.swift in Sources */, - DD24A504D1BB91B71B67B4A93A92F1DA /* ConcurrentMainScheduler.swift in Sources */, - E83CDC839BC5CA753A57BE04CB66F85D /* ConnectableObservableType.swift in Sources */, - AE143D6485273A676FF9FBF637EE32B3 /* Create.swift in Sources */, - D13BDCB5C86CD4018E19F1DA207BA61A /* CurrentThreadScheduler.swift in Sources */, - 90429156F020B4490158F6686EEFCB02 /* Date+Dispatch.swift in Sources */, - 0722A6B0D2DE0B9620F5C9659CB679D8 /* Debounce.swift in Sources */, - D597C1B3CBDE4896A022E9422A4F4874 /* Debug.swift in Sources */, - D21D80287E6B1C56E0BE86B1E3F08249 /* Decode.swift in Sources */, - ADF86969180231C97A14929F02866A1E /* DefaultIfEmpty.swift in Sources */, - 519260344D4291AA4C1CEAD7711B1489 /* Deferred.swift in Sources */, - 3212BC4884F26AE9244A7548691A0CE0 /* Delay.swift in Sources */, - A6652D3942752A05ED133DB77C955216 /* DelaySubscription.swift in Sources */, - 1A630AD9EFDB068A1544BD51CA5E99B7 /* Dematerialize.swift in Sources */, - 6E75ECF4BDC7AF83E3151274539DFF93 /* DispatchQueue+Extensions.swift in Sources */, - BAC5C3D7F895C6A95B5EA70D1C4BB998 /* DispatchQueueConfiguration.swift in Sources */, - E06F7DEDC12A706F1AA7067CA7D58BD8 /* Disposable.swift in Sources */, - 0D8B936D823A959DDE9005A1C1D89487 /* Disposables.swift in Sources */, - 109ADA4349083858A198CA863E457E37 /* DisposeBag.swift in Sources */, - 3D8428BE717C8E76FA50C1D8B93561EE /* DisposeBase.swift in Sources */, - 9F77A1FFC61AF7C54E88B7436893C91B /* DistinctUntilChanged.swift in Sources */, - F1F7AF19C5D50FB5BCD1D357FB9A5946 /* Do.swift in Sources */, - 44D30DA4840EF46F1C4BCEA6179AAE60 /* ElementAt.swift in Sources */, - D6389E438CF72863B7F4832592B60428 /* Empty.swift in Sources */, - 0E7C902AB09DA1CA05D07D36BD55C73E /* Enumerated.swift in Sources */, - 84E576015933A4F6F431759174C62956 /* Error.swift in Sources */, - 2375AD3B88ECB4A1C01F9F70DCFB05E7 /* Errors.swift in Sources */, - E46EB73E26A44700E41C3CD2F1E847FD /* Event.swift in Sources */, - 52CB53A7C3EF4BD88F73996450B73AA7 /* Filter.swift in Sources */, - E5A162C30F57D3A21BD9D74BC97E782E /* First.swift in Sources */, - E9C69CBF2B72EC9A5031BA6FF30BC251 /* Generate.swift in Sources */, - 7885432DE1DDE9F2A4607033B2808E5B /* GroupBy.swift in Sources */, - B3C0F4C71E972214529455424C69E544 /* GroupedObservable.swift in Sources */, - 2453CFD81C667B99753FF8354AA82C60 /* HistoricalScheduler.swift in Sources */, - 6CA2AE8DA8D630D83FAED6FC2F081967 /* HistoricalSchedulerTimeConverter.swift in Sources */, - B4E0DA5CB21C859040F39077A2731701 /* ImmediateSchedulerType.swift in Sources */, - 99E2AEBB5C39DB1661C5C03DDAA451EC /* Infallible+CombineLatest+arity.swift in Sources */, - 66207468882614FB8CE9896DC4250F13 /* Infallible+Create.swift in Sources */, - 4B9CC90686F274845EBBB82F230C11EE /* Infallible+Operators.swift in Sources */, - 1EC23A9ACE471AAE845CE9ACD4588932 /* Infallible+Zip+arity.swift in Sources */, - 652118C36365C28E76826357E309EADE /* Infallible.swift in Sources */, - B59F717CE3CD531818EAFE88FBB454AA /* InfiniteSequence.swift in Sources */, - 3AB06F4DB0A01BA8F6662D0EDC495981 /* InvocableScheduledItem.swift in Sources */, - 4A33F1A7BD2AD1F318E081E17B0AA80F /* InvocableType.swift in Sources */, - EA82A6A287EA96119DF03722AB2F25B8 /* Just.swift in Sources */, - 6D5BDAE5D8D991B874AD4D7FF2EA7C8C /* Lock.swift in Sources */, - 830F06C3D23016D62112E4BA1C22A766 /* LockOwnerType.swift in Sources */, - 34C033CDDD8217EE4221E9BDFFC23086 /* MainScheduler.swift in Sources */, - F1A73AB066B6EC8C012F4044B542568D /* Map.swift in Sources */, - E5F1157CAB86D8C0C166874A6E826739 /* Materialize.swift in Sources */, - 2C8A055494092F137EDB2E3BDCA74DFC /* Maybe.swift in Sources */, - 9360BB098EFD18F90BA16149E8EF8A34 /* Merge.swift in Sources */, - 42DBD7750A47DE5273041BDEE8850195 /* Multicast.swift in Sources */, - 8F66042610AE99F62D17E50EF0C83B0D /* Never.swift in Sources */, - 4C6CC049B53AF49050AD6428C5B50AB0 /* NopDisposable.swift in Sources */, - 432B3CB444984CCCFB4EF37E2D762F05 /* Observable.swift in Sources */, - F89A75BE493264635F9977B0A9233617 /* ObservableConvertibleType+Infallible.swift in Sources */, - A0F9BB688F14F5B350A388BA60C184A0 /* ObservableConvertibleType.swift in Sources */, - 3E6A74677BA3612A449B323631B44559 /* ObservableType+Extensions.swift in Sources */, - 11B06B47E4CB24A05B1299D730643803 /* ObservableType+PrimitiveSequence.swift in Sources */, - 2CD9AC66F1727C363449C4072DA57F89 /* ObservableType.swift in Sources */, - 0A8A30C3BF493120607DD0157A560065 /* ObserveOn.swift in Sources */, - DCC8DE3CDC74A5E38864303C8C2404EF /* ObserverBase.swift in Sources */, - 7B99EC9A5D3CF7B6DE0330773143F15F /* ObserverType.swift in Sources */, - 516E4177ED65653EA9DAADBA3CF3FBED /* OperationQueueScheduler.swift in Sources */, - CCE2D9FB50D6084FD48013ED3474F992 /* Optional.swift in Sources */, - 73E48515343BD4E57358BAD9F3B2F590 /* Platform.Darwin.swift in Sources */, - 27C5636F69D717D7745A0235D715E4FB /* Platform.Linux.swift in Sources */, - B21C782362344F1FBCA4C5792EC1DED4 /* PrimitiveSequence+Zip+arity.swift in Sources */, - B6634C3C7216D0A7B063174C16BA1922 /* PrimitiveSequence.swift in Sources */, - 8EEA6795ED2806C80FBE6A00B615CB76 /* PriorityQueue.swift in Sources */, - ED82861E104428E8C3FA8D1B2618C875 /* Producer.swift in Sources */, - A3D78B5A2E0E6B987B021DA58CA55BEB /* PublishSubject.swift in Sources */, - 9141315B460BE4CD3030B62BE7692B73 /* Queue.swift in Sources */, - 5E3681E1F77D4A9B58F332348935EE8C /* Range.swift in Sources */, - 6A3972E7F1ACA4CEE36E0AA3B2BA34FB /* Reactive.swift in Sources */, - 1C0A940E6D4FD420BEC04B9F16914D71 /* RecursiveLock.swift in Sources */, - 262C2E49711CEA356F7C2031AE074C8A /* RecursiveScheduler.swift in Sources */, - 774C726DE2716860799DAEAD0B801A94 /* Reduce.swift in Sources */, - C0ACE318CA3576826A53026F9C253E0B /* RefCountDisposable.swift in Sources */, - 4728113A1BA4AE948E1B2FB610A473B4 /* Repeat.swift in Sources */, - C81FF014587AC7E1A51D4F3F2C6F72EA /* ReplaySubject.swift in Sources */, - 9D5CD154B7C49DA0BCBFF996CA9A6E62 /* RetryWhen.swift in Sources */, - A9DD82DFCFA49DC81169D82415DE7B94 /* Rx.swift in Sources */, - 0A4DF5D6FC29A34C999E1ECBB53C696B /* RxMutableBox.swift in Sources */, - 8EB4272CE33A59083F0DC9746C0F71D0 /* RxSwift-dummy.m in Sources */, - A4CE525F7E6904D7D244727C90DBDBE2 /* Sample.swift in Sources */, - 5CDF229542C4FC347E9D1DFDBAC8B230 /* Scan.swift in Sources */, - 9F794FB773B632DAC0416008A8EC3F45 /* ScheduledDisposable.swift in Sources */, - AA5CBA43C0BF98751988A758EB180BA6 /* ScheduledItem.swift in Sources */, - 14E31D647AFA8F0FBE3793EF61872247 /* ScheduledItemType.swift in Sources */, - 10993D369AADB3E2BCA4E966DE514C09 /* SchedulerServices+Emulation.swift in Sources */, - 4C88ED296D3687C973B0472D047CE3E8 /* SchedulerType.swift in Sources */, - D57542063237724C1CA2962EAC1764C7 /* Sequence.swift in Sources */, - 2D890B63806F7465912098B60052B092 /* SerialDispatchQueueScheduler.swift in Sources */, - 239AC2D5500F4E4FB04BC341A1335DF7 /* SerialDisposable.swift in Sources */, - 4EC10410410410FF3A33C6015FD5927D /* ShareReplayScope.swift in Sources */, - D574A95C82CDFCC40442A4C5A20645D9 /* Single.swift in Sources */, - B936FB1A1779B971BCE58D1CFB84036B /* SingleAssignmentDisposable.swift in Sources */, - FAEF22DB65A2C18EAF044623FF4ECA43 /* SingleAsync.swift in Sources */, - 4673A5004D211FA68BB8506B9A323034 /* Sink.swift in Sources */, - 83470A9EFB9948DED806CC1D1233D21C /* Skip.swift in Sources */, - D0B9EA4DC98653D58DEAE9629A2F0285 /* SkipUntil.swift in Sources */, - DBFA45EBB79E16D7B6780CDA789B0D08 /* SkipWhile.swift in Sources */, - 7CF0187F571D299FE14788318D720152 /* StartWith.swift in Sources */, - 0FB5F248B62BC1F0113E53461E807AE5 /* SubjectType.swift in Sources */, - B9C2804D9E9FD66CF22595DBFED0DC79 /* SubscribeOn.swift in Sources */, - FA547DB169BA1CB0759702BA51F1C52E /* SubscriptionDisposable.swift in Sources */, - BB15F798287F7447B78B4D49522030C4 /* SwiftSupport.swift in Sources */, - 535519D2B25D1784AA6D6A9BDE60C759 /* Switch.swift in Sources */, - A5DC2335899B03F0130A9C739319C92A /* SwitchIfEmpty.swift in Sources */, - CE622A228B2F310835326CCF0B83F031 /* SynchronizedDisposeType.swift in Sources */, - BC184A6D6502B7B4B308496F5172E4FE /* SynchronizedOnType.swift in Sources */, - 543010884F5B7C1F2920A0DF33A3A9D1 /* SynchronizedUnsubscribeType.swift in Sources */, - D661EA5F16B11BEE347BAE35961A3AD2 /* TailRecursiveSink.swift in Sources */, - 601A69113478A1336ADA98C7658D2355 /* Take.swift in Sources */, - 14C185529F30494F6B6F0DFA9AEDDC05 /* TakeLast.swift in Sources */, - 44C45DEC66DB1FBBA5F850E79057DC13 /* TakeWithPredicate.swift in Sources */, - 3BAE1C06A091DFA7A91F93BD40BD41B9 /* Throttle.swift in Sources */, - 69D750E3DAB2F11E37761A204A145883 /* Timeout.swift in Sources */, - 1DF080CB9D37CB063C6FEC09BBF8F238 /* Timer.swift in Sources */, - A7A81BFC5D65FDB665AC19E78D4F21B6 /* ToArray.swift in Sources */, - DDA573352B48255CA674E8BB62C306C6 /* Using.swift in Sources */, - 8B67845A8F56DF49F8B22B1BB63C5E10 /* VirtualTimeConverterType.swift in Sources */, - 1B341070BA8EB97021BE7C152639CBF5 /* VirtualTimeScheduler.swift in Sources */, - 9FC8EA2F7B3939D69D1469F9046B166A /* Window.swift in Sources */, - F5E8D9EC4166B35C084791CAEFF2404C /* WithLatestFrom.swift in Sources */, - E26E725D6366FA3AE20B95802F54C4B6 /* WithUnretained.swift in Sources */, - 2B540E502B0EE71D93636BA94B9F0817 /* Zip+arity.swift in Sources */, - 9C3D3F75523B1B1BB4B3051C01F8F6FE /* Zip+Collection.swift in Sources */, - FC22B1E68007E6AC40CC8DF2DF5E0AB6 /* Zip.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 19D1B24F4E402839324A4B4FE36492FB /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - E52E9DB2E0EB574ED157EB478E60D13D /* Pods-proxy_conf_helper-dummy.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 2C8326877F6A9617C2FBE9BD15D95B59 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 1208E81DA8B532D0646D627B50290EB6 /* AFError.swift in Sources */, - C6D5A4B4028B2C43380C9FA58BD5C8CA /* Alamofire-dummy.m in Sources */, - C1F1DB6A9CBDE584D09BA1613AAD4F9D /* Alamofire.swift in Sources */, - 72EC2712926E6D28B52360D9AC41668F /* AlamofireExtended.swift in Sources */, - DC627AFC5B585686898B014184AFCABD /* AuthenticationInterceptor.swift in Sources */, - ABA85887A41495358C83CE3F3030EDEA /* CachedResponseHandler.swift in Sources */, - 0A1849775CF90D514963187D3A771CF8 /* Combine.swift in Sources */, - 27E59A11A2743B0595CDE3A08675EAE1 /* DispatchQueue+Alamofire.swift in Sources */, - 6546D728B69398F93B506845141EBD61 /* EventMonitor.swift in Sources */, - 91B837CE0DCD8EDB300FCDFFA1279162 /* HTTPHeaders.swift in Sources */, - 013BAC24F7AC722E59517CB110A9E685 /* HTTPMethod.swift in Sources */, - 45B8CC1C61E7A0BB28CFA8CE7C12FEBC /* MultipartFormData.swift in Sources */, - D03F1F02DE8606E6057D57866611BEBF /* MultipartUpload.swift in Sources */, - 19D605A3233499828FB6B790869F3E9C /* NetworkReachabilityManager.swift in Sources */, - 8AA937910F87915DE700CAB6C868689E /* Notifications.swift in Sources */, - 0A900DF17E3B64F08AF673E9A0DDD697 /* OperationQueue+Alamofire.swift in Sources */, - 4AEC050FA7D5ED52FDA9DF50EA3560DF /* ParameterEncoder.swift in Sources */, - D14066FAE94E304798E43651E5886D13 /* ParameterEncoding.swift in Sources */, - 218C14EAE5AA31C30314AE0289B732A0 /* Protected.swift in Sources */, - 666EC5C8356E6D4448A2FE7BEE77AD88 /* RedirectHandler.swift in Sources */, - EDC93BD7B9262119AE145E4C7A9D0212 /* Request.swift in Sources */, - 6E54F64E8DA73F4B0B46C216F9F93F63 /* RequestInterceptor.swift in Sources */, - 6C08F6A77889651626583100F560153D /* RequestTaskMap.swift in Sources */, - C1C5B050B55C15103ABC81769551A283 /* Response.swift in Sources */, - 911448B2EDA2FF880108F77642797A88 /* ResponseSerialization.swift in Sources */, - 66B26C6CAE737EC21F4BA1F1851B69C5 /* Result+Alamofire.swift in Sources */, - 9FED70D1E1FBFB80E974E999EF732258 /* RetryPolicy.swift in Sources */, - 47FDBBBD2704901588C3A7C56BBC502D /* ServerTrustEvaluation.swift in Sources */, - 6AE407A4FB6C3D6ADD862CC6E3067A17 /* Session.swift in Sources */, - 381FF05F8B4F611EE9C2FDBE4457BB89 /* SessionDelegate.swift in Sources */, - 212EDC48B68107BEA9247F3464CE696E /* StringEncoding+Alamofire.swift in Sources */, - 9B1D8A7798D8A6F518FC9AF9725431D0 /* URLConvertible+URLRequestConvertible.swift in Sources */, - D31FC7FDD450C4CDD633ECBAD27C6221 /* URLEncodedFormEncoder.swift in Sources */, - D5EAAFB6FAD77A8F0699345149BA3CBB /* URLRequest+Alamofire.swift in Sources */, - F70EF854395CDE981A8336E4FF0310FE /* URLSessionConfiguration+Alamofire.swift in Sources */, - F0F3224FF592F9BA2A044A2FC2BD4CCD /* Validation.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 3DC69F9E1AADA4EC8478D34D6CE9F516 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 53C1A57011F61182535EA4555B7EE67A /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B3E529B0C5581EFBE667B478A97681F6 /* Pods-ShadowsocksX-NG-dummy.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 7A815F2E1A9D4EFD8C4C4BD6D7DC1BCA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F6F5712CC3ED7DD4D51BA12747FCDE6E /* MASDictionaryTransformer.m in Sources */, - DADE159BB4CF9E438FC5DEF80822A710 /* MASHotKey.m in Sources */, - B1501E5B044C314A7E3E08D5172CE6C4 /* MASLocalization.m in Sources */, - 563C41694A1B06EF34752E894297D3FA /* MASShortcut-dummy.m in Sources */, - 1AECEBA213A2C9E6EC56C2C1358849E4 /* MASShortcut.m in Sources */, - FB425C8625656D7AE2AFD1F8A78713B0 /* MASShortcutBinder.m in Sources */, - F515F0E56CBF807E49797455E495074C /* MASShortcutMonitor.m in Sources */, - F9C743AF2433172C84F9365D8DE8CBF3 /* MASShortcutValidator.m in Sources */, - A2F246B7FCDC421BE6098866AA1509C9 /* MASShortcutView+Bindings.m in Sources */, - 805003984E8CFD3375B935DC772A7BF3 /* MASShortcutView.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A169CD366B0A64342FFF6E09CEC61622 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 1C11628696BD0C889E0A4FC6CA4B6922 /* GCDWebServer-dummy.m in Sources */, - E9B95D42F4510C79E2D8A8CFA251CD49 /* GCDWebServer.m in Sources */, - D260B45339932BAA56D7024048E2D155 /* GCDWebServerConnection.m in Sources */, - CD782D1189ADBAA42D087B87D53838A0 /* GCDWebServerDataRequest.m in Sources */, - 3BBEC4A24B60E2276CBC26E555F64F41 /* GCDWebServerDataResponse.m in Sources */, - D5E020763D69E9336EB398ACD48FEBB0 /* GCDWebServerErrorResponse.m in Sources */, - 4940AB8BC3936DEBDC02BF49FE5E97A1 /* GCDWebServerFileRequest.m in Sources */, - 99ABB4C207FE146C78313E8A9A581FD6 /* GCDWebServerFileResponse.m in Sources */, - 36DED9F6B7737F022FB0B01ECE2BB88E /* GCDWebServerFunctions.m in Sources */, - 221F057199246D7709DD91C950746B7B /* GCDWebServerMultiPartFormRequest.m in Sources */, - BF1EB892BE3CF9CDFA0DAC7F9392435C /* GCDWebServerRequest.m in Sources */, - 3685E20BBC5AFEA3BC80FE12732AB269 /* GCDWebServerResponse.m in Sources */, - F7DAD2EF3F86BC40F7D4F2EE49362418 /* GCDWebServerStreamedResponse.m in Sources */, - 5989329B01C0737EFDB490C5A771FDC2 /* GCDWebServerURLEncodedFormRequest.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - CCF785ECCCE66AF314E3E51FEE3B8E42 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - AED84FBEE9189CFC8A946DDC2BFCB2BE /* _RX.m in Sources */, - 62DF258CA1EA9A41A99B93052A72DAB0 /* _RXDelegateProxy.m in Sources */, - 999CAB83E4F6D824DF56B2B755C0B588 /* _RXKVOObserver.m in Sources */, - 4E095DE808150F9350BB9CB3C99A37B2 /* _RXObjCRuntime.m in Sources */, - BD386D2A7F6652D62B9E75803D3AAD3B /* Bag.swift in Sources */, - 75917BCA0645283EC7D9CC3ADEE6DB4F /* BehaviorRelay+Driver.swift in Sources */, - 12E8D9F9C1A9B4FC7669C18954BC4798 /* ControlEvent+Driver.swift in Sources */, - A8EEAAF6FACD8832BE7E4A6331ED57E4 /* ControlEvent+Signal.swift in Sources */, - FD397CD62192F67DF9C2088CC5EBE409 /* ControlEvent.swift in Sources */, - 99210D61FFF596695086F3E51D893204 /* ControlProperty+Driver.swift in Sources */, - E9FD5789C7C4946FC504E7C679BDD156 /* ControlProperty.swift in Sources */, - F44EF6685A8C029EAC293DE9FADC3794 /* ControlTarget.swift in Sources */, - 872E07F59296D07A405BAB9C36936AC8 /* DelegateProxy.swift in Sources */, - 70359E1C7BAA76860EA35A607CCC4309 /* DelegateProxyType.swift in Sources */, - 30536C64EAA45BE64894B48D74144B1E /* DispatchQueue+Extensions.swift in Sources */, - F45717BF2118BB61C328A1F67CFE9238 /* Driver+Subscription.swift in Sources */, - B8B7E2AC4972978F6894F9C22936CA42 /* Driver.swift in Sources */, - A8DBBA1BD18472113BBE931A3F949659 /* Infallible+Bind.swift in Sources */, - 16C263170733039596369C8D4F89077A /* InfiniteSequence.swift in Sources */, - F186B25E38062738E07F219D0289CBFA /* ItemEvents.swift in Sources */, - 3596F8FDA81BECFE1B05B50500447638 /* KVORepresentable+CoreGraphics.swift in Sources */, - 2862DA4097D964B745862F00BB45759D /* KVORepresentable+Swift.swift in Sources */, - C8422B20017685DE0D693EC679FF8BF6 /* KVORepresentable.swift in Sources */, - A2526FE80C9370555D66A0A33EA22E44 /* NotificationCenter+Rx.swift in Sources */, - A9DFF7177D374AF79EEAD9F34B66569A /* NSButton+Rx.swift in Sources */, - BB322452A0B606428489BA2B2F6D3715 /* NSControl+Rx.swift in Sources */, - CA391E5CE794FA6D964DC2DFC8B8E109 /* NSObject+Rx+KVORepresentable.swift in Sources */, - E816A86AE437A96B389D73C115778CFA /* NSObject+Rx+RawRepresentable.swift in Sources */, - 85CD565FB8198B084806FE075B268AB5 /* NSObject+Rx.swift in Sources */, - 7BD242803D2ADF6E50A27C3542C8695D /* NSSlider+Rx.swift in Sources */, - A525A6AE79BA19A9BDEA467D31477916 /* NSTextField+Rx.swift in Sources */, - 58D3BBBF801B54CC74FAAC0374F1948D /* NSTextStorage+Rx.swift in Sources */, - B261ED81ABD31C88EAC460E27E453FAE /* NSTextView+Rx.swift in Sources */, - C0E1B20534F498B9891E956388D79209 /* NSView+Rx.swift in Sources */, - F8C1D484E959F9ADD96E9CD2F3B045B0 /* Observable+Bind.swift in Sources */, - AB83592C5AA99079DA59151D2ACDFBE2 /* ObservableConvertibleType+Driver.swift in Sources */, - E8064C59B797763270D65097B4CD075B /* ObservableConvertibleType+SharedSequence.swift in Sources */, - BC03F491551F314E102DEB2F96110609 /* ObservableConvertibleType+Signal.swift in Sources */, - D0C4275AF3346D1C08B187D04D9606F2 /* Platform.Darwin.swift in Sources */, - 2BD53F1C421E9938A099F3F45C84FBAD /* Platform.Linux.swift in Sources */, - 39988540E9F936FE5085117BB8F32FAC /* PriorityQueue.swift in Sources */, - 934592C980EE09EEE5F4B5074C6A56D8 /* PublishRelay+Signal.swift in Sources */, - 440BDCF5820801BC8A6D740C48EEAB8E /* Queue.swift in Sources */, - 786C836C43BD6428332A4001EE13816F /* RecursiveLock.swift in Sources */, - E1AD1FE46FE8F693F913FEC190210A59 /* RxCocoa-dummy.m in Sources */, - 23CF55A9FA514BDCA0B46320D4ED5DEC /* RxCocoa.swift in Sources */, - 6A5300346FF40392C6A4B5908AA9C027 /* RxCocoaObjCRuntimeError+Extensions.swift in Sources */, - 080F0457EB8E6A9F2841FB0D77AEEF42 /* RxCollectionViewDataSourcePrefetchingProxy.swift in Sources */, - FDEBCA25E0674ADFB66FA6256FF6486F /* RxCollectionViewDataSourceProxy.swift in Sources */, - 51B830516D57359FAB42031193E47CB1 /* RxCollectionViewDataSourceType.swift in Sources */, - 037CEEDED76C75AB19A6A015D66C1322 /* RxCollectionViewDelegateProxy.swift in Sources */, - D9884F11DD4FAA059A45CBBBC68E090F /* RxCollectionViewReactiveArrayDataSource.swift in Sources */, - 7BFBC9F9818BC849C72D672D6B6E4B75 /* RxNavigationControllerDelegateProxy.swift in Sources */, - 953EC9012B7246D01EA866100FAEA023 /* RxPickerViewAdapter.swift in Sources */, - 447B98FAB75F9B738B72DA92A3C581D6 /* RxPickerViewDataSourceProxy.swift in Sources */, - 0FE468D23725DEF3BB913C80A61F9B1B /* RxPickerViewDataSourceType.swift in Sources */, - 63CE2D43072C461D8DE926F0B9EC2E97 /* RxPickerViewDelegateProxy.swift in Sources */, - 26900F59621365F9EF08DB37C7E07C06 /* RxScrollViewDelegateProxy.swift in Sources */, - E84DB9453D7F43DCEC20FDFB5F1CDFD6 /* RxSearchBarDelegateProxy.swift in Sources */, - 4953376F75EEA98570C65CFC41E0A154 /* RxSearchControllerDelegateProxy.swift in Sources */, - 6CD3A3F8ABC5FCE23D15CE6823840010 /* RxTabBarControllerDelegateProxy.swift in Sources */, - DC708FA8C70373D522CB885D4451F3D0 /* RxTabBarDelegateProxy.swift in Sources */, - B2246BF06902F6B9264919F779968CCB /* RxTableViewDataSourcePrefetchingProxy.swift in Sources */, - 1ECDFBCA376564682426B5D8AC70393C /* RxTableViewDataSourceProxy.swift in Sources */, - 60FBA126D0D250DE50F4DD26041E4A9C /* RxTableViewDataSourceType.swift in Sources */, - 9E9A7DA26421695F48AA96DA35B813B4 /* RxTableViewDelegateProxy.swift in Sources */, - F2AB55CF962B7EBDE26DD970C282CEDE /* RxTableViewReactiveArrayDataSource.swift in Sources */, - A5BE980B95C08EDFEBEC17E0433A4A2E /* RxTarget.swift in Sources */, - F71DB74D923AB8F40A88103BDC5ABFA6 /* RxTextStorageDelegateProxy.swift in Sources */, - 8B7EEE0E899778DA279E64E26E38FB30 /* RxTextViewDelegateProxy.swift in Sources */, - DAB6B67BBE65A9ECA898A563CACF442A /* RxWKNavigationDelegateProxy.swift in Sources */, - F9872C7244CA7C80D5E402B3922DB009 /* SchedulerType+SharedSequence.swift in Sources */, - 1FDEA9EB6CAF8FB09C98CEBE607DCFB6 /* SectionedViewDataSourceType.swift in Sources */, - C60C9B7447C5D9555611004E27093043 /* SharedSequence+Operators+arity.swift in Sources */, - B82E2164A69C0D6D3A21B76EFF96F083 /* SharedSequence+Operators.swift in Sources */, - 2F835E1CFB72A43AC17728C6105B9635 /* SharedSequence.swift in Sources */, - FFF63A18CD673B6821ED19EB164316C9 /* Signal+Subscription.swift in Sources */, - 35A428176550E4AA2BB98CDDEE2AFF99 /* Signal.swift in Sources */, - 4407E13BF761D53607A7B419BE64458B /* TextInput.swift in Sources */, - F8EC0962127455A9E5ABEA1B2D0C91D7 /* UIActivityIndicatorView+Rx.swift in Sources */, - 8819CBF35F9919DFC3C17016DF3ACE46 /* UIApplication+Rx.swift in Sources */, - 6C1064F34CFE15C3DB0E923D9D170E0C /* UIBarButtonItem+Rx.swift in Sources */, - 844134211AB7B26FACFFF74B58B81C02 /* UIButton+Rx.swift in Sources */, - 06185F389644D5BD1C84259027C533D5 /* UICollectionView+Rx.swift in Sources */, - 8CE605907DC8FA1F2E4751F939A4E604 /* UIControl+Rx.swift in Sources */, - A1CB4107AB9FDEC58E3A7C0C14B4AB79 /* UIDatePicker+Rx.swift in Sources */, - 611ACC0E723AF0E572160BC75133A9E6 /* UIGestureRecognizer+Rx.swift in Sources */, - 7E8BC075464E9C355B763973CA6C08D2 /* UINavigationController+Rx.swift in Sources */, - 091B8980E4EFE8B81548A8B0369DF1F7 /* UIPickerView+Rx.swift in Sources */, - 77260113D5ADF7B45DAE46C549580AFD /* UIRefreshControl+Rx.swift in Sources */, - BAB6CF7AB28DA0D4BCBC2CF5F53D51AE /* UIScrollView+Rx.swift in Sources */, - 6BDF6DD0C73F197EC93643F477997B40 /* UISearchBar+Rx.swift in Sources */, - 128376A37733CDCD9870A39DE261904E /* UISearchController+Rx.swift in Sources */, - DE76073247081964D8DA688F13021B62 /* UISegmentedControl+Rx.swift in Sources */, - 4BF6073DF04E6CD2C3BD8D2C552D7E65 /* UISlider+Rx.swift in Sources */, - B28F09A584B9F1BBF2EFD17B072A5CE1 /* UIStepper+Rx.swift in Sources */, - DD7EC76A4EB8C3A1741CD5B77B57E0A4 /* UISwitch+Rx.swift in Sources */, - 022F83EC88B467A88CBB491D7C98FA7E /* UITabBar+Rx.swift in Sources */, - 9806F1246774ADD50F50D3F1624EB0EB /* UITabBarController+Rx.swift in Sources */, - AEA40BB1875D2E7B7DCB5E63E672033B /* UITableView+Rx.swift in Sources */, - 9D05E77AB8415BB11EC5C5FB6FD62276 /* UITextField+Rx.swift in Sources */, - 38A45D6FD7DCA41AC0C9CD58EDBB57CB /* UITextView+Rx.swift in Sources */, - D251A0235B97F9217D50C5A1C7C5F311 /* URLSession+Rx.swift in Sources */, - 43BC914A79B9230DA50C9D476DE5114D /* WKWebView+Rx.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DFF2B5F26ABB5074146BB93EA5DBE095 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 3E2FF4CBA1E2C3A36060CB61A25F80F7 /* BRLOptionParser-dummy.m in Sources */, - EDD85DAC7DC88B01D5A2C20969416C9B /* BRLOptionParser.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F0A91985F4DA9728630FB9ABC81A8CC1 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 9281E701873CD72C35440865226A1A8B /* Pods-ShadowsocksX-NGTests-dummy.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - FEE82C527A384A55B52EF357FAA16C22 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6FD62C6E23DE07DF1291500FEFC19354 /* BehaviorRelay.swift in Sources */, - 7813074001D6CD69B3A1EBAF59379E58 /* Observable+Bind.swift in Sources */, - 4D6504A580F9D6278452D19FD3DD35BC /* PublishRelay.swift in Sources */, - C4CD2007BF8F2B0B5125A85B1C43AD24 /* ReplayRelay.swift in Sources */, - E3EE570AEF6808660B0542591285D354 /* RxRelay-dummy.m in Sources */, - CC9F7F2B397CCCC5397750D0B139E373 /* Utils.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 0403456DEA90C0614E5AFBAE92D06199 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = RxSwift; - target = EA9EA43B3B503823EE36C60D9C8A865F /* RxSwift */; - targetProxy = 3A3C6F9E9E958812D1FF93C9737FE5B1 /* PBXContainerItemProxy */; - }; - 16E7E2DB71489A3B3A809EE95AF55896 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = RxRelay; - target = 4622BFEF3DC16E8BD15EEFC30D4D0084 /* RxRelay */; - targetProxy = 93C581FCCE9BCA693063DEB0CB18943C /* PBXContainerItemProxy */; - }; - 18247C9B740C16AA1A1F647B7676E673 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = Alamofire; - target = EAAA1AD3A8A1B59AB91319EE40752C6D /* Alamofire */; - targetProxy = 6C21C08D1A9E4A42298C1E83946EFBF6 /* PBXContainerItemProxy */; - }; - 232E22686FEEB70180F984222B39F949 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = RxSwift; - target = EA9EA43B3B503823EE36C60D9C8A865F /* RxSwift */; - targetProxy = 95ED7E1E76F66FF2AFA473A3D49F574E /* PBXContainerItemProxy */; - }; - 41031387B219D54FF7673356F1696E11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = RxCocoa; - target = 7AD0C6DCDC9CEC8A3C7C10C7FEE07BE6 /* RxCocoa */; - targetProxy = A5DE8E8EE1A9A5D27FEA05AD1FF38C1E /* PBXContainerItemProxy */; - }; - 53637CA92B734D4013B9F99E7AAA9808 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = "MASShortcut-MASShortcut"; - target = 73C37A16ECCEAD845651DCDEE95675BE /* MASShortcut-MASShortcut */; - targetProxy = 3DE69038DEBF7AC72F345377CCA1A457 /* PBXContainerItemProxy */; - }; - 79DC5AF6E7C88EC75AD6D91A9FF3E011 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = BRLOptionParser; - target = 00F92A6698B766C4479D7B608F28D680 /* BRLOptionParser */; - targetProxy = 290D7A27821274F88F50BA4027E877B0 /* PBXContainerItemProxy */; - }; - 7DABF5696F48F5C2D50C0A3DE25289EE /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = RxRelay; - target = 4622BFEF3DC16E8BD15EEFC30D4D0084 /* RxRelay */; - targetProxy = 1CA90026A2A030CD980CB1E78050B63A /* PBXContainerItemProxy */; - }; - B2D17789138C47D21E16F60C47053226 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = MASShortcut; - target = 2B2B481A164695722839BD581D442457 /* MASShortcut */; - targetProxy = B0B5FA86CABF29A7785405416D374CDA /* PBXContainerItemProxy */; - }; - D38F26CBE0B158CB00FD29413295EBDB /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = GCDWebServer; - target = AD904F32069787EFB2DFFE05EB82F5BD /* GCDWebServer */; - targetProxy = E627335D42AC0ADFBA7B40BFD314B204 /* PBXContainerItemProxy */; - }; - F1208697A3C80B8117E54FA1B0E859B1 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = RxSwift; - target = EA9EA43B3B503823EE36C60D9C8A865F /* RxSwift */; - targetProxy = 809667767BFFB7D46B762AD5F006A069 /* PBXContainerItemProxy */; - }; - FF103DE3A0523E2D55DE3D845DD9F0E2 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = "Pods-ShadowsocksX-NG"; - target = E9FDECF69808DB0491D4B4C08CF920DC /* Pods-ShadowsocksX-NG */; - targetProxy = 7569E9B350638EBD714C781E38F158A8 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 12B0FE32A40DD86F2B679BA026ED60EB /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4A70BE8C07BCE9C6D6F47AC73225C959 /* Pods-proxy_conf_helper.release.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - CLANG_ENABLE_OBJC_WEAK = NO; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - EXECUTABLE_PREFIX = lib; - MACH_O_TYPE = staticlib; - MACOSX_DEPLOYMENT_TARGET = 10.12; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - SDKROOT = macosx; - SKIP_INSTALL = YES; - }; - name = Release; - }; - 1B9B12FB7A187E6EA55EABA8BB6F0938 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = FE6138E84780096ADB31F55549931FC6 /* RxSwift.debug.xcconfig */; - buildSettings = { - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/RxSwift/RxSwift-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/RxSwift/RxSwift-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MODULEMAP_FILE = "Target Support Files/RxSwift/RxSwift.modulemap"; - PRODUCT_MODULE_NAME = RxSwift; - PRODUCT_NAME = RxSwift; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.1; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 2539F7AA518E214ED06639F251D62C91 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 2094BFBE78A2839B3C673A3E450C77FC /* GCDWebServer.release.xcconfig */; - buildSettings = { - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/GCDWebServer/GCDWebServer-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/GCDWebServer/GCDWebServer-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MODULEMAP_FILE = "Target Support Files/GCDWebServer/GCDWebServer.modulemap"; - PRODUCT_MODULE_NAME = GCDWebServer; - PRODUCT_NAME = GCDWebServer; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.0; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - 2B85D48D53650AE64148B523322A5F29 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 2F138B6C28378A801D2186B22E1E6224 /* RxCocoa.debug.xcconfig */; - buildSettings = { - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/RxCocoa/RxCocoa-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/RxCocoa/RxCocoa-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MODULEMAP_FILE = "Target Support Files/RxCocoa/RxCocoa.modulemap"; - PRODUCT_MODULE_NAME = RxCocoa; - PRODUCT_NAME = RxCocoa; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.1; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 3AFB1C88E05301BC48B8F2B048ED1025 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = AF22EDE51D4C2AF18359CE03247D06F1 /* RxCocoa.release.xcconfig */; - buildSettings = { - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/RxCocoa/RxCocoa-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/RxCocoa/RxCocoa-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MODULEMAP_FILE = "Target Support Files/RxCocoa/RxCocoa.modulemap"; - PRODUCT_MODULE_NAME = RxCocoa; - PRODUCT_NAME = RxCocoa; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.1; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - 3C142CA6AB0CA7F833124C32A76D5882 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9A71B9958F30759ED2645E0DF9ADF314 /* Pods-ShadowsocksX-NG.debug.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - CLANG_ENABLE_OBJC_WEAK = NO; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MODULEMAP_FILE = "Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SDKROOT = macosx; - SKIP_INSTALL = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 435521A8C1A030B456A3602B835F915D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 70C291AA3C3CEE619534F472C4F04882 /* MASShortcut.debug.xcconfig */; - buildSettings = { - COMBINE_HIDPI_IMAGES = YES; - CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/MASShortcut"; - IBSC_MODULE = MASShortcut; - INFOPLIST_FILE = "Target Support Files/MASShortcut/ResourceBundle-MASShortcut-MASShortcut-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - PRODUCT_NAME = MASShortcut; - SDKROOT = macosx; - SKIP_INSTALL = YES; - WRAPPER_EXTENSION = bundle; - }; - name = Debug; - }; - 464AFC3D045DAC93B8A74739B86B31AE /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 5EE446AD8C625612BFF0E37E4419E0FD /* BRLOptionParser.debug.xcconfig */; - buildSettings = { - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - EXECUTABLE_PREFIX = lib; - GCC_PREFIX_HEADER = "Target Support Files/BRLOptionParser/BRLOptionParser-prefix.pch"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = BRLOptionParser; - PRODUCT_NAME = BRLOptionParser; - PUBLIC_HEADERS_FOLDER_PATH = ""; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - }; - name = Debug; - }; - 5E5046922B2BADEB6AE175DCA2A5C450 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "POD_CONFIGURATION_DEBUG=1", - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - STRIP_INSTALLED_PRODUCT = NO; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - SYMROOT = "${SRCROOT}/../build"; - }; - name = Debug; - }; - 8492155DEB6029C10D570132B7564FA2 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = B81749D1C6130BC14B2386B76041124F /* GCDWebServer.debug.xcconfig */; - buildSettings = { - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/GCDWebServer/GCDWebServer-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/GCDWebServer/GCDWebServer-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MODULEMAP_FILE = "Target Support Files/GCDWebServer/GCDWebServer.modulemap"; - PRODUCT_MODULE_NAME = GCDWebServer; - PRODUCT_NAME = GCDWebServer; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.0; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 8D11F123E993591D305166C07349A576 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 196DA983244F60766BA272090829A16E /* Pods-ShadowsocksX-NGTests.debug.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - CLANG_ENABLE_OBJC_WEAK = NO; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-ShadowsocksX-NGTests/Pods-ShadowsocksX-NGTests-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MODULEMAP_FILE = "Target Support Files/Pods-ShadowsocksX-NGTests/Pods-ShadowsocksX-NGTests.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SDKROOT = macosx; - SKIP_INSTALL = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 8F694BB186184267497C5B29EBD5F103 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 75EA425CE2A4DBDDEB580C7303DD2454 /* Alamofire.debug.xcconfig */; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = NO; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/Alamofire/Alamofire-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/Alamofire/Alamofire-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MODULEMAP_FILE = "Target Support Files/Alamofire/Alamofire.modulemap"; - PRODUCT_MODULE_NAME = Alamofire; - PRODUCT_NAME = Alamofire; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.3; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 90EDC1405B8CA8EDAD433A863FDD47C4 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D70A973E907BDE134197952FF14301CE /* RxRelay.release.xcconfig */; - buildSettings = { - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/RxRelay/RxRelay-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/RxRelay/RxRelay-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MODULEMAP_FILE = "Target Support Files/RxRelay/RxRelay.modulemap"; - PRODUCT_MODULE_NAME = RxRelay; - PRODUCT_NAME = RxRelay; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.1; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - 9570335934A831709D5FDB644D8144D9 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 5C0C485AB4EA81F3E9128F65E9AC66CA /* Pods-ShadowsocksX-NGTests.release.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - CLANG_ENABLE_OBJC_WEAK = NO; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-ShadowsocksX-NGTests/Pods-ShadowsocksX-NGTests-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MODULEMAP_FILE = "Target Support Files/Pods-ShadowsocksX-NGTests/Pods-ShadowsocksX-NGTests.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SDKROOT = macosx; - SKIP_INSTALL = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - 992C0F3AEB140A12268A0B7AB779808B /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 92B4BB091693150E5B1FCC6987683C6F /* Pods-ShadowsocksX-NG.release.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - CLANG_ENABLE_OBJC_WEAK = NO; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MODULEMAP_FILE = "Target Support Files/Pods-ShadowsocksX-NG/Pods-ShadowsocksX-NG.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SDKROOT = macosx; - SKIP_INSTALL = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - 9A282D83C54CDCBE99AC3D556E781819 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D231BAD0830AAA293F76CB7428ADA704 /* MASShortcut.release.xcconfig */; - buildSettings = { - COMBINE_HIDPI_IMAGES = YES; - CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/MASShortcut"; - IBSC_MODULE = MASShortcut; - INFOPLIST_FILE = "Target Support Files/MASShortcut/ResourceBundle-MASShortcut-MASShortcut-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - PRODUCT_NAME = MASShortcut; - SDKROOT = macosx; - SKIP_INSTALL = YES; - WRAPPER_EXTENSION = bundle; - }; - name = Release; - }; - A977C7C72501F07BFFC97CA3F19F344F /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = C3B6C103B3C3936D11BF01C71C0EE380 /* BRLOptionParser.release.xcconfig */; - buildSettings = { - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - EXECUTABLE_PREFIX = lib; - GCC_PREFIX_HEADER = "Target Support Files/BRLOptionParser/BRLOptionParser-prefix.pch"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PRIVATE_HEADERS_FOLDER_PATH = ""; - PRODUCT_MODULE_NAME = BRLOptionParser; - PRODUCT_NAME = BRLOptionParser; - PUBLIC_HEADERS_FOLDER_PATH = ""; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - }; - name = Release; - }; - AE5F5BC820C835E9310C556B3D39E167 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 70C291AA3C3CEE619534F472C4F04882 /* MASShortcut.debug.xcconfig */; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = NO; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/MASShortcut/MASShortcut-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/MASShortcut/MASShortcut-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MODULEMAP_FILE = "Target Support Files/MASShortcut/MASShortcut.modulemap"; - PRODUCT_MODULE_NAME = MASShortcut; - PRODUCT_NAME = MASShortcut; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.0; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - D256BAA9A69C64A728E66C27D53FDD4B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "POD_CONFIGURATION_RELEASE=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - STRIP_INSTALLED_PRODUCT = NO; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 5.0; - SYMROOT = "${SRCROOT}/../build"; - }; - name = Release; - }; - DDA9EC41D966236C68CB4AB50CCF2287 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 848DD5BA5CA758D1F00A7F6F947019EB /* Alamofire.release.xcconfig */; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = NO; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/Alamofire/Alamofire-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/Alamofire/Alamofire-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MODULEMAP_FILE = "Target Support Files/Alamofire/Alamofire.modulemap"; - PRODUCT_MODULE_NAME = Alamofire; - PRODUCT_NAME = Alamofire; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.3; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - DF12A32B61F9AC9FC15D4FEE49C27C64 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D231BAD0830AAA293F76CB7428ADA704 /* MASShortcut.release.xcconfig */; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = NO; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/MASShortcut/MASShortcut-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/MASShortcut/MASShortcut-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MODULEMAP_FILE = "Target Support Files/MASShortcut/MASShortcut.modulemap"; - PRODUCT_MODULE_NAME = MASShortcut; - PRODUCT_NAME = MASShortcut; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 4.0; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - E50DD4E0C6E58142D33757B5C9E7B75C /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = BF25DE5F0433D7BA7D6F91A5F113542A /* RxRelay.debug.xcconfig */; - buildSettings = { - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/RxRelay/RxRelay-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/RxRelay/RxRelay-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MODULEMAP_FILE = "Target Support Files/RxRelay/RxRelay.modulemap"; - PRODUCT_MODULE_NAME = RxRelay; - PRODUCT_NAME = RxRelay; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.1; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - F2D56CB7664FC6CD92EB5B8E9298A5E7 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 28F6CED61832E1CE6BA74AA90F7E45EE /* RxSwift.release.xcconfig */; - buildSettings = { - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/RxSwift/RxSwift-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/RxSwift/RxSwift-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - MODULEMAP_FILE = "Target Support Files/RxSwift/RxSwift.modulemap"; - PRODUCT_MODULE_NAME = RxSwift; - PRODUCT_NAME = RxSwift; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.1; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - F6B84B253DE1626F094BD37FC42474DF /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D8C88B0B7BFE785BC9B00D1C53FDC003 /* Pods-proxy_conf_helper.debug.xcconfig */; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - CLANG_ENABLE_OBJC_WEAK = NO; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - EXECUTABLE_PREFIX = lib; - MACH_O_TYPE = staticlib; - MACOSX_DEPLOYMENT_TARGET = 10.12; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - SDKROOT = macosx; - SKIP_INSTALL = YES; - }; - name = Debug; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 0D501A92E69AF80E7786DD9C0D172BEC /* Build configuration list for PBXNativeTarget "Pods-proxy_conf_helper" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - F6B84B253DE1626F094BD37FC42474DF /* Debug */, - 12B0FE32A40DD86F2B679BA026ED60EB /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 1C26E77821938498151B66E4B3FAFDB5 /* Build configuration list for PBXNativeTarget "MASShortcut-MASShortcut" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 435521A8C1A030B456A3602B835F915D /* Debug */, - 9A282D83C54CDCBE99AC3D556E781819 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 3797157A80385C2407F752CEE1BFEB21 /* Build configuration list for PBXNativeTarget "RxRelay" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - E50DD4E0C6E58142D33757B5C9E7B75C /* Debug */, - 90EDC1405B8CA8EDAD433A863FDD47C4 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5E5046922B2BADEB6AE175DCA2A5C450 /* Debug */, - D256BAA9A69C64A728E66C27D53FDD4B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6331D6AD3A4489B8CBA44A44D38FD80A /* Build configuration list for PBXNativeTarget "RxSwift" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1B9B12FB7A187E6EA55EABA8BB6F0938 /* Debug */, - F2D56CB7664FC6CD92EB5B8E9298A5E7 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 690C9430B03B92419AFA4555712EC873 /* Build configuration list for PBXNativeTarget "GCDWebServer" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 8492155DEB6029C10D570132B7564FA2 /* Debug */, - 2539F7AA518E214ED06639F251D62C91 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 6D442598AC59E49374231C4242255CA3 /* Build configuration list for PBXNativeTarget "BRLOptionParser" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 464AFC3D045DAC93B8A74739B86B31AE /* Debug */, - A977C7C72501F07BFFC97CA3F19F344F /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 78E219AC01CD5AFED663C9AB28280801 /* Build configuration list for PBXNativeTarget "Alamofire" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 8F694BB186184267497C5B29EBD5F103 /* Debug */, - DDA9EC41D966236C68CB4AB50CCF2287 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 84B5ECA69733DA3FEDC652649E6E42C5 /* Build configuration list for PBXNativeTarget "Pods-ShadowsocksX-NGTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 8D11F123E993591D305166C07349A576 /* Debug */, - 9570335934A831709D5FDB644D8144D9 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 975822F53DB5EF99EE2C5EA67BC503C9 /* Build configuration list for PBXNativeTarget "Pods-ShadowsocksX-NG" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 3C142CA6AB0CA7F833124C32A76D5882 /* Debug */, - 992C0F3AEB140A12268A0B7AB779808B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - ABE56D8D3781109924A96BB7837ED223 /* Build configuration list for PBXNativeTarget "RxCocoa" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2B85D48D53650AE64148B523322A5F29 /* Debug */, - 3AFB1C88E05301BC48B8F2B048ED1025 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - E888D466E966B416D89BA302F582A3F5 /* Build configuration list for PBXNativeTarget "MASShortcut" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - AE5F5BC820C835E9310C556B3D39E167 /* Debug */, - DF12A32B61F9AC9FC15D4FEE49C27C64 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */; -} diff --git a/Pods/RxCocoa/LICENSE.md b/Pods/RxCocoa/LICENSE.md deleted file mode 100644 index e32511b38..000000000 --- a/Pods/RxCocoa/LICENSE.md +++ /dev/null @@ -1,9 +0,0 @@ -**The MIT License** -**Copyright © 2015 Krunoslav Zaher, Shai Mishali** -**All rights reserved.** - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Pods/RxCocoa/Platform/DataStructures/Bag.swift b/Pods/RxCocoa/Platform/DataStructures/Bag.swift deleted file mode 100644 index 5720a3b44..000000000 --- a/Pods/RxCocoa/Platform/DataStructures/Bag.swift +++ /dev/null @@ -1,181 +0,0 @@ -// -// Bag.swift -// Platform -// -// Created by Krunoslav Zaher on 2/28/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import Swift - -let arrayDictionaryMaxSize = 30 - -struct BagKey { - /** - Unique identifier for object added to `Bag`. - - It's underlying type is UInt64. If we assume there in an idealized CPU that works at 4GHz, - it would take ~150 years of continuous running time for it to overflow. - */ - fileprivate let rawValue: UInt64 -} - -/** -Data structure that represents a bag of elements typed `T`. - -Single element can be stored multiple times. - -Time and space complexity of insertion and deletion is O(n). - -It is suitable for storing small number of elements. -*/ -struct Bag : CustomDebugStringConvertible { - /// Type of identifier for inserted elements. - typealias KeyType = BagKey - - typealias Entry = (key: BagKey, value: T) - - private var _nextKey: BagKey = BagKey(rawValue: 0) - - // data - - // first fill inline variables - var _key0: BagKey? - var _value0: T? - - // then fill "array dictionary" - var _pairs = ContiguousArray() - - // last is sparse dictionary - var _dictionary: [BagKey: T]? - - var _onlyFastPath = true - - /// Creates new empty `Bag`. - init() { - } - - /** - Inserts `value` into bag. - - - parameter element: Element to insert. - - returns: Key that can be used to remove element from bag. - */ - mutating func insert(_ element: T) -> BagKey { - let key = _nextKey - - _nextKey = BagKey(rawValue: _nextKey.rawValue &+ 1) - - if _key0 == nil { - _key0 = key - _value0 = element - return key - } - - _onlyFastPath = false - - if _dictionary != nil { - _dictionary![key] = element - return key - } - - if _pairs.count < arrayDictionaryMaxSize { - _pairs.append((key: key, value: element)) - return key - } - - _dictionary = [key: element] - - return key - } - - /// - returns: Number of elements in bag. - var count: Int { - let dictionaryCount: Int = _dictionary?.count ?? 0 - return (_value0 != nil ? 1 : 0) + _pairs.count + dictionaryCount - } - - /// Removes all elements from bag and clears capacity. - mutating func removeAll() { - _key0 = nil - _value0 = nil - - _pairs.removeAll(keepingCapacity: false) - _dictionary?.removeAll(keepingCapacity: false) - } - - /** - Removes element with a specific `key` from bag. - - - parameter key: Key that identifies element to remove from bag. - - returns: Element that bag contained, or nil in case element was already removed. - */ - mutating func removeKey(_ key: BagKey) -> T? { - if _key0 == key { - _key0 = nil - let value = _value0! - _value0 = nil - return value - } - - if let existingObject = _dictionary?.removeValue(forKey: key) { - return existingObject - } - - for i in 0 ..< _pairs.count where _pairs[i].key == key { - let value = _pairs[i].value - _pairs.remove(at: i) - return value - } - - return nil - } -} - -extension Bag { - /// A textual representation of `self`, suitable for debugging. - var debugDescription : String { - "\(self.count) elements in Bag" - } -} - -extension Bag { - /// Enumerates elements inside the bag. - /// - /// - parameter action: Enumeration closure. - func forEach(_ action: (T) -> Void) { - if _onlyFastPath { - if let value0 = _value0 { - action(value0) - } - return - } - - let value0 = _value0 - let dictionary = _dictionary - - if let value0 = value0 { - action(value0) - } - - for i in 0 ..< _pairs.count { - action(_pairs[i].value) - } - - if dictionary?.count ?? 0 > 0 { - for element in dictionary!.values { - action(element) - } - } - } -} - -extension BagKey: Hashable { - func hash(into hasher: inout Hasher) { - hasher.combine(rawValue) - } -} - -func ==(lhs: BagKey, rhs: BagKey) -> Bool { - lhs.rawValue == rhs.rawValue -} diff --git a/Pods/RxCocoa/Platform/DataStructures/InfiniteSequence.swift b/Pods/RxCocoa/Platform/DataStructures/InfiniteSequence.swift deleted file mode 100644 index 75d7bea7f..000000000 --- a/Pods/RxCocoa/Platform/DataStructures/InfiniteSequence.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// InfiniteSequence.swift -// Platform -// -// Created by Krunoslav Zaher on 6/13/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// Sequence that repeats `repeatedValue` infinite number of times. -struct InfiniteSequence : Sequence { - typealias Iterator = AnyIterator - - private let repeatedValue: Element - - init(repeatedValue: Element) { - self.repeatedValue = repeatedValue - } - - func makeIterator() -> Iterator { - let repeatedValue = self.repeatedValue - return AnyIterator { repeatedValue } - } -} diff --git a/Pods/RxCocoa/Platform/DataStructures/PriorityQueue.swift b/Pods/RxCocoa/Platform/DataStructures/PriorityQueue.swift deleted file mode 100644 index 9ed856b91..000000000 --- a/Pods/RxCocoa/Platform/DataStructures/PriorityQueue.swift +++ /dev/null @@ -1,111 +0,0 @@ -// -// PriorityQueue.swift -// Platform -// -// Created by Krunoslav Zaher on 12/27/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -struct PriorityQueue { - private let hasHigherPriority: (Element, Element) -> Bool - private let isEqual: (Element, Element) -> Bool - - private var elements = [Element]() - - init(hasHigherPriority: @escaping (Element, Element) -> Bool, isEqual: @escaping (Element, Element) -> Bool) { - self.hasHigherPriority = hasHigherPriority - self.isEqual = isEqual - } - - mutating func enqueue(_ element: Element) { - elements.append(element) - bubbleToHigherPriority(elements.count - 1) - } - - func peek() -> Element? { - elements.first - } - - var isEmpty: Bool { - elements.count == 0 - } - - mutating func dequeue() -> Element? { - guard let front = peek() else { - return nil - } - - removeAt(0) - - return front - } - - mutating func remove(_ element: Element) { - for i in 0 ..< elements.count { - if self.isEqual(elements[i], element) { - removeAt(i) - return - } - } - } - - private mutating func removeAt(_ index: Int) { - let removingLast = index == elements.count - 1 - if !removingLast { - elements.swapAt(index, elements.count - 1) - } - - _ = elements.popLast() - - if !removingLast { - bubbleToHigherPriority(index) - bubbleToLowerPriority(index) - } - } - - private mutating func bubbleToHigherPriority(_ initialUnbalancedIndex: Int) { - precondition(initialUnbalancedIndex >= 0) - precondition(initialUnbalancedIndex < elements.count) - - var unbalancedIndex = initialUnbalancedIndex - - while unbalancedIndex > 0 { - let parentIndex = (unbalancedIndex - 1) / 2 - guard self.hasHigherPriority(elements[unbalancedIndex], elements[parentIndex]) else { break } - elements.swapAt(unbalancedIndex, parentIndex) - unbalancedIndex = parentIndex - } - } - - private mutating func bubbleToLowerPriority(_ initialUnbalancedIndex: Int) { - precondition(initialUnbalancedIndex >= 0) - precondition(initialUnbalancedIndex < elements.count) - - var unbalancedIndex = initialUnbalancedIndex - while true { - let leftChildIndex = unbalancedIndex * 2 + 1 - let rightChildIndex = unbalancedIndex * 2 + 2 - - var highestPriorityIndex = unbalancedIndex - - if leftChildIndex < elements.count && self.hasHigherPriority(elements[leftChildIndex], elements[highestPriorityIndex]) { - highestPriorityIndex = leftChildIndex - } - - if rightChildIndex < elements.count && self.hasHigherPriority(elements[rightChildIndex], elements[highestPriorityIndex]) { - highestPriorityIndex = rightChildIndex - } - - guard highestPriorityIndex != unbalancedIndex else { break } - elements.swapAt(highestPriorityIndex, unbalancedIndex) - - unbalancedIndex = highestPriorityIndex - } - } -} - -extension PriorityQueue : CustomDebugStringConvertible { - var debugDescription: String { - elements.debugDescription - } -} diff --git a/Pods/RxCocoa/Platform/DataStructures/Queue.swift b/Pods/RxCocoa/Platform/DataStructures/Queue.swift deleted file mode 100644 index 625d4733e..000000000 --- a/Pods/RxCocoa/Platform/DataStructures/Queue.swift +++ /dev/null @@ -1,148 +0,0 @@ -// -// Queue.swift -// Platform -// -// Created by Krunoslav Zaher on 3/21/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/** -Data structure that represents queue. - -Complexity of `enqueue`, `dequeue` is O(1) when number of operations is -averaged over N operations. - -Complexity of `peek` is O(1). -*/ -struct Queue: Sequence { - /// Type of generator. - typealias Generator = AnyIterator - - private let resizeFactor = 2 - - private var storage: ContiguousArray - private var innerCount = 0 - private var pushNextIndex = 0 - private let initialCapacity: Int - - /** - Creates new queue. - - - parameter capacity: Capacity of newly created queue. - */ - init(capacity: Int) { - initialCapacity = capacity - - storage = ContiguousArray(repeating: nil, count: capacity) - } - - private var dequeueIndex: Int { - let index = pushNextIndex - count - return index < 0 ? index + storage.count : index - } - - /// - returns: Is queue empty. - var isEmpty: Bool { count == 0 } - - /// - returns: Number of elements inside queue. - var count: Int { innerCount } - - /// - returns: Element in front of a list of elements to `dequeue`. - func peek() -> T { - precondition(count > 0) - - return storage[dequeueIndex]! - } - - mutating private func resizeTo(_ size: Int) { - var newStorage = ContiguousArray(repeating: nil, count: size) - - let count = self.count - - let dequeueIndex = self.dequeueIndex - let spaceToEndOfQueue = storage.count - dequeueIndex - - // first batch is from dequeue index to end of array - let countElementsInFirstBatch = Swift.min(count, spaceToEndOfQueue) - // second batch is wrapped from start of array to end of queue - let numberOfElementsInSecondBatch = count - countElementsInFirstBatch - - newStorage[0 ..< countElementsInFirstBatch] = storage[dequeueIndex ..< (dequeueIndex + countElementsInFirstBatch)] - newStorage[countElementsInFirstBatch ..< (countElementsInFirstBatch + numberOfElementsInSecondBatch)] = storage[0 ..< numberOfElementsInSecondBatch] - - self.innerCount = count - pushNextIndex = count - storage = newStorage - } - - /// Enqueues `element`. - /// - /// - parameter element: Element to enqueue. - mutating func enqueue(_ element: T) { - if count == storage.count { - resizeTo(Swift.max(storage.count, 1) * resizeFactor) - } - - storage[pushNextIndex] = element - pushNextIndex += 1 - innerCount += 1 - - if pushNextIndex >= storage.count { - pushNextIndex -= storage.count - } - } - - private mutating func dequeueElementOnly() -> T { - precondition(count > 0) - - let index = dequeueIndex - - defer { - storage[index] = nil - innerCount -= 1 - } - - return storage[index]! - } - - /// Dequeues element or throws an exception in case queue is empty. - /// - /// - returns: Dequeued element. - mutating func dequeue() -> T? { - if self.count == 0 { - return nil - } - - defer { - let downsizeLimit = storage.count / (resizeFactor * resizeFactor) - if count < downsizeLimit && downsizeLimit >= initialCapacity { - resizeTo(storage.count / resizeFactor) - } - } - - return dequeueElementOnly() - } - - /// - returns: Generator of contained elements. - func makeIterator() -> AnyIterator { - var i = dequeueIndex - var innerCount = count - - return AnyIterator { - if innerCount == 0 { - return nil - } - - defer { - innerCount -= 1 - i += 1 - } - - if i >= self.storage.count { - i -= self.storage.count - } - - return self.storage[i] - } - } -} diff --git a/Pods/RxCocoa/Platform/DispatchQueue+Extensions.swift b/Pods/RxCocoa/Platform/DispatchQueue+Extensions.swift deleted file mode 100644 index aaf24cae6..000000000 --- a/Pods/RxCocoa/Platform/DispatchQueue+Extensions.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// DispatchQueue+Extensions.swift -// Platform -// -// Created by Krunoslav Zaher on 10/22/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -import Dispatch - -extension DispatchQueue { - private static var token: DispatchSpecificKey<()> = { - let key = DispatchSpecificKey<()>() - DispatchQueue.main.setSpecific(key: key, value: ()) - return key - }() - - static var isMain: Bool { - DispatchQueue.getSpecific(key: token) != nil - } -} diff --git a/Pods/RxCocoa/Platform/Platform.Darwin.swift b/Pods/RxCocoa/Platform/Platform.Darwin.swift deleted file mode 100644 index eacc19431..000000000 --- a/Pods/RxCocoa/Platform/Platform.Darwin.swift +++ /dev/null @@ -1,35 +0,0 @@ -// -// Platform.Darwin.swift -// Platform -// -// Created by Krunoslav Zaher on 12/29/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) - - import Darwin - import Foundation - - extension Thread { - static func setThreadLocalStorageValue(_ value: T?, forKey key: NSCopying) { - let currentThread = Thread.current - let threadDictionary = currentThread.threadDictionary - - if let newValue = value { - threadDictionary[key] = newValue - } - else { - threadDictionary[key] = nil - } - } - - static func getThreadLocalStorageValueForKey(_ key: NSCopying) -> T? { - let currentThread = Thread.current - let threadDictionary = currentThread.threadDictionary - - return threadDictionary[key] as? T - } - } - -#endif diff --git a/Pods/RxCocoa/Platform/Platform.Linux.swift b/Pods/RxCocoa/Platform/Platform.Linux.swift deleted file mode 100644 index 52a3e3af8..000000000 --- a/Pods/RxCocoa/Platform/Platform.Linux.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// Platform.Linux.swift -// Platform -// -// Created by Krunoslav Zaher on 12/29/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(Linux) - - import Foundation - - extension Thread { - - static func setThreadLocalStorageValue(_ value: T?, forKey key: String) { - if let newValue = value { - Thread.current.threadDictionary[key] = newValue - } - else { - Thread.current.threadDictionary[key] = nil - } - } - - static func getThreadLocalStorageValueForKey(_ key: String) -> T? { - let currentThread = Thread.current - let threadDictionary = currentThread.threadDictionary - - return threadDictionary[key] as? T - } - } - -#endif diff --git a/Pods/RxCocoa/Platform/RecursiveLock.swift b/Pods/RxCocoa/Platform/RecursiveLock.swift deleted file mode 100644 index 10b9bbb0b..000000000 --- a/Pods/RxCocoa/Platform/RecursiveLock.swift +++ /dev/null @@ -1,34 +0,0 @@ -// -// RecursiveLock.swift -// Platform -// -// Created by Krunoslav Zaher on 12/18/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -import Foundation - -#if TRACE_RESOURCES - class RecursiveLock: NSRecursiveLock { - override init() { - _ = Resources.incrementTotal() - super.init() - } - - override func lock() { - super.lock() - _ = Resources.incrementTotal() - } - - override func unlock() { - super.unlock() - _ = Resources.decrementTotal() - } - - deinit { - _ = Resources.decrementTotal() - } - } -#else - typealias RecursiveLock = NSRecursiveLock -#endif diff --git a/Pods/RxCocoa/README.md b/Pods/RxCocoa/README.md deleted file mode 100644 index 20330166b..000000000 --- a/Pods/RxCocoa/README.md +++ /dev/null @@ -1,254 +0,0 @@ -

-RxSwift Logo -
-Build Status -Supported Platforms: iOS, macOS, tvOS, watchOS & Linux -
- - - -

- -Rx is a [generic abstraction of computation](https://youtu.be/looJcaeboBY) expressed through `Observable` interface, which lets you broadcast and subscribe to values and other events from an `Observable` stream. - -RxSwift is the Swift-specific implementation of the [Reactive Extensions](http://reactivex.io) standard. - -

RxSwift Observable Example of a price constantly changing and updating the app's UI

- -While this version aims to stay true to the original spirit and naming conventions of Rx, this projects also aims to provide a true Swift-first API for Rx APIs. - -Cross platform documentation can be found on [ReactiveX.io](http://reactivex.io/). - -Like other Rx implementation, RxSwift's intention is to enable easy composition of asynchronous operations and streams of data in the form of `Observable` objects and a suite of methods to transform and compose these pieces of asynchronous work. - -KVO observation, async operations, UI Events and other streams of data are all unified under [abstraction of sequence](Documentation/GettingStarted.md#observables-aka-sequences). This is the reason why Rx is so simple, elegant and powerful. - -## I came here because I want to ... - -###### ... understand - -* [why use rx?](Documentation/Why.md) -* [the basics, getting started with RxSwift](Documentation/GettingStarted.md) -* [traits](Documentation/Traits.md) - what are `Single`, `Completable`, `Maybe`, `Driver`, and `ControlProperty` ... and why do they exist? -* [testing](Documentation/UnitTests.md) -* [tips and common errors](Documentation/Tips.md) -* [debugging](Documentation/GettingStarted.md#debugging) -* [the math behind Rx](Documentation/MathBehindRx.md) -* [what are hot and cold observable sequences?](Documentation/HotAndColdObservables.md) - -###### ... install - -* Integrate RxSwift/RxCocoa with my app. [Installation Guide](#installation) - -###### ... hack around - -* with the example app. [Running Example App](Documentation/ExampleApp.md) -* with operators in playgrounds. [Playgrounds](Documentation/Playgrounds.md) - -###### ... interact - -* All of this is great, but it would be nice to talk with other people using RxSwift and exchange experiences.
[Join Slack Channel](http://slack.rxswift.org) -* Report a problem using the library. [Open an Issue With Bug Template](.github/ISSUE_TEMPLATE.md) -* Request a new feature. [Open an Issue With Feature Request Template](Documentation/NewFeatureRequestTemplate.md) -* Help out [Check out contribution guide](CONTRIBUTING.md) - -###### ... compare - -* [with Combine and ReactiveSwift](Documentation/ComparisonWithOtherLibraries.md). - -###### ... understand the structure - -RxSwift is as compositional as the asynchronous work it drives. The core unit is RxSwift itself, while other dependencies can be added for UI Work, testing, and more. - -It comprises five separate components depending on each other in the following way: - -```none -┌──────────────┐ ┌──────────────┐ -│ RxCocoa ├────▶ RxRelay │ -└───────┬──────┘ └──────┬───────┘ - │ │ -┌───────▼──────────────────▼───────┐ -│ RxSwift │ -└───────▲──────────────────▲───────┘ - │ │ -┌───────┴──────┐ ┌──────┴───────┐ -│ RxTest │ │ RxBlocking │ -└──────────────┘ └──────────────┘ -``` - -* **RxSwift**: The core of RxSwift, providing the Rx standard as (mostly) defined by [ReactiveX](https://reactivex.io). It has no other dependencies. -* **RxCocoa**: Provides Cocoa-specific capabilities for general iOS/macOS/watchOS & tvOS app development, such as Shared Sequences, Traits, and much more. It depends on both `RxSwift` and `RxRelay`. -* **RxRelay**: Provides `PublishRelay`, `BehaviorRelay` and `ReplayRelay`, three [simple wrappers around Subjects](https://github.com/ReactiveX/RxSwift/blob/main/Documentation/Subjects.md#relays). It depends on `RxSwift`. -* **RxTest** and **RxBlocking**: Provides testing capabilities for Rx-based systems. It depends on `RxSwift`. - -## Usage - - - - - - - - - - - - - - - - - - - -
Here's an exampleIn Action
Define search for GitHub repositories ...
-let searchResults = searchBar.rx.text.orEmpty
-    .throttle(.milliseconds(300), scheduler: MainScheduler.instance)
-    .distinctUntilChanged()
-    .flatMapLatest { query -> Observable<[Repository]> in
-        if query.isEmpty {
-            return .just([])
-        }
-        return searchGitHub(query)
-            .catchAndReturn([])
-    }
-    .observe(on: MainScheduler.instance)
... then bind the results to your tableview
-searchResults
-    .bind(to: tableView.rx.items(cellIdentifier: "Cell")) {
-        (index, repository: Repository, cell) in
-        cell.textLabel?.text = repository.name
-        cell.detailTextLabel?.text = repository.url
-    }
-    .disposed(by: disposeBag)
- - -## Requirements - -* Xcode 12.x -* Swift 5.x - -For Xcode 11 and below, [use RxSwift 5.x](https://github.com/ReactiveX/RxSwift/releases/tag/5.1.1). - -## Installation - -RxSwift doesn't contain any external dependencies. - -These are currently the supported installation options: - -### Manual - -Open Rx.xcworkspace, choose `RxExample` and hit run. This method will build everything and run the sample app - -### [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html) - -```ruby -# Podfile -use_frameworks! - -target 'YOUR_TARGET_NAME' do - pod 'RxSwift', '6.2.0' - pod 'RxCocoa', '6.2.0' -end - -# RxTest and RxBlocking make the most sense in the context of unit/integration tests -target 'YOUR_TESTING_TARGET' do - pod 'RxBlocking', '6.2.0' - pod 'RxTest', '6.2.0' -end -``` - -Replace `YOUR_TARGET_NAME` and then, in the `Podfile` directory, type: - -```bash -$ pod install -``` - -### XCFrameworks - -Each release starting with RxSwift 6 includes `*.xcframework` framework binaries. - -Simply drag the needed framework binaries to your **Frameworks, Libraries, and Embedded Content** section under your target's **General** tab. - -> **Note**: If you're using `RxCocoa`, be sure to also drag **RxCocoaRuntime.xcframework** before importing `RxCocoa`. - -XCFrameworks instructions - -### [Carthage](https://github.com/Carthage/Carthage) - -Add this to `Cartfile` - -``` -github "ReactiveX/RxSwift" "6.2.0" -``` - -```bash -$ carthage update -``` - -#### Carthage as a Static Library - -Carthage defaults to building RxSwift as a Dynamic Library. - -If you wish to build RxSwift as a Static Library using Carthage you may use the script below to manually modify the framework type before building with Carthage: - -```bash -carthage update RxSwift --platform iOS --no-build -sed -i -e 's/MACH_O_TYPE = mh_dylib/MACH_O_TYPE = staticlib/g' Carthage/Checkouts/RxSwift/Rx.xcodeproj/project.pbxproj -carthage build RxSwift --platform iOS -``` - -### [Swift Package Manager](https://github.com/apple/swift-package-manager) - -> **Note**: There is a critical cross-dependency bug affecting many projects including RxSwift in Swift Package Manager. We've [filed a bug (SR-12303)](https://bugs.swift.org/browse/SR-12303) in early 2020 but have no answer yet. Your mileage may vary. A partial workaround can be found [here](https://github.com/ReactiveX/RxSwift/issues/2127#issuecomment-717830502). - -Create a `Package.swift` file. - -```swift -// swift-tools-version:5.0 - -import PackageDescription - -let package = Package( - name: "RxTestProject", - dependencies: [ - .package(url: "https://github.com/ReactiveX/RxSwift.git", .exact("6.2.0")) - ], - targets: [ - .target(name: "RxTestProject", dependencies: ["RxSwift", "RxCocoa"]) - ] -) -``` - -```bash -$ swift build -``` - -To build or test a module with RxTest dependency, set `TEST=1`. - -```bash -$ TEST=1 swift test -``` - -### Manually using git submodules - -* Add RxSwift as a submodule - -```bash -$ git submodule add git@github.com:ReactiveX/RxSwift.git -``` - -* Drag `Rx.xcodeproj` into Project Navigator -* Go to `Project > Targets > Build Phases > Link Binary With Libraries`, click `+` and select `RxSwift`, `RxCocoa` and `RxRelay` targets - -## References - -* [http://reactivex.io/](http://reactivex.io/) -* [Reactive Extensions GitHub (GitHub)](https://github.com/Reactive-Extensions) -* [RxSwift RayWenderlich.com Book](https://store.raywenderlich.com/products/rxswift-reactive-programming-with-swift) -* [RxSwift: Debunking the myth of hard (YouTube)](https://www.youtube.com/watch?v=GdvLP0ZAhhc) -* [Boxue.io RxSwift Online Course](https://boxueio.com/series/rxswift-101) (Chinese 🇨🇳) -* [Expert to Expert: Brian Beckman and Erik Meijer - Inside the .NET Reactive Framework (Rx) (video)](https://youtu.be/looJcaeboBY) -* [Reactive Programming Overview (Jafar Husain from Netflix)](https://youtu.be/-8Y1-lE6NSA) -* [Subject/Observer is Dual to Iterator (paper)](http://csl.stanford.edu/~christos/pldi2010.fit/meijer.duality.pdf) -* [Rx standard sequence operators visualized (visualization tool)](http://rxmarbles.com/) -* [Haskell](https://www.haskell.org/) diff --git a/Pods/RxCocoa/RxCocoa/Common/ControlTarget.swift b/Pods/RxCocoa/RxCocoa/Common/ControlTarget.swift deleted file mode 100644 index 231c3fe5d..000000000 --- a/Pods/RxCocoa/RxCocoa/Common/ControlTarget.swift +++ /dev/null @@ -1,88 +0,0 @@ -// -// ControlTarget.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 2/21/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) || os(macOS) - -import RxSwift - -#if os(iOS) || os(tvOS) - import UIKit - - typealias Control = UIKit.UIControl -#elseif os(macOS) - import Cocoa - - typealias Control = Cocoa.NSControl -#endif - -// This should be only used from `MainScheduler` -final class ControlTarget: RxTarget { - typealias Callback = (Control) -> Void - - let selector: Selector = #selector(ControlTarget.eventHandler(_:)) - - weak var control: Control? -#if os(iOS) || os(tvOS) - let controlEvents: UIControl.Event -#endif - var callback: Callback? - #if os(iOS) || os(tvOS) - init(control: Control, controlEvents: UIControl.Event, callback: @escaping Callback) { - MainScheduler.ensureRunningOnMainThread() - - self.control = control - self.controlEvents = controlEvents - self.callback = callback - - super.init() - - control.addTarget(self, action: selector, for: controlEvents) - - let method = self.method(for: selector) - if method == nil { - rxFatalError("Can't find method") - } - } -#elseif os(macOS) - init(control: Control, callback: @escaping Callback) { - MainScheduler.ensureRunningOnMainThread() - - self.control = control - self.callback = callback - - super.init() - - control.target = self - control.action = self.selector - - let method = self.method(for: self.selector) - if method == nil { - rxFatalError("Can't find method") - } - } -#endif - - @objc func eventHandler(_ sender: Control!) { - if let callback = self.callback, let control = self.control { - callback(control) - } - } - - override func dispose() { - super.dispose() -#if os(iOS) || os(tvOS) - self.control?.removeTarget(self, action: self.selector, for: self.controlEvents) -#elseif os(macOS) - self.control?.target = nil - self.control?.action = nil -#endif - self.callback = nil - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/Common/DelegateProxy.swift b/Pods/RxCocoa/RxCocoa/Common/DelegateProxy.swift deleted file mode 100644 index 4ef8de73b..000000000 --- a/Pods/RxCocoa/RxCocoa/Common/DelegateProxy.swift +++ /dev/null @@ -1,293 +0,0 @@ -// -// DelegateProxy.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 6/14/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if !os(Linux) - - import RxSwift - #if SWIFT_PACKAGE && !os(Linux) - import RxCocoaRuntime - #endif - - /// Base class for `DelegateProxyType` protocol. - /// - /// This implementation is not thread safe and can be used only from one thread (Main thread). - open class DelegateProxy: _RXDelegateProxy { - public typealias ParentObject = P - public typealias Delegate = D - - private var _sentMessageForSelector = [Selector: MessageDispatcher]() - private var _methodInvokedForSelector = [Selector: MessageDispatcher]() - - /// Parent object associated with delegate proxy. - private weak var _parentObject: ParentObject? - - private let _currentDelegateFor: (ParentObject) -> AnyObject? - private let _setCurrentDelegateTo: (AnyObject?, ParentObject) -> Void - - /// Initializes new instance. - /// - /// - parameter parentObject: Optional parent object that owns `DelegateProxy` as associated object. - public init(parentObject: ParentObject, delegateProxy: Proxy.Type) - where Proxy: DelegateProxy, Proxy.ParentObject == ParentObject, Proxy.Delegate == Delegate { - self._parentObject = parentObject - self._currentDelegateFor = delegateProxy._currentDelegate - self._setCurrentDelegateTo = delegateProxy._setCurrentDelegate - - MainScheduler.ensureRunningOnMainThread() - #if TRACE_RESOURCES - _ = Resources.incrementTotal() - #endif - super.init() - } - - /** - Returns observable sequence of invocations of delegate methods. Elements are sent *before method is invoked*. - - Only methods that have `void` return value can be observed using this method because - those methods are used as a notification mechanism. It doesn't matter if they are optional - or not. Observing is performed by installing a hidden associated `PublishSubject` that is - used to dispatch messages to observers. - - Delegate methods that have non `void` return value can't be observed directly using this method - because: - * those methods are not intended to be used as a notification mechanism, but as a behavior customization mechanism - * there is no sensible automatic way to determine a default return value - - In case observing of delegate methods that have return type is required, it can be done by - manually installing a `PublishSubject` or `BehaviorSubject` and implementing delegate method. - - e.g. - - // delegate proxy part (RxScrollViewDelegateProxy) - - let internalSubject = PublishSubject - - public func requiredDelegateMethod(scrollView: UIScrollView, arg1: CGPoint) -> Bool { - internalSubject.on(.next(arg1)) - return self._forwardToDelegate?.requiredDelegateMethod?(scrollView, arg1: arg1) ?? defaultReturnValue - } - - .... - - // reactive property implementation in a real class (`UIScrollView`) - public var property: Observable { - let proxy = RxScrollViewDelegateProxy.proxy(for: base) - return proxy.internalSubject.asObservable() - } - - **In case calling this method prints "Delegate proxy is already implementing `\(selector)`, - a more performant way of registering might exist.", that means that manual observing method - is required analog to the example above because delegate method has already been implemented.** - - - parameter selector: Selector used to filter observed invocations of delegate methods. - - returns: Observable sequence of arguments passed to `selector` method. - */ - open func sentMessage(_ selector: Selector) -> Observable<[Any]> { - MainScheduler.ensureRunningOnMainThread() - - let subject = self._sentMessageForSelector[selector] - - if let subject = subject { - return subject.asObservable() - } - else { - let subject = MessageDispatcher(selector: selector, delegateProxy: self) - self._sentMessageForSelector[selector] = subject - return subject.asObservable() - } - } - - /** - Returns observable sequence of invoked delegate methods. Elements are sent *after method is invoked*. - - Only methods that have `void` return value can be observed using this method because - those methods are used as a notification mechanism. It doesn't matter if they are optional - or not. Observing is performed by installing a hidden associated `PublishSubject` that is - used to dispatch messages to observers. - - Delegate methods that have non `void` return value can't be observed directly using this method - because: - * those methods are not intended to be used as a notification mechanism, but as a behavior customization mechanism - * there is no sensible automatic way to determine a default return value - - In case observing of delegate methods that have return type is required, it can be done by - manually installing a `PublishSubject` or `BehaviorSubject` and implementing delegate method. - - e.g. - - // delegate proxy part (RxScrollViewDelegateProxy) - - let internalSubject = PublishSubject - - public func requiredDelegateMethod(scrollView: UIScrollView, arg1: CGPoint) -> Bool { - internalSubject.on(.next(arg1)) - return self._forwardToDelegate?.requiredDelegateMethod?(scrollView, arg1: arg1) ?? defaultReturnValue - } - - .... - - // reactive property implementation in a real class (`UIScrollView`) - public var property: Observable { - let proxy = RxScrollViewDelegateProxy.proxy(for: base) - return proxy.internalSubject.asObservable() - } - - **In case calling this method prints "Delegate proxy is already implementing `\(selector)`, - a more performant way of registering might exist.", that means that manual observing method - is required analog to the example above because delegate method has already been implemented.** - - - parameter selector: Selector used to filter observed invocations of delegate methods. - - returns: Observable sequence of arguments passed to `selector` method. - */ - open func methodInvoked(_ selector: Selector) -> Observable<[Any]> { - MainScheduler.ensureRunningOnMainThread() - - let subject = self._methodInvokedForSelector[selector] - - if let subject = subject { - return subject.asObservable() - } - else { - let subject = MessageDispatcher(selector: selector, delegateProxy: self) - self._methodInvokedForSelector[selector] = subject - return subject.asObservable() - } - } - - fileprivate func checkSelectorIsObservable(_ selector: Selector) { - MainScheduler.ensureRunningOnMainThread() - - if self.hasWiredImplementation(for: selector) { - print("⚠️ Delegate proxy is already implementing `\(selector)`, a more performant way of registering might exist.") - return - } - - if self.voidDelegateMethodsContain(selector) { - return - } - - // In case `_forwardToDelegate` is `nil`, it is assumed the check is being done prematurely. - if !(self._forwardToDelegate?.responds(to: selector) ?? true) { - print("⚠️ Using delegate proxy dynamic interception method but the target delegate object doesn't respond to the requested selector. " + - "In case pure Swift delegate proxy is being used please use manual observing method by using`PublishSubject`s. " + - " (selector: `\(selector)`, forwardToDelegate: `\(self._forwardToDelegate ?? self)`)") - } - } - - // proxy - - open override func _sentMessage(_ selector: Selector, withArguments arguments: [Any]) { - self._sentMessageForSelector[selector]?.on(.next(arguments)) - } - - open override func _methodInvoked(_ selector: Selector, withArguments arguments: [Any]) { - self._methodInvokedForSelector[selector]?.on(.next(arguments)) - } - - /// Returns reference of normal delegate that receives all forwarded messages - /// through `self`. - /// - /// - returns: Value of reference if set or nil. - open func forwardToDelegate() -> Delegate? { - return castOptionalOrFatalError(self._forwardToDelegate) - } - - /// Sets reference of normal delegate that receives all forwarded messages - /// through `self`. - /// - /// - parameter forwardToDelegate: Reference of delegate that receives all messages through `self`. - /// - parameter retainDelegate: Should `self` retain `forwardToDelegate`. - open func setForwardToDelegate(_ delegate: Delegate?, retainDelegate: Bool) { - #if DEBUG // 4.0 all configurations - MainScheduler.ensureRunningOnMainThread() - #endif - self._setForwardToDelegate(delegate, retainDelegate: retainDelegate) - - let sentSelectors: [Selector] = self._sentMessageForSelector.values.filter { $0.hasObservers }.map { $0.selector } - let invokedSelectors: [Selector] = self._methodInvokedForSelector.values.filter { $0.hasObservers }.map { $0.selector } - let allUsedSelectors = sentSelectors + invokedSelectors - - for selector in Set(allUsedSelectors) { - self.checkSelectorIsObservable(selector) - } - - self.reset() - } - - private func hasObservers(selector: Selector) -> Bool { - return (self._sentMessageForSelector[selector]?.hasObservers ?? false) - || (self._methodInvokedForSelector[selector]?.hasObservers ?? false) - } - - override open func responds(to aSelector: Selector!) -> Bool { - return super.responds(to: aSelector) - || (self._forwardToDelegate?.responds(to: aSelector) ?? false) - || (self.voidDelegateMethodsContain(aSelector) && self.hasObservers(selector: aSelector)) - } - - fileprivate func reset() { - guard let parentObject = self._parentObject else { return } - - let maybeCurrentDelegate = self._currentDelegateFor(parentObject) - - if maybeCurrentDelegate === self { - self._setCurrentDelegateTo(nil, parentObject) - self._setCurrentDelegateTo(castOrFatalError(self), parentObject) - } - } - - deinit { - for v in self._sentMessageForSelector.values { - v.on(.completed) - } - for v in self._methodInvokedForSelector.values { - v.on(.completed) - } - #if TRACE_RESOURCES - _ = Resources.decrementTotal() - #endif - } - - - } - - private let mainScheduler = MainScheduler() - - private final class MessageDispatcher { - private let dispatcher: PublishSubject<[Any]> - private let result: Observable<[Any]> - - fileprivate let selector: Selector - - init(selector: Selector, delegateProxy _delegateProxy: DelegateProxy) { - weak var weakDelegateProxy = _delegateProxy - - let dispatcher = PublishSubject<[Any]>() - self.dispatcher = dispatcher - self.selector = selector - - self.result = dispatcher - .do(onSubscribed: { weakDelegateProxy?.checkSelectorIsObservable(selector); weakDelegateProxy?.reset() }, onDispose: { weakDelegateProxy?.reset() }) - .share() - .subscribe(on: mainScheduler) - } - - var on: (Event<[Any]>) -> Void { - return self.dispatcher.on - } - - var hasObservers: Bool { - return self.dispatcher.hasObservers - } - - func asObservable() -> Observable<[Any]> { - return self.result - } - } - -#endif diff --git a/Pods/RxCocoa/RxCocoa/Common/DelegateProxyType.swift b/Pods/RxCocoa/RxCocoa/Common/DelegateProxyType.swift deleted file mode 100644 index 42fa50dc2..000000000 --- a/Pods/RxCocoa/RxCocoa/Common/DelegateProxyType.swift +++ /dev/null @@ -1,435 +0,0 @@ -// -// DelegateProxyType.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 6/15/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if !os(Linux) - - import Foundation - import RxSwift - -/** -`DelegateProxyType` protocol enables using both normal delegates and Rx observable sequences with -views that can have only one delegate/datasource registered. - -`Proxies` store information about observers, subscriptions and delegates -for specific views. - -Type implementing `DelegateProxyType` should never be initialized directly. - -To fetch initialized instance of type implementing `DelegateProxyType`, `proxy` method -should be used. - -This is more or less how it works. - - - - +-------------------------------------------+ - | | - | UIView subclass (UIScrollView) | - | | - +-----------+-------------------------------+ - | - | Delegate - | - | - +-----------v-------------------------------+ - | | - | Delegate proxy : DelegateProxyType +-----+----> Observable - | , UIScrollViewDelegate | | - +-----------+-------------------------------+ +----> Observable - | | - | +----> Observable - | | - | forwards events | - | to custom delegate | - | v - +-----------v-------------------------------+ - | | - | Custom delegate (UIScrollViewDelegate) | - | | - +-------------------------------------------+ - - -Since RxCocoa needs to automagically create those Proxys and because views that have delegates can be hierarchical - - UITableView : UIScrollView : UIView - -.. and corresponding delegates are also hierarchical - - UITableViewDelegate : UIScrollViewDelegate : NSObject - -... this mechanism can be extended by using the following snippet in `registerKnownImplementations` or in some other - part of your app that executes before using `rx.*` (e.g. appDidFinishLaunching). - - RxScrollViewDelegateProxy.register { RxTableViewDelegateProxy(parentObject: $0) } - -*/ -public protocol DelegateProxyType: AnyObject { - associatedtype ParentObject: AnyObject - associatedtype Delegate - - /// It is require that enumerate call `register` of the extended DelegateProxy subclasses here. - static func registerKnownImplementations() - - /// Unique identifier for delegate - static var identifier: UnsafeRawPointer { get } - - /// Returns designated delegate property for object. - /// - /// Objects can have multiple delegate properties. - /// - /// Each delegate property needs to have it's own type implementing `DelegateProxyType`. - /// - /// It's abstract method. - /// - /// - parameter object: Object that has delegate property. - /// - returns: Value of delegate property. - static func currentDelegate(for object: ParentObject) -> Delegate? - - /// Sets designated delegate property for object. - /// - /// Objects can have multiple delegate properties. - /// - /// Each delegate property needs to have it's own type implementing `DelegateProxyType`. - /// - /// It's abstract method. - /// - /// - parameter toObject: Object that has delegate property. - /// - parameter delegate: Delegate value. - static func setCurrentDelegate(_ delegate: Delegate?, to object: ParentObject) - - /// Returns reference of normal delegate that receives all forwarded messages - /// through `self`. - /// - /// - returns: Value of reference if set or nil. - func forwardToDelegate() -> Delegate? - - /// Sets reference of normal delegate that receives all forwarded messages - /// through `self`. - /// - /// - parameter forwardToDelegate: Reference of delegate that receives all messages through `self`. - /// - parameter retainDelegate: Should `self` retain `forwardToDelegate`. - func setForwardToDelegate(_ forwardToDelegate: Delegate?, retainDelegate: Bool) -} - -// default implementations -extension DelegateProxyType { - /// Unique identifier for delegate - public static var identifier: UnsafeRawPointer { - let delegateIdentifier = ObjectIdentifier(Delegate.self) - let integerIdentifier = Int(bitPattern: delegateIdentifier) - return UnsafeRawPointer(bitPattern: integerIdentifier)! - } -} - -// workaround of Delegate: class -extension DelegateProxyType { - static func _currentDelegate(for object: ParentObject) -> AnyObject? { - currentDelegate(for: object).map { $0 as AnyObject } - } - - static func _setCurrentDelegate(_ delegate: AnyObject?, to object: ParentObject) { - setCurrentDelegate(castOptionalOrFatalError(delegate), to: object) - } - - func _forwardToDelegate() -> AnyObject? { - self.forwardToDelegate().map { $0 as AnyObject } - } - - func _setForwardToDelegate(_ forwardToDelegate: AnyObject?, retainDelegate: Bool) { - self.setForwardToDelegate(castOptionalOrFatalError(forwardToDelegate), retainDelegate: retainDelegate) - } -} - -extension DelegateProxyType { - - /// Store DelegateProxy subclass to factory. - /// When make 'Rx*DelegateProxy' subclass, call 'Rx*DelegateProxySubclass.register(for:_)' 1 time, or use it in DelegateProxyFactory - /// 'Rx*DelegateProxy' can have one subclass implementation per concrete ParentObject type. - /// Should call it from concrete DelegateProxy type, not generic. - public static func register(make: @escaping (Parent) -> Self) { - self.factory.extend(make: make) - } - - /// Creates new proxy for target object. - /// Should not call this function directory, use 'DelegateProxy.proxy(for:)' - public static func createProxy(for object: AnyObject) -> Self { - castOrFatalError(factory.createProxy(for: object)) - } - - /// Returns existing proxy for object or installs new instance of delegate proxy. - /// - /// - parameter object: Target object on which to install delegate proxy. - /// - returns: Installed instance of delegate proxy. - /// - /// - /// extension Reactive where Base: UISearchBar { - /// - /// public var delegate: DelegateProxy { - /// return RxSearchBarDelegateProxy.proxy(for: base) - /// } - /// - /// public var text: ControlProperty { - /// let source: Observable = self.delegate.observe(#selector(UISearchBarDelegate.searchBar(_:textDidChange:))) - /// ... - /// } - /// } - public static func proxy(for object: ParentObject) -> Self { - MainScheduler.ensureRunningOnMainThread() - - let maybeProxy = self.assignedProxy(for: object) - - let proxy: AnyObject - if let existingProxy = maybeProxy { - proxy = existingProxy - } - else { - proxy = castOrFatalError(self.createProxy(for: object)) - self.assignProxy(proxy, toObject: object) - assert(self.assignedProxy(for: object) === proxy) - } - let currentDelegate = self._currentDelegate(for: object) - let delegateProxy: Self = castOrFatalError(proxy) - - if currentDelegate !== delegateProxy { - delegateProxy._setForwardToDelegate(currentDelegate, retainDelegate: false) - assert(delegateProxy._forwardToDelegate() === currentDelegate) - self._setCurrentDelegate(proxy, to: object) - assert(self._currentDelegate(for: object) === proxy) - assert(delegateProxy._forwardToDelegate() === currentDelegate) - } - - return delegateProxy - } - - /// Sets forward delegate for `DelegateProxyType` associated with a specific object and return disposable that can be used to unset the forward to delegate. - /// Using this method will also make sure that potential original object cached selectors are cleared and will report any accidental forward delegate mutations. - /// - /// - parameter forwardDelegate: Delegate object to set. - /// - parameter retainDelegate: Retain `forwardDelegate` while it's being set. - /// - parameter onProxyForObject: Object that has `delegate` property. - /// - returns: Disposable object that can be used to clear forward delegate. - public static func installForwardDelegate(_ forwardDelegate: Delegate, retainDelegate: Bool, onProxyForObject object: ParentObject) -> Disposable { - weak var weakForwardDelegate: AnyObject? = forwardDelegate as AnyObject - let proxy = self.proxy(for: object) - - assert(proxy._forwardToDelegate() === nil, "This is a feature to warn you that there is already a delegate (or data source) set somewhere previously. The action you are trying to perform will clear that delegate (data source) and that means that some of your features that depend on that delegate (data source) being set will likely stop working.\n" + - "If you are ok with this, try to set delegate (data source) to `nil` in front of this operation.\n" + - " This is the source object value: \(object)\n" + - " This is the original delegate (data source) value: \(proxy.forwardToDelegate()!)\n" + - "Hint: Maybe delegate was already set in xib or storyboard and now it's being overwritten in code.\n") - - proxy.setForwardToDelegate(forwardDelegate, retainDelegate: retainDelegate) - - return Disposables.create { - MainScheduler.ensureRunningOnMainThread() - - let delegate: AnyObject? = weakForwardDelegate - - assert(delegate == nil || proxy._forwardToDelegate() === delegate, "Delegate was changed from time it was first set. Current \(String(describing: proxy.forwardToDelegate())), and it should have been \(proxy)") - - proxy.setForwardToDelegate(nil, retainDelegate: retainDelegate) - } - } -} - - -// private extensions -extension DelegateProxyType { - private static var factory: DelegateProxyFactory { - DelegateProxyFactory.sharedFactory(for: self) - } - - private static func assignedProxy(for object: ParentObject) -> AnyObject? { - let maybeDelegate = objc_getAssociatedObject(object, self.identifier) - return castOptionalOrFatalError(maybeDelegate) - } - - private static func assignProxy(_ proxy: AnyObject, toObject object: ParentObject) { - objc_setAssociatedObject(object, self.identifier, proxy, .OBJC_ASSOCIATION_RETAIN) - } -} - -/// Describes an object that has a delegate. -public protocol HasDelegate: AnyObject { - /// Delegate type - associatedtype Delegate - - /// Delegate - var delegate: Delegate? { get set } -} - -extension DelegateProxyType where ParentObject: HasDelegate, Self.Delegate == ParentObject.Delegate { - public static func currentDelegate(for object: ParentObject) -> Delegate? { - object.delegate - } - - public static func setCurrentDelegate(_ delegate: Delegate?, to object: ParentObject) { - object.delegate = delegate - } -} - -/// Describes an object that has a data source. -public protocol HasDataSource: AnyObject { - /// Data source type - associatedtype DataSource - - /// Data source - var dataSource: DataSource? { get set } -} - -extension DelegateProxyType where ParentObject: HasDataSource, Self.Delegate == ParentObject.DataSource { - public static func currentDelegate(for object: ParentObject) -> Delegate? { - object.dataSource - } - - public static func setCurrentDelegate(_ delegate: Delegate?, to object: ParentObject) { - object.dataSource = delegate - } -} - -/// Describes an object that has a prefetch data source. -@available(iOS 10.0, tvOS 10.0, *) -public protocol HasPrefetchDataSource: AnyObject { - /// Prefetch data source type - associatedtype PrefetchDataSource - - /// Prefetch data source - var prefetchDataSource: PrefetchDataSource? { get set } -} - -@available(iOS 10.0, tvOS 10.0, *) -extension DelegateProxyType where ParentObject: HasPrefetchDataSource, Self.Delegate == ParentObject.PrefetchDataSource { - public static func currentDelegate(for object: ParentObject) -> Delegate? { - object.prefetchDataSource - } - - public static func setCurrentDelegate(_ delegate: Delegate?, to object: ParentObject) { - object.prefetchDataSource = delegate - } -} - - #if os(iOS) || os(tvOS) - import UIKit - - extension ObservableType { - func subscribeProxyDataSource(ofObject object: DelegateProxy.ParentObject, dataSource: DelegateProxy.Delegate, retainDataSource: Bool, binding: @escaping (DelegateProxy, Event) -> Void) - -> Disposable - where DelegateProxy.ParentObject: UIView - , DelegateProxy.Delegate: AnyObject { - let proxy = DelegateProxy.proxy(for: object) - let unregisterDelegate = DelegateProxy.installForwardDelegate(dataSource, retainDelegate: retainDataSource, onProxyForObject: object) - - // Do not perform layoutIfNeeded if the object is still not in the view heirarchy - if object.window != nil { - // this is needed to flush any delayed old state (https://github.com/RxSwiftCommunity/RxDataSources/pull/75) - object.layoutIfNeeded() - } - - let subscription = self.asObservable() - .observe(on:MainScheduler()) - .catch { error in - bindingError(error) - return Observable.empty() - } - // source can never end, otherwise it would release the subscriber, and deallocate the data source - .concat(Observable.never()) - .take(until: object.rx.deallocated) - .subscribe { [weak object] (event: Event) in - - if let object = object { - assert(proxy === DelegateProxy.currentDelegate(for: object), "Proxy changed from the time it was first set.\nOriginal: \(proxy)\nExisting: \(String(describing: DelegateProxy.currentDelegate(for: object)))") - } - - binding(proxy, event) - - switch event { - case .error(let error): - bindingError(error) - unregisterDelegate.dispose() - case .completed: - unregisterDelegate.dispose() - default: - break - } - } - - return Disposables.create { [weak object] in - subscription.dispose() - - if object?.window != nil { - object?.layoutIfNeeded() - } - - unregisterDelegate.dispose() - } - } - } - - #endif - - /** - - To add delegate proxy subclasses call `DelegateProxySubclass.register()` in `registerKnownImplementations` or in some other - part of your app that executes before using `rx.*` (e.g. appDidFinishLaunching). - - class RxScrollViewDelegateProxy: DelegateProxy { - public static func registerKnownImplementations() { - self.register { RxTableViewDelegateProxy(parentObject: $0) } - } - ... - - - */ - private class DelegateProxyFactory { - private static var _sharedFactories: [UnsafeRawPointer: DelegateProxyFactory] = [:] - - fileprivate static func sharedFactory(for proxyType: DelegateProxy.Type) -> DelegateProxyFactory { - MainScheduler.ensureRunningOnMainThread() - let identifier = DelegateProxy.identifier - if let factory = _sharedFactories[identifier] { - return factory - } - let factory = DelegateProxyFactory(for: proxyType) - _sharedFactories[identifier] = factory - DelegateProxy.registerKnownImplementations() - return factory - } - - private var _factories: [ObjectIdentifier: ((AnyObject) -> AnyObject)] - private var _delegateProxyType: Any.Type - private var _identifier: UnsafeRawPointer - - private init(for proxyType: DelegateProxy.Type) { - self._factories = [:] - self._delegateProxyType = proxyType - self._identifier = proxyType.identifier - } - - fileprivate func extend(make: @escaping (ParentObject) -> DelegateProxy) { - MainScheduler.ensureRunningOnMainThread() - precondition(self._identifier == DelegateProxy.identifier, "Delegate proxy has inconsistent identifier") - guard self._factories[ObjectIdentifier(ParentObject.self)] == nil else { - rxFatalError("The factory of \(ParentObject.self) is duplicated. DelegateProxy is not allowed of duplicated base object type.") - } - self._factories[ObjectIdentifier(ParentObject.self)] = { make(castOrFatalError($0)) } - } - - fileprivate func createProxy(for object: AnyObject) -> AnyObject { - MainScheduler.ensureRunningOnMainThread() - var maybeMirror: Mirror? = Mirror(reflecting: object) - while let mirror = maybeMirror { - if let factory = self._factories[ObjectIdentifier(mirror.subjectType)] { - return factory(object) - } - maybeMirror = mirror.superclassMirror - } - rxFatalError("DelegateProxy has no factory of \(object). Implement DelegateProxy subclass for \(object) first.") - } - } - -#endif diff --git a/Pods/RxCocoa/RxCocoa/Common/Infallible+Bind.swift b/Pods/RxCocoa/RxCocoa/Common/Infallible+Bind.swift deleted file mode 100644 index 82c2922d6..000000000 --- a/Pods/RxCocoa/RxCocoa/Common/Infallible+Bind.swift +++ /dev/null @@ -1,148 +0,0 @@ -// -// Infallible+Bind.swift -// RxCocoa -// -// Created by Shai Mishali on 27/08/2020. -// Copyright © 2020 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - -extension InfallibleType { - /** - Creates new subscription and sends elements to observer(s). - In this form, it's equivalent to the `subscribe` method, but it better conveys intent, and enables - writing more consistent binding code. - - parameter to: Observers to receives events. - - returns: Disposable object that can be used to unsubscribe the observers. - */ - public func bind(to observers: Observer...) -> Disposable where Observer.Element == Element { - self.subscribe { event in - observers.forEach { $0.on(event) } - } - } - - /** - Creates new subscription and sends elements to observer(s). - In this form, it's equivalent to the `subscribe` method, but it better conveys intent, and enables - writing more consistent binding code. - - parameter to: Observers to receives events. - - returns: Disposable object that can be used to unsubscribe the observers. - */ - public func bind(to observers: Observer...) -> Disposable where Observer.Element == Element? { - self.map { $0 as Element? } - .subscribe { event in - observers.forEach { $0.on(event) } - } - } - - /** - Subscribes to observable sequence using custom binder function. - - - parameter to: Function used to bind elements from `self`. - - returns: Object representing subscription. - */ - public func bind(to binder: (Self) -> Result) -> Result { - binder(self) - } - - /** - Subscribes to observable sequence using custom binder function and final parameter passed to binder function - after `self` is passed. - - public func bind(to binder: Self -> R1 -> R2, curriedArgument: R1) -> R2 { - return binder(self)(curriedArgument) - } - - - parameter to: Function used to bind elements from `self`. - - parameter curriedArgument: Final argument passed to `binder` to finish binding process. - - returns: Object representing subscription. - */ - public func bind(to binder: (Self) -> (R1) -> R2, curriedArgument: R1) -> R2 { - binder(self)(curriedArgument) - } - - /** - Subscribes an element handler to an observable sequence. - In case error occurs in debug mode, `fatalError` will be raised. - In case error occurs in release mode, `error` will be logged. - - - parameter onNext: Action to invoke for each element in the observable sequence. - - returns: Subscription object used to unsubscribe from the observable sequence. - */ - public func bind(onNext: @escaping (Element) -> Void) -> Disposable { - self.subscribe(onNext: onNext) - } - - /** - Creates new subscription and sends elements to `BehaviorRelay`. - - - parameter relay: Target relay for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer from the relay. - */ - public func bind(to relays: BehaviorRelay...) -> Disposable { - return self.subscribe(onNext: { e in - relays.forEach { $0.accept(e) } - }) - } - - /** - Creates new subscription and sends elements to `BehaviorRelay`. - - - parameter relay: Target relay for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer from the relay. - */ - public func bind(to relays: BehaviorRelay...) -> Disposable { - return self.subscribe(onNext: { e in - relays.forEach { $0.accept(e) } - }) - } - - /** - Creates new subscription and sends elements to `PublishRelay`. - - - parameter relay: Target relay for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer from the relay. - */ - public func bind(to relays: PublishRelay...) -> Disposable { - return self.subscribe(onNext: { e in - relays.forEach { $0.accept(e) } - }) - } - - /** - Creates new subscription and sends elements to `PublishRelay`. - - - parameter relay: Target relay for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer from the relay. - */ - public func bind(to relays: PublishRelay...) -> Disposable { - return self.subscribe(onNext: { e in - relays.forEach { $0.accept(e) } - }) - } - - /** - Creates new subscription and sends elements to `ReplayRelay`. - - - parameter relay: Target relay for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer from the relay. - */ - public func bind(to relays: ReplayRelay...) -> Disposable { - return self.subscribe(onNext: { e in - relays.forEach { $0.accept(e) } - }) - } - - /** - Creates new subscription and sends elements to `ReplayRelay`. - - - parameter relay: Target relay for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer from the relay. - */ - public func bind(to relays: ReplayRelay...) -> Disposable { - return self.subscribe(onNext: { e in - relays.forEach { $0.accept(e) } - }) - } -} diff --git a/Pods/RxCocoa/RxCocoa/Common/Observable+Bind.swift b/Pods/RxCocoa/RxCocoa/Common/Observable+Bind.swift deleted file mode 100644 index edded6b87..000000000 --- a/Pods/RxCocoa/RxCocoa/Common/Observable+Bind.swift +++ /dev/null @@ -1,103 +0,0 @@ -// -// Observable+Bind.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 8/29/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - -extension ObservableType { - /** - Creates new subscription and sends elements to observer(s). - In this form, it's equivalent to the `subscribe` method, but it better conveys intent, and enables - writing more consistent binding code. - - parameter to: Observers to receives events. - - returns: Disposable object that can be used to unsubscribe the observers. - */ - public func bind(to observers: Observer...) -> Disposable where Observer.Element == Element { - self.subscribe { event in - observers.forEach { $0.on(event) } - } - } - - /** - Creates new subscription and sends elements to observer(s). - In this form, it's equivalent to the `subscribe` method, but it better conveys intent, and enables - writing more consistent binding code. - - parameter to: Observers to receives events. - - returns: Disposable object that can be used to unsubscribe the observers. - */ - public func bind(to observers: Observer...) -> Disposable where Observer.Element == Element? { - self.map { $0 as Element? } - .subscribe { event in - observers.forEach { $0.on(event) } - } - } - - /** - Subscribes to observable sequence using custom binder function. - - - parameter to: Function used to bind elements from `self`. - - returns: Object representing subscription. - */ - public func bind(to binder: (Self) -> Result) -> Result { - binder(self) - } - - /** - Subscribes to observable sequence using custom binder function and final parameter passed to binder function - after `self` is passed. - - public func bind(to binder: Self -> R1 -> R2, curriedArgument: R1) -> R2 { - return binder(self)(curriedArgument) - } - - - parameter to: Function used to bind elements from `self`. - - parameter curriedArgument: Final argument passed to `binder` to finish binding process. - - returns: Object representing subscription. - */ - public func bind(to binder: (Self) -> (R1) -> R2, curriedArgument: R1) -> R2 { - binder(self)(curriedArgument) - } - - /** - Subscribes an element handler to an observable sequence. - In case error occurs in debug mode, `fatalError` will be raised. - In case error occurs in release mode, `error` will be logged. - - - Note: If `object` can't be retained, none of the other closures will be invoked. - - - parameter object: The object to provide an unretained reference on. - - parameter onNext: Action to invoke for each element in the observable sequence. - - returns: Subscription object used to unsubscribe from the observable sequence. - */ - public func bind( - with object: Object, - onNext: @escaping (Object, Element) -> Void - ) -> Disposable { - self.subscribe(onNext: { [weak object] in - guard let object = object else { return } - onNext(object, $0) - }, - onError: { error in - rxFatalErrorInDebug("Binding error: \(error)") - }) - } - - /** - Subscribes an element handler to an observable sequence. - In case error occurs in debug mode, `fatalError` will be raised. - In case error occurs in release mode, `error` will be logged. - - - parameter onNext: Action to invoke for each element in the observable sequence. - - returns: Subscription object used to unsubscribe from the observable sequence. - */ - public func bind(onNext: @escaping (Element) -> Void) -> Disposable { - self.subscribe(onNext: onNext, - onError: { error in - rxFatalErrorInDebug("Binding error: \(error)") - }) - } -} diff --git a/Pods/RxCocoa/RxCocoa/Common/RxCocoaObjCRuntimeError+Extensions.swift b/Pods/RxCocoa/RxCocoa/Common/RxCocoaObjCRuntimeError+Extensions.swift deleted file mode 100644 index 4abf8808c..000000000 --- a/Pods/RxCocoa/RxCocoa/Common/RxCocoaObjCRuntimeError+Extensions.swift +++ /dev/null @@ -1,161 +0,0 @@ -// -// RxCocoaObjCRuntimeError+Extensions.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 10/9/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -#if SWIFT_PACKAGE && !DISABLE_SWIZZLING && !os(Linux) - import RxCocoaRuntime -#endif - -#if !DISABLE_SWIZZLING && !os(Linux) - /// RxCocoa ObjC runtime interception mechanism. - public enum RxCocoaInterceptionMechanism { - /// Unknown message interception mechanism. - case unknown - /// Key value observing interception mechanism. - case kvo - } - - /// RxCocoa ObjC runtime modification errors. - public enum RxCocoaObjCRuntimeError - : Swift.Error - , CustomDebugStringConvertible { - /// Unknown error has occurred. - case unknown(target: AnyObject) - - /** - If the object is reporting a different class then it's real class, that means that there is probably - already some interception mechanism in place or something weird is happening. - - The most common case when this would happen is when using a combination of KVO (`observe`) and `sentMessage`. - - This error is easily resolved by just using `sentMessage` observing before `observe`. - - The reason why the other way around could create issues is because KVO will unregister it's interceptor - class and restore original class. Unfortunately that will happen no matter was there another interceptor - subclass registered in hierarchy or not. - - Failure scenario: - * KVO sets class to be `__KVO__OriginalClass` (subclass of `OriginalClass`) - * `sentMessage` sets object class to be `_RX_namespace___KVO__OriginalClass` (subclass of `__KVO__OriginalClass`) - * then unobserving with KVO will restore class to be `OriginalClass` -> failure point (possibly a bug in KVO) - - The reason why changing order of observing works is because any interception method on unregistration - should return object's original real class (if that doesn't happen then it's really easy to argue that's a bug - in that interception mechanism). - - This library won't remove registered interceptor even if there aren't any observers left because - it's highly unlikely it would have any benefit in real world use cases, and it's even more - dangerous. - */ - case objectMessagesAlreadyBeingIntercepted(target: AnyObject, interceptionMechanism: RxCocoaInterceptionMechanism) - - /// Trying to observe messages for selector that isn't implemented. - case selectorNotImplemented(target: AnyObject) - - /// Core Foundation classes are usually toll free bridged. Those classes crash the program in case - /// `object_setClass` is performed on them. - /// - /// There is a possibility to just swizzle methods on original object, but since those won't be usual use - /// cases for this library, then an error will just be reported for now. - case cantInterceptCoreFoundationTollFreeBridgedObjects(target: AnyObject) - - /// Two libraries have simultaneously tried to modify ObjC runtime and that was detected. This can only - /// happen in scenarios where multiple interception libraries are used. - /// - /// To synchronize other libraries intercepting messages for an object, use `synchronized` on target object and - /// it's meta-class. - case threadingCollisionWithOtherInterceptionMechanism(target: AnyObject) - - /// For some reason saving original method implementation under RX namespace failed. - case savingOriginalForwardingMethodFailed(target: AnyObject) - - /// Intercepting a sent message by replacing a method implementation with `_objc_msgForward` failed for some reason. - case replacingMethodWithForwardingImplementation(target: AnyObject) - - /// Attempt to intercept one of the performance sensitive methods: - /// * class - /// * respondsToSelector: - /// * methodSignatureForSelector: - /// * forwardingTargetForSelector: - case observingPerformanceSensitiveMessages(target: AnyObject) - - /// Message implementation has unsupported return type (for example large struct). The reason why this is a error - /// is because in some cases intercepting sent messages requires replacing implementation with `_objc_msgForward_stret` - /// instead of `_objc_msgForward`. - /// - /// The unsupported cases should be fairly uncommon. - case observingMessagesWithUnsupportedReturnType(target: AnyObject) - } - - extension RxCocoaObjCRuntimeError { - /// A textual representation of `self`, suitable for debugging. - public var debugDescription: String { - switch self { - case let .unknown(target): - return "Unknown error occurred.\nTarget: `\(target)`" - case let .objectMessagesAlreadyBeingIntercepted(target, interceptionMechanism): - let interceptionMechanismDescription = interceptionMechanism == .kvo ? "KVO" : "other interception mechanism" - return "Collision between RxCocoa interception mechanism and \(interceptionMechanismDescription)." - + " To resolve this conflict please use this interception mechanism first.\nTarget: \(target)" - case let .selectorNotImplemented(target): - return "Trying to observe messages for selector that isn't implemented.\nTarget: \(target)" - case let .cantInterceptCoreFoundationTollFreeBridgedObjects(target): - return "Interception of messages sent to Core Foundation isn't supported.\nTarget: \(target)" - case let .threadingCollisionWithOtherInterceptionMechanism(target): - return "Detected a conflict while modifying ObjC runtime.\nTarget: \(target)" - case let .savingOriginalForwardingMethodFailed(target): - return "Saving original method implementation failed.\nTarget: \(target)" - case let .replacingMethodWithForwardingImplementation(target): - return "Intercepting a sent message by replacing a method implementation with `_objc_msgForward` failed for some reason.\nTarget: \(target)" - case let .observingPerformanceSensitiveMessages(target): - return "Attempt to intercept one of the performance sensitive methods. \nTarget: \(target)" - case let .observingMessagesWithUnsupportedReturnType(target): - return "Attempt to intercept a method with unsupported return type. \nTarget: \(target)" - } - } - } - - // MARK: Conversions `NSError` > `RxCocoaObjCRuntimeError` - - extension Error { - func rxCocoaErrorForTarget(_ target: AnyObject) -> RxCocoaObjCRuntimeError { - let error = self as NSError - - if error.domain == RXObjCRuntimeErrorDomain { - let errorCode = RXObjCRuntimeError(rawValue: error.code) ?? .unknown - - switch errorCode { - case .unknown: - return .unknown(target: target) - case .objectMessagesAlreadyBeingIntercepted: - let isKVO = (error.userInfo[RXObjCRuntimeErrorIsKVOKey] as? NSNumber)?.boolValue ?? false - return .objectMessagesAlreadyBeingIntercepted(target: target, interceptionMechanism: isKVO ? .kvo : .unknown) - case .selectorNotImplemented: - return .selectorNotImplemented(target: target) - case .cantInterceptCoreFoundationTollFreeBridgedObjects: - return .cantInterceptCoreFoundationTollFreeBridgedObjects(target: target) - case .threadingCollisionWithOtherInterceptionMechanism: - return .threadingCollisionWithOtherInterceptionMechanism(target: target) - case .savingOriginalForwardingMethodFailed: - return .savingOriginalForwardingMethodFailed(target: target) - case .replacingMethodWithForwardingImplementation: - return .replacingMethodWithForwardingImplementation(target: target) - case .observingPerformanceSensitiveMessages: - return .observingPerformanceSensitiveMessages(target: target) - case .observingMessagesWithUnsupportedReturnType: - return .observingMessagesWithUnsupportedReturnType(target: target) - @unknown default: - fatalError("Unhandled Objective C Runtime Error") - } - } - - return RxCocoaObjCRuntimeError.unknown(target: target) - } - } - -#endif - diff --git a/Pods/RxCocoa/RxCocoa/Common/RxTarget.swift b/Pods/RxCocoa/RxCocoa/Common/RxTarget.swift deleted file mode 100644 index 5a2c464b0..000000000 --- a/Pods/RxCocoa/RxCocoa/Common/RxTarget.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// RxTarget.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 7/12/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import Foundation - -import RxSwift - -class RxTarget : NSObject - , Disposable { - - private var retainSelf: RxTarget? - - override init() { - super.init() - self.retainSelf = self - -#if TRACE_RESOURCES - _ = Resources.incrementTotal() -#endif - -#if DEBUG - MainScheduler.ensureRunningOnMainThread() -#endif - } - - func dispose() { -#if DEBUG - MainScheduler.ensureRunningOnMainThread() -#endif - self.retainSelf = nil - } - -#if TRACE_RESOURCES - deinit { - _ = Resources.decrementTotal() - } -#endif -} diff --git a/Pods/RxCocoa/RxCocoa/Common/SectionedViewDataSourceType.swift b/Pods/RxCocoa/RxCocoa/Common/SectionedViewDataSourceType.swift deleted file mode 100644 index 5c3cf3ca4..000000000 --- a/Pods/RxCocoa/RxCocoa/Common/SectionedViewDataSourceType.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// SectionedViewDataSourceType.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 1/10/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -import Foundation - -/// Data source with access to underlying sectioned model. -public protocol SectionedViewDataSourceType { - /// Returns model at index path. - /// - /// In case data source doesn't contain any sections when this method is being called, `RxCocoaError.ItemsNotYetBound(object: self)` is thrown. - - /// - parameter indexPath: Model index path - /// - returns: Model at index path. - func model(at indexPath: IndexPath) throws -> Any -} diff --git a/Pods/RxCocoa/RxCocoa/Common/TextInput.swift b/Pods/RxCocoa/RxCocoa/Common/TextInput.swift deleted file mode 100644 index 2268882fa..000000000 --- a/Pods/RxCocoa/RxCocoa/Common/TextInput.swift +++ /dev/null @@ -1,78 +0,0 @@ -// -// TextInput.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 5/12/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - -#if os(iOS) || os(tvOS) - import UIKit - - /// Represents text input with reactive extensions. - public struct TextInput { - /// Base text input to extend. - public let base: Base - - /// Reactive wrapper for `text` property. - public let text: ControlProperty - - /// Initializes new text input. - /// - /// - parameter base: Base object. - /// - parameter text: Textual control property. - public init(base: Base, text: ControlProperty) { - self.base = base - self.text = text - } - } - - extension Reactive where Base: UITextField { - /// Reactive text input. - public var textInput: TextInput { - return TextInput(base: base, text: self.text) - } - } - - extension Reactive where Base: UITextView { - /// Reactive text input. - public var textInput: TextInput { - return TextInput(base: base, text: self.text) - } - } - -#endif - -#if os(macOS) - import Cocoa - - /// Represents text input with reactive extensions. - public struct TextInput { - /// Base text input to extend. - public let base: Base - - /// Reactive wrapper for `text` property. - public let text: ControlProperty - - /// Initializes new text input. - /// - /// - parameter base: Base object. - /// - parameter text: Textual control property. - public init(base: Base, text: ControlProperty) { - self.base = base - self.text = text - } - } - - extension Reactive where Base: NSTextField, Base: NSTextInputClient { - /// Reactive text input. - public var textInput: TextInput { - return TextInput(base: self.base, text: self.text) - } - } - -#endif - - diff --git a/Pods/RxCocoa/RxCocoa/Foundation/KVORepresentable+CoreGraphics.swift b/Pods/RxCocoa/RxCocoa/Foundation/KVORepresentable+CoreGraphics.swift deleted file mode 100644 index 30026bf99..000000000 --- a/Pods/RxCocoa/RxCocoa/Foundation/KVORepresentable+CoreGraphics.swift +++ /dev/null @@ -1,68 +0,0 @@ -// -// KVORepresentable+CoreGraphics.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 11/14/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if !os(Linux) - -import RxSwift -import CoreGraphics - -import Foundation - -#if arch(x86_64) || arch(arm64) - let CGRectType = "{CGRect={CGPoint=dd}{CGSize=dd}}" - let CGSizeType = "{CGSize=dd}" - let CGPointType = "{CGPoint=dd}" -#elseif arch(i386) || arch(arm) || os(watchOS) - let CGRectType = "{CGRect={CGPoint=ff}{CGSize=ff}}" - let CGSizeType = "{CGSize=ff}" - let CGPointType = "{CGPoint=ff}" -#endif - -extension CGRect : KVORepresentable { - public typealias KVOType = NSValue - - /// Constructs self from `NSValue`. - public init?(KVOValue: KVOType) { - if strcmp(KVOValue.objCType, CGRectType) != 0 { - return nil - } - var typedValue = CGRect(x: 0, y: 0, width: 0, height: 0) - KVOValue.getValue(&typedValue) - self = typedValue - } -} - -extension CGPoint : KVORepresentable { - public typealias KVOType = NSValue - - /// Constructs self from `NSValue`. - public init?(KVOValue: KVOType) { - if strcmp(KVOValue.objCType, CGPointType) != 0 { - return nil - } - var typedValue = CGPoint(x: 0, y: 0) - KVOValue.getValue(&typedValue) - self = typedValue - } -} - -extension CGSize : KVORepresentable { - public typealias KVOType = NSValue - - /// Constructs self from `NSValue`. - public init?(KVOValue: KVOType) { - if strcmp(KVOValue.objCType, CGSizeType) != 0 { - return nil - } - var typedValue = CGSize(width: 0, height: 0) - KVOValue.getValue(&typedValue) - self = typedValue - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/Foundation/KVORepresentable+Swift.swift b/Pods/RxCocoa/RxCocoa/Foundation/KVORepresentable+Swift.swift deleted file mode 100644 index 00d53dd09..000000000 --- a/Pods/RxCocoa/RxCocoa/Foundation/KVORepresentable+Swift.swift +++ /dev/null @@ -1,88 +0,0 @@ -// -// KVORepresentable+Swift.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 11/14/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import Foundation - -extension Int : KVORepresentable { - public typealias KVOType = NSNumber - - /// Constructs `Self` using KVO value. - public init?(KVOValue: KVOType) { - self.init(KVOValue.int32Value) - } -} - -extension Int32 : KVORepresentable { - public typealias KVOType = NSNumber - - /// Constructs `Self` using KVO value. - public init?(KVOValue: KVOType) { - self.init(KVOValue.int32Value) - } -} - -extension Int64 : KVORepresentable { - public typealias KVOType = NSNumber - - /// Constructs `Self` using KVO value. - public init?(KVOValue: KVOType) { - self.init(KVOValue.int64Value) - } -} - -extension UInt : KVORepresentable { - public typealias KVOType = NSNumber - - /// Constructs `Self` using KVO value. - public init?(KVOValue: KVOType) { - self.init(KVOValue.uintValue) - } -} - -extension UInt32 : KVORepresentable { - public typealias KVOType = NSNumber - - /// Constructs `Self` using KVO value. - public init?(KVOValue: KVOType) { - self.init(KVOValue.uint32Value) - } -} - -extension UInt64 : KVORepresentable { - public typealias KVOType = NSNumber - - /// Constructs `Self` using KVO value. - public init?(KVOValue: KVOType) { - self.init(KVOValue.uint64Value) - } -} - -extension Bool : KVORepresentable { - public typealias KVOType = NSNumber - - /// Constructs `Self` using KVO value. - public init?(KVOValue: KVOType) { - self.init(KVOValue.boolValue) - } -} - - -extension RawRepresentable where RawValue: KVORepresentable { - /// Constructs `Self` using optional KVO value. - init?(KVOValue: RawValue.KVOType?) { - guard let KVOValue = KVOValue else { - return nil - } - - guard let rawValue = RawValue(KVOValue: KVOValue) else { - return nil - } - - self.init(rawValue: rawValue) - } -} diff --git a/Pods/RxCocoa/RxCocoa/Foundation/KVORepresentable.swift b/Pods/RxCocoa/RxCocoa/Foundation/KVORepresentable.swift deleted file mode 100644 index be12b332f..000000000 --- a/Pods/RxCocoa/RxCocoa/Foundation/KVORepresentable.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// KVORepresentable.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 11/14/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// Type that is KVO representable (KVO mechanism can be used to observe it). -public protocol KVORepresentable { - /// Associated KVO type. - associatedtype KVOType - - /// Constructs `Self` using KVO value. - init?(KVOValue: KVOType) -} - -extension KVORepresentable { - /// Initializes `KVORepresentable` with optional value. - init?(KVOValue: KVOType?) { - guard let KVOValue = KVOValue else { - return nil - } - - self.init(KVOValue: KVOValue) - } -} - diff --git a/Pods/RxCocoa/RxCocoa/Foundation/NSObject+Rx+KVORepresentable.swift b/Pods/RxCocoa/RxCocoa/Foundation/NSObject+Rx+KVORepresentable.swift deleted file mode 100644 index 1be5a212d..000000000 --- a/Pods/RxCocoa/RxCocoa/Foundation/NSObject+Rx+KVORepresentable.swift +++ /dev/null @@ -1,60 +0,0 @@ -// -// NSObject+Rx+KVORepresentable.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 11/14/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if !os(Linux) - -import Foundation -import RxSwift - -/// Key value observing options -public struct KeyValueObservingOptions: OptionSet { - /// Raw value - public let rawValue: UInt - - public init(rawValue: UInt) { - self.rawValue = rawValue - } - - /// Whether a sequence element should be sent to the observer immediately, before the subscribe method even returns. - public static let initial = KeyValueObservingOptions(rawValue: 1 << 0) - /// Whether to send updated values. - public static let new = KeyValueObservingOptions(rawValue: 1 << 1) -} - -extension Reactive where Base: NSObject { - - /** - Specialization of generic `observe` method. - - This is a special overload because to observe values of some type (for example `Int`), first values of KVO type - need to be observed (`NSNumber`), and then converted to result type. - - For more information take a look at `observe` method. - */ - public func observe(_ type: Element.Type, _ keyPath: String, options: KeyValueObservingOptions = [.new, .initial], retainSelf: Bool = true) -> Observable { - return self.observe(Element.KVOType.self, keyPath, options: options, retainSelf: retainSelf) - .map(Element.init) - } -} - -#if !DISABLE_SWIZZLING && !os(Linux) - // KVO - extension Reactive where Base: NSObject { - /** - Specialization of generic `observeWeakly` method. - - For more information take a look at `observeWeakly` method. - */ - public func observeWeakly(_ type: Element.Type, _ keyPath: String, options: KeyValueObservingOptions = [.new, .initial]) -> Observable { - return self.observeWeakly(Element.KVOType.self, keyPath, options: options) - .map(Element.init) - } - } -#endif - -#endif diff --git a/Pods/RxCocoa/RxCocoa/Foundation/NSObject+Rx+RawRepresentable.swift b/Pods/RxCocoa/RxCocoa/Foundation/NSObject+Rx+RawRepresentable.swift deleted file mode 100644 index 6e47cb243..000000000 --- a/Pods/RxCocoa/RxCocoa/Foundation/NSObject+Rx+RawRepresentable.swift +++ /dev/null @@ -1,52 +0,0 @@ -// -// NSObject+Rx+RawRepresentable.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 11/9/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if !os(Linux) - -import RxSwift - -import Foundation - -extension Reactive where Base: NSObject { - /** - Specialization of generic `observe` method. - - This specialization first observes `KVORepresentable` value and then converts it to `RawRepresentable` value. - - It is useful for observing bridged ObjC enum values. - - For more information take a look at `observe` method. - */ - public func observe(_ type: Element.Type, _ keyPath: String, options: KeyValueObservingOptions = [.new, .initial], retainSelf: Bool = true) -> Observable where Element.RawValue: KVORepresentable { - return self.observe(Element.RawValue.KVOType.self, keyPath, options: options, retainSelf: retainSelf) - .map(Element.init) - } -} - -#if !DISABLE_SWIZZLING - - // observeWeakly + RawRepresentable - extension Reactive where Base: NSObject { - - /** - Specialization of generic `observeWeakly` method. - - This specialization first observes `KVORepresentable` value and then converts it to `RawRepresentable` value. - - It is useful for observing bridged ObjC enum values. - - For more information take a look at `observeWeakly` method. - */ - public func observeWeakly(_ type: Element.Type, _ keyPath: String, options: KeyValueObservingOptions = [.new, .initial]) -> Observable where Element.RawValue: KVORepresentable { - return self.observeWeakly(Element.RawValue.KVOType.self, keyPath, options: options) - .map(Element.init) - } - } -#endif - -#endif diff --git a/Pods/RxCocoa/RxCocoa/Foundation/NSObject+Rx.swift b/Pods/RxCocoa/RxCocoa/Foundation/NSObject+Rx.swift deleted file mode 100644 index 68affa722..000000000 --- a/Pods/RxCocoa/RxCocoa/Foundation/NSObject+Rx.swift +++ /dev/null @@ -1,569 +0,0 @@ -// -// NSObject+Rx.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 2/21/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if !os(Linux) - -import Foundation -import RxSwift -#if SWIFT_PACKAGE && !DISABLE_SWIZZLING && !os(Linux) - import RxCocoaRuntime -#endif - -#if !DISABLE_SWIZZLING && !os(Linux) -private var deallocatingSubjectTriggerContext: UInt8 = 0 -private var deallocatingSubjectContext: UInt8 = 0 -#endif -private var deallocatedSubjectTriggerContext: UInt8 = 0 -private var deallocatedSubjectContext: UInt8 = 0 - -#if !os(Linux) - -/** -KVO is a tricky mechanism. - -When observing child in a ownership hierarchy, usually retaining observing target is wanted behavior. -When observing parent in a ownership hierarchy, usually retaining target isn't wanter behavior. - -KVO with weak references is especially tricky. For it to work, some kind of swizzling is required. -That can be done by - * replacing object class dynamically (like KVO does) - * by swizzling `dealloc` method on all instances for a class. - * some third method ... - -Both approaches can fail in certain scenarios: - * problems arise when swizzlers return original object class (like KVO does when nobody is observing) - * Problems can arise because replacing dealloc method isn't atomic operation (get implementation, - set implementation). - -Second approach is chosen. It can fail in case there are multiple libraries dynamically trying -to replace dealloc method. In case that isn't the case, it should be ok. -*/ -extension Reactive where Base: NSObject { - - - /** - Observes values on `keyPath` starting from `self` with `options` and retains `self` if `retainSelf` is set. - - `observe` is just a simple and performant wrapper around KVO mechanism. - - * it can be used to observe paths starting from `self` or from ancestors in ownership graph (`retainSelf = false`) - * it can be used to observe paths starting from descendants in ownership graph (`retainSelf = true`) - * the paths have to consist only of `strong` properties, otherwise you are risking crashing the system by not unregistering KVO observer before dealloc. - - If support for weak properties is needed or observing arbitrary or unknown relationships in the - ownership tree, `observeWeakly` is the preferred option. - - - parameter keyPath: Key path of property names to observe. - - parameter options: KVO mechanism notification options. - - parameter retainSelf: Retains self during observation if set `true`. - - returns: Observable sequence of objects on `keyPath`. - */ - public func observe(_ type: Element.Type, - _ keyPath: String, - options: KeyValueObservingOptions = [.new, .initial], - retainSelf: Bool = true) -> Observable { - KVOObservable(object: self.base, keyPath: keyPath, options: options, retainTarget: retainSelf).asObservable() - } - - /** - Observes values at the provided key path using the provided options. - - - parameter keyPath: A key path between the object and one of its properties. - - parameter options: Key-value observation options, defaults to `.new` and `.initial`. - - - note: When the object is deallocated, a completion event is emitted. - - - returns: An observable emitting value changes at the provided key path. - */ - public func observe(_ keyPath: KeyPath, - options: NSKeyValueObservingOptions = [.new, .initial]) -> Observable { - Observable.create { [weak base] observer in - let observation = base?.observe(keyPath, options: options) { obj, _ in - observer.on(.next(obj[keyPath: keyPath])) - } - - return Disposables.create { observation?.invalidate() } - } - .take(until: base.rx.deallocated) - } -} - -#endif - -#if !DISABLE_SWIZZLING && !os(Linux) -// KVO -extension Reactive where Base: NSObject { - /** - Observes values on `keyPath` starting from `self` with `options` and doesn't retain `self`. - - It can be used in all cases where `observe` can be used and additionally - - * because it won't retain observed target, it can be used to observe arbitrary object graph whose ownership relation is unknown - * it can be used to observe `weak` properties - - **Since it needs to intercept object deallocation process it needs to perform swizzling of `dealloc` method on observed object.** - - - parameter keyPath: Key path of property names to observe. - - parameter options: KVO mechanism notification options. - - returns: Observable sequence of objects on `keyPath`. - */ - public func observeWeakly(_ type: Element.Type, _ keyPath: String, options: KeyValueObservingOptions = [.new, .initial]) -> Observable { - return observeWeaklyKeyPathFor(self.base, keyPath: keyPath, options: options) - .map { n in - return n as? Element - } - } -} -#endif - -// Dealloc -extension Reactive where Base: AnyObject { - - /** - Observable sequence of object deallocated events. - - After object is deallocated one `()` element will be produced and sequence will immediately complete. - - - returns: Observable sequence of object deallocated events. - */ - public var deallocated: Observable { - return self.synchronized { - if let deallocObservable = objc_getAssociatedObject(self.base, &deallocatedSubjectContext) as? DeallocObservable { - return deallocObservable.subject - } - - let deallocObservable = DeallocObservable() - - objc_setAssociatedObject(self.base, &deallocatedSubjectContext, deallocObservable, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - return deallocObservable.subject - } - } - -#if !DISABLE_SWIZZLING && !os(Linux) - - /** - Observable sequence of message arguments that completes when object is deallocated. - - Each element is produced before message is invoked on target object. `methodInvoked` - exists in case observing of invoked messages is needed. - - In case an error occurs sequence will fail with `RxCocoaObjCRuntimeError`. - - In case some argument is `nil`, instance of `NSNull()` will be sent. - - - returns: Observable sequence of arguments passed to `selector` method. - */ - public func sentMessage(_ selector: Selector) -> Observable<[Any]> { - return self.synchronized { - // in case of dealloc selector replay subject behavior needs to be used - if selector == deallocSelector { - return self.deallocating.map { _ in [] } - } - - do { - let proxy: MessageSentProxy = try self.registerMessageInterceptor(selector) - return proxy.messageSent.asObservable() - } - catch let e { - return Observable.error(e) - } - } - } - - /** - Observable sequence of message arguments that completes when object is deallocated. - - Each element is produced after message is invoked on target object. `sentMessage` - exists in case interception of sent messages before they were invoked is needed. - - In case an error occurs sequence will fail with `RxCocoaObjCRuntimeError`. - - In case some argument is `nil`, instance of `NSNull()` will be sent. - - - returns: Observable sequence of arguments passed to `selector` method. - */ - public func methodInvoked(_ selector: Selector) -> Observable<[Any]> { - return self.synchronized { - // in case of dealloc selector replay subject behavior needs to be used - if selector == deallocSelector { - return self.deallocated.map { _ in [] } - } - - - do { - let proxy: MessageSentProxy = try self.registerMessageInterceptor(selector) - return proxy.methodInvoked.asObservable() - } - catch let e { - return Observable.error(e) - } - } - } - - /** - Observable sequence of object deallocating events. - - When `dealloc` message is sent to `self` one `()` element will be produced and after object is deallocated sequence - will immediately complete. - - In case an error occurs sequence will fail with `RxCocoaObjCRuntimeError`. - - - returns: Observable sequence of object deallocating events. - */ - public var deallocating: Observable<()> { - return self.synchronized { - do { - let proxy: DeallocatingProxy = try self.registerMessageInterceptor(deallocSelector) - return proxy.messageSent.asObservable() - } - catch let e { - return Observable.error(e) - } - } - } - - private func registerMessageInterceptor(_ selector: Selector) throws -> T { - let rxSelector = RX_selector(selector) - let selectorReference = RX_reference_from_selector(rxSelector) - - let subject: T - if let existingSubject = objc_getAssociatedObject(self.base, selectorReference) as? T { - subject = existingSubject - } - else { - subject = T() - objc_setAssociatedObject( - self.base, - selectorReference, - subject, - .OBJC_ASSOCIATION_RETAIN_NONATOMIC - ) - } - - if subject.isActive { - return subject - } - - var error: NSError? - let targetImplementation = RX_ensure_observing(self.base, selector, &error) - if targetImplementation == nil { - throw error?.rxCocoaErrorForTarget(self.base) ?? RxCocoaError.unknown - } - - subject.targetImplementation = targetImplementation! - - return subject - } -#endif -} - -// MARK: Message interceptors - -#if !DISABLE_SWIZZLING && !os(Linux) - - private protocol MessageInterceptorSubject: AnyObject { - init() - - var isActive: Bool { - get - } - - var targetImplementation: IMP { get set } - } - - private final class DeallocatingProxy - : MessageInterceptorSubject - , RXDeallocatingObserver { - typealias Element = () - - let messageSent = ReplaySubject<()>.create(bufferSize: 1) - - @objc var targetImplementation: IMP = RX_default_target_implementation() - - var isActive: Bool { - return self.targetImplementation != RX_default_target_implementation() - } - - init() { - } - - @objc func deallocating() { - self.messageSent.on(.next(())) - } - - deinit { - self.messageSent.on(.completed) - } - } - - private final class MessageSentProxy - : MessageInterceptorSubject - , RXMessageSentObserver { - typealias Element = [AnyObject] - - let messageSent = PublishSubject<[Any]>() - let methodInvoked = PublishSubject<[Any]>() - - @objc var targetImplementation: IMP = RX_default_target_implementation() - - var isActive: Bool { - return self.targetImplementation != RX_default_target_implementation() - } - - init() { - } - - @objc func messageSent(withArguments arguments: [Any]) { - self.messageSent.on(.next(arguments)) - } - - @objc func methodInvoked(withArguments arguments: [Any]) { - self.methodInvoked.on(.next(arguments)) - } - - deinit { - self.messageSent.on(.completed) - self.methodInvoked.on(.completed) - } - } - -#endif - - -private final class DeallocObservable { - let subject = ReplaySubject.create(bufferSize:1) - - init() { - } - - deinit { - self.subject.on(.next(())) - self.subject.on(.completed) - } -} - -// MARK: KVO - -#if !os(Linux) - -private protocol KVOObservableProtocol { - var target: AnyObject { get } - var keyPath: String { get } - var retainTarget: Bool { get } - var options: KeyValueObservingOptions { get } -} - -private final class KVOObserver - : _RXKVOObserver - , Disposable { - typealias Callback = (Any?) -> Void - - var retainSelf: KVOObserver? - - init(parent: KVOObservableProtocol, callback: @escaping Callback) { - #if TRACE_RESOURCES - _ = Resources.incrementTotal() - #endif - - super.init(target: parent.target, retainTarget: parent.retainTarget, keyPath: parent.keyPath, options: parent.options.nsOptions, callback: callback) - self.retainSelf = self - } - - override func dispose() { - super.dispose() - self.retainSelf = nil - } - - deinit { - #if TRACE_RESOURCES - _ = Resources.decrementTotal() - #endif - } -} - -private final class KVOObservable - : ObservableType - , KVOObservableProtocol { - typealias Element = Element? - - unowned var target: AnyObject - var strongTarget: AnyObject? - - var keyPath: String - var options: KeyValueObservingOptions - var retainTarget: Bool - - init(object: AnyObject, keyPath: String, options: KeyValueObservingOptions, retainTarget: Bool) { - self.target = object - self.keyPath = keyPath - self.options = options - self.retainTarget = retainTarget - if retainTarget { - self.strongTarget = object - } - } - - func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element? { - let observer = KVOObserver(parent: self) { value in - if value as? NSNull != nil { - observer.on(.next(nil)) - return - } - observer.on(.next(value as? Element)) - } - - return Disposables.create(with: observer.dispose) - } - -} - -private extension KeyValueObservingOptions { - var nsOptions: NSKeyValueObservingOptions { - var result: UInt = 0 - if self.contains(.new) { - result |= NSKeyValueObservingOptions.new.rawValue - } - if self.contains(.initial) { - result |= NSKeyValueObservingOptions.initial.rawValue - } - - return NSKeyValueObservingOptions(rawValue: result) - } -} - -#endif - -#if !DISABLE_SWIZZLING && !os(Linux) - - private func observeWeaklyKeyPathFor(_ target: NSObject, keyPath: String, options: KeyValueObservingOptions) -> Observable { - let components = keyPath.components(separatedBy: ".").filter { $0 != "self" } - - let observable = observeWeaklyKeyPathFor(target, keyPathSections: components, options: options) - .finishWithNilWhenDealloc(target) - - if !options.isDisjoint(with: .initial) { - return observable - } - else { - return observable - .skip(1) - } - } - - // This should work correctly - // Identifiers can't contain `,`, so the only place where `,` can appear - // is as a delimiter. - // This means there is `W` as element in an array of property attributes. - private func isWeakProperty(_ properyRuntimeInfo: String) -> Bool { - properyRuntimeInfo.range(of: ",W,") != nil - } - - private extension ObservableType where Element == AnyObject? { - func finishWithNilWhenDealloc(_ target: NSObject) - -> Observable { - let deallocating = target.rx.deallocating - - return deallocating - .map { _ in - return Observable.just(nil) - } - .startWith(self.asObservable()) - .switchLatest() - } - } - - private func observeWeaklyKeyPathFor( - _ target: NSObject, - keyPathSections: [String], - options: KeyValueObservingOptions - ) -> Observable { - - weak var weakTarget: AnyObject? = target - - let propertyName = keyPathSections[0] - let remainingPaths = Array(keyPathSections[1.. - - // KVO recursion for value changes - return propertyObservable - .flatMapLatest { (nextTarget: AnyObject?) -> Observable in - if nextTarget == nil { - return Observable.just(nil) - } - let nextObject = nextTarget! as? NSObject - - let strongTarget: AnyObject? = weakTarget - - if nextObject == nil { - return Observable.error(RxCocoaError.invalidObjectOnKeyPath(object: nextTarget!, sourceObject: strongTarget ?? NSNull(), propertyName: propertyName)) - } - - // if target is alive, then send change - // if it's deallocated, don't send anything - if strongTarget == nil { - return Observable.empty() - } - - let nextElementsObservable = keyPathSections.count == 1 - ? Observable.just(nextTarget) - : observeWeaklyKeyPathFor(nextObject!, keyPathSections: remainingPaths, options: options) - - if isWeak { - return nextElementsObservable - .finishWithNilWhenDealloc(nextObject!) - } - else { - return nextElementsObservable - } - } - } -#endif - -// MARK: Constants - -private let deallocSelector = NSSelectorFromString("dealloc") - -// MARK: AnyObject + Reactive - -extension Reactive where Base: AnyObject { - func synchronized( _ action: () -> T) -> T { - objc_sync_enter(self.base) - let result = action() - objc_sync_exit(self.base) - return result - } -} - -extension Reactive where Base: AnyObject { - /** - Helper to make sure that `Observable` returned from `createCachedObservable` is only created once. - This is important because there is only one `target` and `action` properties on `NSControl` or `UIBarButtonItem`. - */ - func lazyInstanceObservable(_ key: UnsafeRawPointer, createCachedObservable: () -> T) -> T { - if let value = objc_getAssociatedObject(self.base, key) { - return value as! T - } - - let observable = createCachedObservable() - - objc_setAssociatedObject(self.base, key, observable, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - - return observable - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/Foundation/NotificationCenter+Rx.swift b/Pods/RxCocoa/RxCocoa/Foundation/NotificationCenter+Rx.swift deleted file mode 100644 index 30ffa2bfd..000000000 --- a/Pods/RxCocoa/RxCocoa/Foundation/NotificationCenter+Rx.swift +++ /dev/null @@ -1,31 +0,0 @@ -// -// NotificationCenter+Rx.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 5/2/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import Foundation -import RxSwift - -extension Reactive where Base: NotificationCenter { - /** - Transforms notifications posted to notification center to observable sequence of notifications. - - - parameter name: Optional name used to filter notifications. - - parameter object: Optional object used to filter notifications. - - returns: Observable sequence of posted notifications. - */ - public func notification(_ name: Notification.Name?, object: AnyObject? = nil) -> Observable { - return Observable.create { [weak object] observer in - let nsObserver = self.base.addObserver(forName: name, object: object, queue: nil) { notification in - observer.on(.next(notification)) - } - - return Disposables.create { - self.base.removeObserver(nsObserver) - } - } - } -} diff --git a/Pods/RxCocoa/RxCocoa/Foundation/URLSession+Rx.swift b/Pods/RxCocoa/RxCocoa/Foundation/URLSession+Rx.swift deleted file mode 100644 index 93e65ccf8..000000000 --- a/Pods/RxCocoa/RxCocoa/Foundation/URLSession+Rx.swift +++ /dev/null @@ -1,240 +0,0 @@ -// -// URLSession+Rx.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 3/23/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import Foundation -import RxSwift - -#if canImport(FoundationNetworking) -import FoundationNetworking -#endif - -/// RxCocoa URL errors. -public enum RxCocoaURLError - : Swift.Error { - /// Unknown error occurred. - case unknown - /// Response is not NSHTTPURLResponse - case nonHTTPResponse(response: URLResponse) - /// Response is not successful. (not in `200 ..< 300` range) - case httpRequestFailed(response: HTTPURLResponse, data: Data?) - /// Deserialization error. - case deserializationError(error: Swift.Error) -} - -extension RxCocoaURLError - : CustomDebugStringConvertible { - /// A textual representation of `self`, suitable for debugging. - public var debugDescription: String { - switch self { - case .unknown: - return "Unknown error has occurred." - case let .nonHTTPResponse(response): - return "Response is not NSHTTPURLResponse `\(response)`." - case let .httpRequestFailed(response, _): - return "HTTP request failed with `\(response.statusCode)`." - case let .deserializationError(error): - return "Error during deserialization of the response: \(error)" - } - } -} - -private func escapeTerminalString(_ value: String) -> String { - return value.replacingOccurrences(of: "\"", with: "\\\"", options:[], range: nil) -} - -private func convertURLRequestToCurlCommand(_ request: URLRequest) -> String { - let method = request.httpMethod ?? "GET" - var returnValue = "curl -X \(method) " - - if let httpBody = request.httpBody { - let maybeBody = String(data: httpBody, encoding: String.Encoding.utf8) - if let body = maybeBody { - returnValue += "-d \"\(escapeTerminalString(body))\" " - } - } - - for (key, value) in request.allHTTPHeaderFields ?? [:] { - let escapedKey = escapeTerminalString(key as String) - let escapedValue = escapeTerminalString(value as String) - returnValue += "\n -H \"\(escapedKey): \(escapedValue)\" " - } - - let URLString = request.url?.absoluteString ?? "" - - returnValue += "\n\"\(escapeTerminalString(URLString))\"" - - returnValue += " -i -v" - - return returnValue -} - -private func convertResponseToString(_ response: URLResponse?, _ error: NSError?, _ interval: TimeInterval) -> String { - let ms = Int(interval * 1000) - - if let response = response as? HTTPURLResponse { - if 200 ..< 300 ~= response.statusCode { - return "Success (\(ms)ms): Status \(response.statusCode)" - } - else { - return "Failure (\(ms)ms): Status \(response.statusCode)" - } - } - - if let error = error { - if error.domain == NSURLErrorDomain && error.code == NSURLErrorCancelled { - return "Canceled (\(ms)ms)" - } - return "Failure (\(ms)ms): NSError > \(error)" - } - - return "" -} - -extension Reactive where Base: URLSession { - /** - Observable sequence of responses for URL request. - - Performing of request starts after observer is subscribed and not after invoking this method. - - **URL requests will be performed per subscribed observer.** - - Any error during fetching of the response will cause observed sequence to terminate with error. - - - parameter request: URL request. - - returns: Observable sequence of URL responses. - */ - public func response(request: URLRequest) -> Observable<(response: HTTPURLResponse, data: Data)> { - return Observable.create { observer in - - // smart compiler should be able to optimize this out - let d: Date? - - if URLSession.rx.shouldLogRequest(request) { - d = Date() - } - else { - d = nil - } - - let task = self.base.dataTask(with: request) { data, response, error in - - if URLSession.rx.shouldLogRequest(request) { - let interval = Date().timeIntervalSince(d ?? Date()) - print(convertURLRequestToCurlCommand(request)) - #if os(Linux) - print(convertResponseToString(response, error.flatMap { $0 as NSError }, interval)) - #else - print(convertResponseToString(response, error.map { $0 as NSError }, interval)) - #endif - } - - guard let response = response, let data = data else { - observer.on(.error(error ?? RxCocoaURLError.unknown)) - return - } - - guard let httpResponse = response as? HTTPURLResponse else { - observer.on(.error(RxCocoaURLError.nonHTTPResponse(response: response))) - return - } - - observer.on(.next((httpResponse, data))) - observer.on(.completed) - } - - task.resume() - - return Disposables.create(with: task.cancel) - } - } - - /** - Observable sequence of response data for URL request. - - Performing of request starts after observer is subscribed and not after invoking this method. - - **URL requests will be performed per subscribed observer.** - - Any error during fetching of the response will cause observed sequence to terminate with error. - - If response is not HTTP response with status code in the range of `200 ..< 300`, sequence - will terminate with `(RxCocoaErrorDomain, RxCocoaError.NetworkError)`. - - - parameter request: URL request. - - returns: Observable sequence of response data. - */ - public func data(request: URLRequest) -> Observable { - return self.response(request: request).map { pair -> Data in - if 200 ..< 300 ~= pair.0.statusCode { - return pair.1 - } - else { - throw RxCocoaURLError.httpRequestFailed(response: pair.0, data: pair.1) - } - } - } - - /** - Observable sequence of response JSON for URL request. - - Performing of request starts after observer is subscribed and not after invoking this method. - - **URL requests will be performed per subscribed observer.** - - Any error during fetching of the response will cause observed sequence to terminate with error. - - If response is not HTTP response with status code in the range of `200 ..< 300`, sequence - will terminate with `(RxCocoaErrorDomain, RxCocoaError.NetworkError)`. - - If there is an error during JSON deserialization observable sequence will fail with that error. - - - parameter request: URL request. - - returns: Observable sequence of response JSON. - */ - public func json(request: URLRequest, options: JSONSerialization.ReadingOptions = []) -> Observable { - return self.data(request: request).map { data -> Any in - do { - return try JSONSerialization.jsonObject(with: data, options: options) - } catch let error { - throw RxCocoaURLError.deserializationError(error: error) - } - } - } - - /** - Observable sequence of response JSON for GET request with `URL`. - - Performing of request starts after observer is subscribed and not after invoking this method. - - **URL requests will be performed per subscribed observer.** - - Any error during fetching of the response will cause observed sequence to terminate with error. - - If response is not HTTP response with status code in the range of `200 ..< 300`, sequence - will terminate with `(RxCocoaErrorDomain, RxCocoaError.NetworkError)`. - - If there is an error during JSON deserialization observable sequence will fail with that error. - - - parameter url: URL of `NSURLRequest` request. - - returns: Observable sequence of response JSON. - */ - public func json(url: Foundation.URL) -> Observable { - self.json(request: URLRequest(url: url)) - } -} - -extension Reactive where Base == URLSession { - /// Log URL requests to standard output in curl format. - public static var shouldLogRequest: (URLRequest) -> Bool = { _ in - #if DEBUG - return true - #else - return false - #endif - } -} diff --git a/Pods/RxCocoa/RxCocoa/Runtime/_RX.m b/Pods/RxCocoa/RxCocoa/Runtime/_RX.m deleted file mode 100644 index cffbfbcce..000000000 --- a/Pods/RxCocoa/RxCocoa/Runtime/_RX.m +++ /dev/null @@ -1,10 +0,0 @@ -// -// _RX.m -// RxCocoa -// -// Created by Krunoslav Zaher on 7/12/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#import "include/_RX.h" - diff --git a/Pods/RxCocoa/RxCocoa/Runtime/_RXDelegateProxy.m b/Pods/RxCocoa/RxCocoa/Runtime/_RXDelegateProxy.m deleted file mode 100644 index 36338a575..000000000 --- a/Pods/RxCocoa/RxCocoa/Runtime/_RXDelegateProxy.m +++ /dev/null @@ -1,147 +0,0 @@ -// -// _RXDelegateProxy.m -// RxCocoa -// -// Created by Krunoslav Zaher on 7/4/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#import "include/_RXDelegateProxy.h" -#import "include/_RX.h" -#import "include/_RXObjCRuntime.h" - -@interface _RXDelegateProxy () { - id __weak __forwardToDelegate; -} - -@property (nonatomic, strong) id strongForwardDelegate; - -@end - -static NSMutableDictionary *voidSelectorsPerClass = nil; - -@implementation _RXDelegateProxy - -+(NSSet*)collectVoidSelectorsForProtocol:(Protocol *)protocol { - NSMutableSet *selectors = [NSMutableSet set]; - - unsigned int protocolMethodCount = 0; - struct objc_method_description *pMethods = protocol_copyMethodDescriptionList(protocol, NO, YES, &protocolMethodCount); - - for (unsigned int i = 0; i < protocolMethodCount; ++i) { - struct objc_method_description method = pMethods[i]; - if (RX_is_method_with_description_void(method)) { - [selectors addObject:SEL_VALUE(method.name)]; - } - } - - free(pMethods); - - unsigned int numberOfBaseProtocols = 0; - Protocol * __unsafe_unretained * pSubprotocols = protocol_copyProtocolList(protocol, &numberOfBaseProtocols); - - for (unsigned int i = 0; i < numberOfBaseProtocols; ++i) { - [selectors unionSet:[self collectVoidSelectorsForProtocol:pSubprotocols[i]]]; - } - - free(pSubprotocols); - - return selectors; -} - -+(void)initialize { - @synchronized (_RXDelegateProxy.class) { - if (voidSelectorsPerClass == nil) { - voidSelectorsPerClass = [[NSMutableDictionary alloc] init]; - } - - NSMutableSet *voidSelectors = [NSMutableSet set]; - -#define CLASS_HIERARCHY_MAX_DEPTH 100 - - NSInteger classHierarchyDepth = 0; - Class targetClass = NULL; - - for (classHierarchyDepth = 0, targetClass = self; - classHierarchyDepth < CLASS_HIERARCHY_MAX_DEPTH && targetClass != nil; - ++classHierarchyDepth, targetClass = class_getSuperclass(targetClass) - ) { - unsigned int count; - Protocol *__unsafe_unretained *pProtocols = class_copyProtocolList(targetClass, &count); - - for (unsigned int i = 0; i < count; i++) { - NSSet *selectorsForProtocol = [self collectVoidSelectorsForProtocol:pProtocols[i]]; - [voidSelectors unionSet:selectorsForProtocol]; - } - - free(pProtocols); - } - - if (classHierarchyDepth == CLASS_HIERARCHY_MAX_DEPTH) { - NSLog(@"Detected weird class hierarchy with depth over %d. Starting with this class -> %@", CLASS_HIERARCHY_MAX_DEPTH, self); -#if DEBUG - abort(); -#endif - } - - voidSelectorsPerClass[CLASS_VALUE(self)] = voidSelectors; - } -} - --(id)_forwardToDelegate { - return __forwardToDelegate; -} - --(void)_setForwardToDelegate:(id __nullable)forwardToDelegate retainDelegate:(BOOL)retainDelegate { - __forwardToDelegate = forwardToDelegate; - if (retainDelegate) { - self.strongForwardDelegate = forwardToDelegate; - } - else { - self.strongForwardDelegate = nil; - } -} - --(BOOL)hasWiredImplementationForSelector:(SEL)selector { - return [super respondsToSelector:selector]; -} - --(BOOL)voidDelegateMethodsContain:(SEL)selector { - @synchronized(_RXDelegateProxy.class) { - NSSet *voidSelectors = voidSelectorsPerClass[CLASS_VALUE(self.class)]; - NSAssert(voidSelectors != nil, @"Set of allowed methods not initialized"); - return [voidSelectors containsObject:SEL_VALUE(selector)]; - } -} - --(void)forwardInvocation:(NSInvocation *)anInvocation { - BOOL isVoid = RX_is_method_signature_void(anInvocation.methodSignature); - NSArray *arguments = nil; - if (isVoid) { - arguments = RX_extract_arguments(anInvocation); - [self _sentMessage:anInvocation.selector withArguments:arguments]; - } - - if (self._forwardToDelegate && [self._forwardToDelegate respondsToSelector:anInvocation.selector]) { - [anInvocation invokeWithTarget:self._forwardToDelegate]; - } - - if (isVoid) { - [self _methodInvoked:anInvocation.selector withArguments:arguments]; - } -} - -// abstract method --(void)_sentMessage:(SEL)selector withArguments:(NSArray *)arguments { - -} - -// abstract method --(void)_methodInvoked:(SEL)selector withArguments:(NSArray *)arguments { - -} - --(void)dealloc { -} - -@end diff --git a/Pods/RxCocoa/RxCocoa/Runtime/_RXKVOObserver.m b/Pods/RxCocoa/RxCocoa/Runtime/_RXKVOObserver.m deleted file mode 100644 index fc8fb75c1..000000000 --- a/Pods/RxCocoa/RxCocoa/Runtime/_RXKVOObserver.m +++ /dev/null @@ -1,54 +0,0 @@ -// -// _RXKVOObserver.m -// RxCocoa -// -// Created by Krunoslav Zaher on 7/11/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#import "include/_RXKVOObserver.h" - -@interface _RXKVOObserver () - -@property (nonatomic, unsafe_unretained) id target; -@property (nonatomic, strong ) id retainedTarget; -@property (nonatomic, copy ) NSString *keyPath; -@property (nonatomic, copy ) void (^callback)(id); - -@end - -@implementation _RXKVOObserver - --(instancetype)initWithTarget:(id)target - retainTarget:(BOOL)retainTarget - keyPath:(NSString*)keyPath - options:(NSKeyValueObservingOptions)options - callback:(void (^)(id))callback { - self = [super init]; - if (!self) return nil; - - self.target = target; - if (retainTarget) { - self.retainedTarget = target; - } - self.keyPath = keyPath; - self.callback = callback; - - [self.target addObserver:self forKeyPath:self.keyPath options:options context:nil]; - - return self; -} - --(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - @synchronized(self) { - self.callback(change[NSKeyValueChangeNewKey]); - } -} - --(void)dispose { - [self.target removeObserver:self forKeyPath:self.keyPath context:nil]; - self.target = nil; - self.retainedTarget = nil; -} - -@end diff --git a/Pods/RxCocoa/RxCocoa/Runtime/_RXObjCRuntime.m b/Pods/RxCocoa/RxCocoa/Runtime/_RXObjCRuntime.m deleted file mode 100644 index 2e685aaa7..000000000 --- a/Pods/RxCocoa/RxCocoa/Runtime/_RXObjCRuntime.m +++ /dev/null @@ -1,1062 +0,0 @@ -// -// _RXObjCRuntime.m -// RxCocoa -// -// Created by Krunoslav Zaher on 7/11/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#import -#import -#import -#import -#import -#import - -#import "include/_RX.h" -#import "include/_RXObjCRuntime.h" - -// self + cmd -#define HIDDEN_ARGUMENT_COUNT 2 - -#if !DISABLE_SWIZZLING - -#define NSErrorParam NSError *__autoreleasing __nullable * __nullable - -@class RXObjCRuntime; - -BOOL RXAbortOnThreadingHazard = NO; - -typedef NSInvocation *NSInvocationRef; -typedef NSMethodSignature *NSMethodSignatureRef; -typedef unsigned char rx_uchar; -typedef unsigned short rx_ushort; -typedef unsigned int rx_uint; -typedef unsigned long rx_ulong; -typedef id (^rx_block)(id); -typedef BOOL (^RXInterceptWithOptimizedObserver)(RXObjCRuntime * __nonnull self, Class __nonnull class, SEL __nonnull selector, NSErrorParam error); - -static CFTypeID defaultTypeID; -static SEL deallocSelector; - -static int RxSwizzlingTargetClassKey = 0; - -#if TRACE_RESOURCES -_Atomic static int32_t numberOInterceptedMethods = 0; -_Atomic static int32_t numberOfForwardedMethods = 0; -#endif - -#define THREADING_HAZARD(class) \ - NSLog(@"There was a problem swizzling on `%@`.\nYou have probably two libraries performing swizzling in runtime.\nWe didn't want to crash your program, but this is not good ...\nYou an solve this problem by either not using swizzling in this library, removing one of those other libraries, or making sure that swizzling parts are synchronized (only perform them on main thread).\nAnd yes, this message will self destruct when you clear the console, and since it's non deterministic, the problem could still exist and it will be hard for you to reproduce it.", NSStringFromClass(class)); ABORT_IN_DEBUG if (RXAbortOnThreadingHazard) { abort(); } - -#define ALWAYS(condition, message) if (!(condition)) { [NSException raise:@"RX Invalid Operator" format:@"%@", message]; } -#define ALWAYS_WITH_INFO(condition, message) NSAssert((condition), @"%@ [%@] > %@", NSStringFromClass(class), NSStringFromSelector(selector), (message)) -#define C_ALWAYS(condition, message) NSCAssert((condition), @"%@ [%@] > %@", NSStringFromClass(class), NSStringFromSelector(selector), (message)) - -#define RX_PREFIX @"_RX_namespace_" - -#define RX_ARG_id(value) ((value) ?: [NSNull null]) -#define RX_ARG_char(value) [NSNumber numberWithChar:value] -#define RX_ARG_short(value) [NSNumber numberWithShort:value] -#define RX_ARG_int(value) [NSNumber numberWithInt:value] -#define RX_ARG_long(value) [NSNumber numberWithLong:value] -#define RX_ARG_BOOL(value) [NSNumber numberWithBool:value] -#define RX_ARG_SEL(value) [NSNumber valueWithPointer:value] -#define RX_ARG_rx_uchar(value) [NSNumber numberWithUnsignedInt:value] -#define RX_ARG_rx_ushort(value) [NSNumber numberWithUnsignedInt:value] -#define RX_ARG_rx_uint(value) [NSNumber numberWithUnsignedInt:value] -#define RX_ARG_rx_ulong(value) [NSNumber numberWithUnsignedLong:value] -#define RX_ARG_rx_block(value) ((id)(value) ?: [NSNull null]) -#define RX_ARG_float(value) [NSNumber numberWithFloat:value] -#define RX_ARG_double(value) [NSNumber numberWithDouble:value] - -typedef struct supported_type { - const char *encoding; -} supported_type_t; - -static supported_type_t supported_types[] = { - { .encoding = @encode(void)}, - { .encoding = @encode(id)}, - { .encoding = @encode(Class)}, - { .encoding = @encode(void (^)(void))}, - { .encoding = @encode(char)}, - { .encoding = @encode(short)}, - { .encoding = @encode(int)}, - { .encoding = @encode(long)}, - { .encoding = @encode(long long)}, - { .encoding = @encode(unsigned char)}, - { .encoding = @encode(unsigned short)}, - { .encoding = @encode(unsigned int)}, - { .encoding = @encode(unsigned long)}, - { .encoding = @encode(unsigned long long)}, - { .encoding = @encode(float)}, - { .encoding = @encode(double)}, - { .encoding = @encode(BOOL)}, - { .encoding = @encode(const char*)}, -}; - -NSString * __nonnull const RXObjCRuntimeErrorDomain = @"RXObjCRuntimeErrorDomain"; -NSString * __nonnull const RXObjCRuntimeErrorIsKVOKey = @"RXObjCRuntimeErrorIsKVOKey"; - -BOOL RX_return_type_is_supported(const char *type) { - if (type == nil) { - return NO; - } - - for (int i = 0; i < sizeof(supported_types) / sizeof(supported_type_t); ++i) { - if (supported_types[i].encoding[0] != type[0]) { - continue; - } - if (strcmp(supported_types[i].encoding, type) == 0) { - return YES; - } - } - - return NO; -} - -static BOOL RX_method_has_supported_return_type(Method method) { - const char *rawEncoding = method_getTypeEncoding(method); - ALWAYS(rawEncoding != nil, @"Example encoding method is nil."); - - NSMethodSignature *methodSignature = [NSMethodSignature signatureWithObjCTypes:rawEncoding]; - ALWAYS(methodSignature != nil, @"Method signature method is nil."); - - return RX_return_type_is_supported(methodSignature.methodReturnType); -} - -SEL __nonnull RX_selector(SEL __nonnull selector) { - NSString *selectorString = NSStringFromSelector(selector); - return NSSelectorFromString([RX_PREFIX stringByAppendingString:selectorString]); -} - -#endif - -BOOL RX_is_method_signature_void(NSMethodSignature * __nonnull methodSignature) { - const char *methodReturnType = methodSignature.methodReturnType; - return strcmp(methodReturnType, @encode(void)) == 0; -} - -BOOL RX_is_method_with_description_void(struct objc_method_description method) { - return strncmp(method.types, @encode(void), 1) == 0; -} - -id __nonnull RX_extract_argument_at_index(NSInvocation * __nonnull invocation, NSUInteger index) { - const char *argumentType = [invocation.methodSignature getArgumentTypeAtIndex:index]; - -#define RETURN_VALUE(type) \ - else if (strcmp(argumentType, @encode(type)) == 0) {\ - type val = 0; \ - [invocation getArgument:&val atIndex:index]; \ - return @(val); \ - } - - // Skip const type qualifier. - if (argumentType[0] == 'r') { - argumentType++; - } - - if (strcmp(argumentType, @encode(id)) == 0 - || strcmp(argumentType, @encode(Class)) == 0 - || strcmp(argumentType, @encode(void (^)(void))) == 0 - ) { - __unsafe_unretained id argument = nil; - [invocation getArgument:&argument atIndex:index]; - return argument; - } - RETURN_VALUE(char) - RETURN_VALUE(short) - RETURN_VALUE(int) - RETURN_VALUE(long) - RETURN_VALUE(long long) - RETURN_VALUE(unsigned char) - RETURN_VALUE(unsigned short) - RETURN_VALUE(unsigned int) - RETURN_VALUE(unsigned long) - RETURN_VALUE(unsigned long long) - RETURN_VALUE(float) - RETURN_VALUE(double) - RETURN_VALUE(BOOL) - RETURN_VALUE(const char *) - else { - NSUInteger size = 0; - NSGetSizeAndAlignment(argumentType, &size, NULL); - NSCParameterAssert(size > 0); - uint8_t data[size]; - [invocation getArgument:&data atIndex:index]; - - return [NSValue valueWithBytes:&data objCType:argumentType]; - } -} - -NSArray *RX_extract_arguments(NSInvocation *invocation) { - NSUInteger numberOfArguments = invocation.methodSignature.numberOfArguments; - NSUInteger numberOfVisibleArguments = numberOfArguments - HIDDEN_ARGUMENT_COUNT; - - NSCParameterAssert(numberOfVisibleArguments >= 0); - - NSMutableArray *arguments = [NSMutableArray arrayWithCapacity:numberOfVisibleArguments]; - - for (NSUInteger index = HIDDEN_ARGUMENT_COUNT; index < numberOfArguments; ++index) { - [arguments addObject:RX_extract_argument_at_index(invocation, index) ?: [NSNull null]]; - } - - return arguments; -} - -IMP __nonnull RX_default_target_implementation(void) { - return _objc_msgForward; -} - -#if !DISABLE_SWIZZLING - -void * __nonnull RX_reference_from_selector(SEL __nonnull selector) { - return selector; -} - -static BOOL RX_forward_invocation(id __nonnull __unsafe_unretained self, NSInvocation *invocation) { - SEL originalSelector = RX_selector(invocation.selector); - - id messageSentObserver = objc_getAssociatedObject(self, originalSelector); - - if (messageSentObserver != nil) { - NSArray *arguments = RX_extract_arguments(invocation); - [messageSentObserver messageSentWithArguments:arguments]; - } - - if ([self respondsToSelector:originalSelector]) { - invocation.selector = originalSelector; - [invocation invokeWithTarget:self]; - - if (messageSentObserver != nil) { - NSArray *arguments = RX_extract_arguments(invocation); - [messageSentObserver methodInvokedWithArguments:arguments]; - } - - return YES; - } - - return NO; -} - -static BOOL RX_responds_to_selector(id __nonnull __unsafe_unretained self, SEL selector) { - Class class = object_getClass(self); - if (class == nil) { return NO; } - - Method m = class_getInstanceMethod(class, selector); - return m != nil; - -} - -static NSMethodSignatureRef RX_method_signature(id __nonnull __unsafe_unretained self, SEL selector) { - Class class = object_getClass(self); - if (class == nil) { return nil; } - - Method method = class_getInstanceMethod(class, selector); - if (method == nil) { return nil; } - - const char *encoding = method_getTypeEncoding(method); - if (encoding == nil) { return nil; } - - return [NSMethodSignature signatureWithObjCTypes:encoding]; -} - -static NSString * __nonnull RX_method_encoding(Method __nonnull method) { - const char *typeEncoding = method_getTypeEncoding(method); - ALWAYS(typeEncoding != nil, @"Method encoding is nil."); - - NSString *encoding = [NSString stringWithCString:typeEncoding encoding:NSASCIIStringEncoding]; - ALWAYS(encoding != nil, @"Can't convert encoding to NSString."); - return encoding; -} - -@interface RXObjCRuntime: NSObject - -@property (nonatomic, assign) pthread_mutex_t lock; - -@property (nonatomic, strong) NSMutableSet *classesThatSupportObservingByForwarding; -@property (nonatomic, strong) NSMutableDictionary *> *forwardedSelectorsByClass; - -@property (nonatomic, strong) NSMutableDictionary *dynamicSubclassByRealClass; -@property (nonatomic, strong) NSMutableDictionary*> *interceptorIMPbySelectorsByClass; - -+(RXObjCRuntime*)instance; - --(void)performLocked:(void (^)(RXObjCRuntime* __nonnull))action; --(IMP __nullable)ensurePrepared:(id __nonnull)target forObserving:(SEL __nonnull)selector error:(NSErrorParam)error; --(BOOL)ensureSwizzledSelector:(SEL __nonnull)selector - ofClass:(Class __nonnull)class - newImplementationGenerator:(IMP(^)(void))newImplementationGenerator -replacementImplementationGenerator:(IMP (^)(IMP originalImplementation))replacementImplementationGenerator - error:(NSErrorParam)error; - - -+(void)registerOptimizedObserver:(RXInterceptWithOptimizedObserver)registration encodedAs:(SEL)selector; - -@end - -/** - All API methods perform work on locked instance of `RXObjCRuntime`. In that way it's easy to prove - that every action is properly locked. - */ -IMP __nullable RX_ensure_observing(id __nonnull target, SEL __nonnull selector, NSErrorParam error) { - __block IMP targetImplementation = nil; - // Target is the second object that needs to be synchronized to TRY to make sure other swizzling framework - // won't do something in parallel. - // Even though this is too fine grained locking and more coarse grained locks should exist, this is just in case - // someone calls this method directly without any external lock. - @synchronized(target) { - // The only other resource that all other swizzling libraries have in common without introducing external - // dependencies is class object. - // - // It is polite to try to synchronize it in hope other unknown entities will also attempt to do so. - // It's like trying to figure out how to communicate with aliens without actually communicating, - // save for the fact that aliens are people, programmers, authors of swizzling libraries. - @synchronized([target class]) { - [[RXObjCRuntime instance] performLocked:^(RXObjCRuntime * __nonnull self) { - targetImplementation = [self ensurePrepared:target - forObserving:selector - error:error]; - }]; - } - } - - return targetImplementation; -} - -// bodies - -#define FORWARD_BODY(invocation) if (RX_forward_invocation(self, NAME_CAT(_, 0, invocation))) { return; } - -#define RESPONDS_TO_SELECTOR_BODY(selector) if (RX_responds_to_selector(self, NAME_CAT(_, 0, selector))) return YES; - -#define CLASS_BODY(...) return actAsClass; - -#define METHOD_SIGNATURE_FOR_SELECTOR_BODY(selector) \ - NSMethodSignatureRef methodSignature = RX_method_signature(self, NAME_CAT(_, 0, selector)); \ - if (methodSignature != nil) { \ - return methodSignature; \ - } - -#define DEALLOCATING_BODY(...) \ - id observer = objc_getAssociatedObject(self, rxSelector); \ - if (observer != nil && observer.targetImplementation == thisIMP) { \ - [observer deallocating]; \ - } - -#define OBSERVE_BODY(...) \ - id observer = objc_getAssociatedObject(self, rxSelector); \ - \ - if (observer != nil && observer.targetImplementation == thisIMP) { \ - [observer messageSentWithArguments:@[COMMA_DELIMITED_ARGUMENTS(__VA_ARGS__)]]; \ - } \ - - -#define OBSERVE_INVOKED_BODY(...) \ - if (observer != nil && observer.targetImplementation == thisIMP) { \ - [observer methodInvokedWithArguments:@[COMMA_DELIMITED_ARGUMENTS(__VA_ARGS__)]]; \ - } \ - - -#define BUILD_ARG_WRAPPER(type) RX_ARG_ ## type //RX_ARG_ ## type - -#define CAT(_1, _2, head, tail) RX_CAT2(head, tail) -#define SEPARATE_BY_COMMA(_1, _2, head, tail) head, tail -#define SEPARATE_BY_SPACE(_1, _2, head, tail) head tail -#define SEPARATE_BY_UNDERSCORE(head, tail) RX_CAT2(RX_CAT2(head, _), tail) - -#define UNDERSCORE_TYPE_CAT(_1, index, type) RX_CAT2(_, type) // generates -> _type -#define NAME_CAT(_1, index, type) SEPARATE_BY_UNDERSCORE(type, index) // generates -> type_0 -#define TYPE_AND_NAME_CAT(_1, index, type) type SEPARATE_BY_UNDERSCORE(type, index) // generates -> type type_0 -#define NOT_NULL_ARGUMENT_CAT(_1, index, type) BUILD_ARG_WRAPPER(type)(NAME_CAT(_1, index, type)) // generates -> ((id)(type_0) ?: [NSNull null]) -#define EXAMPLE_PARAMETER(_1, index, type) RX_CAT2(_, type):(type)SEPARATE_BY_UNDERSCORE(type, index) // generates -> _type:(type)type_0 -#define SELECTOR_PART(_1, index, type) RX_CAT2(_, type:) // generates -> _type: - -#define COMMA_DELIMITED_ARGUMENTS(...) RX_FOREACH(_, SEPARATE_BY_COMMA, NOT_NULL_ARGUMENT_CAT, ## __VA_ARGS__) -#define ARGUMENTS(...) RX_FOREACH_COMMA(_, NAME_CAT, ## __VA_ARGS__) -#define DECLARE_ARGUMENTS(...) RX_FOREACH_COMMA(_, TYPE_AND_NAME_CAT, ## __VA_ARGS__) - -// optimized observe methods - -#define GENERATE_SELECTOR_IDENTIFIER(...) RX_CAT2(exampleSelector, RX_FOREACH(_, CAT, UNDERSCORE_TYPE_CAT, ## __VA_ARGS__)) - -#define GENERATE_METHOD_IDENTIFIER(...) RX_CAT2(swizzle, RX_FOREACH(_, CAT, UNDERSCORE_TYPE_CAT, ## __VA_ARGS__)) - -#define GENERATE_OBSERVE_METHOD_DECLARATION(...) \ - -(BOOL)GENERATE_METHOD_IDENTIFIER(__VA_ARGS__):(Class __nonnull)class \ - selector:(SEL)selector \ - error:(NSErrorParam)error { \ - - -#define BUILD_EXAMPLE_METHOD(return_value, ...) \ - +(return_value)RX_CAT2(RX_CAT2(example_, return_value), RX_FOREACH(_, SEPARATE_BY_SPACE, EXAMPLE_PARAMETER, ## __VA_ARGS__)) {} - -#define BUILD_EXAMPLE_METHOD_SELECTOR(return_value, ...) \ - RX_CAT2(RX_CAT2(example_, return_value), RX_FOREACH(_, SEPARATE_BY_SPACE, SELECTOR_PART, ## __VA_ARGS__)) - -#define SWIZZLE_OBSERVE_METHOD_DEFINITIONS(return_value, ...) \ - BUILD_EXAMPLE_METHOD(return_value, ## __VA_ARGS__) \ - SWIZZLE_METHOD(return_value, GENERATE_OBSERVE_METHOD_DECLARATION(return_value, ## __VA_ARGS__), OBSERVE_BODY, OBSERVE_INVOKED_BODY, ## __VA_ARGS__) \ - -#define SWIZZLE_OBSERVE_METHOD_BODY(return_value, ...) \ - __unused SEL GENERATE_SELECTOR_IDENTIFIER(return_value, ## __VA_ARGS__) = @selector(BUILD_EXAMPLE_METHOD_SELECTOR(return_value, ## __VA_ARGS__)); \ - [self registerOptimizedObserver:^BOOL(RXObjCRuntime * __nonnull self, Class __nonnull class, \ - SEL __nonnull selector, NSErrorParam error) { \ - return [self GENERATE_METHOD_IDENTIFIER(return_value, ## __VA_ARGS__):class selector:selector error:error]; \ - } encodedAs:GENERATE_SELECTOR_IDENTIFIER(return_value, ## __VA_ARGS__)]; \ - -// infrastructure method - -#define NO_BODY(...) - -#define SWIZZLE_INFRASTRUCTURE_METHOD(return_value, method_name, parameters, method_selector, body, ...) \ - SWIZZLE_METHOD(return_value, -(BOOL)method_name:(Class __nonnull)class parameters error:(NSErrorParam)error \ - { \ - SEL selector = method_selector; , body, NO_BODY, __VA_ARGS__) \ - - -// common base - -#define SWIZZLE_METHOD(return_value, method_prototype, body, invoked_body, ...) \ -method_prototype \ - __unused SEL rxSelector = RX_selector(selector); \ - IMP (^newImplementationGenerator)(void) = ^() { \ - __block IMP thisIMP = nil; \ - id newImplementation = ^return_value(__unsafe_unretained id self DECLARE_ARGUMENTS(__VA_ARGS__)) { \ - body(__VA_ARGS__) \ - \ - struct objc_super superInfo = { \ - .receiver = self, \ - .super_class = class_getSuperclass(class) \ - }; \ - \ - return_value (*msgSend)(struct objc_super *, SEL DECLARE_ARGUMENTS(__VA_ARGS__)) \ - = (__typeof__(msgSend))objc_msgSendSuper; \ - @try { \ - return msgSend(&superInfo, selector ARGUMENTS(__VA_ARGS__)); \ - } \ - @finally { invoked_body(__VA_ARGS__) } \ - }; \ - \ - thisIMP = imp_implementationWithBlock(newImplementation); \ - return thisIMP; \ - }; \ - \ - IMP (^replacementImplementationGenerator)(IMP) = ^(IMP originalImplementation) { \ - __block return_value (*originalImplementationTyped)(__unsafe_unretained id, SEL DECLARE_ARGUMENTS(__VA_ARGS__) ) \ - = (__typeof__(originalImplementationTyped))(originalImplementation); \ - \ - __block IMP thisIMP = nil; \ - id implementationReplacement = ^return_value(__unsafe_unretained id self DECLARE_ARGUMENTS(__VA_ARGS__) ) { \ - body(__VA_ARGS__) \ - @try { \ - return originalImplementationTyped(self, selector ARGUMENTS(__VA_ARGS__)); \ - } \ - @finally { invoked_body(__VA_ARGS__) } \ - }; \ - \ - thisIMP = imp_implementationWithBlock(implementationReplacement); \ - return thisIMP; \ - }; \ - \ - return [self ensureSwizzledSelector:selector \ - ofClass:class \ - newImplementationGenerator:newImplementationGenerator \ - replacementImplementationGenerator:replacementImplementationGenerator \ - error:error]; \ - } \ - - -@interface RXObjCRuntime (InfrastructureMethods) -@end - -// MARK: Infrastructure Methods - -@implementation RXObjCRuntime (InfrastructureMethods) - -SWIZZLE_INFRASTRUCTURE_METHOD( - void, - swizzleForwardInvocation, - , - @selector(forwardInvocation:), - FORWARD_BODY, - NSInvocationRef -) -SWIZZLE_INFRASTRUCTURE_METHOD( - BOOL, - swizzleRespondsToSelector, - , - @selector(respondsToSelector:), - RESPONDS_TO_SELECTOR_BODY, - SEL -) -SWIZZLE_INFRASTRUCTURE_METHOD( - Class __nonnull, - swizzleClass, - toActAs:(Class)actAsClass, - @selector(class), - CLASS_BODY -) -SWIZZLE_INFRASTRUCTURE_METHOD( - NSMethodSignatureRef, - swizzleMethodSignatureForSelector, - , - @selector(methodSignatureForSelector:), - METHOD_SIGNATURE_FOR_SELECTOR_BODY, - SEL -) -SWIZZLE_INFRASTRUCTURE_METHOD( - void, - swizzleDeallocating, - , - deallocSelector, - DEALLOCATING_BODY -) - -@end - -// MARK: Optimized intercepting methods for specific combination of parameter types - -@interface RXObjCRuntime (swizzle) - -@end - -@implementation RXObjCRuntime(swizzle) - -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void) - -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, id) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, char) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, short) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, int) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, long) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, rx_uchar) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, rx_ushort) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, rx_uint) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, rx_ulong) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, rx_block) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, float) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, double) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, SEL) - -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, id, id) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, id, char) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, id, short) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, id, int) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, id, long) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, id, rx_uchar) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, id, rx_ushort) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, id, rx_uint) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, id, rx_ulong) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, id, rx_block) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, id, float) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, id, double) -SWIZZLE_OBSERVE_METHOD_DEFINITIONS(void, id, SEL) - -+(void)load { - SWIZZLE_OBSERVE_METHOD_BODY(void) - - SWIZZLE_OBSERVE_METHOD_BODY(void, id) - SWIZZLE_OBSERVE_METHOD_BODY(void, char) - SWIZZLE_OBSERVE_METHOD_BODY(void, short) - SWIZZLE_OBSERVE_METHOD_BODY(void, int) - SWIZZLE_OBSERVE_METHOD_BODY(void, long) - SWIZZLE_OBSERVE_METHOD_BODY(void, rx_uchar) - SWIZZLE_OBSERVE_METHOD_BODY(void, rx_ushort) - SWIZZLE_OBSERVE_METHOD_BODY(void, rx_uint) - SWIZZLE_OBSERVE_METHOD_BODY(void, rx_ulong) - SWIZZLE_OBSERVE_METHOD_BODY(void, rx_block) - SWIZZLE_OBSERVE_METHOD_BODY(void, float) - SWIZZLE_OBSERVE_METHOD_BODY(void, double) - SWIZZLE_OBSERVE_METHOD_BODY(void, SEL) - - SWIZZLE_OBSERVE_METHOD_BODY(void, id, id) - SWIZZLE_OBSERVE_METHOD_BODY(void, id, char) - SWIZZLE_OBSERVE_METHOD_BODY(void, id, short) - SWIZZLE_OBSERVE_METHOD_BODY(void, id, int) - SWIZZLE_OBSERVE_METHOD_BODY(void, id, long) - SWIZZLE_OBSERVE_METHOD_BODY(void, id, rx_uchar) - SWIZZLE_OBSERVE_METHOD_BODY(void, id, rx_ushort) - SWIZZLE_OBSERVE_METHOD_BODY(void, id, rx_uint) - SWIZZLE_OBSERVE_METHOD_BODY(void, id, rx_ulong) - SWIZZLE_OBSERVE_METHOD_BODY(void, id, rx_block) - SWIZZLE_OBSERVE_METHOD_BODY(void, id, float) - SWIZZLE_OBSERVE_METHOD_BODY(void, id, double) - SWIZZLE_OBSERVE_METHOD_BODY(void, id, SEL) -} - -@end - -// MARK: RXObjCRuntime - -@implementation RXObjCRuntime - -static RXObjCRuntime *_instance = nil; -static NSMutableDictionary *optimizedObserversByMethodEncoding = nil; - -+(RXObjCRuntime*)instance { - return _instance; -} - -+(void)initialize { - _instance = [[RXObjCRuntime alloc] init]; - defaultTypeID = CFGetTypeID((CFTypeRef)RXObjCRuntime.class); // just need a reference of some object not from CF - deallocSelector = NSSelectorFromString(@"dealloc"); - NSAssert(_instance != nil, @"Failed to initialize swizzling"); -} - --(instancetype)init { - self = [super init]; - if (!self) return nil; - - self.classesThatSupportObservingByForwarding = [NSMutableSet set]; - self.forwardedSelectorsByClass = [NSMutableDictionary dictionary]; - - self.dynamicSubclassByRealClass = [NSMutableDictionary dictionary]; - self.interceptorIMPbySelectorsByClass = [NSMutableDictionary dictionary]; - - pthread_mutexattr_t lock_attr; - pthread_mutexattr_init(&lock_attr); - pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&_lock, &lock_attr); - pthread_mutexattr_destroy(&lock_attr); - - return self; -} - --(void)performLocked:(void (^)(RXObjCRuntime* __nonnull))action { - pthread_mutex_lock(&_lock); - action(self); - pthread_mutex_unlock(&_lock); -} - -+(void)registerOptimizedObserver:(RXInterceptWithOptimizedObserver)registration encodedAs:(SEL)selector { - Method exampleEncodingMethod = class_getClassMethod(self, selector); - ALWAYS(exampleEncodingMethod != nil, @"Example encoding method is nil."); - - NSString *methodEncoding = RX_method_encoding(exampleEncodingMethod); - - if (optimizedObserversByMethodEncoding == nil) { - optimizedObserversByMethodEncoding = [NSMutableDictionary dictionary]; - } - - DLOG(@"Added optimized method: %@ (%@)", methodEncoding, NSStringFromSelector(selector)); - ALWAYS(optimizedObserversByMethodEncoding[methodEncoding] == nil, @"Optimized observer already registered") - optimizedObserversByMethodEncoding[methodEncoding] = registration; -} - -/** - This is the main entry point for observing messages sent to arbitrary objects. - */ --(IMP __nullable)ensurePrepared:(id __nonnull)target forObserving:(SEL __nonnull)selector error:(NSErrorParam)error { - Method instanceMethod = class_getInstanceMethod([target class], selector); - if (instanceMethod == nil) { - RX_THROW_ERROR([NSError errorWithDomain:RXObjCRuntimeErrorDomain - code:RXObjCRuntimeErrorSelectorNotImplemented - userInfo:nil], nil); - } - - if (selector == @selector(class) - || selector == @selector(forwardingTargetForSelector:) - || selector == @selector(methodSignatureForSelector:) - || selector == @selector(respondsToSelector:)) { - RX_THROW_ERROR([NSError errorWithDomain:RXObjCRuntimeErrorDomain - code:RXObjCRuntimeErrorObservingPerformanceSensitiveMessages - userInfo:nil], nil); - } - - // For `dealloc` message, original implementation will be swizzled. - // This is a special case because observing `dealloc` message is performed when `observeWeakly` is used. - // - // Some toll free bridged classes don't handle `object_setClass` well and cause crashes. - // - // To make `deallocating` as robust as possible, original implementation will be replaced. - if (selector == deallocSelector) { - Class __nonnull deallocSwizzingTarget = [target class]; - IMP interceptorIMPForSelector = [self interceptorImplementationForSelector:selector forClass:deallocSwizzingTarget]; - if (interceptorIMPForSelector != nil) { - return interceptorIMPForSelector; - } - - if (![self swizzleDeallocating:deallocSwizzingTarget error:error]) { - return nil; - } - - interceptorIMPForSelector = [self interceptorImplementationForSelector:selector forClass:deallocSwizzingTarget]; - if (interceptorIMPForSelector != nil) { - return interceptorIMPForSelector; - } - } - else { - Class __nullable swizzlingImplementorClass = [self prepareTargetClassForObserving:target error:error]; - if (swizzlingImplementorClass == nil) { - return nil; - } - - NSString *methodEncoding = RX_method_encoding(instanceMethod); - RXInterceptWithOptimizedObserver optimizedIntercept = optimizedObserversByMethodEncoding[methodEncoding]; - - if (!RX_method_has_supported_return_type(instanceMethod)) { - RX_THROW_ERROR([NSError errorWithDomain:RXObjCRuntimeErrorDomain - code:RXObjCRuntimeErrorObservingMessagesWithUnsupportedReturnType - userInfo:nil], nil); - } - - // optimized interception method - if (optimizedIntercept != nil) { - IMP interceptorIMPForSelector = [self interceptorImplementationForSelector:selector forClass:swizzlingImplementorClass]; - if (interceptorIMPForSelector != nil) { - return interceptorIMPForSelector; - } - - if (!optimizedIntercept(self, swizzlingImplementorClass, selector, error)) { - return nil; - } - - interceptorIMPForSelector = [self interceptorImplementationForSelector:selector forClass:swizzlingImplementorClass]; - if (interceptorIMPForSelector != nil) { - return interceptorIMPForSelector; - } - } - // default fallback to observing by forwarding messages - else { - if ([self forwardingSelector:selector forClass:swizzlingImplementorClass]) { - return RX_default_target_implementation(); - } - - if (![self observeByForwardingMessages:swizzlingImplementorClass - selector:selector - target:target - error:error]) { - return nil; - } - - if ([self forwardingSelector:selector forClass:swizzlingImplementorClass]) { - return RX_default_target_implementation(); - } - } - } - - RX_THROW_ERROR([NSError errorWithDomain:RXObjCRuntimeErrorDomain - code:RXObjCRuntimeErrorUnknown - userInfo:nil], nil); -} - --(Class __nullable)prepareTargetClassForObserving:(id __nonnull)target error:(NSErrorParam)error { - Class swizzlingClass = objc_getAssociatedObject(target, &RxSwizzlingTargetClassKey); - if (swizzlingClass != nil) { - return swizzlingClass; - } - - Class __nonnull wannaBeClass = [target class]; - /** - Core Foundation classes are usually toll free bridged. Those classes crash the program in case - `object_setClass` is performed on them. - - There is a possibility to just swizzle methods on original object, but since those won't be usual use - cases for this library, then an error will just be reported for now. - */ - BOOL isThisTollFreeFoundationClass = CFGetTypeID((CFTypeRef)target) != defaultTypeID; - - if (isThisTollFreeFoundationClass) { - RX_THROW_ERROR([NSError errorWithDomain:RXObjCRuntimeErrorDomain - code:RXObjCRuntimeErrorCantInterceptCoreFoundationTollFreeBridgedObjects - userInfo:nil], nil); - } - - /** - If the object is reporting a different class then what it's real class, that means that there is probably - already some interception mechanism in place or something weird is happening. - - Most common case when this would happen is when using KVO (`observe`) and `sentMessage`. - - This error is easily resolved by just using `sentMessage` observing before `observe`. - - The reason why other way around could create issues is because KVO will unregister it's interceptor - class and restore original class. Unfortunately that will happen no matter was there another interceptor - subclass registered in hierarchy or not. - - Failure scenario: - * KVO sets class to be `__KVO__OriginalClass` (subclass of `OriginalClass`) - * `sentMessage` sets object class to be `_RX_namespace___KVO__OriginalClass` (subclass of `__KVO__OriginalClass`) - * then unobserving with KVO will restore class to be `OriginalClass` -> failure point - - The reason why changing order of observing works is because any interception method should return - object's original real class (if that doesn't happen then it's really easy to argue that's a bug - in that other library). - - This library won't remove registered interceptor even if there aren't any observers left because - it's highly unlikely it would have any benefit in real world use cases, and it's even more - dangerous. - */ - if ([target class] != object_getClass(target)) { - BOOL isKVO = [target respondsToSelector:NSSelectorFromString(@"_isKVOA")]; - - RX_THROW_ERROR([NSError errorWithDomain:RXObjCRuntimeErrorDomain - code:RXObjCRuntimeErrorObjectMessagesAlreadyBeingIntercepted - userInfo:@{ - RXObjCRuntimeErrorIsKVOKey : @(isKVO) - }], nil); - } - - Class __nullable dynamicFakeSubclass = [self ensureHasDynamicFakeSubclass:wannaBeClass error:error]; - - if (dynamicFakeSubclass == nil) { - return nil; - } - - Class previousClass = object_setClass(target, dynamicFakeSubclass); - if (previousClass != wannaBeClass) { - THREADING_HAZARD(wannaBeClass); - RX_THROW_ERROR([NSError errorWithDomain:RXObjCRuntimeErrorDomain - code:RXObjCRuntimeErrorThreadingCollisionWithOtherInterceptionMechanism - userInfo:nil], nil); - } - - objc_setAssociatedObject(target, &RxSwizzlingTargetClassKey, dynamicFakeSubclass, OBJC_ASSOCIATION_RETAIN_NONATOMIC); - return dynamicFakeSubclass; -} - - --(BOOL)forwardingSelector:(SEL)selector forClass:(Class __nonnull)class { - return [self.forwardedSelectorsByClass[CLASS_VALUE(class)] containsObject:SEL_VALUE(selector)]; -} - --(void)registerForwardedSelector:(SEL)selector forClass:(Class __nonnull)class { - NSValue *classValue = CLASS_VALUE(class); - - NSMutableSet *forwardedSelectors = self.forwardedSelectorsByClass[classValue]; - - if (forwardedSelectors == nil) { - forwardedSelectors = [NSMutableSet set]; - self.forwardedSelectorsByClass[classValue] = forwardedSelectors; - } - - [forwardedSelectors addObject:SEL_VALUE(selector)]; -} - --(BOOL)observeByForwardingMessages:(Class __nonnull)swizzlingImplementorClass - selector:(SEL)selector - target:(id __nonnull)target - error:(NSErrorParam)error { - if (![self ensureForwardingMethodsAreSwizzled:swizzlingImplementorClass error:error]) { - return NO; - } - - ALWAYS(![self forwardingSelector:selector forClass:swizzlingImplementorClass], @"Already observing selector for class"); - -#if TRACE_RESOURCES - atomic_fetch_add(&numberOfForwardedMethods, 1); -#endif - SEL rxSelector = RX_selector(selector); - - Method instanceMethod = class_getInstanceMethod(swizzlingImplementorClass, selector); - ALWAYS(instanceMethod != nil, @"Instance method is nil"); - - const char* methodEncoding = method_getTypeEncoding(instanceMethod); - ALWAYS(methodEncoding != nil, @"Method encoding is nil."); - NSMethodSignature *methodSignature = [NSMethodSignature signatureWithObjCTypes:methodEncoding]; - ALWAYS(methodSignature != nil, @"Method signature is invalid."); - - IMP implementation = method_getImplementation(instanceMethod); - - if (implementation == nil) { - RX_THROW_ERROR([NSError errorWithDomain:RXObjCRuntimeErrorDomain - code:RXObjCRuntimeErrorSelectorNotImplemented - userInfo:nil], NO); - } - - if (!class_addMethod(swizzlingImplementorClass, rxSelector, implementation, methodEncoding)) { - RX_THROW_ERROR([NSError errorWithDomain:RXObjCRuntimeErrorDomain - code:RXObjCRuntimeErrorSavingOriginalForwardingMethodFailed - userInfo:nil], NO); - } - - if (!class_addMethod(swizzlingImplementorClass, selector, _objc_msgForward, methodEncoding)) { - if (implementation != method_setImplementation(instanceMethod, _objc_msgForward)) { - THREADING_HAZARD(swizzlingImplementorClass); - RX_THROW_ERROR([NSError errorWithDomain:RXObjCRuntimeErrorDomain - code:RXObjCRuntimeErrorReplacingMethodWithForwardingImplementation - userInfo:nil], NO); - } - } - - DLOG(@"Rx uses forwarding to observe `%@` for `%@`.", NSStringFromSelector(selector), swizzlingImplementorClass); - [self registerForwardedSelector:selector forClass:swizzlingImplementorClass]; - - return YES; -} - -/** - If object don't have some weird behavior, claims it's the same class that runtime shows, - then dynamic subclass is created (only this instance will have performance hit). - - In case something weird is detected, then original base class is being swizzled and all instances - will have somewhat reduced performance. - - This is especially handy optimization for weak KVO. Nobody will swizzle for example `NSString`, - but to know when instance of a `NSString` was deallocated, performance hit will be only felt on a - single instance of `NSString`, not all instances of `NSString`s. - */ --(Class __nullable)ensureHasDynamicFakeSubclass:(Class __nonnull)class error:(NSErrorParam)error { - Class dynamicFakeSubclass = self.dynamicSubclassByRealClass[CLASS_VALUE(class)]; - if (dynamicFakeSubclass != nil) { - return dynamicFakeSubclass; - } - - NSString *dynamicFakeSubclassName = [RX_PREFIX stringByAppendingString:NSStringFromClass(class)]; - const char *dynamicFakeSubclassNameRaw = dynamicFakeSubclassName.UTF8String; - dynamicFakeSubclass = objc_allocateClassPair(class, dynamicFakeSubclassNameRaw, 0); - ALWAYS(dynamicFakeSubclass != nil, @"Class not generated"); - - if (![self swizzleClass:dynamicFakeSubclass toActAs:class error:error]) { - return nil; - } - - objc_registerClassPair(dynamicFakeSubclass); - - [self.dynamicSubclassByRealClass setObject:dynamicFakeSubclass forKey:CLASS_VALUE(class)]; - ALWAYS(self.dynamicSubclassByRealClass[CLASS_VALUE(class)] != nil, @"Class not registered"); - - return dynamicFakeSubclass; -} - --(BOOL)ensureForwardingMethodsAreSwizzled:(Class __nonnull)class error:(NSErrorParam)error { - NSValue *classValue = CLASS_VALUE(class); - if ([self.classesThatSupportObservingByForwarding containsObject:classValue]) { - return YES; - } - - if (![self swizzleForwardInvocation:class error:error]) { return NO; } - if (![self swizzleMethodSignatureForSelector:class error:error]) { return NO; } - if (![self swizzleRespondsToSelector:class error:error]) { return NO; } - - [self.classesThatSupportObservingByForwarding addObject:classValue]; - - return YES; -} - --(void)registerInterceptedSelector:(SEL)selector implementation:(IMP)implementation forClass:(Class)class { - NSValue * __nonnull classValue = CLASS_VALUE(class); - NSValue * __nonnull selectorValue = SEL_VALUE(selector); - - NSMutableDictionary *swizzledIMPBySelectorsForClass = self.interceptorIMPbySelectorsByClass[classValue]; - - if (swizzledIMPBySelectorsForClass == nil) { - swizzledIMPBySelectorsForClass = [NSMutableDictionary dictionary]; - self.interceptorIMPbySelectorsByClass[classValue] = swizzledIMPBySelectorsForClass; - } - - swizzledIMPBySelectorsForClass[selectorValue] = IMP_VALUE(implementation); - - ALWAYS([self interceptorImplementationForSelector:selector forClass:class] != nil, @"Class should have been swizzled"); -} - --(IMP)interceptorImplementationForSelector:(SEL)selector forClass:(Class)class { - NSValue * __nonnull classValue = CLASS_VALUE(class); - NSValue * __nonnull selectorValue = SEL_VALUE(selector); - - NSMutableDictionary *swizzledIMPBySelectorForClass = self.interceptorIMPbySelectorsByClass[classValue]; - - NSValue *impValue = swizzledIMPBySelectorForClass[selectorValue]; - return impValue.pointerValue; -} - --(BOOL)ensureSwizzledSelector:(SEL __nonnull)selector - ofClass:(Class __nonnull)class - newImplementationGenerator:(IMP(^)(void))newImplementationGenerator -replacementImplementationGenerator:(IMP (^)(IMP originalImplementation))replacementImplementationGenerator - error:(NSErrorParam)error { - if ([self interceptorImplementationForSelector:selector forClass:class] != nil) { - DLOG(@"Trying to register same intercept at least once, this sounds like a possible bug"); - return YES; - } - -#if TRACE_RESOURCES - atomic_fetch_add(&numberOInterceptedMethods, 1); -#endif - - DLOG(@"Rx is swizzling `%@` for `%@`", NSStringFromSelector(selector), class); - - Method existingMethod = class_getInstanceMethod(class, selector); - ALWAYS(existingMethod != nil, @"Method doesn't exist"); - - const char *encoding = method_getTypeEncoding(existingMethod); - ALWAYS(encoding != nil, @"Encoding is nil"); - - IMP newImplementation = newImplementationGenerator(); - - if (class_addMethod(class, selector, newImplementation, encoding)) { - // new method added, job done - [self registerInterceptedSelector:selector implementation:newImplementation forClass:class]; - - return YES; - } - - imp_removeBlock(newImplementation); - - // if add fails, that means that method already exists on targetClass - Method existingMethodOnTargetClass = existingMethod; - - IMP originalImplementation = method_getImplementation(existingMethodOnTargetClass); - ALWAYS(originalImplementation != nil, @"Method must exist."); - IMP implementationReplacementIMP = replacementImplementationGenerator(originalImplementation); - ALWAYS(implementationReplacementIMP != nil, @"Method must exist."); - IMP originalImplementationAfterChange = method_setImplementation(existingMethodOnTargetClass, implementationReplacementIMP); - ALWAYS(originalImplementation != nil, @"Method must exist."); - - // If method replacing failed, who knows what happened, better not trying again, otherwise program can get - // corrupted. - [self registerInterceptedSelector:selector implementation:implementationReplacementIMP forClass:class]; - - // ¯\_(ツ)_/¯ - if (originalImplementationAfterChange != originalImplementation) { - THREADING_HAZARD(class); - return NO; - } - - return YES; -} - -@end - -#if TRACE_RESOURCES - -NSInteger RX_number_of_dynamic_subclasses(void) { - __block NSInteger count = 0; - [[RXObjCRuntime instance] performLocked:^(RXObjCRuntime * __nonnull self) { - count = self.dynamicSubclassByRealClass.count; - }]; - - return count; -} - -NSInteger RX_number_of_forwarding_enabled_classes(void) { - __block NSInteger count = 0; - [[RXObjCRuntime instance] performLocked:^(RXObjCRuntime * __nonnull self) { - count = self.classesThatSupportObservingByForwarding.count; - }]; - - return count; -} - -NSInteger RX_number_of_intercepting_classes(void) { - __block NSInteger count = 0; - [[RXObjCRuntime instance] performLocked:^(RXObjCRuntime * __nonnull self) { - count = self.interceptorIMPbySelectorsByClass.count; - }]; - - return count; -} - -NSInteger RX_number_of_forwarded_methods(void) { - return numberOfForwardedMethods; -} - -NSInteger RX_number_of_swizzled_methods(void) { - return numberOInterceptedMethods; -} - -#endif - -#endif diff --git a/Pods/RxCocoa/RxCocoa/Runtime/include/RxCocoaRuntime.h b/Pods/RxCocoa/RxCocoa/Runtime/include/RxCocoaRuntime.h deleted file mode 100644 index 8cf762ec8..000000000 --- a/Pods/RxCocoa/RxCocoa/Runtime/include/RxCocoaRuntime.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// RxCocoaRuntime.h -// RxCocoa -// -// Created by Krunoslav Zaher on 2/21/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#import -#import "_RX.h" -#import "_RXDelegateProxy.h" -#import "_RXKVOObserver.h" -#import "_RXObjCRuntime.h" - -//! Project version number for RxCocoa. -FOUNDATION_EXPORT double RxCocoaVersionNumber; - -//! Project version string for RxCocoa. -FOUNDATION_EXPORT const unsigned char RxCocoaVersionString[]; diff --git a/Pods/RxCocoa/RxCocoa/Runtime/include/_RX.h b/Pods/RxCocoa/RxCocoa/Runtime/include/_RX.h deleted file mode 100644 index b868ac97e..000000000 --- a/Pods/RxCocoa/RxCocoa/Runtime/include/_RX.h +++ /dev/null @@ -1,93 +0,0 @@ -// -// _RX.h -// RxCocoa -// -// Created by Krunoslav Zaher on 7/12/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#import -#import - -/** - ################################################################################ - This file is part of RX private API - ################################################################################ - */ - -#if TRACE_RESOURCES >= 2 -# define DLOG(...) NSLog(__VA_ARGS__) -#else -# define DLOG(...) -#endif - -#if DEBUG -# define ABORT_IN_DEBUG abort(); -#else -# define ABORT_IN_DEBUG -#endif - - -#define SEL_VALUE(x) [NSValue valueWithPointer:(x)] -#define CLASS_VALUE(x) [NSValue valueWithNonretainedObject:(x)] -#define IMP_VALUE(x) [NSValue valueWithPointer:(x)] - -/** - Checks that the local `error` instance exists before assigning it's value by reference. - This macro exists to work around static analysis warnings — `NSError` is always assumed to be `nullable`, even though we explicitly define the method parameter as `nonnull`. See http://www.openradar.me/21766176 for more details. - */ -#define RX_THROW_ERROR(errorValue, returnValue) if (error != nil) { *error = (errorValue); } return (returnValue); - -#define RX_CAT2(_1, _2) _RX_CAT2(_1, _2) -#define _RX_CAT2(_1, _2) _1 ## _2 - -#define RX_ELEMENT_AT(n, ...) RX_CAT2(_RX_ELEMENT_AT_, n)(__VA_ARGS__) -#define _RX_ELEMENT_AT_0(x, ...) x -#define _RX_ELEMENT_AT_1(_0, x, ...) x -#define _RX_ELEMENT_AT_2(_0, _1, x, ...) x -#define _RX_ELEMENT_AT_3(_0, _1, _2, x, ...) x -#define _RX_ELEMENT_AT_4(_0, _1, _2, _3, x, ...) x -#define _RX_ELEMENT_AT_5(_0, _1, _2, _3, _4, x, ...) x -#define _RX_ELEMENT_AT_6(_0, _1, _2, _3, _4, _5, x, ...) x - -#define RX_COUNT(...) RX_ELEMENT_AT(6, ## __VA_ARGS__, 6, 5, 4, 3, 2, 1, 0) -#define RX_EMPTY(...) RX_ELEMENT_AT(6, ## __VA_ARGS__, 0, 0, 0, 0, 0, 0, 1) - -/** - #define SUM(context, index, head, tail) head + tail - #define MAP(context, index, element) (context)[index] * (element) - - RX_FOR(numbers, SUM, MAP, b0, b1, b2); - - (numbers)[0] * (b0) + (numbers)[1] * (b1) + (numbers[2]) * (b2) - */ - -#define RX_FOREACH(context, concat, map, ...) RX_FOR_MAX(RX_COUNT(__VA_ARGS__), _RX_FOREACH_CONCAT, _RX_FOREACH_MAP, context, concat, map, __VA_ARGS__) -#define _RX_FOREACH_CONCAT(index, head, tail, context, concat, map, ...) concat(context, index, head, tail) -#define _RX_FOREACH_MAP(index, context, concat, map, ...) map(context, index, RX_ELEMENT_AT(index, __VA_ARGS__)) - -/** - #define MAP(context, index, item) (context)[index] * (item) - - RX_FOR_COMMA(numbers, MAP, b0, b1); - - ,(numbers)[0] * b0, (numbers)[1] * b1 - */ -#define RX_FOREACH_COMMA(context, map, ...) RX_CAT2(_RX_FOREACH_COMMA_EMPTY_, RX_EMPTY(__VA_ARGS__))(context, map, ## __VA_ARGS__) -#define _RX_FOREACH_COMMA_EMPTY_1(context, map, ...) -#define _RX_FOREACH_COMMA_EMPTY_0(context, map, ...) , RX_FOR_MAX(RX_COUNT(__VA_ARGS__), _RX_FOREACH_COMMA_CONCAT, _RX_FOREACH_COMMA_MAP, context, map, __VA_ARGS__) -#define _RX_FOREACH_COMMA_CONCAT(index, head, tail, context, map, ...) head, tail -#define _RX_FOREACH_COMMA_MAP(index, context, map, ...) map(context, index, RX_ELEMENT_AT(index, __VA_ARGS__)) - -// rx for - -#define RX_FOR_MAX(max, concat, map, ...) RX_CAT2(RX_FOR_, max)(concat, map, ## __VA_ARGS__) - -#define RX_FOR_0(concat, map, ...) -#define RX_FOR_1(concat, map, ...) map(0, __VA_ARGS__) -#define RX_FOR_2(concat, map, ...) concat(1, RX_FOR_1(concat, map, ## __VA_ARGS__), map(1, __VA_ARGS__), __VA_ARGS__) -#define RX_FOR_3(concat, map, ...) concat(2, RX_FOR_2(concat, map, ## __VA_ARGS__), map(2, __VA_ARGS__), __VA_ARGS__) -#define RX_FOR_4(concat, map, ...) concat(3, RX_FOR_3(concat, map, ## __VA_ARGS__), map(3, __VA_ARGS__), __VA_ARGS__) -#define RX_FOR_5(concat, map, ...) concat(4, RX_FOR_4(concat, map, ## __VA_ARGS__), map(4, __VA_ARGS__), __VA_ARGS__) -#define RX_FOR_6(concat, map, ...) concat(5, RX_FOR_5(concat, map, ## __VA_ARGS__), map(5, __VA_ARGS__), __VA_ARGS__) - diff --git a/Pods/RxCocoa/RxCocoa/Runtime/include/_RXDelegateProxy.h b/Pods/RxCocoa/RxCocoa/Runtime/include/_RXDelegateProxy.h deleted file mode 100644 index e1cc207d1..000000000 --- a/Pods/RxCocoa/RxCocoa/Runtime/include/_RXDelegateProxy.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// _RXDelegateProxy.h -// RxCocoa -// -// Created by Krunoslav Zaher on 7/4/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface _RXDelegateProxy : NSObject - -@property (nonatomic, weak, readonly) id _forwardToDelegate; - --(void)_setForwardToDelegate:(id __nullable)forwardToDelegate retainDelegate:(BOOL)retainDelegate NS_SWIFT_NAME(_setForwardToDelegate(_:retainDelegate:)) ; - --(BOOL)hasWiredImplementationForSelector:(SEL)selector; --(BOOL)voidDelegateMethodsContain:(SEL)selector; - --(void)_sentMessage:(SEL)selector withArguments:(NSArray*)arguments; --(void)_methodInvoked:(SEL)selector withArguments:(NSArray*)arguments; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Pods/RxCocoa/RxCocoa/Runtime/include/_RXKVOObserver.h b/Pods/RxCocoa/RxCocoa/Runtime/include/_RXKVOObserver.h deleted file mode 100644 index adcfd0a3b..000000000 --- a/Pods/RxCocoa/RxCocoa/Runtime/include/_RXKVOObserver.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// _RXKVOObserver.h -// RxCocoa -// -// Created by Krunoslav Zaher on 7/11/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#import - -/** - ################################################################################ - This file is part of RX private API - ################################################################################ - */ - -// Exists because if written in Swift, reading unowned is disabled during dealloc process -@interface _RXKVOObserver : NSObject - --(instancetype)initWithTarget:(id)target - retainTarget:(BOOL)retainTarget - keyPath:(NSString*)keyPath - options:(NSKeyValueObservingOptions)options - callback:(void (^)(id))callback; - --(void)dispose; - -@end diff --git a/Pods/RxCocoa/RxCocoa/Runtime/include/_RXObjCRuntime.h b/Pods/RxCocoa/RxCocoa/Runtime/include/_RXObjCRuntime.h deleted file mode 100644 index bc6a76af7..000000000 --- a/Pods/RxCocoa/RxCocoa/Runtime/include/_RXObjCRuntime.h +++ /dev/null @@ -1,102 +0,0 @@ -// -// _RXObjCRuntime.h -// RxCocoa -// -// Created by Krunoslav Zaher on 7/11/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#import - -#if !DISABLE_SWIZZLING - -/** - ################################################################################ - This file is part of RX private API - ################################################################################ - */ - -/** - This flag controls `RELEASE` configuration behavior in case race was detecting while modifying - ObjC runtime. - - In case this value is set to `YES`, after runtime race is detected, `abort()` will be called. - Otherwise, only error will be reported using normal error reporting mechanism. - - In `DEBUG` mode `abort` will be always called in case race is detected. - - Races can't happen in case this is the only library modifying ObjC runtime, but in case there are multiple libraries - changing ObjC runtime, race conditions can occur because there is no way to synchronize multiple libraries unaware of - each other. - - To help remedy this situation this library will use `synchronized` on target object and it's meta-class, but - there aren't any guarantees of how other libraries will behave. - - Default value is `NO`. - - */ -extern BOOL RXAbortOnThreadingHazard; - -/// Error domain for RXObjCRuntime. -extern NSString * __nonnull const RXObjCRuntimeErrorDomain; - -/// `userInfo` key with additional information is interceptor probably KVO. -extern NSString * __nonnull const RXObjCRuntimeErrorIsKVOKey; - -typedef NS_ENUM(NSInteger, RXObjCRuntimeError) { - RXObjCRuntimeErrorUnknown = 1, - RXObjCRuntimeErrorObjectMessagesAlreadyBeingIntercepted = 2, - RXObjCRuntimeErrorSelectorNotImplemented = 3, - RXObjCRuntimeErrorCantInterceptCoreFoundationTollFreeBridgedObjects = 4, - RXObjCRuntimeErrorThreadingCollisionWithOtherInterceptionMechanism = 5, - RXObjCRuntimeErrorSavingOriginalForwardingMethodFailed = 6, - RXObjCRuntimeErrorReplacingMethodWithForwardingImplementation = 7, - RXObjCRuntimeErrorObservingPerformanceSensitiveMessages = 8, - RXObjCRuntimeErrorObservingMessagesWithUnsupportedReturnType = 9, -}; - -/// Transforms normal selector into a selector with RX prefix. -SEL _Nonnull RX_selector(SEL _Nonnull selector); - -/// Transforms selector into a unique pointer (because of Swift conversion rules) -void * __nonnull RX_reference_from_selector(SEL __nonnull selector); - -/// Protocol that interception observers must implement. -@protocol RXMessageSentObserver - -/// In case the same selector is being intercepted for a pair of base/sub classes, -/// this property will differentiate between interceptors that need to fire. -@property (nonatomic, assign, readonly) IMP __nonnull targetImplementation; - --(void)messageSentWithArguments:(NSArray* __nonnull)arguments; --(void)methodInvokedWithArguments:(NSArray* __nonnull)arguments; - -@end - -/// Protocol that deallocating observer must implement. -@protocol RXDeallocatingObserver - -/// In case the same selector is being intercepted for a pair of base/sub classes, -/// this property will differentiate between interceptors that need to fire. -@property (nonatomic, assign, readonly) IMP __nonnull targetImplementation; - --(void)deallocating; - -@end - -/// Ensures interceptor is installed on target object. -IMP __nullable RX_ensure_observing(id __nonnull target, SEL __nonnull selector, NSError *__autoreleasing __nullable * __nullable error); - -#endif - -/// Extracts arguments for `invocation`. -NSArray * __nonnull RX_extract_arguments(NSInvocation * __nonnull invocation); - -/// Returns `YES` in case method has `void` return type. -BOOL RX_is_method_with_description_void(struct objc_method_description method); - -/// Returns `YES` in case methodSignature has `void` return type. -BOOL RX_is_method_signature_void(NSMethodSignature * __nonnull methodSignature); - -/// Default value for `RXInterceptionObserver.targetImplementation`. -IMP __nonnull RX_default_target_implementation(void); diff --git a/Pods/RxCocoa/RxCocoa/RxCocoa.h b/Pods/RxCocoa/RxCocoa/RxCocoa.h deleted file mode 100644 index 0bca1bc75..000000000 --- a/Pods/RxCocoa/RxCocoa/RxCocoa.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// RxCocoa.h -// RxCocoa -// -// Created by Krunoslav Zaher on 2/21/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#import -#import -#import -#import -#import - -//! Project version number for RxCocoa. -FOUNDATION_EXPORT double RxCocoaVersionNumber; - -//! Project version string for RxCocoa. -FOUNDATION_EXPORT const unsigned char RxCocoaVersionString[]; diff --git a/Pods/RxCocoa/RxCocoa/RxCocoa.swift b/Pods/RxCocoa/RxCocoa/RxCocoa.swift deleted file mode 100644 index 5e569fc2b..000000000 --- a/Pods/RxCocoa/RxCocoa/RxCocoa.swift +++ /dev/null @@ -1,155 +0,0 @@ -// -// RxCocoa.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 2/21/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import Foundation - -// Importing RxCocoa also imports RxRelay -@_exported import RxRelay - -import RxSwift -#if os(iOS) - import UIKit -#endif - -/// RxCocoa errors. -public enum RxCocoaError - : Swift.Error - , CustomDebugStringConvertible { - /// Unknown error has occurred. - case unknown - /// Invalid operation was attempted. - case invalidOperation(object: Any) - /// Items are not yet bound to user interface but have been requested. - case itemsNotYetBound(object: Any) - /// Invalid KVO Path. - case invalidPropertyName(object: Any, propertyName: String) - /// Invalid object on key path. - case invalidObjectOnKeyPath(object: Any, sourceObject: AnyObject, propertyName: String) - /// Error during swizzling. - case errorDuringSwizzling - /// Casting error. - case castingError(object: Any, targetType: Any.Type) -} - - -// MARK: Debug descriptions - -extension RxCocoaError { - /// A textual representation of `self`, suitable for debugging. - public var debugDescription: String { - switch self { - case .unknown: - return "Unknown error occurred." - case let .invalidOperation(object): - return "Invalid operation was attempted on `\(object)`." - case let .itemsNotYetBound(object): - return "Data source is set, but items are not yet bound to user interface for `\(object)`." - case let .invalidPropertyName(object, propertyName): - return "Object `\(object)` doesn't have a property named `\(propertyName)`." - case let .invalidObjectOnKeyPath(object, sourceObject, propertyName): - return "Unobservable object `\(object)` was observed as `\(propertyName)` of `\(sourceObject)`." - case .errorDuringSwizzling: - return "Error during swizzling." - case let .castingError(object, targetType): - return "Error casting `\(object)` to `\(targetType)`" - } - } -} - - - -// MARK: Error binding policies - -func bindingError(_ error: Swift.Error) { - let error = "Binding error: \(error)" -#if DEBUG - rxFatalError(error) -#else - print(error) -#endif -} - -/// Swift does not implement abstract methods. This method is used as a runtime check to ensure that methods which intended to be abstract (i.e., they should be implemented in subclasses) are not called directly on the superclass. -func rxAbstractMethod(message: String = "Abstract method", file: StaticString = #file, line: UInt = #line) -> Swift.Never { - rxFatalError(message, file: file, line: line) -} - -func rxFatalError(_ lastMessage: @autoclosure () -> String, file: StaticString = #file, line: UInt = #line) -> Swift.Never { - // The temptation to comment this line is great, but please don't, it's for your own good. The choice is yours. - fatalError(lastMessage(), file: file, line: line) -} - -func rxFatalErrorInDebug(_ lastMessage: @autoclosure () -> String, file: StaticString = #file, line: UInt = #line) { - #if DEBUG - fatalError(lastMessage(), file: file, line: line) - #else - print("\(file):\(line): \(lastMessage())") - #endif -} - -// MARK: casts or fatal error - -// workaround for Swift compiler bug, cheers compiler team :) -func castOptionalOrFatalError(_ value: Any?) -> T? { - if value == nil { - return nil - } - let v: T = castOrFatalError(value) - return v -} - -func castOrThrow(_ resultType: T.Type, _ object: Any) throws -> T { - guard let returnValue = object as? T else { - throw RxCocoaError.castingError(object: object, targetType: resultType) - } - - return returnValue -} - -func castOptionalOrThrow(_ resultType: T.Type, _ object: AnyObject) throws -> T? { - if NSNull().isEqual(object) { - return nil - } - - guard let returnValue = object as? T else { - throw RxCocoaError.castingError(object: object, targetType: resultType) - } - - return returnValue -} - -func castOrFatalError(_ value: AnyObject!, message: String) -> T { - let maybeResult: T? = value as? T - guard let result = maybeResult else { - rxFatalError(message) - } - - return result -} - -func castOrFatalError(_ value: Any!) -> T { - let maybeResult: T? = value as? T - guard let result = maybeResult else { - rxFatalError("Failure converting from \(String(describing: value)) to \(T.self)") - } - - return result -} - -// MARK: Error messages - -let dataSourceNotSet = "DataSource not set" -let delegateNotSet = "Delegate not set" - -// MARK: Shared with RxSwift - -func rxFatalError(_ lastMessage: String) -> Never { - // The temptation to comment this line is great, but please don't, it's for your own good. The choice is yours. - fatalError(lastMessage) -} - diff --git a/Pods/RxCocoa/RxCocoa/Traits/ControlEvent.swift b/Pods/RxCocoa/RxCocoa/Traits/ControlEvent.swift deleted file mode 100644 index bea1d83d9..000000000 --- a/Pods/RxCocoa/RxCocoa/Traits/ControlEvent.swift +++ /dev/null @@ -1,68 +0,0 @@ -// -// ControlEvent.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 8/28/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - -/// A protocol that extends `ControlEvent`. -public protocol ControlEventType : ObservableType { - - /// - returns: `ControlEvent` interface - func asControlEvent() -> ControlEvent -} - -/** - A trait for `Observable`/`ObservableType` that represents an event on a UI element. - - Properties: - - - it doesn’t send any initial value on subscription, - - it `Complete`s the sequence when the control deallocates, - - it never errors out - - it delivers events on `MainScheduler.instance`. - - **The implementation of `ControlEvent` will ensure that sequence of events is being subscribed on main scheduler - (`subscribe(on: ConcurrentMainScheduler.instance)` behavior).** - - **It is the implementor’s responsibility to make sure that all other properties enumerated above are satisfied.** - - **If they aren’t, using this trait will communicate wrong properties, and could potentially break someone’s code.** - - **If the `events` observable sequence passed into the initializer doesn’t satisfy all enumerated - properties, don’t use this trait.** -*/ -public struct ControlEvent : ControlEventType { - public typealias Element = PropertyType - - let events: Observable - - /// Initializes control event with a observable sequence that represents events. - /// - /// - parameter events: Observable sequence that represents events. - /// - returns: Control event created with a observable sequence of events. - public init(events: Ev) where Ev.Element == Element { - self.events = events.subscribe(on: ConcurrentMainScheduler.instance) - } - - /// Subscribes an observer to control events. - /// - /// - parameter observer: Observer to subscribe to events. - /// - returns: Disposable object that can be used to unsubscribe the observer from receiving control events. - public func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { - self.events.subscribe(observer) - } - - /// - returns: `Observable` interface. - public func asObservable() -> Observable { - self.events - } - - /// - returns: `ControlEvent` interface. - public func asControlEvent() -> ControlEvent { - self - } -} diff --git a/Pods/RxCocoa/RxCocoa/Traits/ControlProperty.swift b/Pods/RxCocoa/RxCocoa/Traits/ControlProperty.swift deleted file mode 100644 index 3068afbf2..000000000 --- a/Pods/RxCocoa/RxCocoa/Traits/ControlProperty.swift +++ /dev/null @@ -1,118 +0,0 @@ -// -// ControlProperty.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 8/28/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - -/// Protocol that enables extension of `ControlProperty`. -public protocol ControlPropertyType : ObservableType, ObserverType { - - /// - returns: `ControlProperty` interface - func asControlProperty() -> ControlProperty -} - -/** - Trait for `Observable`/`ObservableType` that represents property of UI element. - - Sequence of values only represents initial control value and user initiated value changes. - Programmatic value changes won't be reported. - - It's properties are: - - - `shareReplay(1)` behavior - - it's stateful, upon subscription (calling subscribe) last element is immediately replayed if it was produced - - it will `Complete` sequence on control being deallocated - - it never errors out - - it delivers events on `MainScheduler.instance` - - **The implementation of `ControlProperty` will ensure that sequence of values is being subscribed on main scheduler - (`subscribe(on: ConcurrentMainScheduler.instance)` behavior).** - - **It is implementor's responsibility to make sure that that all other properties enumerated above are satisfied.** - - **If they aren't, then using this trait communicates wrong properties and could potentially break someone's code.** - - **In case `values` observable sequence that is being passed into initializer doesn't satisfy all enumerated - properties, please don't use this trait.** -*/ -public struct ControlProperty : ControlPropertyType { - public typealias Element = PropertyType - - let values: Observable - let valueSink: AnyObserver - - /// Initializes control property with a observable sequence that represents property values and observer that enables - /// binding values to property. - /// - /// - parameter values: Observable sequence that represents property values. - /// - parameter valueSink: Observer that enables binding values to control property. - /// - returns: Control property created with a observable sequence of values and an observer that enables binding values - /// to property. - public init(values: Values, valueSink: Sink) where Element == Values.Element, Element == Sink.Element { - self.values = values.subscribe(on: ConcurrentMainScheduler.instance) - self.valueSink = valueSink.asObserver() - } - - /// Subscribes an observer to control property values. - /// - /// - parameter observer: Observer to subscribe to property values. - /// - returns: Disposable object that can be used to unsubscribe the observer from receiving control property values. - public func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { - self.values.subscribe(observer) - } - - /// `ControlEvent` of user initiated value changes. Every time user updates control value change event - /// will be emitted from `changed` event. - /// - /// Programmatic changes to control value won't be reported. - /// - /// It contains all control property values except for first one. - /// - /// The name only implies that sequence element will be generated once user changes a value and not that - /// adjacent sequence values need to be different (e.g. because of interaction between programmatic and user updates, - /// or for any other reason). - public var changed: ControlEvent { - ControlEvent(events: self.values.skip(1)) - } - - /// - returns: `Observable` interface. - public func asObservable() -> Observable { - self.values - } - - /// - returns: `ControlProperty` interface. - public func asControlProperty() -> ControlProperty { - self - } - - /// Binds event to user interface. - /// - /// - In case next element is received, it is being set to control value. - /// - In case error is received, DEBUG buids raise fatal error, RELEASE builds log event to standard output. - /// - In case sequence completes, nothing happens. - public func on(_ event: Event) { - switch event { - case .error(let error): - bindingError(error) - case .next: - self.valueSink.on(event) - case .completed: - self.valueSink.on(event) - } - } -} - -extension ControlPropertyType where Element == String? { - /// Transforms control property of type `String?` into control property of type `String`. - public var orEmpty: ControlProperty { - let original: ControlProperty = self.asControlProperty() - - let values: Observable = original.values.map { $0 ?? "" } - let valueSink: AnyObserver = original.valueSink.mapObserver { $0 } - return ControlProperty(values: values, valueSink: valueSink) - } -} diff --git a/Pods/RxCocoa/RxCocoa/Traits/Driver/BehaviorRelay+Driver.swift b/Pods/RxCocoa/RxCocoa/Traits/Driver/BehaviorRelay+Driver.swift deleted file mode 100644 index 76d960f0c..000000000 --- a/Pods/RxCocoa/RxCocoa/Traits/Driver/BehaviorRelay+Driver.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// BehaviorRelay+Driver.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 10/7/17. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -import RxSwift -import RxRelay - -extension BehaviorRelay { - /// Converts `BehaviorRelay` to `Driver`. - /// - /// - returns: Observable sequence. - public func asDriver() -> Driver { - let source = self.asObservable() - .observe(on:DriverSharingStrategy.scheduler) - return SharedSequence(source) - } -} diff --git a/Pods/RxCocoa/RxCocoa/Traits/Driver/ControlEvent+Driver.swift b/Pods/RxCocoa/RxCocoa/Traits/Driver/ControlEvent+Driver.swift deleted file mode 100644 index b59c7533e..000000000 --- a/Pods/RxCocoa/RxCocoa/Traits/Driver/ControlEvent+Driver.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// ControlEvent+Driver.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 9/19/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - -extension ControlEvent { - /// Converts `ControlEvent` to `Driver` trait. - /// - /// `ControlEvent` already can't fail, so no special case needs to be handled. - public func asDriver() -> Driver { - return self.asDriver { _ -> Driver in - #if DEBUG - rxFatalError("Somehow driver received error from a source that shouldn't fail.") - #else - return Driver.empty() - #endif - } - } -} diff --git a/Pods/RxCocoa/RxCocoa/Traits/Driver/ControlProperty+Driver.swift b/Pods/RxCocoa/RxCocoa/Traits/Driver/ControlProperty+Driver.swift deleted file mode 100644 index 790452970..000000000 --- a/Pods/RxCocoa/RxCocoa/Traits/Driver/ControlProperty+Driver.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// ControlProperty+Driver.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 9/19/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - -extension ControlProperty { - /// Converts `ControlProperty` to `Driver` trait. - /// - /// `ControlProperty` already can't fail, so no special case needs to be handled. - public func asDriver() -> Driver { - return self.asDriver { _ -> Driver in - #if DEBUG - rxFatalError("Somehow driver received error from a source that shouldn't fail.") - #else - return Driver.empty() - #endif - } - } -} diff --git a/Pods/RxCocoa/RxCocoa/Traits/Driver/Driver+Subscription.swift b/Pods/RxCocoa/RxCocoa/Traits/Driver/Driver+Subscription.swift deleted file mode 100644 index da9659c49..000000000 --- a/Pods/RxCocoa/RxCocoa/Traits/Driver/Driver+Subscription.swift +++ /dev/null @@ -1,203 +0,0 @@ -// -// Driver+Subscription.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 9/19/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import RxSwift -import RxRelay - -private let errorMessage = "`drive*` family of methods can be only called from `MainThread`.\n" + -"This is required to ensure that the last replayed `Driver` element is delivered on `MainThread`.\n" - -extension SharedSequenceConvertibleType where SharingStrategy == DriverSharingStrategy { - /** - Creates new subscription and sends elements to observer. - This method can be only called from `MainThread`. - - In this form it's equivalent to `subscribe` method, but it communicates intent better. - - - parameter observers: Observers that receives events. - - returns: Disposable object that can be used to unsubscribe the observer from the subject. - */ - public func drive(_ observers: Observer...) -> Disposable where Observer.Element == Element { - MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage) - return self.asSharedSequence() - .asObservable() - .subscribe { e in - observers.forEach { $0.on(e) } - } - } - - /** - Creates new subscription and sends elements to observer. - This method can be only called from `MainThread`. - - In this form it's equivalent to `subscribe` method, but it communicates intent better. - - - parameter observers: Observers that receives events. - - returns: Disposable object that can be used to unsubscribe the observer from the subject. - */ - public func drive(_ observers: Observer...) -> Disposable where Observer.Element == Element? { - MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage) - return self.asSharedSequence() - .asObservable() - .map { $0 as Element? } - .subscribe { e in - observers.forEach { $0.on(e) } - } - } - - /** - Creates new subscription and sends elements to `BehaviorRelay`. - This method can be only called from `MainThread`. - - - parameter relays: Target relays for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer from the relay. - */ - public func drive(_ relays: BehaviorRelay...) -> Disposable { - MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage) - return self.drive(onNext: { e in - relays.forEach { $0.accept(e) } - }) - } - - /** - Creates new subscription and sends elements to `BehaviorRelay`. - This method can be only called from `MainThread`. - - - parameter relays: Target relays for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer from the relay. - */ - public func drive(_ relays: BehaviorRelay...) -> Disposable { - MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage) - return self.drive(onNext: { e in - relays.forEach { $0.accept(e) } - }) - } - - /** - Creates new subscription and sends elements to `ReplayRelay`. - This method can be only called from `MainThread`. - - - parameter relays: Target relays for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer from the relay. - */ - public func drive(_ relays: ReplayRelay...) -> Disposable { - MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage) - return self.drive(onNext: { e in - relays.forEach { $0.accept(e) } - }) - } - - /** - Creates new subscription and sends elements to `ReplayRelay`. - This method can be only called from `MainThread`. - - - parameter relays: Target relays for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer from the relay. - */ - public func drive(_ relays: ReplayRelay...) -> Disposable { - MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage) - return self.drive(onNext: { e in - relays.forEach { $0.accept(e) } - }) - } - - /** - Subscribes to observable sequence using custom binder function. - This method can be only called from `MainThread`. - - - parameter with: Function used to bind elements from `self`. - - returns: Object representing subscription. - */ - public func drive(_ transformation: (Observable) -> Result) -> Result { - MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage) - return transformation(self.asObservable()) - } - - /** - Subscribes to observable sequence using custom binder function and final parameter passed to binder function - after `self` is passed. - - public func drive(with: Self -> R1 -> R2, curriedArgument: R1) -> R2 { - return with(self)(curriedArgument) - } - - This method can be only called from `MainThread`. - - - parameter with: Function used to bind elements from `self`. - - parameter curriedArgument: Final argument passed to `binder` to finish binding process. - - returns: Object representing subscription. - */ - public func drive(_ with: (Observable) -> (R1) -> R2, curriedArgument: R1) -> R2 { - MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage) - return with(self.asObservable())(curriedArgument) - } - - /** - Subscribes an element handler, a completion handler and disposed handler to an observable sequence. - This method can be only called from `MainThread`. - - Also, take in an object and provide an unretained, safe to use (i.e. not implicitly unwrapped), reference to it along with the events emitted by the sequence. - - Error callback is not exposed because `Driver` can't error out. - - - Note: If `object` can't be retained, none of the other closures will be invoked. - - - parameter object: The object to provide an unretained reference on. - - parameter onNext: Action to invoke for each element in the observable sequence. - - parameter onCompleted: Action to invoke upon graceful termination of the observable sequence. - gracefully completed, errored, or if the generation is canceled by disposing subscription) - - parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has - gracefully completed, errored, or if the generation is canceled by disposing subscription) - - returns: Subscription object used to unsubscribe from the observable sequence. - */ - public func drive( - with object: Object, - onNext: ((Object, Element) -> Void)? = nil, - onCompleted: ((Object) -> Void)? = nil, - onDisposed: ((Object) -> Void)? = nil - ) -> Disposable { - MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage) - return self.asObservable().subscribe(with: object, onNext: onNext, onCompleted: onCompleted, onDisposed: onDisposed) - } - - /** - Subscribes an element handler, a completion handler and disposed handler to an observable sequence. - This method can be only called from `MainThread`. - - Error callback is not exposed because `Driver` can't error out. - - - parameter onNext: Action to invoke for each element in the observable sequence. - - parameter onCompleted: Action to invoke upon graceful termination of the observable sequence. - gracefully completed, errored, or if the generation is canceled by disposing subscription) - - parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has - gracefully completed, errored, or if the generation is canceled by disposing subscription) - - returns: Subscription object used to unsubscribe from the observable sequence. - */ - public func drive( - onNext: ((Element) -> Void)? = nil, - onCompleted: (() -> Void)? = nil, - onDisposed: (() -> Void)? = nil - ) -> Disposable { - MainScheduler.ensureRunningOnMainThread(errorMessage: errorMessage) - return self.asObservable().subscribe(onNext: onNext, onCompleted: onCompleted, onDisposed: onDisposed) - } - - /** - Subscribes to this `Driver` with a no-op. - This method can be only called from `MainThread`. - - - note: This is an alias of `drive(onNext: nil, onCompleted: nil, onDisposed: nil)` used to fix an ambiguity bug in Swift: https://bugs.swift.org/browse/SR-13657 - - - returns: Subscription object used to unsubscribe from the observable sequence. - */ - public func drive() -> Disposable { - drive(onNext: nil, onCompleted: nil, onDisposed: nil) - } -} - - diff --git a/Pods/RxCocoa/RxCocoa/Traits/Driver/Driver.swift b/Pods/RxCocoa/RxCocoa/Traits/Driver/Driver.swift deleted file mode 100644 index 5de8b3a56..000000000 --- a/Pods/RxCocoa/RxCocoa/Traits/Driver/Driver.swift +++ /dev/null @@ -1,53 +0,0 @@ -// -// Driver.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 9/26/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - -/** - Trait that represents observable sequence with following properties: - - - it never fails - - it delivers events on `MainScheduler.instance` - - `share(replay: 1, scope: .whileConnected)` sharing strategy - - Additional explanation: - - all observers share sequence computation resources - - it's stateful, upon subscription (calling subscribe) last element is immediately replayed if it was produced - - computation of elements is reference counted with respect to the number of observers - - if there are no subscribers, it will release sequence computation resources - - In case trait that models event bus is required, please check `Signal`. - - `Driver` can be considered a builder pattern for observable sequences that drive the application. - - If observable sequence has produced at least one element, after new subscription is made last produced element will be - immediately replayed on the same thread on which the subscription was made. - - When using `drive*`, `subscribe*` and `bind*` family of methods, they should always be called from main thread. - - If `drive*`, `subscribe*` and `bind*` are called from background thread, it is possible that initial replay - will happen on background thread, and subsequent events will arrive on main thread. - - To find out more about traits and how to use them, please visit `Documentation/Traits.md`. - */ -public typealias Driver = SharedSequence - -public struct DriverSharingStrategy: SharingStrategyProtocol { - public static var scheduler: SchedulerType { SharingScheduler.make() } - public static func share(_ source: Observable) -> Observable { - source.share(replay: 1, scope: .whileConnected) - } -} - -extension SharedSequenceConvertibleType where SharingStrategy == DriverSharingStrategy { - /// Adds `asDriver` to `SharingSequence` with `DriverSharingStrategy`. - public func asDriver() -> Driver { - self.asSharedSequence() - } -} - diff --git a/Pods/RxCocoa/RxCocoa/Traits/Driver/ObservableConvertibleType+Driver.swift b/Pods/RxCocoa/RxCocoa/Traits/Driver/ObservableConvertibleType+Driver.swift deleted file mode 100644 index bcac66b66..000000000 --- a/Pods/RxCocoa/RxCocoa/Traits/Driver/ObservableConvertibleType+Driver.swift +++ /dev/null @@ -1,57 +0,0 @@ -// -// ObservableConvertibleType+Driver.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 9/19/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - -extension ObservableConvertibleType { - /** - Converts observable sequence to `Driver` trait. - - - parameter onErrorJustReturn: Element to return in case of error and after that complete the sequence. - - returns: Driver trait. - */ - public func asDriver(onErrorJustReturn: Element) -> Driver { - let source = self - .asObservable() - .observe(on:DriverSharingStrategy.scheduler) - .catchAndReturn(onErrorJustReturn) - return Driver(source) - } - - /** - Converts observable sequence to `Driver` trait. - - - parameter onErrorDriveWith: Driver that continues to drive the sequence in case of error. - - returns: Driver trait. - */ - public func asDriver(onErrorDriveWith: Driver) -> Driver { - let source = self - .asObservable() - .observe(on:DriverSharingStrategy.scheduler) - .catch { _ in - onErrorDriveWith.asObservable() - } - return Driver(source) - } - - /** - Converts observable sequence to `Driver` trait. - - - parameter onErrorRecover: Calculates driver that continues to drive the sequence in case of error. - - returns: Driver trait. - */ - public func asDriver(onErrorRecover: @escaping (_ error: Swift.Error) -> Driver) -> Driver { - let source = self - .asObservable() - .observe(on:DriverSharingStrategy.scheduler) - .catch { error in - onErrorRecover(error).asObservable() - } - return Driver(source) - } -} diff --git a/Pods/RxCocoa/RxCocoa/Traits/SharedSequence/ObservableConvertibleType+SharedSequence.swift b/Pods/RxCocoa/RxCocoa/Traits/SharedSequence/ObservableConvertibleType+SharedSequence.swift deleted file mode 100644 index 20ddf868f..000000000 --- a/Pods/RxCocoa/RxCocoa/Traits/SharedSequence/ObservableConvertibleType+SharedSequence.swift +++ /dev/null @@ -1,57 +0,0 @@ -// -// ObservableConvertibleType+SharedSequence.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 11/1/17. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - -extension ObservableConvertibleType { - /** - Converts anything convertible to `Observable` to `SharedSequence` unit. - - - parameter onErrorJustReturn: Element to return in case of error and after that complete the sequence. - - returns: Driving observable sequence. - */ - public func asSharedSequence(sharingStrategy: S.Type = S.self, onErrorJustReturn: Element) -> SharedSequence { - let source = self - .asObservable() - .observe(on:S.scheduler) - .catchAndReturn(onErrorJustReturn) - return SharedSequence(source) - } - - /** - Converts anything convertible to `Observable` to `SharedSequence` unit. - - - parameter onErrorDriveWith: SharedSequence that provides elements of the sequence in case of error. - - returns: Driving observable sequence. - */ - public func asSharedSequence(sharingStrategy: S.Type = S.self, onErrorDriveWith: SharedSequence) -> SharedSequence { - let source = self - .asObservable() - .observe(on:S.scheduler) - .catch { _ in - onErrorDriveWith.asObservable() - } - return SharedSequence(source) - } - - /** - Converts anything convertible to `Observable` to `SharedSequence` unit. - - - parameter onErrorRecover: Calculates driver that continues to drive the sequence in case of error. - - returns: Driving observable sequence. - */ - public func asSharedSequence(sharingStrategy: S.Type = S.self, onErrorRecover: @escaping (_ error: Swift.Error) -> SharedSequence) -> SharedSequence { - let source = self - .asObservable() - .observe(on:S.scheduler) - .catch { error in - onErrorRecover(error).asObservable() - } - return SharedSequence(source) - } -} diff --git a/Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SchedulerType+SharedSequence.swift b/Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SchedulerType+SharedSequence.swift deleted file mode 100644 index 5111e06d8..000000000 --- a/Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SchedulerType+SharedSequence.swift +++ /dev/null @@ -1,62 +0,0 @@ -// -// SchedulerType+SharedSequence.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 8/27/17. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - -public enum SharingScheduler { - /// Default scheduler used in SharedSequence based traits. - public private(set) static var make: () -> SchedulerType = { MainScheduler() } - - /** - This method can be used in unit tests to ensure that built in shared sequences are using mock schedulers instead - of main schedulers. - - **This shouldn't be used in normal release builds.** - */ - static public func mock(scheduler: SchedulerType, action: () throws -> Void) rethrows { - return try mock(makeScheduler: { scheduler }, action: action) - } - - /** - This method can be used in unit tests to ensure that built in shared sequences are using mock schedulers instead - of main schedulers. - - **This shouldn't be used in normal release builds.** - */ - static public func mock(makeScheduler: @escaping () -> SchedulerType, action: () throws -> Void) rethrows { - let originalMake = make - make = makeScheduler - defer { - make = originalMake - } - - try action() - - // If you remove this line , compiler buggy optimizations will change behavior of this code - _forceCompilerToStopDoingInsaneOptimizationsThatBreakCode(makeScheduler) - // Scary, I know - } -} - -#if os(Linux) - import Glibc -#else - import Foundation -#endif - -func _forceCompilerToStopDoingInsaneOptimizationsThatBreakCode(_ scheduler: () -> SchedulerType) { - let a: Int32 = 1 -#if os(Linux) - let b = 314 + Int32(Glibc.random() & 1) -#else - let b = 314 + Int32(arc4random() & 1) -#endif - if a == b { - print(scheduler()) - } -} diff --git a/Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SharedSequence+Operators+arity.swift b/Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SharedSequence+Operators+arity.swift deleted file mode 100644 index 4cc967cfb..000000000 --- a/Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SharedSequence+Operators+arity.swift +++ /dev/null @@ -1,656 +0,0 @@ -// This file is autogenerated. Take a look at `Preprocessor` target in RxSwift project -// -// SharedSequence+Operators+arity.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 10/14/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - - - -// 2 - -extension SharedSequence { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index. - - - parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func zip - (_ source1: O1, _ source2: O2, resultSelector: @escaping (O1.Element, O2.Element) throws -> Element) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy { - let source = Observable.zip( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), - resultSelector: resultSelector - ) - - return SharedSequence(source) - } -} - -extension SharedSequenceConvertibleType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of element tuples whenever all of the observable sequences have produced an element at a corresponding index. - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func zip - (_ source1: O1, _ source2: O2) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy { - let source = Observable.zip( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable() - ) - - return SharedSequence(source) - } -} - -extension SharedSequence { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element. - - - parameter resultSelector: Function to invoke whenever any of the sources produces an element. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, resultSelector: @escaping (O1.Element, O2.Element) throws -> Element) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy { - let source = Observable.combineLatest( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), - resultSelector: resultSelector - ) - - return SharedSequence(source) - } -} - -extension SharedSequenceConvertibleType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of element tuples whenever any of the observable sequences produces an element. - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy { - let source = Observable.combineLatest( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable() - ) - - return SharedSequence(source) - } -} - - - -// 3 - -extension SharedSequence { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index. - - - parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, resultSelector: @escaping (O1.Element, O2.Element, O3.Element) throws -> Element) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy { - let source = Observable.zip( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), - resultSelector: resultSelector - ) - - return SharedSequence(source) - } -} - -extension SharedSequenceConvertibleType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of element tuples whenever all of the observable sequences have produced an element at a corresponding index. - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy { - let source = Observable.zip( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable() - ) - - return SharedSequence(source) - } -} - -extension SharedSequence { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element. - - - parameter resultSelector: Function to invoke whenever any of the sources produces an element. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, resultSelector: @escaping (O1.Element, O2.Element, O3.Element) throws -> Element) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy { - let source = Observable.combineLatest( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), - resultSelector: resultSelector - ) - - return SharedSequence(source) - } -} - -extension SharedSequenceConvertibleType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of element tuples whenever any of the observable sequences produces an element. - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy { - let source = Observable.combineLatest( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable() - ) - - return SharedSequence(source) - } -} - - - -// 4 - -extension SharedSequence { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index. - - - parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element) throws -> Element) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy, - SharingStrategy == O4.SharingStrategy { - let source = Observable.zip( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), - resultSelector: resultSelector - ) - - return SharedSequence(source) - } -} - -extension SharedSequenceConvertibleType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of element tuples whenever all of the observable sequences have produced an element at a corresponding index. - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy, - SharingStrategy == O4.SharingStrategy { - let source = Observable.zip( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable() - ) - - return SharedSequence(source) - } -} - -extension SharedSequence { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element. - - - parameter resultSelector: Function to invoke whenever any of the sources produces an element. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element) throws -> Element) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy, - SharingStrategy == O4.SharingStrategy { - let source = Observable.combineLatest( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), - resultSelector: resultSelector - ) - - return SharedSequence(source) - } -} - -extension SharedSequenceConvertibleType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of element tuples whenever any of the observable sequences produces an element. - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy, - SharingStrategy == O4.SharingStrategy { - let source = Observable.combineLatest( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable() - ) - - return SharedSequence(source) - } -} - - - -// 5 - -extension SharedSequence { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index. - - - parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element) throws -> Element) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy, - SharingStrategy == O4.SharingStrategy, - SharingStrategy == O5.SharingStrategy { - let source = Observable.zip( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), - resultSelector: resultSelector - ) - - return SharedSequence(source) - } -} - -extension SharedSequenceConvertibleType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of element tuples whenever all of the observable sequences have produced an element at a corresponding index. - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy, - SharingStrategy == O4.SharingStrategy, - SharingStrategy == O5.SharingStrategy { - let source = Observable.zip( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable() - ) - - return SharedSequence(source) - } -} - -extension SharedSequence { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element. - - - parameter resultSelector: Function to invoke whenever any of the sources produces an element. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element) throws -> Element) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy, - SharingStrategy == O4.SharingStrategy, - SharingStrategy == O5.SharingStrategy { - let source = Observable.combineLatest( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), - resultSelector: resultSelector - ) - - return SharedSequence(source) - } -} - -extension SharedSequenceConvertibleType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of element tuples whenever any of the observable sequences produces an element. - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy, - SharingStrategy == O4.SharingStrategy, - SharingStrategy == O5.SharingStrategy { - let source = Observable.combineLatest( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable() - ) - - return SharedSequence(source) - } -} - - - -// 6 - -extension SharedSequence { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index. - - - parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element) throws -> Element) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy, - SharingStrategy == O4.SharingStrategy, - SharingStrategy == O5.SharingStrategy, - SharingStrategy == O6.SharingStrategy { - let source = Observable.zip( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable(), - resultSelector: resultSelector - ) - - return SharedSequence(source) - } -} - -extension SharedSequenceConvertibleType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of element tuples whenever all of the observable sequences have produced an element at a corresponding index. - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy, - SharingStrategy == O4.SharingStrategy, - SharingStrategy == O5.SharingStrategy, - SharingStrategy == O6.SharingStrategy { - let source = Observable.zip( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable() - ) - - return SharedSequence(source) - } -} - -extension SharedSequence { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element. - - - parameter resultSelector: Function to invoke whenever any of the sources produces an element. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element) throws -> Element) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy, - SharingStrategy == O4.SharingStrategy, - SharingStrategy == O5.SharingStrategy, - SharingStrategy == O6.SharingStrategy { - let source = Observable.combineLatest( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable(), - resultSelector: resultSelector - ) - - return SharedSequence(source) - } -} - -extension SharedSequenceConvertibleType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of element tuples whenever any of the observable sequences produces an element. - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy, - SharingStrategy == O4.SharingStrategy, - SharingStrategy == O5.SharingStrategy, - SharingStrategy == O6.SharingStrategy { - let source = Observable.combineLatest( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable() - ) - - return SharedSequence(source) - } -} - - - -// 7 - -extension SharedSequence { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index. - - - parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element) throws -> Element) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy, - SharingStrategy == O4.SharingStrategy, - SharingStrategy == O5.SharingStrategy, - SharingStrategy == O6.SharingStrategy, - SharingStrategy == O7.SharingStrategy { - let source = Observable.zip( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable(), source7.asSharedSequence().asObservable(), - resultSelector: resultSelector - ) - - return SharedSequence(source) - } -} - -extension SharedSequenceConvertibleType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of element tuples whenever all of the observable sequences have produced an element at a corresponding index. - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy, - SharingStrategy == O4.SharingStrategy, - SharingStrategy == O5.SharingStrategy, - SharingStrategy == O6.SharingStrategy, - SharingStrategy == O7.SharingStrategy { - let source = Observable.zip( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable(), source7.asSharedSequence().asObservable() - ) - - return SharedSequence(source) - } -} - -extension SharedSequence { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element. - - - parameter resultSelector: Function to invoke whenever any of the sources produces an element. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element) throws -> Element) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy, - SharingStrategy == O4.SharingStrategy, - SharingStrategy == O5.SharingStrategy, - SharingStrategy == O6.SharingStrategy, - SharingStrategy == O7.SharingStrategy { - let source = Observable.combineLatest( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable(), source7.asSharedSequence().asObservable(), - resultSelector: resultSelector - ) - - return SharedSequence(source) - } -} - -extension SharedSequenceConvertibleType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of element tuples whenever any of the observable sequences produces an element. - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy, - SharingStrategy == O4.SharingStrategy, - SharingStrategy == O5.SharingStrategy, - SharingStrategy == O6.SharingStrategy, - SharingStrategy == O7.SharingStrategy { - let source = Observable.combineLatest( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable(), source7.asSharedSequence().asObservable() - ) - - return SharedSequence(source) - } -} - - - -// 8 - -extension SharedSequence { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index. - - - parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, _ source8: O8, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element, O8.Element) throws -> Element) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy, - SharingStrategy == O4.SharingStrategy, - SharingStrategy == O5.SharingStrategy, - SharingStrategy == O6.SharingStrategy, - SharingStrategy == O7.SharingStrategy, - SharingStrategy == O8.SharingStrategy { - let source = Observable.zip( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable(), source7.asSharedSequence().asObservable(), source8.asSharedSequence().asObservable(), - resultSelector: resultSelector - ) - - return SharedSequence(source) - } -} - -extension SharedSequenceConvertibleType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of element tuples whenever all of the observable sequences have produced an element at a corresponding index. - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, _ source8: O8) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy, - SharingStrategy == O4.SharingStrategy, - SharingStrategy == O5.SharingStrategy, - SharingStrategy == O6.SharingStrategy, - SharingStrategy == O7.SharingStrategy, - SharingStrategy == O8.SharingStrategy { - let source = Observable.zip( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable(), source7.asSharedSequence().asObservable(), source8.asSharedSequence().asObservable() - ) - - return SharedSequence(source) - } -} - -extension SharedSequence { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element. - - - parameter resultSelector: Function to invoke whenever any of the sources produces an element. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, _ source8: O8, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element, O8.Element) throws -> Element) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy, - SharingStrategy == O4.SharingStrategy, - SharingStrategy == O5.SharingStrategy, - SharingStrategy == O6.SharingStrategy, - SharingStrategy == O7.SharingStrategy, - SharingStrategy == O8.SharingStrategy { - let source = Observable.combineLatest( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable(), source7.asSharedSequence().asObservable(), source8.asSharedSequence().asObservable(), - resultSelector: resultSelector - ) - - return SharedSequence(source) - } -} - -extension SharedSequenceConvertibleType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of element tuples whenever any of the observable sequences produces an element. - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, _ source8: O8) - -> SharedSequence where SharingStrategy == O1.SharingStrategy, - SharingStrategy == O2.SharingStrategy, - SharingStrategy == O3.SharingStrategy, - SharingStrategy == O4.SharingStrategy, - SharingStrategy == O5.SharingStrategy, - SharingStrategy == O6.SharingStrategy, - SharingStrategy == O7.SharingStrategy, - SharingStrategy == O8.SharingStrategy { - let source = Observable.combineLatest( - source1.asSharedSequence().asObservable(), source2.asSharedSequence().asObservable(), source3.asSharedSequence().asObservable(), source4.asSharedSequence().asObservable(), source5.asSharedSequence().asObservable(), source6.asSharedSequence().asObservable(), source7.asSharedSequence().asObservable(), source8.asSharedSequence().asObservable() - ) - - return SharedSequence(source) - } -} - - diff --git a/Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SharedSequence+Operators.swift b/Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SharedSequence+Operators.swift deleted file mode 100644 index 45383ef05..000000000 --- a/Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SharedSequence+Operators.swift +++ /dev/null @@ -1,585 +0,0 @@ -// -// SharedSequence+Operators.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 9/19/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - -// MARK: map -extension SharedSequenceConvertibleType { - - /** - Projects each element of an observable sequence into a new form. - - - parameter selector: A transform function to apply to each source element. - - returns: An observable sequence whose elements are the result of invoking the transform function on each element of source. - */ - public func map(_ selector: @escaping (Element) -> Result) -> SharedSequence { - let source = self - .asObservable() - .map(selector) - return SharedSequence(source) - } -} - -// MARK: compactMap -extension SharedSequenceConvertibleType { - - /** - Projects each element of an observable sequence into an optional form and filters all optional results. - - - parameter transform: A transform function to apply to each source element and which returns an element or nil. - - returns: An observable sequence whose elements are the result of filtering the transform function for each element of the source. - - */ - public func compactMap(_ selector: @escaping (Element) -> Result?) -> SharedSequence { - let source = self - .asObservable() - .compactMap(selector) - return SharedSequence(source) - } -} - -// MARK: filter -extension SharedSequenceConvertibleType { - /** - Filters the elements of an observable sequence based on a predicate. - - - parameter predicate: A function to test each source element for a condition. - - returns: An observable sequence that contains elements from the input sequence that satisfy the condition. - */ - public func filter(_ predicate: @escaping (Element) -> Bool) -> SharedSequence { - let source = self - .asObservable() - .filter(predicate) - return SharedSequence(source) - } -} - -// MARK: switchLatest -extension SharedSequenceConvertibleType where Element: SharedSequenceConvertibleType { - - /** - Transforms an observable sequence of observable sequences into an observable sequence - producing values only from the most recent observable sequence. - - Each time a new inner observable sequence is received, unsubscribe from the - previous inner observable sequence. - - - returns: The observable sequence that at any point in time produces the elements of the most recent inner observable sequence that has been received. - */ - public func switchLatest() -> SharedSequence { - let source: Observable = self - .asObservable() - .map { $0.asSharedSequence() } - .switchLatest() - return SharedSequence(source) - } -} - -// MARK: flatMapLatest -extension SharedSequenceConvertibleType { - /** - Projects each element of an observable sequence into a new sequence of observable sequences and then - transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence. - - It is a combination of `map` + `switchLatest` operator - - - parameter selector: A transform function to apply to each element. - - returns: An observable sequence whose elements are the result of invoking the transform function on each element of source producing an - Observable of Observable sequences and that at any point in time produces the elements of the most recent inner observable sequence that has been received. - */ - public func flatMapLatest(_ selector: @escaping (Element) -> SharedSequence) - -> SharedSequence { - let source: Observable = self - .asObservable() - .flatMapLatest(selector) - return SharedSequence(source) - } -} - -// MARK: flatMapFirst -extension SharedSequenceConvertibleType { - - /** - Projects each element of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence. - If element is received while there is some projected observable sequence being merged it will simply be ignored. - - - parameter selector: A transform function to apply to element that was observed while no observable is executing in parallel. - - returns: An observable sequence whose elements are the result of invoking the one-to-many transform function on each element of the input sequence that was received while no other sequence was being calculated. - */ - public func flatMapFirst(_ selector: @escaping (Element) -> SharedSequence) - -> SharedSequence { - let source: Observable = self - .asObservable() - .flatMapFirst(selector) - return SharedSequence(source) - } -} - -// MARK: do -extension SharedSequenceConvertibleType { - /** - Invokes an action for each event in the observable sequence, and propagates all observer messages through the result sequence. - - - parameter onNext: Action to invoke for each element in the observable sequence. - - parameter afterNext: Action to invoke for each element after the observable has passed an onNext event along to its downstream. - - parameter onCompleted: Action to invoke upon graceful termination of the observable sequence. - - parameter afterCompleted: Action to invoke after graceful termination of the observable sequence. - - parameter onSubscribe: Action to invoke before subscribing to source observable sequence. - - parameter onSubscribed: Action to invoke after subscribing to source observable sequence. - - parameter onDispose: Action to invoke after subscription to source observable has been disposed for any reason. It can be either because sequence terminates for some reason or observer subscription being disposed. - - returns: The source sequence with the side-effecting behavior applied. - */ - public func `do`(onNext: ((Element) -> Void)? = nil, afterNext: ((Element) -> Void)? = nil, onCompleted: (() -> Void)? = nil, afterCompleted: (() -> Void)? = nil, onSubscribe: (() -> Void)? = nil, onSubscribed: (() -> Void)? = nil, onDispose: (() -> Void)? = nil) - -> SharedSequence { - let source = self.asObservable() - .do(onNext: onNext, afterNext: afterNext, onCompleted: onCompleted, afterCompleted: afterCompleted, onSubscribe: onSubscribe, onSubscribed: onSubscribed, onDispose: onDispose) - - return SharedSequence(source) - } -} - -// MARK: debug -extension SharedSequenceConvertibleType { - - /** - Prints received events for all observers on standard output. - - - parameter identifier: Identifier that is printed together with event description to standard output. - - returns: An observable sequence whose events are printed to standard output. - */ - public func debug(_ identifier: String? = nil, trimOutput: Bool = false, file: String = #file, line: UInt = #line, function: String = #function) -> SharedSequence { - let source = self.asObservable() - .debug(identifier, trimOutput: trimOutput, file: file, line: line, function: function) - return SharedSequence(source) - } -} - -// MARK: distinctUntilChanged -extension SharedSequenceConvertibleType where Element: Equatable { - - /** - Returns an observable sequence that contains only distinct contiguous elements according to equality operator. - - - returns: An observable sequence only containing the distinct contiguous elements, based on equality operator, from the source sequence. - */ - public func distinctUntilChanged() - -> SharedSequence { - let source = self.asObservable() - .distinctUntilChanged({ $0 }, comparer: { ($0 == $1) }) - - return SharedSequence(source) - } -} - -extension SharedSequenceConvertibleType { - - /** - Returns an observable sequence that contains only distinct contiguous elements according to the `keySelector`. - - - parameter keySelector: A function to compute the comparison key for each element. - - returns: An observable sequence only containing the distinct contiguous elements, based on a computed key value, from the source sequence. - */ - public func distinctUntilChanged(_ keySelector: @escaping (Element) -> Key) -> SharedSequence { - let source = self.asObservable() - .distinctUntilChanged(keySelector, comparer: { $0 == $1 }) - return SharedSequence(source) - } - - /** - Returns an observable sequence that contains only distinct contiguous elements according to the `comparer`. - - - parameter comparer: Equality comparer for computed key values. - - returns: An observable sequence only containing the distinct contiguous elements, based on `comparer`, from the source sequence. - */ - public func distinctUntilChanged(_ comparer: @escaping (Element, Element) -> Bool) -> SharedSequence { - let source = self.asObservable() - .distinctUntilChanged({ $0 }, comparer: comparer) - return SharedSequence(source) - } - - /** - Returns an observable sequence that contains only distinct contiguous elements according to the keySelector and the comparer. - - - parameter keySelector: A function to compute the comparison key for each element. - - parameter comparer: Equality comparer for computed key values. - - returns: An observable sequence only containing the distinct contiguous elements, based on a computed key value and the comparer, from the source sequence. - */ - public func distinctUntilChanged(_ keySelector: @escaping (Element) -> K, comparer: @escaping (K, K) -> Bool) -> SharedSequence { - let source = self.asObservable() - .distinctUntilChanged(keySelector, comparer: comparer) - return SharedSequence(source) - } -} - - -// MARK: flatMap -extension SharedSequenceConvertibleType { - - /** - Projects each element of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence. - - - parameter selector: A transform function to apply to each element. - - returns: An observable sequence whose elements are the result of invoking the one-to-many transform function on each element of the input sequence. - */ - public func flatMap(_ selector: @escaping (Element) -> SharedSequence) -> SharedSequence { - let source = self.asObservable() - .flatMap(selector) - - return SharedSequence(source) - } -} - -// MARK: merge -extension SharedSequenceConvertibleType { - /** - Merges elements from all observable sequences from collection into a single observable sequence. - - - seealso: [merge operator on reactivex.io](http://reactivex.io/documentation/operators/merge.html) - - - parameter sources: Collection of observable sequences to merge. - - returns: The observable sequence that merges the elements of the observable sequences. - */ - public static func merge(_ sources: Collection) -> SharedSequence - where Collection.Element == SharedSequence { - let source = Observable.merge(sources.map { $0.asObservable() }) - return SharedSequence(source) - } - - /** - Merges elements from all observable sequences from array into a single observable sequence. - - - seealso: [merge operator on reactivex.io](http://reactivex.io/documentation/operators/merge.html) - - - parameter sources: Array of observable sequences to merge. - - returns: The observable sequence that merges the elements of the observable sequences. - */ - public static func merge(_ sources: [SharedSequence]) -> SharedSequence { - let source = Observable.merge(sources.map { $0.asObservable() }) - return SharedSequence(source) - } - - /** - Merges elements from all observable sequences into a single observable sequence. - - - seealso: [merge operator on reactivex.io](http://reactivex.io/documentation/operators/merge.html) - - - parameter sources: Collection of observable sequences to merge. - - returns: The observable sequence that merges the elements of the observable sequences. - */ - public static func merge(_ sources: SharedSequence...) -> SharedSequence { - let source = Observable.merge(sources.map { $0.asObservable() }) - return SharedSequence(source) - } - -} - -// MARK: merge -extension SharedSequenceConvertibleType where Element: SharedSequenceConvertibleType { - /** - Merges elements from all observable sequences in the given enumerable sequence into a single observable sequence. - - - returns: The observable sequence that merges the elements of the observable sequences. - */ - public func merge() -> SharedSequence { - let source = self.asObservable() - .map { $0.asSharedSequence() } - .merge() - return SharedSequence(source) - } - - /** - Merges elements from all inner observable sequences into a single observable sequence, limiting the number of concurrent subscriptions to inner sequences. - - - parameter maxConcurrent: Maximum number of inner observable sequences being subscribed to concurrently. - - returns: The observable sequence that merges the elements of the inner sequences. - */ - public func merge(maxConcurrent: Int) - -> SharedSequence { - let source = self.asObservable() - .map { $0.asSharedSequence() } - .merge(maxConcurrent: maxConcurrent) - return SharedSequence(source) - } -} - -// MARK: throttle -extension SharedSequenceConvertibleType { - - /** - Returns an Observable that emits the first and the latest item emitted by the source Observable during sequential time windows of a specified duration. - - This operator makes sure that no two elements are emitted in less then dueTime. - - - seealso: [debounce operator on reactivex.io](http://reactivex.io/documentation/operators/debounce.html) - - - parameter dueTime: Throttling duration for each element. - - parameter latest: Should latest element received in a dueTime wide time window since last element emission be emitted. - - returns: The throttled sequence. - */ - public func throttle(_ dueTime: RxTimeInterval, latest: Bool = true) - -> SharedSequence { - let source = self.asObservable() - .throttle(dueTime, latest: latest, scheduler: SharingStrategy.scheduler) - - return SharedSequence(source) - } - - /** - Ignores elements from an observable sequence which are followed by another element within a specified relative time duration, using the specified scheduler to run throttling timers. - - - parameter dueTime: Throttling duration for each element. - - returns: The throttled sequence. - */ - public func debounce(_ dueTime: RxTimeInterval) - -> SharedSequence { - let source = self.asObservable() - .debounce(dueTime, scheduler: SharingStrategy.scheduler) - - return SharedSequence(source) - } -} - -// MARK: scan -extension SharedSequenceConvertibleType { - /** - Applies an accumulator function over an observable sequence and returns each intermediate result. The specified seed value is used as the initial accumulator value. - - For aggregation behavior with no intermediate results, see `reduce`. - - - parameter seed: The initial accumulator value. - - parameter accumulator: An accumulator function to be invoked on each element. - - returns: An observable sequence containing the accumulated values. - */ - public func scan(_ seed: A, accumulator: @escaping (A, Element) -> A) - -> SharedSequence { - let source = self.asObservable() - .scan(seed, accumulator: accumulator) - return SharedSequence(source) - } -} - -// MARK: concat - -extension SharedSequence { - /** - Concatenates all observable sequences in the given sequence, as long as the previous observable sequence terminated successfully. - - - returns: An observable sequence that contains the elements of each given sequence, in sequential order. - */ - public static func concat(_ sequence: Sequence) -> SharedSequence - where Sequence.Element == SharedSequence { - let source = Observable.concat(sequence.lazy.map { $0.asObservable() }) - return SharedSequence(source) - } - - /** - Concatenates all observable sequences in the given sequence, as long as the previous observable sequence terminated successfully. - - - returns: An observable sequence that contains the elements of each given sequence, in sequential order. - */ - public static func concat(_ collection: Collection) -> SharedSequence - where Collection.Element == SharedSequence { - let source = Observable.concat(collection.map { $0.asObservable() }) - return SharedSequence(source) - } -} - -// MARK: zip - -extension SharedSequence { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index. - - - parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func zip(_ collection: Collection, resultSelector: @escaping ([Element]) throws -> Result) -> SharedSequence - where Collection.Element == SharedSequence { - let source = Observable.zip(collection.map { $0.asSharedSequence().asObservable() }, resultSelector: resultSelector) - return SharedSequence(source) - } - - /** - Merges the specified observable sequences into one observable sequence all of the observable sequences have produced an element at a corresponding index. - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func zip(_ collection: Collection) -> SharedSequence - where Collection.Element == SharedSequence { - let source = Observable.zip(collection.map { $0.asSharedSequence().asObservable() }) - return SharedSequence(source) - } -} - -// MARK: combineLatest - -extension SharedSequence { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element. - - - parameter resultSelector: Function to invoke whenever any of the sources produces an element. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func combineLatest(_ collection: Collection, resultSelector: @escaping ([Element]) throws -> Result) -> SharedSequence - where Collection.Element == SharedSequence { - let source = Observable.combineLatest(collection.map { $0.asObservable() }, resultSelector: resultSelector) - return SharedSequence(source) - } - - /** - Merges the specified observable sequences into one observable sequence whenever any of the observable sequences produces an element. - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func combineLatest(_ collection: Collection) -> SharedSequence - where Collection.Element == SharedSequence { - let source = Observable.combineLatest(collection.map { $0.asObservable() }) - return SharedSequence(source) - } -} - -// MARK: - withUnretained -extension SharedSequenceConvertibleType where SharingStrategy == SignalSharingStrategy { - /** - Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence. - - In the case the provided object cannot be retained successfully, the seqeunce will complete. - - - note: Be careful when using this operator in a sequence that has a buffer or replay, for example `share(replay: 1)`, as the sharing buffer will also include the provided object, which could potentially cause a retain cycle. - - - parameter obj: The object to provide an unretained reference on. - - parameter resultSelector: A function to combine the unretained referenced on `obj` and the value of the observable sequence. - - returns: An observable sequence that contains the result of `resultSelector` being called with an unretained reference on `obj` and the values of the original sequence. - */ - public func withUnretained( - _ obj: Object, - resultSelector: @escaping (Object, Element) -> Out - ) -> SharedSequence { - SharedSequence(self.asObservable().withUnretained(obj, resultSelector: resultSelector)) - } - - /** - Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence. - - In the case the provided object cannot be retained successfully, the seqeunce will complete. - - - note: Be careful when using this operator in a sequence that has a buffer or replay, for example `share(replay: 1)`, as the sharing buffer will also include the provided object, which could potentially cause a retain cycle. - - - parameter obj: The object to provide an unretained reference on. - - returns: An observable sequence of tuples that contains both an unretained reference on `obj` and the values of the original sequence. - */ - public func withUnretained(_ obj: Object) -> SharedSequence { - withUnretained(obj) { ($0, $1) } - } -} - -extension SharedSequenceConvertibleType where SharingStrategy == DriverSharingStrategy { - @available(*, message: "withUnretained has been deprecated for Driver. Consider using `drive(with:onNext:onCompleted:onDisposed:)`, instead", unavailable) - public func withUnretained( - _ obj: Object, - resultSelector: @escaping (Object, Element) -> Out - ) -> SharedSequence { - SharedSequence(self.asObservable().withUnretained(obj, resultSelector: resultSelector)) - } - - @available(*, message: "withUnretained has been deprecated for Driver. Consider using `drive(with:onNext:onCompleted:onDisposed:)`, instead", unavailable) - public func withUnretained(_ obj: Object) -> SharedSequence { - SharedSequence(self.asObservable().withUnretained(obj) { ($0, $1) }) - } -} - -// MARK: withLatestFrom -extension SharedSequenceConvertibleType { - - /** - Merges two observable sequences into one observable sequence by combining each element from self with the latest element from the second source, if any. - - - parameter second: Second observable source. - - parameter resultSelector: Function to invoke for each element from the self combined with the latest element from the second source, if any. - - returns: An observable sequence containing the result of combining each element of the self with the latest element from the second source, if any, using the specified result selector function. - */ - public func withLatestFrom(_ second: SecondO, resultSelector: @escaping (Element, SecondO.Element) -> ResultType) -> SharedSequence where SecondO.SharingStrategy == SharingStrategy { - let source = self.asObservable() - .withLatestFrom(second.asSharedSequence(), resultSelector: resultSelector) - - return SharedSequence(source) - } - - /** - Merges two observable sequences into one observable sequence by using latest element from the second sequence every time when `self` emits an element. - - - parameter second: Second observable source. - - returns: An observable sequence containing the result of combining each element of the self with the latest element from the second source, if any, using the specified result selector function. - */ - public func withLatestFrom(_ second: SecondO) -> SharedSequence { - let source = self.asObservable() - .withLatestFrom(second.asSharedSequence()) - - return SharedSequence(source) - } -} - -// MARK: skip -extension SharedSequenceConvertibleType { - - /** - Bypasses a specified number of elements in an observable sequence and then returns the remaining elements. - - - seealso: [skip operator on reactivex.io](http://reactivex.io/documentation/operators/skip.html) - - - parameter count: The number of elements to skip before returning the remaining elements. - - returns: An observable sequence that contains the elements that occur after the specified index in the input sequence. - */ - public func skip(_ count: Int) - -> SharedSequence { - let source = self.asObservable() - .skip(count) - return SharedSequence(source) - } -} - -// MARK: startWith -extension SharedSequenceConvertibleType { - - /** - Prepends a value to an observable sequence. - - - seealso: [startWith operator on reactivex.io](http://reactivex.io/documentation/operators/startwith.html) - - - parameter element: Element to prepend to the specified sequence. - - returns: The source sequence prepended with the specified values. - */ - public func startWith(_ element: Element) - -> SharedSequence { - let source = self.asObservable() - .startWith(element) - - return SharedSequence(source) - } -} - -// MARK: delay -extension SharedSequenceConvertibleType { - - /** - Returns an observable sequence by the source observable sequence shifted forward in time by a specified delay. Error events from the source observable sequence are not delayed. - - - seealso: [delay operator on reactivex.io](http://reactivex.io/documentation/operators/delay.html) - - - parameter dueTime: Relative time shift of the source by. - - parameter scheduler: Scheduler to run the subscription delay timer on. - - returns: the source Observable shifted in time by the specified delay. - */ - public func delay(_ dueTime: RxTimeInterval) - -> SharedSequence { - let source = self.asObservable() - .delay(dueTime, scheduler: SharingStrategy.scheduler) - - return SharedSequence(source) - } -} diff --git a/Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SharedSequence.swift b/Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SharedSequence.swift deleted file mode 100644 index 4db2ee49b..000000000 --- a/Pods/RxCocoa/RxCocoa/Traits/SharedSequence/SharedSequence.swift +++ /dev/null @@ -1,226 +0,0 @@ -// -// SharedSequence.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 8/27/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - -/** - Trait that represents observable sequence that shares computation resources with following properties: - - - it never fails - - it delivers events on `SharingStrategy.scheduler` - - sharing strategy is customizable using `SharingStrategy.share` behavior - - `SharedSequence` can be considered a builder pattern for observable sequences that share computation resources. - - To find out more about units and how to use them, please visit `Documentation/Traits.md`. -*/ -public struct SharedSequence : SharedSequenceConvertibleType, ObservableConvertibleType { - let source: Observable - - init(_ source: Observable) { - self.source = SharingStrategy.share(source) - } - - init(raw: Observable) { - self.source = raw - } - - #if EXPANDABLE_SHARED_SEQUENCE - /** - This method is extension hook in case this unit needs to extended from outside the library. - - By defining `EXPANDABLE_SHARED_SEQUENCE` one agrees that it's up to them to ensure shared sequence - properties are preserved after extension. - */ - public static func createUnsafe(source: Source) -> SharedSequence { - SharedSequence(raw: source.asObservable()) - } - #endif - - /** - - returns: Built observable sequence. - */ - public func asObservable() -> Observable { - self.source - } - - /** - - returns: `self` - */ - public func asSharedSequence() -> SharedSequence { - self - } -} - -/** - Different `SharedSequence` sharing strategies must conform to this protocol. - */ -public protocol SharingStrategyProtocol { - /** - Scheduled on which all sequence events will be delivered. - */ - static var scheduler: SchedulerType { get } - - /** - Computation resources sharing strategy for multiple sequence observers. - - E.g. One can choose `share(replay:scope:)` - as sequence event sharing strategies, but also do something more exotic, like - implementing promises or lazy loading chains. - */ - static func share(_ source: Observable) -> Observable -} - -/** -A type that can be converted to `SharedSequence`. -*/ -public protocol SharedSequenceConvertibleType : ObservableConvertibleType { - associatedtype SharingStrategy: SharingStrategyProtocol - - /** - Converts self to `SharedSequence`. - */ - func asSharedSequence() -> SharedSequence -} - -extension SharedSequenceConvertibleType { - public func asObservable() -> Observable { - self.asSharedSequence().asObservable() - } -} - - -extension SharedSequence { - - /** - Returns an empty observable sequence, using the specified scheduler to send out the single `Completed` message. - - - returns: An observable sequence with no elements. - */ - public static func empty() -> SharedSequence { - SharedSequence(raw: Observable.empty().subscribe(on: SharingStrategy.scheduler)) - } - - /** - Returns a non-terminating observable sequence, which can be used to denote an infinite duration. - - - returns: An observable sequence whose observers will never get called. - */ - public static func never() -> SharedSequence { - SharedSequence(raw: Observable.never()) - } - - /** - Returns an observable sequence that contains a single element. - - - parameter element: Single element in the resulting observable sequence. - - returns: An observable sequence containing the single specified element. - */ - public static func just(_ element: Element) -> SharedSequence { - SharedSequence(raw: Observable.just(element).subscribe(on: SharingStrategy.scheduler)) - } - - /** - Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes. - - - parameter observableFactory: Observable factory function to invoke for each observer that subscribes to the resulting sequence. - - returns: An observable sequence whose observers trigger an invocation of the given observable factory function. - */ - public static func deferred(_ observableFactory: @escaping () -> SharedSequence) - -> SharedSequence { - SharedSequence(Observable.deferred { observableFactory().asObservable() }) - } - - /** - This method creates a new Observable instance with a variable number of elements. - - - seealso: [from operator on reactivex.io](http://reactivex.io/documentation/operators/from.html) - - - parameter elements: Elements to generate. - - returns: The observable sequence whose elements are pulled from the given arguments. - */ - public static func of(_ elements: Element ...) -> SharedSequence { - let source = Observable.from(elements, scheduler: SharingStrategy.scheduler) - return SharedSequence(raw: source) - } -} - -extension SharedSequence { - - /** - This method converts an array to an observable sequence. - - - seealso: [from operator on reactivex.io](http://reactivex.io/documentation/operators/from.html) - - - returns: The observable sequence whose elements are pulled from the given enumerable sequence. - */ - public static func from(_ array: [Element]) -> SharedSequence { - let source = Observable.from(array, scheduler: SharingStrategy.scheduler) - return SharedSequence(raw: source) - } - - /** - This method converts a sequence to an observable sequence. - - - seealso: [from operator on reactivex.io](http://reactivex.io/documentation/operators/from.html) - - - returns: The observable sequence whose elements are pulled from the given enumerable sequence. - */ - public static func from(_ sequence: Sequence) -> SharedSequence where Sequence.Element == Element { - let source = Observable.from(sequence, scheduler: SharingStrategy.scheduler) - return SharedSequence(raw: source) - } - - /** - This method converts a optional to an observable sequence. - - - seealso: [from operator on reactivex.io](http://reactivex.io/documentation/operators/from.html) - - - parameter optional: Optional element in the resulting observable sequence. - - - returns: An observable sequence containing the wrapped value or not from given optional. - */ - public static func from(optional: Element?) -> SharedSequence { - let source = Observable.from(optional: optional, scheduler: SharingStrategy.scheduler) - return SharedSequence(raw: source) - } -} - -extension SharedSequence where Element: RxAbstractInteger { - /** - Returns an observable sequence that produces a value after each period, using the specified scheduler to run timers and to send out observer messages. - - - seealso: [interval operator on reactivex.io](http://reactivex.io/documentation/operators/interval.html) - - - parameter period: Period for producing the values in the resulting sequence. - - returns: An observable sequence that produces a value after each period. - */ - public static func interval(_ period: RxTimeInterval) - -> SharedSequence { - SharedSequence(Observable.interval(period, scheduler: SharingStrategy.scheduler)) - } -} - -// MARK: timer - -extension SharedSequence where Element: RxAbstractInteger { - /** - Returns an observable sequence that periodically produces a value after the specified initial relative due time has elapsed, using the specified scheduler to run timers. - - - seealso: [timer operator on reactivex.io](http://reactivex.io/documentation/operators/timer.html) - - - parameter dueTime: Relative time at which to produce the first value. - - parameter period: Period to produce subsequent values. - - returns: An observable sequence that produces a value after due time has elapsed and then each period. - */ - public static func timer(_ dueTime: RxTimeInterval, period: RxTimeInterval) - -> SharedSequence { - SharedSequence(Observable.timer(dueTime, period: period, scheduler: SharingStrategy.scheduler)) - } -} - diff --git a/Pods/RxCocoa/RxCocoa/Traits/Signal/ControlEvent+Signal.swift b/Pods/RxCocoa/RxCocoa/Traits/Signal/ControlEvent+Signal.swift deleted file mode 100644 index bec4723d4..000000000 --- a/Pods/RxCocoa/RxCocoa/Traits/Signal/ControlEvent+Signal.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// ControlEvent+Signal.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 11/1/17. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - -extension ControlEvent { - /// Converts `ControlEvent` to `Signal` trait. - /// - /// `ControlEvent` already can't fail, so no special case needs to be handled. - public func asSignal() -> Signal { - return self.asSignal { _ -> Signal in - #if DEBUG - rxFatalError("Somehow signal received error from a source that shouldn't fail.") - #else - return Signal.empty() - #endif - } - } -} - diff --git a/Pods/RxCocoa/RxCocoa/Traits/Signal/ObservableConvertibleType+Signal.swift b/Pods/RxCocoa/RxCocoa/Traits/Signal/ObservableConvertibleType+Signal.swift deleted file mode 100644 index b962d4ed0..000000000 --- a/Pods/RxCocoa/RxCocoa/Traits/Signal/ObservableConvertibleType+Signal.swift +++ /dev/null @@ -1,57 +0,0 @@ -// -// ObservableConvertibleType+Signal.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 9/19/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - -extension ObservableConvertibleType { - /** - Converts observable sequence to `Signal` trait. - - - parameter onErrorJustReturn: Element to return in case of error and after that complete the sequence. - - returns: Signal trait. - */ - public func asSignal(onErrorJustReturn: Element) -> Signal { - let source = self - .asObservable() - .observe(on: SignalSharingStrategy.scheduler) - .catchAndReturn(onErrorJustReturn) - return Signal(source) - } - - /** - Converts observable sequence to `Signal` trait. - - - parameter onErrorSignalWith: Signal that continues to emit the sequence in case of error. - - returns: Signal trait. - */ - public func asSignal(onErrorSignalWith: Signal) -> Signal { - let source = self - .asObservable() - .observe(on: SignalSharingStrategy.scheduler) - .catch { _ in - onErrorSignalWith.asObservable() - } - return Signal(source) - } - - /** - Converts observable sequence to `Signal` trait. - - - parameter onErrorRecover: Calculates signal that continues to emit the sequence in case of error. - - returns: Signal trait. - */ - public func asSignal(onErrorRecover: @escaping (_ error: Swift.Error) -> Signal) -> Signal { - let source = self - .asObservable() - .observe(on: SignalSharingStrategy.scheduler) - .catch { error in - onErrorRecover(error).asObservable() - } - return Signal(source) - } -} diff --git a/Pods/RxCocoa/RxCocoa/Traits/Signal/PublishRelay+Signal.swift b/Pods/RxCocoa/RxCocoa/Traits/Signal/PublishRelay+Signal.swift deleted file mode 100644 index 79b975dbe..000000000 --- a/Pods/RxCocoa/RxCocoa/Traits/Signal/PublishRelay+Signal.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// PublishRelay+Signal.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 12/28/15. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -import RxSwift -import RxRelay - -extension PublishRelay { - /// Converts `PublishRelay` to `Signal`. - /// - /// - returns: Observable sequence. - public func asSignal() -> Signal { - let source = self.asObservable() - .observe(on:SignalSharingStrategy.scheduler) - return SharedSequence(source) - } -} diff --git a/Pods/RxCocoa/RxCocoa/Traits/Signal/Signal+Subscription.swift b/Pods/RxCocoa/RxCocoa/Traits/Signal/Signal+Subscription.swift deleted file mode 100644 index ce3f94bd7..000000000 --- a/Pods/RxCocoa/RxCocoa/Traits/Signal/Signal+Subscription.swift +++ /dev/null @@ -1,178 +0,0 @@ -// -// Signal+Subscription.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 9/19/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import RxSwift -import RxRelay - -extension SharedSequenceConvertibleType where SharingStrategy == SignalSharingStrategy { - /** - Creates new subscription and sends elements to observer. - - In this form it's equivalent to `subscribe` method, but it communicates intent better. - - - parameter to: Observers that receives events. - - returns: Disposable object that can be used to unsubscribe the observer from the subject. - */ - public func emit(to observers: Observer...) -> Disposable where Observer.Element == Element { - return self.asSharedSequence() - .asObservable() - .subscribe { event in - observers.forEach { $0.on(event) } - } - } - - /** - Creates new subscription and sends elements to observer. - - In this form it's equivalent to `subscribe` method, but it communicates intent better. - - - parameter to: Observers that receives events. - - returns: Disposable object that can be used to unsubscribe the observer from the subject. - */ - public func emit(to observers: Observer...) -> Disposable where Observer.Element == Element? { - return self.asSharedSequence() - .asObservable() - .map { $0 as Element? } - .subscribe { event in - observers.forEach { $0.on(event) } - } - } - - /** - Creates new subscription and sends elements to `BehaviorRelay`. - - parameter to: Target relays for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer from the relay. - */ - public func emit(to relays: BehaviorRelay...) -> Disposable { - return self.emit(onNext: { e in - relays.forEach { $0.accept(e) } - }) - } - - /** - Creates new subscription and sends elements to `BehaviorRelay`. - - parameter to: Target relays for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer from the relay. - */ - public func emit(to relays: BehaviorRelay...) -> Disposable { - return self.emit(onNext: { e in - relays.forEach { $0.accept(e) } - }) - } - - /** - Creates new subscription and sends elements to `PublishRelay`. - - - parameter to: Target relays for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer from the relay. - */ - public func emit(to relays: PublishRelay...) -> Disposable { - return self.emit(onNext: { e in - relays.forEach { $0.accept(e) } - }) - } - - /** - Creates new subscription and sends elements to `PublishRelay`. - - - parameter to: Target relay for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer from the relay. - */ - public func emit(to relays: PublishRelay...) -> Disposable { - return self.emit(onNext: { e in - relays.forEach { $0.accept(e) } - }) - } - - /** - Creates new subscription and sends elements to `ReplayRelay`. - - - parameter to: Target relays for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer from the relay. - */ - public func emit(to relays: ReplayRelay...) -> Disposable { - return self.emit(onNext: { e in - relays.forEach { $0.accept(e) } - }) - } - - /** - Creates new subscription and sends elements to `ReplayRelay`. - - - parameter to: Target relay for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer from the relay. - */ - public func emit(to relays: ReplayRelay...) -> Disposable { - return self.emit(onNext: { e in - relays.forEach { $0.accept(e) } - }) - } - - /** - Subscribes an element handler, a completion handler and disposed handler to an observable sequence. - - Also, take in an object and provide an unretained, safe to use (i.e. not implicitly unwrapped), reference to it along with the events emitted by the sequence. - - Error callback is not exposed because `Signal` can't error out. - - - Note: If `object` can't be retained, none of the other closures will be invoked. - - - parameter object: The object to provide an unretained reference on. - - parameter onNext: Action to invoke for each element in the observable sequence. - - parameter onCompleted: Action to invoke upon graceful termination of the observable sequence. - gracefully completed, errored, or if the generation is canceled by disposing subscription) - - parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has - gracefully completed, errored, or if the generation is canceled by disposing subscription) - - returns: Subscription object used to unsubscribe from the observable sequence. - */ - public func emit( - with object: Object, - onNext: ((Object, Element) -> Void)? = nil, - onCompleted: ((Object) -> Void)? = nil, - onDisposed: ((Object) -> Void)? = nil - ) -> Disposable { - self.asObservable().subscribe( - with: object, - onNext: onNext, - onCompleted: onCompleted, - onDisposed: onDisposed - ) - } - - /** - Subscribes an element handler, a completion handler and disposed handler to an observable sequence. - - Error callback is not exposed because `Signal` can't error out. - - - parameter onNext: Action to invoke for each element in the observable sequence. - - parameter onCompleted: Action to invoke upon graceful termination of the observable sequence. - gracefully completed, errored, or if the generation is canceled by disposing subscription) - - parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has - gracefully completed, errored, or if the generation is canceled by disposing subscription) - - returns: Subscription object used to unsubscribe from the observable sequence. - */ - public func emit( - onNext: ((Element) -> Void)? = nil, - onCompleted: (() -> Void)? = nil, - onDisposed: (() -> Void)? = nil - ) -> Disposable { - self.asObservable().subscribe(onNext: onNext, onCompleted: onCompleted, onDisposed: onDisposed) - } - - /** - Subscribes to this `Signal` with a no-op. - This method can be only called from `MainThread`. - - - note: This is an alias of `emit(onNext: nil, onCompleted: nil, onDisposed: nil)` used to fix an ambiguity bug in Swift: https://bugs.swift.org/browse/SR-13657 - - - returns: Subscription object used to unsubscribe from the observable sequence. - */ - public func emit() -> Disposable { - emit(onNext: nil, onCompleted: nil, onDisposed: nil) - } -} diff --git a/Pods/RxCocoa/RxCocoa/Traits/Signal/Signal.swift b/Pods/RxCocoa/RxCocoa/Traits/Signal/Signal.swift deleted file mode 100644 index e066b7ec2..000000000 --- a/Pods/RxCocoa/RxCocoa/Traits/Signal/Signal.swift +++ /dev/null @@ -1,45 +0,0 @@ -// -// Signal.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 9/26/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - -/** - Trait that represents observable sequence with following properties: - - - it never fails - - it delivers events on `MainScheduler.instance` - - `share(scope: .whileConnected)` sharing strategy - - Additional explanation: - - all observers share sequence computation resources - - there is no replaying of sequence elements on new observer subscription - - computation of elements is reference counted with respect to the number of observers - - if there are no subscribers, it will release sequence computation resources - - In case trait that models state propagation is required, please check `Driver`. - - `Signal` can be considered a builder pattern for observable sequences that model imperative events part of the application. - - To find out more about units and how to use them, please visit `Documentation/Traits.md`. - */ -public typealias Signal = SharedSequence - -public struct SignalSharingStrategy: SharingStrategyProtocol { - public static var scheduler: SchedulerType { SharingScheduler.make() } - - public static func share(_ source: Observable) -> Observable { - source.share(scope: .whileConnected) - } -} - -extension SharedSequenceConvertibleType where SharingStrategy == SignalSharingStrategy { - /// Adds `asPublisher` to `SharingSequence` with `PublishSharingStrategy`. - public func asSignal() -> Signal { - self.asSharedSequence() - } -} diff --git a/Pods/RxCocoa/RxCocoa/iOS/DataSources/RxCollectionViewReactiveArrayDataSource.swift b/Pods/RxCocoa/RxCocoa/iOS/DataSources/RxCollectionViewReactiveArrayDataSource.swift deleted file mode 100644 index 1acc998ae..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/DataSources/RxCollectionViewReactiveArrayDataSource.swift +++ /dev/null @@ -1,108 +0,0 @@ -// -// RxCollectionViewReactiveArrayDataSource.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 6/29/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -// objc monkey business -class _RxCollectionViewReactiveArrayDataSource - : NSObject - , UICollectionViewDataSource { - - @objc(numberOfSectionsInCollectionView:) - func numberOfSections(in: UICollectionView) -> Int { - 1 - } - - func _collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { - 0 - } - - func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { - _collectionView(collectionView, numberOfItemsInSection: section) - } - - fileprivate func _collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - rxAbstractMethod() - } - - func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - _collectionView(collectionView, cellForItemAt: indexPath) - } -} - -class RxCollectionViewReactiveArrayDataSourceSequenceWrapper - : RxCollectionViewReactiveArrayDataSource - , RxCollectionViewDataSourceType { - typealias Element = Sequence - - override init(cellFactory: @escaping CellFactory) { - super.init(cellFactory: cellFactory) - } - - func collectionView(_ collectionView: UICollectionView, observedEvent: Event) { - Binder(self) { collectionViewDataSource, sectionModels in - let sections = Array(sectionModels) - collectionViewDataSource.collectionView(collectionView, observedElements: sections) - }.on(observedEvent) - } -} - - -// Please take a look at `DelegateProxyType.swift` -class RxCollectionViewReactiveArrayDataSource - : _RxCollectionViewReactiveArrayDataSource - , SectionedViewDataSourceType { - - typealias CellFactory = (UICollectionView, Int, Element) -> UICollectionViewCell - - var itemModels: [Element]? - - func modelAtIndex(_ index: Int) -> Element? { - itemModels?[index] - } - - func model(at indexPath: IndexPath) throws -> Any { - precondition(indexPath.section == 0) - guard let item = itemModels?[indexPath.item] else { - throw RxCocoaError.itemsNotYetBound(object: self) - } - return item - } - - var cellFactory: CellFactory - - init(cellFactory: @escaping CellFactory) { - self.cellFactory = cellFactory - } - - // data source - - override func _collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { - itemModels?.count ?? 0 - } - - override func _collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - cellFactory(collectionView, indexPath.item, itemModels![indexPath.item]) - } - - // reactive - - func collectionView(_ collectionView: UICollectionView, observedElements: [Element]) { - self.itemModels = observedElements - - collectionView.reloadData() - - // workaround for http://stackoverflow.com/questions/39867325/ios-10-bug-uicollectionview-received-layout-attributes-for-a-cell-with-an-index - collectionView.collectionViewLayout.invalidateLayout() - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/DataSources/RxPickerViewAdapter.swift b/Pods/RxCocoa/RxCocoa/iOS/DataSources/RxPickerViewAdapter.swift deleted file mode 100644 index 53b847549..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/DataSources/RxPickerViewAdapter.swift +++ /dev/null @@ -1,92 +0,0 @@ -// -// RxPickerViewAdapter.swift -// RxCocoa -// -// Created by Sergey Shulga on 12/07/2017. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) - -import UIKit -import RxSwift - -class RxPickerViewArrayDataSource: NSObject, UIPickerViewDataSource, SectionedViewDataSourceType { - fileprivate var items: [T] = [] - - func model(at indexPath: IndexPath) throws -> Any { - guard items.indices ~= indexPath.row else { - throw RxCocoaError.itemsNotYetBound(object: self) - } - return items[indexPath.row] - } - - func numberOfComponents(in pickerView: UIPickerView) -> Int { - 1 - } - - func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { - items.count - } -} - -class RxPickerViewSequenceDataSource - : RxPickerViewArrayDataSource - , RxPickerViewDataSourceType { - typealias Element = Sequence - - func pickerView(_ pickerView: UIPickerView, observedEvent: Event) { - Binder(self) { dataSource, items in - dataSource.items = items - pickerView.reloadAllComponents() - } - .on(observedEvent.map(Array.init)) - } -} - -final class RxStringPickerViewAdapter - : RxPickerViewSequenceDataSource - , UIPickerViewDelegate { - - typealias TitleForRow = (Int, Sequence.Element) -> String? - private let titleForRow: TitleForRow - - init(titleForRow: @escaping TitleForRow) { - self.titleForRow = titleForRow - super.init() - } - - func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { - titleForRow(row, items[row]) - } -} - -final class RxAttributedStringPickerViewAdapter: RxPickerViewSequenceDataSource, UIPickerViewDelegate { - typealias AttributedTitleForRow = (Int, Sequence.Element) -> NSAttributedString? - private let attributedTitleForRow: AttributedTitleForRow - - init(attributedTitleForRow: @escaping AttributedTitleForRow) { - self.attributedTitleForRow = attributedTitleForRow - super.init() - } - - func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? { - attributedTitleForRow(row, items[row]) - } -} - -final class RxPickerViewAdapter: RxPickerViewSequenceDataSource, UIPickerViewDelegate { - typealias ViewForRow = (Int, Sequence.Element, UIView?) -> UIView - private let viewForRow: ViewForRow - - init(viewForRow: @escaping ViewForRow) { - self.viewForRow = viewForRow - super.init() - } - - func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView { - viewForRow(row, items[row], view) - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/DataSources/RxTableViewReactiveArrayDataSource.swift b/Pods/RxCocoa/RxCocoa/iOS/DataSources/RxTableViewReactiveArrayDataSource.swift deleted file mode 100644 index 6d612f327..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/DataSources/RxTableViewReactiveArrayDataSource.swift +++ /dev/null @@ -1,101 +0,0 @@ -// -// RxTableViewReactiveArrayDataSource.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 6/26/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -// objc monkey business -class _RxTableViewReactiveArrayDataSource - : NSObject - , UITableViewDataSource { - - func numberOfSections(in tableView: UITableView) -> Int { - 1 - } - - func _tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - 0 - } - - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - _tableView(tableView, numberOfRowsInSection: section) - } - - fileprivate func _tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - rxAbstractMethod() - } - - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - _tableView(tableView, cellForRowAt: indexPath) - } -} - - -class RxTableViewReactiveArrayDataSourceSequenceWrapper - : RxTableViewReactiveArrayDataSource - , RxTableViewDataSourceType { - typealias Element = Sequence - - override init(cellFactory: @escaping CellFactory) { - super.init(cellFactory: cellFactory) - } - - func tableView(_ tableView: UITableView, observedEvent: Event) { - Binder(self) { tableViewDataSource, sectionModels in - let sections = Array(sectionModels) - tableViewDataSource.tableView(tableView, observedElements: sections) - }.on(observedEvent) - } -} - -// Please take a look at `DelegateProxyType.swift` -class RxTableViewReactiveArrayDataSource - : _RxTableViewReactiveArrayDataSource - , SectionedViewDataSourceType { - typealias CellFactory = (UITableView, Int, Element) -> UITableViewCell - - var itemModels: [Element]? - - func modelAtIndex(_ index: Int) -> Element? { - itemModels?[index] - } - - func model(at indexPath: IndexPath) throws -> Any { - precondition(indexPath.section == 0) - guard let item = itemModels?[indexPath.item] else { - throw RxCocoaError.itemsNotYetBound(object: self) - } - return item - } - - let cellFactory: CellFactory - - init(cellFactory: @escaping CellFactory) { - self.cellFactory = cellFactory - } - - override func _tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - itemModels?.count ?? 0 - } - - override func _tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - cellFactory(tableView, indexPath.item, itemModels![indexPath.row]) - } - - // reactive - - func tableView(_ tableView: UITableView, observedElements: [Element]) { - self.itemModels = observedElements - - tableView.reloadData() - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/Events/ItemEvents.swift b/Pods/RxCocoa/RxCocoa/iOS/Events/ItemEvents.swift deleted file mode 100644 index aadf74980..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Events/ItemEvents.swift +++ /dev/null @@ -1,15 +0,0 @@ -// -// ItemEvents.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 6/20/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) -import UIKit - -public typealias ItemMovedEvent = (sourceIndex: IndexPath, destinationIndex: IndexPath) -public typealias WillDisplayCellEvent = (cell: UITableViewCell, indexPath: IndexPath) -public typealias DidEndDisplayingCellEvent = (cell: UITableViewCell, indexPath: IndexPath) -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/NSTextStorage+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/NSTextStorage+Rx.swift deleted file mode 100644 index ba3054761..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/NSTextStorage+Rx.swift +++ /dev/null @@ -1,35 +0,0 @@ -// -// NSTextStorage+Rx.swift -// RxCocoa -// -// Created by Segii Shulga on 12/30/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - import RxSwift - import UIKit - - extension Reactive where Base: NSTextStorage { - - /// Reactive wrapper for `delegate`. - /// - /// For more information take a look at `DelegateProxyType` protocol documentation. - public var delegate: DelegateProxy { - return RxTextStorageDelegateProxy.proxy(for: base) - } - - /// Reactive wrapper for `delegate` message. - public var didProcessEditingRangeChangeInLength: Observable<(editedMask: NSTextStorage.EditActions, editedRange: NSRange, delta: Int)> { - return delegate - .methodInvoked(#selector(NSTextStorageDelegate.textStorage(_:didProcessEditing:range:changeInLength:))) - .map { a in - let editedMask = NSTextStorage.EditActions(rawValue: try castOrThrow(UInt.self, a[1]) ) - let editedRange = try castOrThrow(NSValue.self, a[2]).rangeValue - let delta = try castOrThrow(Int.self, a[3]) - - return (editedMask, editedRange, delta) - } - } - } -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/Protocols/RxCollectionViewDataSourceType.swift b/Pods/RxCocoa/RxCocoa/iOS/Protocols/RxCollectionViewDataSourceType.swift deleted file mode 100644 index b098a9eda..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Protocols/RxCollectionViewDataSourceType.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// RxCollectionViewDataSourceType.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 6/29/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -/// Marks data source as `UICollectionView` reactive data source enabling it to be used with one of the `bindTo` methods. -public protocol RxCollectionViewDataSourceType /*: UICollectionViewDataSource*/ { - - /// Type of elements that can be bound to collection view. - associatedtype Element - - /// New observable sequence event observed. - /// - /// - parameter collectionView: Bound collection view. - /// - parameter observedEvent: Event - func collectionView(_ collectionView: UICollectionView, observedEvent: Event) -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/Protocols/RxPickerViewDataSourceType.swift b/Pods/RxCocoa/RxCocoa/iOS/Protocols/RxPickerViewDataSourceType.swift deleted file mode 100644 index 1f390bff1..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Protocols/RxPickerViewDataSourceType.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// RxPickerViewDataSourceType.swift -// RxCocoa -// -// Created by Sergey Shulga on 05/07/2017. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) - -import UIKit -import RxSwift - -/// Marks data source as `UIPickerView` reactive data source enabling it to be used with one of the `bindTo` methods. -public protocol RxPickerViewDataSourceType { - /// Type of elements that can be bound to picker view. - associatedtype Element - - /// New observable sequence event observed. - /// - /// - parameter pickerView: Bound picker view. - /// - parameter observedEvent: Event - func pickerView(_ pickerView: UIPickerView, observedEvent: Event) -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/Protocols/RxTableViewDataSourceType.swift b/Pods/RxCocoa/RxCocoa/iOS/Protocols/RxTableViewDataSourceType.swift deleted file mode 100644 index d59af9e40..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Protocols/RxTableViewDataSourceType.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// RxTableViewDataSourceType.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 6/26/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -/// Marks data source as `UITableView` reactive data source enabling it to be used with one of the `bindTo` methods. -public protocol RxTableViewDataSourceType /*: UITableViewDataSource*/ { - - /// Type of elements that can be bound to table view. - associatedtype Element - - /// New observable sequence event observed. - /// - /// - parameter tableView: Bound table view. - /// - parameter observedEvent: Event - func tableView(_ tableView: UITableView, observedEvent: Event) -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxCollectionViewDataSourcePrefetchingProxy.swift b/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxCollectionViewDataSourcePrefetchingProxy.swift deleted file mode 100644 index efb7554c7..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxCollectionViewDataSourcePrefetchingProxy.swift +++ /dev/null @@ -1,92 +0,0 @@ -// -// RxCollectionViewDataSourcePrefetchingProxy.swift -// RxCocoa -// -// Created by Rowan Livingstone on 2/15/18. -// Copyright © 2018 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -@available(iOS 10.0, tvOS 10.0, *) -extension UICollectionView: HasPrefetchDataSource { - public typealias PrefetchDataSource = UICollectionViewDataSourcePrefetching -} - -@available(iOS 10.0, tvOS 10.0, *) -private let collectionViewPrefetchDataSourceNotSet = CollectionViewPrefetchDataSourceNotSet() - -@available(iOS 10.0, tvOS 10.0, *) -private final class CollectionViewPrefetchDataSourceNotSet - : NSObject - , UICollectionViewDataSourcePrefetching { - - func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) {} - -} - -@available(iOS 10.0, tvOS 10.0, *) -open class RxCollectionViewDataSourcePrefetchingProxy - : DelegateProxy - , DelegateProxyType - , UICollectionViewDataSourcePrefetching { - - /// Typed parent object. - public weak private(set) var collectionView: UICollectionView? - - /// - parameter collectionView: Parent object for delegate proxy. - public init(collectionView: ParentObject) { - self.collectionView = collectionView - super.init(parentObject: collectionView, delegateProxy: RxCollectionViewDataSourcePrefetchingProxy.self) - } - - // Register known implementations - public static func registerKnownImplementations() { - self.register { RxCollectionViewDataSourcePrefetchingProxy(collectionView: $0) } - } - - private var _prefetchItemsPublishSubject: PublishSubject<[IndexPath]>? - - /// Optimized version used for observing prefetch items callbacks. - internal var prefetchItemsPublishSubject: PublishSubject<[IndexPath]> { - if let subject = _prefetchItemsPublishSubject { - return subject - } - - let subject = PublishSubject<[IndexPath]>() - _prefetchItemsPublishSubject = subject - - return subject - } - - private weak var _requiredMethodsPrefetchDataSource: UICollectionViewDataSourcePrefetching? = collectionViewPrefetchDataSourceNotSet - - // MARK: delegate - - /// Required delegate method implementation. - public func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) { - if let subject = _prefetchItemsPublishSubject { - subject.on(.next(indexPaths)) - } - - (_requiredMethodsPrefetchDataSource ?? collectionViewPrefetchDataSourceNotSet).collectionView(collectionView, prefetchItemsAt: indexPaths) - } - - /// For more information take a look at `DelegateProxyType`. - open override func setForwardToDelegate(_ forwardToDelegate: UICollectionViewDataSourcePrefetching?, retainDelegate: Bool) { - _requiredMethodsPrefetchDataSource = forwardToDelegate ?? collectionViewPrefetchDataSourceNotSet - super.setForwardToDelegate(forwardToDelegate, retainDelegate: retainDelegate) - } - - deinit { - if let subject = _prefetchItemsPublishSubject { - subject.on(.completed) - } - } - -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxCollectionViewDataSourceProxy.swift b/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxCollectionViewDataSourceProxy.swift deleted file mode 100644 index 793e54485..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxCollectionViewDataSourceProxy.swift +++ /dev/null @@ -1,76 +0,0 @@ -// -// RxCollectionViewDataSourceProxy.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 6/29/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -extension UICollectionView: HasDataSource { - public typealias DataSource = UICollectionViewDataSource -} - -private let collectionViewDataSourceNotSet = CollectionViewDataSourceNotSet() - -private final class CollectionViewDataSourceNotSet - : NSObject - , UICollectionViewDataSource { - - func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { - 0 - } - - // The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath: - func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - rxAbstractMethod(message: dataSourceNotSet) - } - -} - -/// For more information take a look at `DelegateProxyType`. -open class RxCollectionViewDataSourceProxy - : DelegateProxy - , DelegateProxyType - , UICollectionViewDataSource { - - /// Typed parent object. - public weak private(set) var collectionView: UICollectionView? - - /// - parameter collectionView: Parent object for delegate proxy. - public init(collectionView: ParentObject) { - self.collectionView = collectionView - super.init(parentObject: collectionView, delegateProxy: RxCollectionViewDataSourceProxy.self) - } - - // Register known implementations - public static func registerKnownImplementations() { - self.register { RxCollectionViewDataSourceProxy(collectionView: $0) } - } - - private weak var _requiredMethodsDataSource: UICollectionViewDataSource? = collectionViewDataSourceNotSet - - // MARK: delegate - - /// Required delegate method implementation. - public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { - (_requiredMethodsDataSource ?? collectionViewDataSourceNotSet).collectionView(collectionView, numberOfItemsInSection: section) - } - - /// Required delegate method implementation. - public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - (_requiredMethodsDataSource ?? collectionViewDataSourceNotSet).collectionView(collectionView, cellForItemAt: indexPath) - } - - /// For more information take a look at `DelegateProxyType`. - open override func setForwardToDelegate(_ forwardToDelegate: UICollectionViewDataSource?, retainDelegate: Bool) { - _requiredMethodsDataSource = forwardToDelegate ?? collectionViewDataSourceNotSet - super.setForwardToDelegate(forwardToDelegate, retainDelegate: retainDelegate) - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxCollectionViewDelegateProxy.swift b/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxCollectionViewDelegateProxy.swift deleted file mode 100644 index dd8f4b43b..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxCollectionViewDelegateProxy.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// RxCollectionViewDelegateProxy.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 6/29/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -/// For more information take a look at `DelegateProxyType`. -open class RxCollectionViewDelegateProxy - : RxScrollViewDelegateProxy - , UICollectionViewDelegate - , UICollectionViewDelegateFlowLayout { - - /// Typed parent object. - public weak private(set) var collectionView: UICollectionView? - - /// Initializes `RxCollectionViewDelegateProxy` - /// - /// - parameter collectionView: Parent object for delegate proxy. - public init(collectionView: UICollectionView) { - self.collectionView = collectionView - super.init(scrollView: collectionView) - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxNavigationControllerDelegateProxy.swift b/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxNavigationControllerDelegateProxy.swift deleted file mode 100644 index 372bf7959..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxNavigationControllerDelegateProxy.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// RxNavigationControllerDelegateProxy.swift -// RxCocoa -// -// Created by Diogo on 13/04/17. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - - import UIKit - import RxSwift - - extension UINavigationController: HasDelegate { - public typealias Delegate = UINavigationControllerDelegate - } - - /// For more information take a look at `DelegateProxyType`. - open class RxNavigationControllerDelegateProxy - : DelegateProxy - , DelegateProxyType - , UINavigationControllerDelegate { - - /// Typed parent object. - public weak private(set) var navigationController: UINavigationController? - - /// - parameter navigationController: Parent object for delegate proxy. - public init(navigationController: ParentObject) { - self.navigationController = navigationController - super.init(parentObject: navigationController, delegateProxy: RxNavigationControllerDelegateProxy.self) - } - - // Register known implementations - public static func registerKnownImplementations() { - self.register { RxNavigationControllerDelegateProxy(navigationController: $0) } - } - } -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxPickerViewDataSourceProxy.swift b/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxPickerViewDataSourceProxy.swift deleted file mode 100644 index f9c65d1cd..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxPickerViewDataSourceProxy.swift +++ /dev/null @@ -1,71 +0,0 @@ -// -// RxPickerViewDataSourceProxy.swift -// RxCocoa -// -// Created by Sergey Shulga on 05/07/2017. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) - -import UIKit -import RxSwift - -extension UIPickerView: HasDataSource { - public typealias DataSource = UIPickerViewDataSource -} - -private let pickerViewDataSourceNotSet = PickerViewDataSourceNotSet() - -final private class PickerViewDataSourceNotSet: NSObject, UIPickerViewDataSource { - func numberOfComponents(in pickerView: UIPickerView) -> Int { - 0 - } - - func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { - 0 - } -} - -/// For more information take a look at `DelegateProxyType`. -public class RxPickerViewDataSourceProxy - : DelegateProxy - , DelegateProxyType - , UIPickerViewDataSource { - - /// Typed parent object. - public weak private(set) var pickerView: UIPickerView? - - /// - parameter pickerView: Parent object for delegate proxy. - public init(pickerView: ParentObject) { - self.pickerView = pickerView - super.init(parentObject: pickerView, delegateProxy: RxPickerViewDataSourceProxy.self) - } - - // Register known implementations - public static func registerKnownImplementations() { - self.register { RxPickerViewDataSourceProxy(pickerView: $0) } - } - - private weak var _requiredMethodsDataSource: UIPickerViewDataSource? = pickerViewDataSourceNotSet - - // MARK: UIPickerViewDataSource - - /// Required delegate method implementation. - public func numberOfComponents(in pickerView: UIPickerView) -> Int { - (_requiredMethodsDataSource ?? pickerViewDataSourceNotSet).numberOfComponents(in: pickerView) - } - - /// Required delegate method implementation. - public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { - (_requiredMethodsDataSource ?? pickerViewDataSourceNotSet).pickerView(pickerView, numberOfRowsInComponent: component) - } - - /// For more information take a look at `DelegateProxyType`. - public override func setForwardToDelegate(_ forwardToDelegate: UIPickerViewDataSource?, retainDelegate: Bool) { - _requiredMethodsDataSource = forwardToDelegate ?? pickerViewDataSourceNotSet - super.setForwardToDelegate(forwardToDelegate, retainDelegate: retainDelegate) - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxPickerViewDelegateProxy.swift b/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxPickerViewDelegateProxy.swift deleted file mode 100644 index 922126f84..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxPickerViewDelegateProxy.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// RxPickerViewDelegateProxy.swift -// RxCocoa -// -// Created by Segii Shulga on 5/12/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) - - import RxSwift - import UIKit - - extension UIPickerView: HasDelegate { - public typealias Delegate = UIPickerViewDelegate - } - - open class RxPickerViewDelegateProxy - : DelegateProxy - , DelegateProxyType - , UIPickerViewDelegate { - - /// Typed parent object. - public weak private(set) var pickerView: UIPickerView? - - /// - parameter pickerView: Parent object for delegate proxy. - public init(pickerView: ParentObject) { - self.pickerView = pickerView - super.init(parentObject: pickerView, delegateProxy: RxPickerViewDelegateProxy.self) - } - - // Register known implementationss - public static func registerKnownImplementations() { - self.register { RxPickerViewDelegateProxy(pickerView: $0) } - } - } -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxScrollViewDelegateProxy.swift b/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxScrollViewDelegateProxy.swift deleted file mode 100644 index 59608d3b1..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxScrollViewDelegateProxy.swift +++ /dev/null @@ -1,92 +0,0 @@ -// -// RxScrollViewDelegateProxy.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 6/19/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import RxSwift -import UIKit - -extension UIScrollView: HasDelegate { - public typealias Delegate = UIScrollViewDelegate -} - -/// For more information take a look at `DelegateProxyType`. -open class RxScrollViewDelegateProxy - : DelegateProxy - , DelegateProxyType - , UIScrollViewDelegate { - - /// Typed parent object. - public weak private(set) var scrollView: UIScrollView? - - /// - parameter scrollView: Parent object for delegate proxy. - public init(scrollView: ParentObject) { - self.scrollView = scrollView - super.init(parentObject: scrollView, delegateProxy: RxScrollViewDelegateProxy.self) - } - - // Register known implementations - public static func registerKnownImplementations() { - self.register { RxScrollViewDelegateProxy(scrollView: $0) } - self.register { RxTableViewDelegateProxy(tableView: $0) } - self.register { RxCollectionViewDelegateProxy(collectionView: $0) } - self.register { RxTextViewDelegateProxy(textView: $0) } - } - - private var _contentOffsetBehaviorSubject: BehaviorSubject? - private var _contentOffsetPublishSubject: PublishSubject<()>? - - /// Optimized version used for observing content offset changes. - internal var contentOffsetBehaviorSubject: BehaviorSubject { - if let subject = _contentOffsetBehaviorSubject { - return subject - } - - let subject = BehaviorSubject(value: self.scrollView?.contentOffset ?? CGPoint.zero) - _contentOffsetBehaviorSubject = subject - - return subject - } - - /// Optimized version used for observing content offset changes. - internal var contentOffsetPublishSubject: PublishSubject<()> { - if let subject = _contentOffsetPublishSubject { - return subject - } - - let subject = PublishSubject<()>() - _contentOffsetPublishSubject = subject - - return subject - } - - // MARK: delegate methods - - /// For more information take a look at `DelegateProxyType`. - public func scrollViewDidScroll(_ scrollView: UIScrollView) { - if let subject = _contentOffsetBehaviorSubject { - subject.on(.next(scrollView.contentOffset)) - } - if let subject = _contentOffsetPublishSubject { - subject.on(.next(())) - } - self._forwardToDelegate?.scrollViewDidScroll?(scrollView) - } - - deinit { - if let subject = _contentOffsetBehaviorSubject { - subject.on(.completed) - } - - if let subject = _contentOffsetPublishSubject { - subject.on(.completed) - } - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxSearchBarDelegateProxy.swift b/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxSearchBarDelegateProxy.swift deleted file mode 100644 index 532ab6872..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxSearchBarDelegateProxy.swift +++ /dev/null @@ -1,39 +0,0 @@ -// -// RxSearchBarDelegateProxy.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 7/4/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -extension UISearchBar: HasDelegate { - public typealias Delegate = UISearchBarDelegate -} - -/// For more information take a look at `DelegateProxyType`. -open class RxSearchBarDelegateProxy - : DelegateProxy - , DelegateProxyType - , UISearchBarDelegate { - - /// Typed parent object. - public weak private(set) var searchBar: UISearchBar? - - /// - parameter searchBar: Parent object for delegate proxy. - public init(searchBar: ParentObject) { - self.searchBar = searchBar - super.init(parentObject: searchBar, delegateProxy: RxSearchBarDelegateProxy.self) - } - - // Register known implementations - public static func registerKnownImplementations() { - self.register { RxSearchBarDelegateProxy(searchBar: $0) } - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxSearchControllerDelegateProxy.swift b/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxSearchControllerDelegateProxy.swift deleted file mode 100644 index 04e0de096..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxSearchControllerDelegateProxy.swift +++ /dev/null @@ -1,39 +0,0 @@ -// -// RxSearchControllerDelegateProxy.swift -// RxCocoa -// -// Created by Segii Shulga on 3/17/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) - -import RxSwift -import UIKit - -extension UISearchController: HasDelegate { - public typealias Delegate = UISearchControllerDelegate -} - -/// For more information take a look at `DelegateProxyType`. -open class RxSearchControllerDelegateProxy - : DelegateProxy - , DelegateProxyType - , UISearchControllerDelegate { - - /// Typed parent object. - public weak private(set) var searchController: UISearchController? - - /// - parameter searchController: Parent object for delegate proxy. - public init(searchController: UISearchController) { - self.searchController = searchController - super.init(parentObject: searchController, delegateProxy: RxSearchControllerDelegateProxy.self) - } - - // Register known implementations - public static func registerKnownImplementations() { - self.register { RxSearchControllerDelegateProxy(searchController: $0) } - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTabBarControllerDelegateProxy.swift b/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTabBarControllerDelegateProxy.swift deleted file mode 100644 index 585894ce2..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTabBarControllerDelegateProxy.swift +++ /dev/null @@ -1,39 +0,0 @@ -// -// RxTabBarControllerDelegateProxy.swift -// RxCocoa -// -// Created by Yusuke Kita on 2016/12/07. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -extension UITabBarController: HasDelegate { - public typealias Delegate = UITabBarControllerDelegate -} - -/// For more information take a look at `DelegateProxyType`. -open class RxTabBarControllerDelegateProxy - : DelegateProxy - , DelegateProxyType - , UITabBarControllerDelegate { - - /// Typed parent object. - public weak private(set) var tabBar: UITabBarController? - - /// - parameter tabBar: Parent object for delegate proxy. - public init(tabBar: ParentObject) { - self.tabBar = tabBar - super.init(parentObject: tabBar, delegateProxy: RxTabBarControllerDelegateProxy.self) - } - - // Register known implementations - public static func registerKnownImplementations() { - self.register { RxTabBarControllerDelegateProxy(tabBar: $0) } - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTabBarDelegateProxy.swift b/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTabBarDelegateProxy.swift deleted file mode 100644 index 620573090..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTabBarDelegateProxy.swift +++ /dev/null @@ -1,49 +0,0 @@ -// -// RxTabBarDelegateProxy.swift -// RxCocoa -// -// Created by Jesse Farless on 5/14/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -extension UITabBar: HasDelegate { - public typealias Delegate = UITabBarDelegate -} - -/// For more information take a look at `DelegateProxyType`. -open class RxTabBarDelegateProxy - : DelegateProxy - , DelegateProxyType - , UITabBarDelegate { - - /// Typed parent object. - public weak private(set) var tabBar: UITabBar? - - /// - parameter tabBar: Parent object for delegate proxy. - public init(tabBar: ParentObject) { - self.tabBar = tabBar - super.init(parentObject: tabBar, delegateProxy: RxTabBarDelegateProxy.self) - } - - // Register known implementations - public static func registerKnownImplementations() { - self.register { RxTabBarDelegateProxy(tabBar: $0) } - } - - /// For more information take a look at `DelegateProxyType`. - open class func currentDelegate(for object: ParentObject) -> UITabBarDelegate? { - object.delegate - } - - /// For more information take a look at `DelegateProxyType`. - open class func setCurrentDelegate(_ delegate: UITabBarDelegate?, to object: ParentObject) { - object.delegate = delegate - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTableViewDataSourcePrefetchingProxy.swift b/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTableViewDataSourcePrefetchingProxy.swift deleted file mode 100644 index 4345312e4..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTableViewDataSourcePrefetchingProxy.swift +++ /dev/null @@ -1,93 +0,0 @@ -// -// RxTableViewDataSourcePrefetchingProxy.swift -// RxCocoa -// -// Created by Rowan Livingstone on 2/15/18. -// Copyright © 2018 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -@available(iOS 10.0, tvOS 10.0, *) -extension UITableView: HasPrefetchDataSource { - public typealias PrefetchDataSource = UITableViewDataSourcePrefetching -} - -@available(iOS 10.0, tvOS 10.0, *) -private let tableViewPrefetchDataSourceNotSet = TableViewPrefetchDataSourceNotSet() - -@available(iOS 10.0, tvOS 10.0, *) -private final class TableViewPrefetchDataSourceNotSet - : NSObject - , UITableViewDataSourcePrefetching { - - func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {} - -} - -@available(iOS 10.0, tvOS 10.0, *) -open class RxTableViewDataSourcePrefetchingProxy - : DelegateProxy - , DelegateProxyType - , UITableViewDataSourcePrefetching { - - /// Typed parent object. - public weak private(set) var tableView: UITableView? - - /// - parameter tableView: Parent object for delegate proxy. - public init(tableView: ParentObject) { - self.tableView = tableView - super.init(parentObject: tableView, delegateProxy: RxTableViewDataSourcePrefetchingProxy.self) - } - - // Register known implementations - public static func registerKnownImplementations() { - self.register { RxTableViewDataSourcePrefetchingProxy(tableView: $0) } - } - - private var _prefetchRowsPublishSubject: PublishSubject<[IndexPath]>? - - /// Optimized version used for observing prefetch rows callbacks. - internal var prefetchRowsPublishSubject: PublishSubject<[IndexPath]> { - if let subject = _prefetchRowsPublishSubject { - return subject - } - - let subject = PublishSubject<[IndexPath]>() - _prefetchRowsPublishSubject = subject - - return subject - } - - private weak var _requiredMethodsPrefetchDataSource: UITableViewDataSourcePrefetching? = tableViewPrefetchDataSourceNotSet - - // MARK: delegate - - /// Required delegate method implementation. - public func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) { - if let subject = _prefetchRowsPublishSubject { - subject.on(.next(indexPaths)) - } - - (_requiredMethodsPrefetchDataSource ?? tableViewPrefetchDataSourceNotSet).tableView(tableView, prefetchRowsAt: indexPaths) - } - - /// For more information take a look at `DelegateProxyType`. - open override func setForwardToDelegate(_ forwardToDelegate: UITableViewDataSourcePrefetching?, retainDelegate: Bool) { - _requiredMethodsPrefetchDataSource = forwardToDelegate ?? tableViewPrefetchDataSourceNotSet - super.setForwardToDelegate(forwardToDelegate, retainDelegate: retainDelegate) - } - - deinit { - if let subject = _prefetchRowsPublishSubject { - subject.on(.completed) - } - } - -} - -#endif - diff --git a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTableViewDataSourceProxy.swift b/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTableViewDataSourceProxy.swift deleted file mode 100644 index 42d9386e5..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTableViewDataSourceProxy.swift +++ /dev/null @@ -1,75 +0,0 @@ -// -// RxTableViewDataSourceProxy.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 6/15/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -extension UITableView: HasDataSource { - public typealias DataSource = UITableViewDataSource -} - -private let tableViewDataSourceNotSet = TableViewDataSourceNotSet() - -private final class TableViewDataSourceNotSet - : NSObject - , UITableViewDataSource { - - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - 0 - } - - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - rxAbstractMethod(message: dataSourceNotSet) - } -} - -/// For more information take a look at `DelegateProxyType`. -open class RxTableViewDataSourceProxy - : DelegateProxy - , DelegateProxyType - , UITableViewDataSource { - - /// Typed parent object. - public weak private(set) var tableView: UITableView? - - /// - parameter tableView: Parent object for delegate proxy. - public init(tableView: UITableView) { - self.tableView = tableView - super.init(parentObject: tableView, delegateProxy: RxTableViewDataSourceProxy.self) - } - - // Register known implementations - public static func registerKnownImplementations() { - self.register { RxTableViewDataSourceProxy(tableView: $0) } - } - - private weak var _requiredMethodsDataSource: UITableViewDataSource? = tableViewDataSourceNotSet - - // MARK: delegate - - /// Required delegate method implementation. - public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - (_requiredMethodsDataSource ?? tableViewDataSourceNotSet).tableView(tableView, numberOfRowsInSection: section) - } - - /// Required delegate method implementation. - public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - (_requiredMethodsDataSource ?? tableViewDataSourceNotSet).tableView(tableView, cellForRowAt: indexPath) - } - - /// For more information take a look at `DelegateProxyType`. - open override func setForwardToDelegate(_ forwardToDelegate: UITableViewDataSource?, retainDelegate: Bool) { - _requiredMethodsDataSource = forwardToDelegate ?? tableViewDataSourceNotSet - super.setForwardToDelegate(forwardToDelegate, retainDelegate: retainDelegate) - } - -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTableViewDelegateProxy.swift b/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTableViewDelegateProxy.swift deleted file mode 100644 index 86a875857..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTableViewDelegateProxy.swift +++ /dev/null @@ -1,30 +0,0 @@ -// -// RxTableViewDelegateProxy.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 6/15/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -/// For more information take a look at `DelegateProxyType`. -open class RxTableViewDelegateProxy - : RxScrollViewDelegateProxy - , UITableViewDelegate { - - /// Typed parent object. - public weak private(set) var tableView: UITableView? - - /// - parameter tableView: Parent object for delegate proxy. - public init(tableView: UITableView) { - self.tableView = tableView - super.init(scrollView: tableView) - } - -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTextStorageDelegateProxy.swift b/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTextStorageDelegateProxy.swift deleted file mode 100644 index 12669f9ca..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTextStorageDelegateProxy.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// RxTextStorageDelegateProxy.swift -// RxCocoa -// -// Created by Segii Shulga on 12/30/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - - import RxSwift - import UIKit - - extension NSTextStorage: HasDelegate { - public typealias Delegate = NSTextStorageDelegate - } - - open class RxTextStorageDelegateProxy - : DelegateProxy - , DelegateProxyType - , NSTextStorageDelegate { - - /// Typed parent object. - public weak private(set) var textStorage: NSTextStorage? - - /// - parameter textStorage: Parent object for delegate proxy. - public init(textStorage: NSTextStorage) { - self.textStorage = textStorage - super.init(parentObject: textStorage, delegateProxy: RxTextStorageDelegateProxy.self) - } - - // Register known implementations - public static func registerKnownImplementations() { - self.register { RxTextStorageDelegateProxy(textStorage: $0) } - } - } -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTextViewDelegateProxy.swift b/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTextViewDelegateProxy.swift deleted file mode 100644 index c8a1dfd67..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxTextViewDelegateProxy.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// RxTextViewDelegateProxy.swift -// RxCocoa -// -// Created by Yuta ToKoRo on 7/19/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -/// For more information take a look at `DelegateProxyType`. -open class RxTextViewDelegateProxy - : RxScrollViewDelegateProxy - , UITextViewDelegate { - - /// Typed parent object. - public weak private(set) var textView: UITextView? - - /// - parameter textview: Parent object for delegate proxy. - public init(textView: UITextView) { - self.textView = textView - super.init(scrollView: textView) - } - - // MARK: delegate methods - - /// For more information take a look at `DelegateProxyType`. - @objc open func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { - /** - We've had some issues with observing text changes. This is here just in case we need the same hack in future and that - we wouldn't need to change the public interface. - */ - let forwardToDelegate = self.forwardToDelegate() as? UITextViewDelegate - return forwardToDelegate?.textView?(textView, - shouldChangeTextIn: range, - replacementText: text) ?? true - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxWKNavigationDelegateProxy.swift b/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxWKNavigationDelegateProxy.swift deleted file mode 100644 index c758c0212..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/Proxies/RxWKNavigationDelegateProxy.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// RxWKNavigationDelegateProxy.swift -// RxCocoa -// -// Created by Giuseppe Lanza on 14/02/2020. -// Copyright © 2020 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(macOS) - -import RxSwift -import WebKit - -@available(iOS 8.0, OSX 10.10, OSXApplicationExtension 10.10, *) -open class RxWKNavigationDelegateProxy - : DelegateProxy - , DelegateProxyType -, WKNavigationDelegate { - - /// Typed parent object. - public weak private(set) var webView: WKWebView? - - /// - parameter webView: Parent object for delegate proxy. - public init(webView: ParentObject) { - self.webView = webView - super.init(parentObject: webView, delegateProxy: RxWKNavigationDelegateProxy.self) - } - - // Register known implementations - public static func registerKnownImplementations() { - self.register { RxWKNavigationDelegateProxy(webView: $0) } - } - - public static func currentDelegate(for object: WKWebView) -> WKNavigationDelegate? { - object.navigationDelegate - } - - public static func setCurrentDelegate(_ delegate: WKNavigationDelegate?, to object: WKWebView) { - object.navigationDelegate = delegate - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UIActivityIndicatorView+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UIActivityIndicatorView+Rx.swift deleted file mode 100644 index ca2d4f1b1..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UIActivityIndicatorView+Rx.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// UIActivityIndicatorView+Rx.swift -// RxCocoa -// -// Created by Ivan Persidskiy on 02/12/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -extension Reactive where Base: UIActivityIndicatorView { - /// Bindable sink for `startAnimating()`, `stopAnimating()` methods. - public var isAnimating: Binder { - Binder(self.base) { activityIndicator, active in - if active { - activityIndicator.startAnimating() - } else { - activityIndicator.stopAnimating() - } - } - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UIApplication+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UIApplication+Rx.swift deleted file mode 100644 index d7761058b..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UIApplication+Rx.swift +++ /dev/null @@ -1,106 +0,0 @@ -// -// UIApplication+Rx.swift -// RxCocoa -// -// Created by Mads Bøgeskov on 18/01/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) - -import UIKit -import RxSwift - -extension Reactive where Base: UIApplication { - /// Bindable sink for `isNetworkActivityIndicatorVisible`. - public var isNetworkActivityIndicatorVisible: Binder { - return Binder(self.base) { application, active in - application.isNetworkActivityIndicatorVisible = active - } - } - - /// Reactive wrapper for `UIApplication.didEnterBackgroundNotification` - public static var didEnterBackground: ControlEvent { - let source = NotificationCenter.default.rx.notification(UIApplication.didEnterBackgroundNotification).map { _ in } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `UIApplication.willEnterForegroundNotification` - public static var willEnterForeground: ControlEvent { - let source = NotificationCenter.default.rx.notification(UIApplication.willEnterForegroundNotification).map { _ in } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `UIApplication.didFinishLaunchingNotification` - public static var didFinishLaunching: ControlEvent { - let source = NotificationCenter.default.rx.notification(UIApplication.didFinishLaunchingNotification).map { _ in } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `UIApplication.didBecomeActiveNotification` - public static var didBecomeActive: ControlEvent { - let source = NotificationCenter.default.rx.notification(UIApplication.didBecomeActiveNotification).map { _ in } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `UIApplication.willResignActiveNotification` - public static var willResignActive: ControlEvent { - let source = NotificationCenter.default.rx.notification(UIApplication.willResignActiveNotification).map { _ in } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `UIApplication.didReceiveMemoryWarningNotification` - public static var didReceiveMemoryWarning: ControlEvent { - let source = NotificationCenter.default.rx.notification(UIApplication.didReceiveMemoryWarningNotification).map { _ in } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `UIApplication.willTerminateNotification` - public static var willTerminate: ControlEvent { - let source = NotificationCenter.default.rx.notification(UIApplication.willTerminateNotification).map { _ in } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `UIApplication.significantTimeChangeNotification` - public static var significantTimeChange: ControlEvent { - let source = NotificationCenter.default.rx.notification(UIApplication.significantTimeChangeNotification).map { _ in } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `UIApplication.backgroundRefreshStatusDidChangeNotification` - public static var backgroundRefreshStatusDidChange: ControlEvent { - let source = NotificationCenter.default.rx.notification(UIApplication.backgroundRefreshStatusDidChangeNotification).map { _ in } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `UIApplication.protectedDataWillBecomeUnavailableNotification` - public static var protectedDataWillBecomeUnavailable: ControlEvent { - let source = NotificationCenter.default.rx.notification(UIApplication.protectedDataWillBecomeUnavailableNotification).map { _ in } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `UIApplication.protectedDataDidBecomeAvailableNotification` - public static var protectedDataDidBecomeAvailable: ControlEvent { - let source = NotificationCenter.default.rx.notification(UIApplication.protectedDataDidBecomeAvailableNotification).map { _ in } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `UIApplication.userDidTakeScreenshotNotification` - public static var userDidTakeScreenshot: ControlEvent { - let source = NotificationCenter.default.rx.notification(UIApplication.userDidTakeScreenshotNotification).map { _ in } - - return ControlEvent(events: source) - } -} -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UIBarButtonItem+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UIBarButtonItem+Rx.swift deleted file mode 100644 index 0bcaa9942..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UIBarButtonItem+Rx.swift +++ /dev/null @@ -1,72 +0,0 @@ -// -// UIBarButtonItem+Rx.swift -// RxCocoa -// -// Created by Daniel Tartaglia on 5/31/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -private var rx_tap_key: UInt8 = 0 - -extension Reactive where Base: UIBarButtonItem { - /// Reactive wrapper for target action pattern on `self`. - public var tap: ControlEvent<()> { - let source = lazyInstanceObservable(&rx_tap_key) { () -> Observable<()> in - Observable.create { [weak control = self.base] observer in - guard let control = control else { - observer.on(.completed) - return Disposables.create() - } - let target = BarButtonItemTarget(barButtonItem: control) { - observer.on(.next(())) - } - return target - } - .take(until: self.deallocated) - .share() - } - - return ControlEvent(events: source) - } -} - - -@objc -final class BarButtonItemTarget: RxTarget { - typealias Callback = () -> Void - - weak var barButtonItem: UIBarButtonItem? - var callback: Callback! - - init(barButtonItem: UIBarButtonItem, callback: @escaping () -> Void) { - self.barButtonItem = barButtonItem - self.callback = callback - super.init() - barButtonItem.target = self - barButtonItem.action = #selector(BarButtonItemTarget.action(_:)) - } - - override func dispose() { - super.dispose() -#if DEBUG - MainScheduler.ensureRunningOnMainThread() -#endif - - barButtonItem?.target = nil - barButtonItem?.action = nil - - callback = nil - } - - @objc func action(_ sender: AnyObject) { - callback() - } - -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UIButton+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UIButton+Rx.swift deleted file mode 100644 index 4d0f4c323..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UIButton+Rx.swift +++ /dev/null @@ -1,82 +0,0 @@ -// -// UIButton+Rx.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 3/28/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) - -import RxSwift -import UIKit - -extension Reactive where Base: UIButton { - - /// Reactive wrapper for `TouchUpInside` control event. - public var tap: ControlEvent { - controlEvent(.touchUpInside) - } -} - -#endif - -#if os(tvOS) - -import RxSwift -import UIKit - -extension Reactive where Base: UIButton { - - /// Reactive wrapper for `PrimaryActionTriggered` control event. - public var primaryAction: ControlEvent { - controlEvent(.primaryActionTriggered) - } - -} - -#endif - -#if os(iOS) || os(tvOS) - -import RxSwift -import UIKit - -extension Reactive where Base: UIButton { - /// Reactive wrapper for `setTitle(_:for:)` - public func title(for controlState: UIControl.State = []) -> Binder { - Binder(self.base) { button, title in - button.setTitle(title, for: controlState) - } - } - - /// Reactive wrapper for `setImage(_:for:)` - public func image(for controlState: UIControl.State = []) -> Binder { - Binder(self.base) { button, image in - button.setImage(image, for: controlState) - } - } - - /// Reactive wrapper for `setBackgroundImage(_:for:)` - public func backgroundImage(for controlState: UIControl.State = []) -> Binder { - Binder(self.base) { button, image in - button.setBackgroundImage(image, for: controlState) - } - } - -} -#endif - -#if os(iOS) || os(tvOS) - import RxSwift - import UIKit - - extension Reactive where Base: UIButton { - /// Reactive wrapper for `setAttributedTitle(_:controlState:)` - public func attributedTitle(for controlState: UIControl.State = []) -> Binder { - return Binder(self.base) { button, attributedTitle -> Void in - button.setAttributedTitle(attributedTitle, for: controlState) - } - } - } -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UICollectionView+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UICollectionView+Rx.swift deleted file mode 100644 index 7f3de007c..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UICollectionView+Rx.swift +++ /dev/null @@ -1,380 +0,0 @@ -// -// UICollectionView+Rx.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 4/2/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import RxSwift -import UIKit - -// Items - -extension Reactive where Base: UICollectionView { - - /** - Binds sequences of elements to collection view items. - - - parameter source: Observable sequence of items. - - parameter cellFactory: Transform between sequence elements and view cells. - - returns: Disposable object that can be used to unbind. - - Example - - let items = Observable.just([ - 1, - 2, - 3 - ]) - - items - .bind(to: collectionView.rx.items) { (collectionView, row, element) in - let indexPath = IndexPath(row: row, section: 0) - let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! NumberCell - cell.value?.text = "\(element) @ \(row)" - return cell - } - .disposed(by: disposeBag) - */ - public func items - (_ source: Source) - -> (_ cellFactory: @escaping (UICollectionView, Int, Sequence.Element) -> UICollectionViewCell) - -> Disposable where Source.Element == Sequence { - return { cellFactory in - let dataSource = RxCollectionViewReactiveArrayDataSourceSequenceWrapper(cellFactory: cellFactory) - return self.items(dataSource: dataSource)(source) - } - - } - - /** - Binds sequences of elements to collection view items. - - - parameter cellIdentifier: Identifier used to dequeue cells. - - parameter source: Observable sequence of items. - - parameter configureCell: Transform between sequence elements and view cells. - - parameter cellType: Type of collection view cell. - - returns: Disposable object that can be used to unbind. - - Example - - let items = Observable.just([ - 1, - 2, - 3 - ]) - - items - .bind(to: collectionView.rx.items(cellIdentifier: "Cell", cellType: NumberCell.self)) { (row, element, cell) in - cell.value?.text = "\(element) @ \(row)" - } - .disposed(by: disposeBag) - */ - public func items - (cellIdentifier: String, cellType: Cell.Type = Cell.self) - -> (_ source: Source) - -> (_ configureCell: @escaping (Int, Sequence.Element, Cell) -> Void) - -> Disposable where Source.Element == Sequence { - return { source in - return { configureCell in - let dataSource = RxCollectionViewReactiveArrayDataSourceSequenceWrapper { cv, i, item in - let indexPath = IndexPath(item: i, section: 0) - let cell = cv.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! Cell - configureCell(i, item, cell) - return cell - } - - return self.items(dataSource: dataSource)(source) - } - } - } - - - /** - Binds sequences of elements to collection view items using a custom reactive data used to perform the transformation. - - - parameter dataSource: Data source used to transform elements to view cells. - - parameter source: Observable sequence of items. - - returns: Disposable object that can be used to unbind. - - Example - - let dataSource = RxCollectionViewSectionedReloadDataSource>() - - let items = Observable.just([ - SectionModel(model: "First section", items: [ - 1.0, - 2.0, - 3.0 - ]), - SectionModel(model: "Second section", items: [ - 1.0, - 2.0, - 3.0 - ]), - SectionModel(model: "Third section", items: [ - 1.0, - 2.0, - 3.0 - ]) - ]) - - dataSource.configureCell = { (dataSource, cv, indexPath, element) in - let cell = cv.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! NumberCell - cell.value?.text = "\(element) @ row \(indexPath.row)" - return cell - } - - items - .bind(to: collectionView.rx.items(dataSource: dataSource)) - .disposed(by: disposeBag) - */ - public func items< - DataSource: RxCollectionViewDataSourceType & UICollectionViewDataSource, - Source: ObservableType> - (dataSource: DataSource) - -> (_ source: Source) - -> Disposable where DataSource.Element == Source.Element - { - return { source in - // This is called for sideeffects only, and to make sure delegate proxy is in place when - // data source is being bound. - // This is needed because theoretically the data source subscription itself might - // call `self.rx.delegate`. If that happens, it might cause weird side effects since - // setting data source will set delegate, and UICollectionView might get into a weird state. - // Therefore it's better to set delegate proxy first, just to be sure. - _ = self.delegate - // Strong reference is needed because data source is in use until result subscription is disposed - return source.subscribeProxyDataSource(ofObject: self.base, dataSource: dataSource, retainDataSource: true) { [weak collectionView = self.base] (_: RxCollectionViewDataSourceProxy, event) -> Void in - guard let collectionView = collectionView else { - return - } - dataSource.collectionView(collectionView, observedEvent: event) - } - } - } -} - -extension Reactive where Base: UICollectionView { - public typealias DisplayCollectionViewCellEvent = (cell: UICollectionViewCell, at: IndexPath) - public typealias DisplayCollectionViewSupplementaryViewEvent = (supplementaryView: UICollectionReusableView, elementKind: String, at: IndexPath) - - /// Reactive wrapper for `dataSource`. - /// - /// For more information take a look at `DelegateProxyType` protocol documentation. - public var dataSource: DelegateProxy { - RxCollectionViewDataSourceProxy.proxy(for: base) - } - - /// Installs data source as forwarding delegate on `rx.dataSource`. - /// Data source won't be retained. - /// - /// It enables using normal delegate mechanism with reactive delegate mechanism. - /// - /// - parameter dataSource: Data source object. - /// - returns: Disposable object that can be used to unbind the data source. - public func setDataSource(_ dataSource: UICollectionViewDataSource) - -> Disposable { - RxCollectionViewDataSourceProxy.installForwardDelegate(dataSource, retainDelegate: false, onProxyForObject: self.base) - } - - /// Reactive wrapper for `delegate` message `collectionView(_:didSelectItemAtIndexPath:)`. - public var itemSelected: ControlEvent { - let source = delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:didSelectItemAt:))) - .map { a in - return try castOrThrow(IndexPath.self, a[1]) - } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `delegate` message `collectionView(_:didDeselectItemAtIndexPath:)`. - public var itemDeselected: ControlEvent { - let source = delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:didDeselectItemAt:))) - .map { a in - return try castOrThrow(IndexPath.self, a[1]) - } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `delegate` message `collectionView(_:didHighlightItemAt:)`. - public var itemHighlighted: ControlEvent { - let source = delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:didHighlightItemAt:))) - .map { a in - return try castOrThrow(IndexPath.self, a[1]) - } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `delegate` message `collectionView(_:didUnhighlightItemAt:)`. - public var itemUnhighlighted: ControlEvent { - let source = delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:didUnhighlightItemAt:))) - .map { a in - return try castOrThrow(IndexPath.self, a[1]) - } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `delegate` message `collectionView:willDisplay:forItemAt:`. - public var willDisplayCell: ControlEvent { - let source: Observable = self.delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:willDisplay:forItemAt:))) - .map { a in - return (try castOrThrow(UICollectionViewCell.self, a[1]), try castOrThrow(IndexPath.self, a[2])) - } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `delegate` message `collectionView(_:willDisplaySupplementaryView:forElementKind:at:)`. - public var willDisplaySupplementaryView: ControlEvent { - let source: Observable = self.delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:willDisplaySupplementaryView:forElementKind:at:))) - .map { a in - return (try castOrThrow(UICollectionReusableView.self, a[1]), - try castOrThrow(String.self, a[2]), - try castOrThrow(IndexPath.self, a[3])) - } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `delegate` message `collectionView:didEndDisplaying:forItemAt:`. - public var didEndDisplayingCell: ControlEvent { - let source: Observable = self.delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:didEndDisplaying:forItemAt:))) - .map { a in - return (try castOrThrow(UICollectionViewCell.self, a[1]), try castOrThrow(IndexPath.self, a[2])) - } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `delegate` message `collectionView(_:didEndDisplayingSupplementaryView:forElementOfKind:at:)`. - public var didEndDisplayingSupplementaryView: ControlEvent { - let source: Observable = self.delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:didEndDisplayingSupplementaryView:forElementOfKind:at:))) - .map { a in - return (try castOrThrow(UICollectionReusableView.self, a[1]), - try castOrThrow(String.self, a[2]), - try castOrThrow(IndexPath.self, a[3])) - } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `delegate` message `collectionView(_:didSelectItemAtIndexPath:)`. - /// - /// It can be only used when one of the `rx.itemsWith*` methods is used to bind observable sequence, - /// or any other data source conforming to `SectionedViewDataSourceType` protocol. - /// - /// ``` - /// collectionView.rx.modelSelected(MyModel.self) - /// .map { ... - /// ``` - public func modelSelected(_ modelType: T.Type) -> ControlEvent { - let source: Observable = itemSelected.flatMap { [weak view = self.base as UICollectionView] indexPath -> Observable in - guard let view = view else { - return Observable.empty() - } - - return Observable.just(try view.rx.model(at: indexPath)) - } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `delegate` message `collectionView(_:didSelectItemAtIndexPath:)`. - /// - /// It can be only used when one of the `rx.itemsWith*` methods is used to bind observable sequence, - /// or any other data source conforming to `SectionedViewDataSourceType` protocol. - /// - /// ``` - /// collectionView.rx.modelDeselected(MyModel.self) - /// .map { ... - /// ``` - public func modelDeselected(_ modelType: T.Type) -> ControlEvent { - let source: Observable = itemDeselected.flatMap { [weak view = self.base as UICollectionView] indexPath -> Observable in - guard let view = view else { - return Observable.empty() - } - - return Observable.just(try view.rx.model(at: indexPath)) - } - - return ControlEvent(events: source) - } - - /// Synchronous helper method for retrieving a model at indexPath through a reactive data source - public func model(at indexPath: IndexPath) throws -> T { - let dataSource: SectionedViewDataSourceType = castOrFatalError(self.dataSource.forwardToDelegate(), message: "This method only works in case one of the `rx.itemsWith*` methods was used.") - - let element = try dataSource.model(at: indexPath) - - return try castOrThrow(T.self, element) - } -} - -@available(iOS 10.0, tvOS 10.0, *) -extension Reactive where Base: UICollectionView { - - /// Reactive wrapper for `prefetchDataSource`. - /// - /// For more information take a look at `DelegateProxyType` protocol documentation. - public var prefetchDataSource: DelegateProxy { - RxCollectionViewDataSourcePrefetchingProxy.proxy(for: base) - } - - /** - Installs prefetch data source as forwarding delegate on `rx.prefetchDataSource`. - Prefetch data source won't be retained. - - It enables using normal delegate mechanism with reactive delegate mechanism. - - - parameter prefetchDataSource: Prefetch data source object. - - returns: Disposable object that can be used to unbind the data source. - */ - public func setPrefetchDataSource(_ prefetchDataSource: UICollectionViewDataSourcePrefetching) - -> Disposable { - return RxCollectionViewDataSourcePrefetchingProxy.installForwardDelegate(prefetchDataSource, retainDelegate: false, onProxyForObject: self.base) - } - - /// Reactive wrapper for `prefetchDataSource` message `collectionView(_:prefetchItemsAt:)`. - public var prefetchItems: ControlEvent<[IndexPath]> { - let source = RxCollectionViewDataSourcePrefetchingProxy.proxy(for: base).prefetchItemsPublishSubject - return ControlEvent(events: source) - } - - /// Reactive wrapper for `prefetchDataSource` message `collectionView(_:cancelPrefetchingForItemsAt:)`. - public var cancelPrefetchingForItems: ControlEvent<[IndexPath]> { - let source = prefetchDataSource.methodInvoked(#selector(UICollectionViewDataSourcePrefetching.collectionView(_:cancelPrefetchingForItemsAt:))) - .map { a in - return try castOrThrow(Array.self, a[1]) - } - - return ControlEvent(events: source) - } - -} -#endif - -#if os(tvOS) - -extension Reactive where Base: UICollectionView { - - /// Reactive wrapper for `delegate` message `collectionView(_:didUpdateFocusInContext:withAnimationCoordinator:)`. - public var didUpdateFocusInContextWithAnimationCoordinator: ControlEvent<(context: UICollectionViewFocusUpdateContext, animationCoordinator: UIFocusAnimationCoordinator)> { - - let source = delegate.methodInvoked(#selector(UICollectionViewDelegate.collectionView(_:didUpdateFocusIn:with:))) - .map { a -> (context: UICollectionViewFocusUpdateContext, animationCoordinator: UIFocusAnimationCoordinator) in - let context = try castOrThrow(UICollectionViewFocusUpdateContext.self, a[1]) - let animationCoordinator = try castOrThrow(UIFocusAnimationCoordinator.self, a[2]) - return (context: context, animationCoordinator: animationCoordinator) - } - - return ControlEvent(events: source) - } -} -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UIControl+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UIControl+Rx.swift deleted file mode 100644 index 6698cf242..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UIControl+Rx.swift +++ /dev/null @@ -1,86 +0,0 @@ -// -// UIControl+Rx.swift -// RxCocoa -// -// Created by Daniel Tartaglia on 5/23/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import RxSwift -import UIKit - -extension Reactive where Base: UIControl { - /// Reactive wrapper for target action pattern. - /// - /// - parameter controlEvents: Filter for observed event types. - public func controlEvent(_ controlEvents: UIControl.Event) -> ControlEvent<()> { - let source: Observable = Observable.create { [weak control = self.base] observer in - MainScheduler.ensureRunningOnMainThread() - - guard let control = control else { - observer.on(.completed) - return Disposables.create() - } - - let controlTarget = ControlTarget(control: control, controlEvents: controlEvents) { _ in - observer.on(.next(())) - } - - return Disposables.create(with: controlTarget.dispose) - } - .take(until: deallocated) - - return ControlEvent(events: source) - } - - /// Creates a `ControlProperty` that is triggered by target/action pattern value updates. - /// - /// - parameter controlEvents: Events that trigger value update sequence elements. - /// - parameter getter: Property value getter. - /// - parameter setter: Property value setter. - public func controlProperty( - editingEvents: UIControl.Event, - getter: @escaping (Base) -> T, - setter: @escaping (Base, T) -> Void - ) -> ControlProperty { - let source: Observable = Observable.create { [weak weakControl = base] observer in - guard let control = weakControl else { - observer.on(.completed) - return Disposables.create() - } - - observer.on(.next(getter(control))) - - let controlTarget = ControlTarget(control: control, controlEvents: editingEvents) { _ in - if let control = weakControl { - observer.on(.next(getter(control))) - } - } - - return Disposables.create(with: controlTarget.dispose) - } - .take(until: deallocated) - - let bindingObserver = Binder(base, binding: setter) - - return ControlProperty(values: source, valueSink: bindingObserver) - } - - /// This is a separate method to better communicate to public consumers that - /// an `editingEvent` needs to fire for control property to be updated. - internal func controlPropertyWithDefaultEvents( - editingEvents: UIControl.Event = [.allEditingEvents, .valueChanged], - getter: @escaping (Base) -> T, - setter: @escaping (Base, T) -> Void - ) -> ControlProperty { - return controlProperty( - editingEvents: editingEvents, - getter: getter, - setter: setter - ) - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UIDatePicker+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UIDatePicker+Rx.swift deleted file mode 100644 index e10c1ec98..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UIDatePicker+Rx.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// UIDatePicker+Rx.swift -// RxCocoa -// -// Created by Daniel Tartaglia on 5/31/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) - -import RxSwift -import UIKit - -extension Reactive where Base: UIDatePicker { - /// Reactive wrapper for `date` property. - public var date: ControlProperty { - value - } - - /// Reactive wrapper for `date` property. - public var value: ControlProperty { - return base.rx.controlPropertyWithDefaultEvents( - getter: { datePicker in - datePicker.date - }, setter: { datePicker, value in - datePicker.date = value - } - ) - } - - /// Reactive wrapper for `countDownDuration` property. - public var countDownDuration: ControlProperty { - return base.rx.controlPropertyWithDefaultEvents( - getter: { datePicker in - datePicker.countDownDuration - }, setter: { datePicker, value in - datePicker.countDownDuration = value - } - ) - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UIGestureRecognizer+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UIGestureRecognizer+Rx.swift deleted file mode 100644 index 551290086..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UIGestureRecognizer+Rx.swift +++ /dev/null @@ -1,75 +0,0 @@ -// -// UIGestureRecognizer+Rx.swift -// RxCocoa -// -// Created by Carlos García on 10/6/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -// This should be only used from `MainScheduler` -final class GestureTarget: RxTarget { - typealias Callback = (Recognizer) -> Void - - let selector = #selector(ControlTarget.eventHandler(_:)) - - weak var gestureRecognizer: Recognizer? - var callback: Callback? - - init(_ gestureRecognizer: Recognizer, callback: @escaping Callback) { - self.gestureRecognizer = gestureRecognizer - self.callback = callback - - super.init() - - gestureRecognizer.addTarget(self, action: selector) - - let method = self.method(for: selector) - if method == nil { - fatalError("Can't find method") - } - } - - @objc func eventHandler(_ sender: UIGestureRecognizer) { - if let callback = self.callback, let gestureRecognizer = self.gestureRecognizer { - callback(gestureRecognizer) - } - } - - override func dispose() { - super.dispose() - - self.gestureRecognizer?.removeTarget(self, action: self.selector) - self.callback = nil - } -} - -extension Reactive where Base: UIGestureRecognizer { - - /// Reactive wrapper for gesture recognizer events. - public var event: ControlEvent { - let source: Observable = Observable.create { [weak control = self.base] observer in - MainScheduler.ensureRunningOnMainThread() - - guard let control = control else { - observer.on(.completed) - return Disposables.create() - } - - let observer = GestureTarget(control) { control in - observer.on(.next(control)) - } - - return observer - }.take(until: deallocated) - - return ControlEvent(events: source) - } - -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UINavigationController+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UINavigationController+Rx.swift deleted file mode 100644 index 94796b659..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UINavigationController+Rx.swift +++ /dev/null @@ -1,49 +0,0 @@ -// -// UINavigationController+Rx.swift -// RxCocoa -// -// Created by Diogo on 13/04/17. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import RxSwift -import UIKit - -extension Reactive where Base: UINavigationController { - public typealias ShowEvent = (viewController: UIViewController, animated: Bool) - - /// Reactive wrapper for `delegate`. - /// - /// For more information take a look at `DelegateProxyType` protocol documentation. - public var delegate: DelegateProxy { - RxNavigationControllerDelegateProxy.proxy(for: base) - } - - /// Reactive wrapper for delegate method `navigationController(:willShow:animated:)`. - public var willShow: ControlEvent { - let source: Observable = delegate - .methodInvoked(#selector(UINavigationControllerDelegate.navigationController(_:willShow:animated:))) - .map { arg in - let viewController = try castOrThrow(UIViewController.self, arg[1]) - let animated = try castOrThrow(Bool.self, arg[2]) - return (viewController, animated) - } - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `navigationController(:didShow:animated:)`. - public var didShow: ControlEvent { - let source: Observable = delegate - .methodInvoked(#selector(UINavigationControllerDelegate.navigationController(_:didShow:animated:))) - .map { arg in - let viewController = try castOrThrow(UIViewController.self, arg[1]) - let animated = try castOrThrow(Bool.self, arg[2]) - return (viewController, animated) - } - return ControlEvent(events: source) - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UIPickerView+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UIPickerView+Rx.swift deleted file mode 100644 index 317dc13ba..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UIPickerView+Rx.swift +++ /dev/null @@ -1,224 +0,0 @@ -// -// UIPickerView+Rx.swift -// RxCocoa -// -// Created by Segii Shulga on 5/12/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) - - import RxSwift - import UIKit - - extension Reactive where Base: UIPickerView { - - /// Reactive wrapper for `delegate`. - /// For more information take a look at `DelegateProxyType` protocol documentation. - public var delegate: DelegateProxy { - return RxPickerViewDelegateProxy.proxy(for: base) - } - - /// Installs delegate as forwarding delegate on `delegate`. - /// Delegate won't be retained. - /// - /// It enables using normal delegate mechanism with reactive delegate mechanism. - /// - /// - parameter delegate: Delegate object. - /// - returns: Disposable object that can be used to unbind the delegate. - public func setDelegate(_ delegate: UIPickerViewDelegate) - -> Disposable { - return RxPickerViewDelegateProxy.installForwardDelegate(delegate, retainDelegate: false, onProxyForObject: self.base) - } - - /** - Reactive wrapper for `dataSource`. - - For more information take a look at `DelegateProxyType` protocol documentation. - */ - public var dataSource: DelegateProxy { - return RxPickerViewDataSourceProxy.proxy(for: base) - } - - /** - Reactive wrapper for `delegate` message `pickerView:didSelectRow:inComponent:`. - */ - public var itemSelected: ControlEvent<(row: Int, component: Int)> { - let source = delegate - .methodInvoked(#selector(UIPickerViewDelegate.pickerView(_:didSelectRow:inComponent:))) - .map { - return (row: try castOrThrow(Int.self, $0[1]), component: try castOrThrow(Int.self, $0[2])) - } - return ControlEvent(events: source) - } - - /** - Reactive wrapper for `delegate` message `pickerView:didSelectRow:inComponent:`. - - It can be only used when one of the `rx.itemTitles, rx.itemAttributedTitles, items(_ source: O)` methods is used to bind observable sequence, - or any other data source conforming to a `ViewDataSourceType` protocol. - - ``` - pickerView.rx.modelSelected(MyModel.self) - .map { ... - ``` - - parameter modelType: Type of a Model which bound to the dataSource - */ - public func modelSelected(_ modelType: T.Type) -> ControlEvent<[T]> { - let source = itemSelected.flatMap { [weak view = self.base as UIPickerView] _, component -> Observable<[T]> in - guard let view = view else { - return Observable.empty() - } - - let model: [T] = try (0 ..< view.numberOfComponents).map { component in - let row = view.selectedRow(inComponent: component) - return try view.rx.model(at: IndexPath(row: row, section: component)) - } - - return Observable.just(model) - } - - return ControlEvent(events: source) - } - - /** - Binds sequences of elements to picker view rows. - - - parameter source: Observable sequence of items. - - parameter titleForRow: Transform between sequence elements and row titles. - - returns: Disposable object that can be used to unbind. - - Example: - - let items = Observable.just([ - "First Item", - "Second Item", - "Third Item" - ]) - - items - .bind(to: pickerView.rx.itemTitles) { (row, element) in - return element.title - } - .disposed(by: disposeBag) - - */ - - public func itemTitles - (_ source: Source) - -> (_ titleForRow: @escaping (Int, Sequence.Element) -> String?) - -> Disposable where Source.Element == Sequence { - return { titleForRow in - let adapter = RxStringPickerViewAdapter(titleForRow: titleForRow) - return self.items(adapter: adapter)(source) - } - } - - /** - Binds sequences of elements to picker view rows. - - - parameter source: Observable sequence of items. - - parameter attributedTitleForRow: Transform between sequence elements and row attributed titles. - - returns: Disposable object that can be used to unbind. - - Example: - - let items = Observable.just([ - "First Item", - "Second Item", - "Third Item" - ]) - - items - .bind(to: pickerView.rx.itemAttributedTitles) { (row, element) in - return NSAttributedString(string: element.title) - } - .disposed(by: disposeBag) - - */ - - public func itemAttributedTitles - (_ source: Source) - -> (_ attributedTitleForRow: @escaping (Int, Sequence.Element) -> NSAttributedString?) - -> Disposable where Source.Element == Sequence { - return { attributedTitleForRow in - let adapter = RxAttributedStringPickerViewAdapter(attributedTitleForRow: attributedTitleForRow) - return self.items(adapter: adapter)(source) - } - } - - /** - Binds sequences of elements to picker view rows. - - - parameter source: Observable sequence of items. - - parameter viewForRow: Transform between sequence elements and row views. - - returns: Disposable object that can be used to unbind. - - Example: - - let items = Observable.just([ - "First Item", - "Second Item", - "Third Item" - ]) - - items - .bind(to: pickerView.rx.items) { (row, element, view) in - guard let myView = view as? MyView else { - let view = MyView() - view.configure(with: element) - return view - } - myView.configure(with: element) - return myView - } - .disposed(by: disposeBag) - - */ - - public func items - (_ source: Source) - -> (_ viewForRow: @escaping (Int, Sequence.Element, UIView?) -> UIView) - -> Disposable where Source.Element == Sequence { - return { viewForRow in - let adapter = RxPickerViewAdapter(viewForRow: viewForRow) - return self.items(adapter: adapter)(source) - } - } - - /** - Binds sequences of elements to picker view rows using a custom reactive adapter used to perform the transformation. - This method will retain the adapter for as long as the subscription isn't disposed (result `Disposable` - being disposed). - In case `source` observable sequence terminates successfully, the adapter will present latest element - until the subscription isn't disposed. - - - parameter adapter: Adapter used to transform elements to picker components. - - parameter source: Observable sequence of items. - - returns: Disposable object that can be used to unbind. - */ - public func items(adapter: Adapter) - -> (_ source: Source) - -> Disposable where Source.Element == Adapter.Element { - return { source in - let delegateSubscription = self.setDelegate(adapter) - let dataSourceSubscription = source.subscribeProxyDataSource(ofObject: self.base, dataSource: adapter, retainDataSource: true, binding: { [weak pickerView = self.base] (_: RxPickerViewDataSourceProxy, event) in - guard let pickerView = pickerView else { return } - adapter.pickerView(pickerView, observedEvent: event) - }) - return Disposables.create(delegateSubscription, dataSourceSubscription) - } - } - - /** - Synchronous helper method for retrieving a model at indexPath through a reactive data source. - */ - public func model(at indexPath: IndexPath) throws -> T { - let dataSource: SectionedViewDataSourceType = castOrFatalError(self.dataSource.forwardToDelegate(), message: "This method only works in case one of the `rx.itemTitles, rx.itemAttributedTitles, items(_ source: O)` methods was used.") - - return castOrFatalError(try dataSource.model(at: indexPath)) - } - } - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UIRefreshControl+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UIRefreshControl+Rx.swift deleted file mode 100644 index cdb10be16..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UIRefreshControl+Rx.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// UIRefreshControl+Rx.swift -// RxCocoa -// -// Created by Yosuke Ishikawa on 1/31/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) - -import UIKit -import RxSwift - -extension Reactive where Base: UIRefreshControl { - /// Bindable sink for `beginRefreshing()`, `endRefreshing()` methods. - public var isRefreshing: Binder { - return Binder(self.base) { refreshControl, refresh in - if refresh { - refreshControl.beginRefreshing() - } else { - refreshControl.endRefreshing() - } - } - } - -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UIScrollView+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UIScrollView+Rx.swift deleted file mode 100644 index f90e1c26f..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UIScrollView+Rx.swift +++ /dev/null @@ -1,131 +0,0 @@ -// -// UIScrollView+Rx.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 4/3/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - - import RxSwift - import UIKit - - extension Reactive where Base: UIScrollView { - public typealias EndZoomEvent = (view: UIView?, scale: CGFloat) - public typealias WillEndDraggingEvent = (velocity: CGPoint, targetContentOffset: UnsafeMutablePointer) - - /// Reactive wrapper for `delegate`. - /// - /// For more information take a look at `DelegateProxyType` protocol documentation. - public var delegate: DelegateProxy { - return RxScrollViewDelegateProxy.proxy(for: base) - } - - /// Reactive wrapper for `contentOffset`. - public var contentOffset: ControlProperty { - let proxy = RxScrollViewDelegateProxy.proxy(for: base) - - let bindingObserver = Binder(self.base) { scrollView, contentOffset in - scrollView.contentOffset = contentOffset - } - - return ControlProperty(values: proxy.contentOffsetBehaviorSubject, valueSink: bindingObserver) - } - - /// Reactive wrapper for delegate method `scrollViewDidScroll` - public var didScroll: ControlEvent { - let source = RxScrollViewDelegateProxy.proxy(for: base).contentOffsetPublishSubject - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `scrollViewWillBeginDecelerating` - public var willBeginDecelerating: ControlEvent { - let source = delegate.methodInvoked(#selector(UIScrollViewDelegate.scrollViewWillBeginDecelerating(_:))).map { _ in } - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `scrollViewDidEndDecelerating` - public var didEndDecelerating: ControlEvent { - let source = delegate.methodInvoked(#selector(UIScrollViewDelegate.scrollViewDidEndDecelerating(_:))).map { _ in } - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `scrollViewWillBeginDragging` - public var willBeginDragging: ControlEvent { - let source = delegate.methodInvoked(#selector(UIScrollViewDelegate.scrollViewWillBeginDragging(_:))).map { _ in } - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `scrollViewWillEndDragging(_:withVelocity:targetContentOffset:)` - public var willEndDragging: ControlEvent { - let source = delegate.methodInvoked(#selector(UIScrollViewDelegate.scrollViewWillEndDragging(_:withVelocity:targetContentOffset:))) - .map { value -> WillEndDraggingEvent in - let velocity = try castOrThrow(CGPoint.self, value[1]) - let targetContentOffsetValue = try castOrThrow(NSValue.self, value[2]) - - guard let rawPointer = targetContentOffsetValue.pointerValue else { throw RxCocoaError.unknown } - let typedPointer = rawPointer.bindMemory(to: CGPoint.self, capacity: MemoryLayout.size) - - return (velocity, typedPointer) - } - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `scrollViewDidEndDragging(_:willDecelerate:)` - public var didEndDragging: ControlEvent { - let source = delegate.methodInvoked(#selector(UIScrollViewDelegate.scrollViewDidEndDragging(_:willDecelerate:))).map { value -> Bool in - return try castOrThrow(Bool.self, value[1]) - } - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `scrollViewDidZoom` - public var didZoom: ControlEvent { - let source = delegate.methodInvoked(#selector(UIScrollViewDelegate.scrollViewDidZoom)).map { _ in } - return ControlEvent(events: source) - } - - - /// Reactive wrapper for delegate method `scrollViewDidScrollToTop` - public var didScrollToTop: ControlEvent { - let source = delegate.methodInvoked(#selector(UIScrollViewDelegate.scrollViewDidScrollToTop(_:))).map { _ in } - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `scrollViewDidEndScrollingAnimation` - public var didEndScrollingAnimation: ControlEvent { - let source = delegate.methodInvoked(#selector(UIScrollViewDelegate.scrollViewDidEndScrollingAnimation(_:))).map { _ in } - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `scrollViewWillBeginZooming(_:with:)` - public var willBeginZooming: ControlEvent { - let source = delegate.methodInvoked(#selector(UIScrollViewDelegate.scrollViewWillBeginZooming(_:with:))).map { value -> UIView? in - return try castOptionalOrThrow(UIView.self, value[1] as AnyObject) - } - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `scrollViewDidEndZooming(_:with:atScale:)` - public var didEndZooming: ControlEvent { - let source = delegate.methodInvoked(#selector(UIScrollViewDelegate.scrollViewDidEndZooming(_:with:atScale:))).map { value -> EndZoomEvent in - return (try castOptionalOrThrow(UIView.self, value[1] as AnyObject), try castOrThrow(CGFloat.self, value[2])) - } - return ControlEvent(events: source) - } - - /// Installs delegate as forwarding delegate on `delegate`. - /// Delegate won't be retained. - /// - /// It enables using normal delegate mechanism with reactive delegate mechanism. - /// - /// - parameter delegate: Delegate object. - /// - returns: Disposable object that can be used to unbind the delegate. - public func setDelegate(_ delegate: UIScrollViewDelegate) - -> Disposable { - return RxScrollViewDelegateProxy.installForwardDelegate(delegate, retainDelegate: false, onProxyForObject: self.base) - } - } - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UISearchBar+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UISearchBar+Rx.swift deleted file mode 100644 index 3892b1caf..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UISearchBar+Rx.swift +++ /dev/null @@ -1,136 +0,0 @@ -// -// UISearchBar+Rx.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 3/28/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import RxSwift -import UIKit - -extension Reactive where Base: UISearchBar { - - /// Reactive wrapper for `delegate`. - /// - /// For more information take a look at `DelegateProxyType` protocol documentation. - public var delegate: DelegateProxy { - RxSearchBarDelegateProxy.proxy(for: base) - } - - /// Reactive wrapper for `text` property. - public var text: ControlProperty { - value - } - - /// Reactive wrapper for `text` property. - public var value: ControlProperty { - let source: Observable = Observable.deferred { [weak searchBar = self.base as UISearchBar] () -> Observable in - let text = searchBar?.text - - let textDidChange = (searchBar?.rx.delegate.methodInvoked(#selector(UISearchBarDelegate.searchBar(_:textDidChange:))) ?? Observable.empty()) - let didEndEditing = (searchBar?.rx.delegate.methodInvoked(#selector(UISearchBarDelegate.searchBarTextDidEndEditing(_:))) ?? Observable.empty()) - - return Observable.merge(textDidChange, didEndEditing) - .map { _ in searchBar?.text ?? "" } - .startWith(text) - } - - let bindingObserver = Binder(self.base) { (searchBar, text: String?) in - searchBar.text = text - } - - return ControlProperty(values: source, valueSink: bindingObserver) - } - - /// Reactive wrapper for `selectedScopeButtonIndex` property. - public var selectedScopeButtonIndex: ControlProperty { - let source: Observable = Observable.deferred { [weak source = self.base as UISearchBar] () -> Observable in - let index = source?.selectedScopeButtonIndex ?? 0 - - return (source?.rx.delegate.methodInvoked(#selector(UISearchBarDelegate.searchBar(_:selectedScopeButtonIndexDidChange:))) ?? Observable.empty()) - .map { a in - return try castOrThrow(Int.self, a[1]) - } - .startWith(index) - } - - let bindingObserver = Binder(self.base) { (searchBar, index: Int) in - searchBar.selectedScopeButtonIndex = index - } - - return ControlProperty(values: source, valueSink: bindingObserver) - } - -#if os(iOS) - /// Reactive wrapper for delegate method `searchBarCancelButtonClicked`. - public var cancelButtonClicked: ControlEvent { - let source: Observable = self.delegate.methodInvoked(#selector(UISearchBarDelegate.searchBarCancelButtonClicked(_:))) - .map { _ in - return () - } - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `searchBarBookmarkButtonClicked`. - public var bookmarkButtonClicked: ControlEvent { - let source: Observable = self.delegate.methodInvoked(#selector(UISearchBarDelegate.searchBarBookmarkButtonClicked(_:))) - .map { _ in - return () - } - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `searchBarResultsListButtonClicked`. - public var resultsListButtonClicked: ControlEvent { - let source: Observable = self.delegate.methodInvoked(#selector(UISearchBarDelegate.searchBarResultsListButtonClicked(_:))) - .map { _ in - return () - } - return ControlEvent(events: source) - } -#endif - - /// Reactive wrapper for delegate method `searchBarSearchButtonClicked`. - public var searchButtonClicked: ControlEvent { - let source: Observable = self.delegate.methodInvoked(#selector(UISearchBarDelegate.searchBarSearchButtonClicked(_:))) - .map { _ in - return () - } - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `searchBarTextDidBeginEditing`. - public var textDidBeginEditing: ControlEvent { - let source: Observable = self.delegate.methodInvoked(#selector(UISearchBarDelegate.searchBarTextDidBeginEditing(_:))) - .map { _ in - return () - } - return ControlEvent(events: source) - } - - /// Reactive wrapper for delegate method `searchBarTextDidEndEditing`. - public var textDidEndEditing: ControlEvent { - let source: Observable = self.delegate.methodInvoked(#selector(UISearchBarDelegate.searchBarTextDidEndEditing(_:))) - .map { _ in - return () - } - return ControlEvent(events: source) - } - - /// Installs delegate as forwarding delegate on `delegate`. - /// Delegate won't be retained. - /// - /// It enables using normal delegate mechanism with reactive delegate mechanism. - /// - /// - parameter delegate: Delegate object. - /// - returns: Disposable object that can be used to unbind the delegate. - public func setDelegate(_ delegate: UISearchBarDelegate) - -> Disposable { - RxSearchBarDelegateProxy.installForwardDelegate(delegate, retainDelegate: false, onProxyForObject: self.base) - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UISearchController+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UISearchController+Rx.swift deleted file mode 100644 index 4f524a51a..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UISearchController+Rx.swift +++ /dev/null @@ -1,58 +0,0 @@ -// -// UISearchController+Rx.swift -// RxCocoa -// -// Created by Segii Shulga on 3/17/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) - - import RxSwift - import UIKit - - extension Reactive where Base: UISearchController { - /// Reactive wrapper for `delegate`. - /// For more information take a look at `DelegateProxyType` protocol documentation. - public var delegate: DelegateProxy { - return RxSearchControllerDelegateProxy.proxy(for: base) - } - - /// Reactive wrapper for `delegate` message. - public var didDismiss: Observable { - return delegate - .methodInvoked( #selector(UISearchControllerDelegate.didDismissSearchController(_:))) - .map { _ in } - } - - /// Reactive wrapper for `delegate` message. - public var didPresent: Observable { - return delegate - .methodInvoked(#selector(UISearchControllerDelegate.didPresentSearchController(_:))) - .map { _ in } - } - - /// Reactive wrapper for `delegate` message. - public var present: Observable { - return delegate - .methodInvoked( #selector(UISearchControllerDelegate.presentSearchController(_:))) - .map { _ in } - } - - /// Reactive wrapper for `delegate` message. - public var willDismiss: Observable { - return delegate - .methodInvoked(#selector(UISearchControllerDelegate.willDismissSearchController(_:))) - .map { _ in } - } - - /// Reactive wrapper for `delegate` message. - public var willPresent: Observable { - return delegate - .methodInvoked( #selector(UISearchControllerDelegate.willPresentSearchController(_:))) - .map { _ in } - } - - } - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UISegmentedControl+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UISegmentedControl+Rx.swift deleted file mode 100644 index 1a6266261..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UISegmentedControl+Rx.swift +++ /dev/null @@ -1,54 +0,0 @@ -// -// UISegmentedControl+Rx.swift -// RxCocoa -// -// Created by Carlos García on 8/7/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -extension Reactive where Base: UISegmentedControl { - /// Reactive wrapper for `selectedSegmentIndex` property. - public var selectedSegmentIndex: ControlProperty { - value - } - - /// Reactive wrapper for `selectedSegmentIndex` property. - public var value: ControlProperty { - return base.rx.controlPropertyWithDefaultEvents( - getter: { segmentedControl in - segmentedControl.selectedSegmentIndex - }, setter: { segmentedControl, value in - segmentedControl.selectedSegmentIndex = value - } - ) - } - - /// Reactive wrapper for `setEnabled(_:forSegmentAt:)` - public func enabledForSegment(at index: Int) -> Binder { - return Binder(self.base) { segmentedControl, segmentEnabled -> Void in - segmentedControl.setEnabled(segmentEnabled, forSegmentAt: index) - } - } - - /// Reactive wrapper for `setTitle(_:forSegmentAt:)` - public func titleForSegment(at index: Int) -> Binder { - return Binder(self.base) { segmentedControl, title -> Void in - segmentedControl.setTitle(title, forSegmentAt: index) - } - } - - /// Reactive wrapper for `setImage(_:forSegmentAt:)` - public func imageForSegment(at index: Int) -> Binder { - return Binder(self.base) { segmentedControl, image -> Void in - segmentedControl.setImage(image, forSegmentAt: index) - } - } - -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UISlider+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UISlider+Rx.swift deleted file mode 100644 index 07d4adb5a..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UISlider+Rx.swift +++ /dev/null @@ -1,29 +0,0 @@ -// -// UISlider+Rx.swift -// RxCocoa -// -// Created by Alexander van der Werff on 28/05/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) - -import RxSwift -import UIKit - -extension Reactive where Base: UISlider { - - /// Reactive wrapper for `value` property. - public var value: ControlProperty { - return base.rx.controlPropertyWithDefaultEvents( - getter: { slider in - slider.value - }, setter: { slider, value in - slider.value = value - } - ) - } - -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UIStepper+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UIStepper+Rx.swift deleted file mode 100644 index 29f638600..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UIStepper+Rx.swift +++ /dev/null @@ -1,29 +0,0 @@ -// -// UIStepper+Rx.swift -// RxCocoa -// -// Created by Yuta ToKoRo on 9/1/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) - -import UIKit -import RxSwift - -extension Reactive where Base: UIStepper { - - /// Reactive wrapper for `value` property. - public var value: ControlProperty { - return base.rx.controlPropertyWithDefaultEvents( - getter: { stepper in - stepper.value - }, setter: { stepper, value in - stepper.value = value - } - ) - } -} - -#endif - diff --git a/Pods/RxCocoa/RxCocoa/iOS/UISwitch+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UISwitch+Rx.swift deleted file mode 100644 index 6e116b390..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UISwitch+Rx.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// UISwitch+Rx.swift -// RxCocoa -// -// Created by Carlos García on 8/7/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) - -import UIKit -import RxSwift - -extension Reactive where Base: UISwitch { - - /// Reactive wrapper for `isOn` property. - public var isOn: ControlProperty { - value - } - - /// Reactive wrapper for `isOn` property. - /// - /// ⚠️ Versions prior to iOS 10.2 were leaking `UISwitch`'s, so on those versions - /// underlying observable sequence won't complete when nothing holds a strong reference - /// to `UISwitch`. - public var value: ControlProperty { - return base.rx.controlPropertyWithDefaultEvents( - getter: { uiSwitch in - uiSwitch.isOn - }, setter: { uiSwitch, value in - uiSwitch.isOn = value - } - ) - } - -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UITabBar+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UITabBar+Rx.swift deleted file mode 100644 index e98966725..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UITabBar+Rx.swift +++ /dev/null @@ -1,92 +0,0 @@ -// -// UITabBar+Rx.swift -// RxCocoa -// -// Created by Jesse Farless on 5/13/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -/** - iOS only - */ -#if os(iOS) -extension Reactive where Base: UITabBar { - - /// Reactive wrapper for `delegate` message `tabBar(_:willBeginCustomizing:)`. - public var willBeginCustomizing: ControlEvent<[UITabBarItem]> { - - let source = delegate.methodInvoked(#selector(UITabBarDelegate.tabBar(_:willBeginCustomizing:))) - .map { a in - return try castOrThrow([UITabBarItem].self, a[1]) - } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `delegate` message `tabBar(_:didBeginCustomizing:)`. - public var didBeginCustomizing: ControlEvent<[UITabBarItem]> { - let source = delegate.methodInvoked(#selector(UITabBarDelegate.tabBar(_:didBeginCustomizing:))) - .map { a in - return try castOrThrow([UITabBarItem].self, a[1]) - } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `delegate` message `tabBar(_:willEndCustomizing:changed:)`. - public var willEndCustomizing: ControlEvent<([UITabBarItem], Bool)> { - let source = delegate.methodInvoked(#selector(UITabBarDelegate.tabBar(_:willEndCustomizing:changed:))) - .map { (a: [Any]) -> (([UITabBarItem], Bool)) in - let items = try castOrThrow([UITabBarItem].self, a[1]) - let changed = try castOrThrow(Bool.self, a[2]) - return (items, changed) - } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `delegate` message `tabBar(_:didEndCustomizing:changed:)`. - public var didEndCustomizing: ControlEvent<([UITabBarItem], Bool)> { - let source = delegate.methodInvoked(#selector(UITabBarDelegate.tabBar(_:didEndCustomizing:changed:))) - .map { (a: [Any]) -> (([UITabBarItem], Bool)) in - let items = try castOrThrow([UITabBarItem].self, a[1]) - let changed = try castOrThrow(Bool.self, a[2]) - return (items, changed) - } - - return ControlEvent(events: source) - } - -} -#endif - -/** - iOS and tvOS - */ - -extension Reactive where Base: UITabBar { - /// Reactive wrapper for `delegate`. - /// - /// For more information take a look at `DelegateProxyType` protocol documentation. - public var delegate: DelegateProxy { - RxTabBarDelegateProxy.proxy(for: base) - } - - /// Reactive wrapper for `delegate` message `tabBar(_:didSelect:)`. - public var didSelectItem: ControlEvent { - let source = delegate.methodInvoked(#selector(UITabBarDelegate.tabBar(_:didSelect:))) - .map { a in - return try castOrThrow(UITabBarItem.self, a[1]) - } - - return ControlEvent(events: source) - } - -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UITabBarController+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UITabBarController+Rx.swift deleted file mode 100644 index 4b48e8e55..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UITabBarController+Rx.swift +++ /dev/null @@ -1,79 +0,0 @@ -// -// UITabBarController+Rx.swift -// RxCocoa -// -// Created by Yusuke Kita on 2016/12/07. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -/** - iOS only - */ -#if os(iOS) -extension Reactive where Base: UITabBarController { - - /// Reactive wrapper for `delegate` message `tabBarController:willBeginCustomizing:`. - public var willBeginCustomizing: ControlEvent<[UIViewController]> { - let source = delegate.methodInvoked(#selector(UITabBarControllerDelegate.tabBarController(_:willBeginCustomizing:))) - .map { a in - return try castOrThrow([UIViewController].self, a[1]) - } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `delegate` message `tabBarController:willEndCustomizing:changed:`. - public var willEndCustomizing: ControlEvent<(viewControllers: [UIViewController], changed: Bool)> { - let source = delegate.methodInvoked(#selector(UITabBarControllerDelegate.tabBarController(_:willEndCustomizing:changed:))) - .map { (a: [Any]) -> (viewControllers: [UIViewController], changed: Bool) in - let viewControllers = try castOrThrow([UIViewController].self, a[1]) - let changed = try castOrThrow(Bool.self, a[2]) - return (viewControllers, changed) - } - - return ControlEvent(events: source) - } - - /// Reactive wrapper for `delegate` message `tabBarController:didEndCustomizing:changed:`. - public var didEndCustomizing: ControlEvent<(viewControllers: [UIViewController], changed: Bool)> { - let source = delegate.methodInvoked(#selector(UITabBarControllerDelegate.tabBarController(_:didEndCustomizing:changed:))) - .map { (a: [Any]) -> (viewControllers: [UIViewController], changed: Bool) in - let viewControllers = try castOrThrow([UIViewController].self, a[1]) - let changed = try castOrThrow(Bool.self, a[2]) - return (viewControllers, changed) - } - - return ControlEvent(events: source) - } -} -#endif - -/** - iOS and tvOS - */ - - extension Reactive where Base: UITabBarController { - /// Reactive wrapper for `delegate`. - /// - /// For more information take a look at `DelegateProxyType` protocol documentation. - public var delegate: DelegateProxy { - RxTabBarControllerDelegateProxy.proxy(for: base) - } - - /// Reactive wrapper for `delegate` message `tabBarController:didSelect:`. - public var didSelect: ControlEvent { - let source = delegate.methodInvoked(#selector(UITabBarControllerDelegate.tabBarController(_:didSelect:))) - .map { a in - return try castOrThrow(UIViewController.self, a[1]) - } - - return ControlEvent(events: source) - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UITableView+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UITableView+Rx.swift deleted file mode 100644 index b21713396..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UITableView+Rx.swift +++ /dev/null @@ -1,429 +0,0 @@ -// -// UITableView+Rx.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 4/2/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import RxSwift -import UIKit - -// Items - -extension Reactive where Base: UITableView { - - /** - Binds sequences of elements to table view rows. - - - parameter source: Observable sequence of items. - - parameter cellFactory: Transform between sequence elements and view cells. - - returns: Disposable object that can be used to unbind. - - Example: - - let items = Observable.just([ - "First Item", - "Second Item", - "Third Item" - ]) - - items - .bind(to: tableView.rx.items) { (tableView, row, element) in - let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")! - cell.textLabel?.text = "\(element) @ row \(row)" - return cell - } - .disposed(by: disposeBag) - - */ - public func items - (_ source: Source) - -> (_ cellFactory: @escaping (UITableView, Int, Sequence.Element) -> UITableViewCell) - -> Disposable - where Source.Element == Sequence { - return { cellFactory in - let dataSource = RxTableViewReactiveArrayDataSourceSequenceWrapper(cellFactory: cellFactory) - return self.items(dataSource: dataSource)(source) - } - } - - /** - Binds sequences of elements to table view rows. - - - parameter cellIdentifier: Identifier used to dequeue cells. - - parameter source: Observable sequence of items. - - parameter configureCell: Transform between sequence elements and view cells. - - parameter cellType: Type of table view cell. - - returns: Disposable object that can be used to unbind. - - Example: - - let items = Observable.just([ - "First Item", - "Second Item", - "Third Item" - ]) - - items - .bind(to: tableView.rx.items(cellIdentifier: "Cell", cellType: UITableViewCell.self)) { (row, element, cell) in - cell.textLabel?.text = "\(element) @ row \(row)" - } - .disposed(by: disposeBag) - */ - public func items - (cellIdentifier: String, cellType: Cell.Type = Cell.self) - -> (_ source: Source) - -> (_ configureCell: @escaping (Int, Sequence.Element, Cell) -> Void) - -> Disposable - where Source.Element == Sequence { - return { source in - return { configureCell in - let dataSource = RxTableViewReactiveArrayDataSourceSequenceWrapper { tv, i, item in - let indexPath = IndexPath(item: i, section: 0) - let cell = tv.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! Cell - configureCell(i, item, cell) - return cell - } - return self.items(dataSource: dataSource)(source) - } - } - } - - - /** - Binds sequences of elements to table view rows using a custom reactive data used to perform the transformation. - This method will retain the data source for as long as the subscription isn't disposed (result `Disposable` - being disposed). - In case `source` observable sequence terminates successfully, the data source will present latest element - until the subscription isn't disposed. - - - parameter dataSource: Data source used to transform elements to view cells. - - parameter source: Observable sequence of items. - - returns: Disposable object that can be used to unbind. - */ - public func items< - DataSource: RxTableViewDataSourceType & UITableViewDataSource, - Source: ObservableType> - (dataSource: DataSource) - -> (_ source: Source) - -> Disposable - where DataSource.Element == Source.Element { - return { source in - // This is called for sideeffects only, and to make sure delegate proxy is in place when - // data source is being bound. - // This is needed because theoretically the data source subscription itself might - // call `self.rx.delegate`. If that happens, it might cause weird side effects since - // setting data source will set delegate, and UITableView might get into a weird state. - // Therefore it's better to set delegate proxy first, just to be sure. - _ = self.delegate - // Strong reference is needed because data source is in use until result subscription is disposed - return source.subscribeProxyDataSource(ofObject: self.base, dataSource: dataSource as UITableViewDataSource, retainDataSource: true) { [weak tableView = self.base] (_: RxTableViewDataSourceProxy, event) -> Void in - guard let tableView = tableView else { - return - } - dataSource.tableView(tableView, observedEvent: event) - } - } - } - -} - -extension Reactive where Base: UITableView { - /** - Reactive wrapper for `dataSource`. - - For more information take a look at `DelegateProxyType` protocol documentation. - */ - public var dataSource: DelegateProxy { - RxTableViewDataSourceProxy.proxy(for: base) - } - - /** - Installs data source as forwarding delegate on `rx.dataSource`. - Data source won't be retained. - - It enables using normal delegate mechanism with reactive delegate mechanism. - - - parameter dataSource: Data source object. - - returns: Disposable object that can be used to unbind the data source. - */ - public func setDataSource(_ dataSource: UITableViewDataSource) - -> Disposable { - RxTableViewDataSourceProxy.installForwardDelegate(dataSource, retainDelegate: false, onProxyForObject: self.base) - } - - // events - - /** - Reactive wrapper for `delegate` message `tableView:didSelectRowAtIndexPath:`. - */ - public var itemSelected: ControlEvent { - let source = self.delegate.methodInvoked(#selector(UITableViewDelegate.tableView(_:didSelectRowAt:))) - .map { a in - return try castOrThrow(IndexPath.self, a[1]) - } - - return ControlEvent(events: source) - } - - /** - Reactive wrapper for `delegate` message `tableView:didDeselectRowAtIndexPath:`. - */ - public var itemDeselected: ControlEvent { - let source = self.delegate.methodInvoked(#selector(UITableViewDelegate.tableView(_:didDeselectRowAt:))) - .map { a in - return try castOrThrow(IndexPath.self, a[1]) - } - - return ControlEvent(events: source) - } - - /** - Reactive wrapper for `delegate` message `tableView:didHighlightRowAt:`. - */ - public var itemHighlighted: ControlEvent { - let source = self.delegate.methodInvoked(#selector(UITableViewDelegate.tableView(_:didHighlightRowAt:))) - .map { a in - return try castOrThrow(IndexPath.self, a[1]) - } - - return ControlEvent(events: source) - } - - /** - Reactive wrapper for `delegate` message `tableView:didUnhighlightRowAt:`. - */ - public var itemUnhighlighted: ControlEvent { - let source = self.delegate.methodInvoked(#selector(UITableViewDelegate.tableView(_:didUnhighlightRowAt:))) - .map { a in - return try castOrThrow(IndexPath.self, a[1]) - } - - return ControlEvent(events: source) - } - - /** - Reactive wrapper for `delegate` message `tableView:accessoryButtonTappedForRowWithIndexPath:`. - */ - public var itemAccessoryButtonTapped: ControlEvent { - let source: Observable = self.delegate.methodInvoked(#selector(UITableViewDelegate.tableView(_:accessoryButtonTappedForRowWith:))) - .map { a in - return try castOrThrow(IndexPath.self, a[1]) - } - - return ControlEvent(events: source) - } - - /** - Reactive wrapper for `delegate` message `tableView:commitEditingStyle:forRowAtIndexPath:`. - */ - public var itemInserted: ControlEvent { - let source = self.dataSource.methodInvoked(#selector(UITableViewDataSource.tableView(_:commit:forRowAt:))) - .filter { a in - return UITableViewCell.EditingStyle(rawValue: (try castOrThrow(NSNumber.self, a[1])).intValue) == .insert - } - .map { a in - return (try castOrThrow(IndexPath.self, a[2])) - } - - return ControlEvent(events: source) - } - - /** - Reactive wrapper for `delegate` message `tableView:commitEditingStyle:forRowAtIndexPath:`. - */ - public var itemDeleted: ControlEvent { - let source = self.dataSource.methodInvoked(#selector(UITableViewDataSource.tableView(_:commit:forRowAt:))) - .filter { a in - return UITableViewCell.EditingStyle(rawValue: (try castOrThrow(NSNumber.self, a[1])).intValue) == .delete - } - .map { a in - return try castOrThrow(IndexPath.self, a[2]) - } - - return ControlEvent(events: source) - } - - /** - Reactive wrapper for `delegate` message `tableView:moveRowAtIndexPath:toIndexPath:`. - */ - public var itemMoved: ControlEvent { - let source: Observable = self.dataSource.methodInvoked(#selector(UITableViewDataSource.tableView(_:moveRowAt:to:))) - .map { a in - return (try castOrThrow(IndexPath.self, a[1]), try castOrThrow(IndexPath.self, a[2])) - } - - return ControlEvent(events: source) - } - - /** - Reactive wrapper for `delegate` message `tableView:willDisplayCell:forRowAtIndexPath:`. - */ - public var willDisplayCell: ControlEvent { - let source: Observable = self.delegate.methodInvoked(#selector(UITableViewDelegate.tableView(_:willDisplay:forRowAt:))) - .map { a in - return (try castOrThrow(UITableViewCell.self, a[1]), try castOrThrow(IndexPath.self, a[2])) - } - - return ControlEvent(events: source) - } - - /** - Reactive wrapper for `delegate` message `tableView:didEndDisplayingCell:forRowAtIndexPath:`. - */ - public var didEndDisplayingCell: ControlEvent { - let source: Observable = self.delegate.methodInvoked(#selector(UITableViewDelegate.tableView(_:didEndDisplaying:forRowAt:))) - .map { a in - return (try castOrThrow(UITableViewCell.self, a[1]), try castOrThrow(IndexPath.self, a[2])) - } - - return ControlEvent(events: source) - } - - /** - Reactive wrapper for `delegate` message `tableView:didSelectRowAtIndexPath:`. - - It can be only used when one of the `rx.itemsWith*` methods is used to bind observable sequence, - or any other data source conforming to `SectionedViewDataSourceType` protocol. - - ``` - tableView.rx.modelSelected(MyModel.self) - .map { ... - ``` - */ - public func modelSelected(_ modelType: T.Type) -> ControlEvent { - let source: Observable = self.itemSelected.flatMap { [weak view = self.base as UITableView] indexPath -> Observable in - guard let view = view else { - return Observable.empty() - } - - return Observable.just(try view.rx.model(at: indexPath)) - } - - return ControlEvent(events: source) - } - - /** - Reactive wrapper for `delegate` message `tableView:didDeselectRowAtIndexPath:`. - - It can be only used when one of the `rx.itemsWith*` methods is used to bind observable sequence, - or any other data source conforming to `SectionedViewDataSourceType` protocol. - - ``` - tableView.rx.modelDeselected(MyModel.self) - .map { ... - ``` - */ - public func modelDeselected(_ modelType: T.Type) -> ControlEvent { - let source: Observable = self.itemDeselected.flatMap { [weak view = self.base as UITableView] indexPath -> Observable in - guard let view = view else { - return Observable.empty() - } - - return Observable.just(try view.rx.model(at: indexPath)) - } - - return ControlEvent(events: source) - } - - /** - Reactive wrapper for `delegate` message `tableView:commitEditingStyle:forRowAtIndexPath:`. - - It can be only used when one of the `rx.itemsWith*` methods is used to bind observable sequence, - or any other data source conforming to `SectionedViewDataSourceType` protocol. - - ``` - tableView.rx.modelDeleted(MyModel.self) - .map { ... - ``` - */ - public func modelDeleted(_ modelType: T.Type) -> ControlEvent { - let source: Observable = self.itemDeleted.flatMap { [weak view = self.base as UITableView] indexPath -> Observable in - guard let view = view else { - return Observable.empty() - } - - return Observable.just(try view.rx.model(at: indexPath)) - } - - return ControlEvent(events: source) - } - - /** - Synchronous helper method for retrieving a model at indexPath through a reactive data source. - */ - public func model(at indexPath: IndexPath) throws -> T { - let dataSource: SectionedViewDataSourceType = castOrFatalError(self.dataSource.forwardToDelegate(), message: "This method only works in case one of the `rx.items*` methods was used.") - - let element = try dataSource.model(at: indexPath) - - return castOrFatalError(element) - } -} - -@available(iOS 10.0, tvOS 10.0, *) -extension Reactive where Base: UITableView { - - /// Reactive wrapper for `prefetchDataSource`. - /// - /// For more information take a look at `DelegateProxyType` protocol documentation. - public var prefetchDataSource: DelegateProxy { - RxTableViewDataSourcePrefetchingProxy.proxy(for: base) - } - - /** - Installs prefetch data source as forwarding delegate on `rx.prefetchDataSource`. - Prefetch data source won't be retained. - - It enables using normal delegate mechanism with reactive delegate mechanism. - - - parameter prefetchDataSource: Prefetch data source object. - - returns: Disposable object that can be used to unbind the data source. - */ - public func setPrefetchDataSource(_ prefetchDataSource: UITableViewDataSourcePrefetching) - -> Disposable { - return RxTableViewDataSourcePrefetchingProxy.installForwardDelegate(prefetchDataSource, retainDelegate: false, onProxyForObject: self.base) - } - - /// Reactive wrapper for `prefetchDataSource` message `tableView(_:prefetchRowsAt:)`. - public var prefetchRows: ControlEvent<[IndexPath]> { - let source = RxTableViewDataSourcePrefetchingProxy.proxy(for: base).prefetchRowsPublishSubject - return ControlEvent(events: source) - } - - /// Reactive wrapper for `prefetchDataSource` message `tableView(_:cancelPrefetchingForRowsAt:)`. - public var cancelPrefetchingForRows: ControlEvent<[IndexPath]> { - let source = prefetchDataSource.methodInvoked(#selector(UITableViewDataSourcePrefetching.tableView(_:cancelPrefetchingForRowsAt:))) - .map { a in - return try castOrThrow(Array.self, a[1]) - } - - return ControlEvent(events: source) - } - -} -#endif - -#if os(tvOS) - - extension Reactive where Base: UITableView { - - /** - Reactive wrapper for `delegate` message `tableView:didUpdateFocusInContext:withAnimationCoordinator:`. - */ - public var didUpdateFocusInContextWithAnimationCoordinator: ControlEvent<(context: UITableViewFocusUpdateContext, animationCoordinator: UIFocusAnimationCoordinator)> { - - let source = delegate.methodInvoked(#selector(UITableViewDelegate.tableView(_:didUpdateFocusIn:with:))) - .map { a -> (context: UITableViewFocusUpdateContext, animationCoordinator: UIFocusAnimationCoordinator) in - let context = try castOrThrow(UITableViewFocusUpdateContext.self, a[1]) - let animationCoordinator = try castOrThrow(UIFocusAnimationCoordinator.self, a[2]) - return (context: context, animationCoordinator: animationCoordinator) - } - - return ControlEvent(events: source) - } - } -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UITextField+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UITextField+Rx.swift deleted file mode 100644 index 614fecc78..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UITextField+Rx.swift +++ /dev/null @@ -1,55 +0,0 @@ -// -// UITextField+Rx.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 2/21/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import RxSwift -import UIKit - -extension Reactive where Base: UITextField { - /// Reactive wrapper for `text` property. - public var text: ControlProperty { - value - } - - /// Reactive wrapper for `text` property. - public var value: ControlProperty { - return base.rx.controlPropertyWithDefaultEvents( - getter: { textField in - textField.text - }, - setter: { textField, value in - // This check is important because setting text value always clears control state - // including marked text selection which is imporant for proper input - // when IME input method is used. - if textField.text != value { - textField.text = value - } - } - ) - } - - /// Bindable sink for `attributedText` property. - public var attributedText: ControlProperty { - return base.rx.controlPropertyWithDefaultEvents( - getter: { textField in - textField.attributedText - }, - setter: { textField, value in - // This check is important because setting text value always clears control state - // including marked text selection which is imporant for proper input - // when IME input method is used. - if textField.attributedText != value { - textField.attributedText = value - } - } - ) - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/UITextView+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/UITextView+Rx.swift deleted file mode 100644 index 497ab66c8..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/UITextView+Rx.swift +++ /dev/null @@ -1,125 +0,0 @@ -// -// UITextView+Rx.swift -// RxCocoa -// -// Created by Yuta ToKoRo on 7/19/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(tvOS) - -import UIKit -import RxSwift - -extension Reactive where Base: UITextView { - /// Reactive wrapper for `text` property - public var text: ControlProperty { - value - } - - /// Reactive wrapper for `text` property. - public var value: ControlProperty { - let source: Observable = Observable.deferred { [weak textView = self.base] in - let text = textView?.text - - let textChanged = textView?.textStorage - // This project uses text storage notifications because - // that's the only way to catch autocorrect changes - // in all cases. Other suggestions are welcome. - .rx.didProcessEditingRangeChangeInLength - // This observe on is here because text storage - // will emit event while process is not completely done, - // so rebinding a value will cause an exception to be thrown. - .observe(on:MainScheduler.asyncInstance) - .map { _ in - return textView?.textStorage.string - } - ?? Observable.empty() - - return textChanged - .startWith(text) - } - - let bindingObserver = Binder(self.base) { (textView, text: String?) in - // This check is important because setting text value always clears control state - // including marked text selection which is imporant for proper input - // when IME input method is used. - if textView.text != text { - textView.text = text - } - } - - return ControlProperty(values: source, valueSink: bindingObserver) - } - - - /// Reactive wrapper for `attributedText` property. - public var attributedText: ControlProperty { - let source: Observable = Observable.deferred { [weak textView = self.base] in - let attributedText = textView?.attributedText - - let textChanged: Observable = textView?.textStorage - // This project uses text storage notifications because - // that's the only way to catch autocorrect changes - // in all cases. Other suggestions are welcome. - .rx.didProcessEditingRangeChangeInLength - // This observe on is here because attributedText storage - // will emit event while process is not completely done, - // so rebinding a value will cause an exception to be thrown. - .observe(on:MainScheduler.asyncInstance) - .map { _ in - return textView?.attributedText - } - ?? Observable.empty() - - return textChanged - .startWith(attributedText) - } - - let bindingObserver = Binder(self.base) { (textView, attributedText: NSAttributedString?) in - // This check is important because setting text value always clears control state - // including marked text selection which is imporant for proper input - // when IME input method is used. - if textView.attributedText != attributedText { - textView.attributedText = attributedText - } - } - - return ControlProperty(values: source, valueSink: bindingObserver) - } - - /// Reactive wrapper for `delegate` message. - public var didBeginEditing: ControlEvent<()> { - return ControlEvent<()>(events: self.delegate.methodInvoked(#selector(UITextViewDelegate.textViewDidBeginEditing(_:))) - .map { _ in - return () - }) - } - - /// Reactive wrapper for `delegate` message. - public var didEndEditing: ControlEvent<()> { - return ControlEvent<()>(events: self.delegate.methodInvoked(#selector(UITextViewDelegate.textViewDidEndEditing(_:))) - .map { _ in - return () - }) - } - - /// Reactive wrapper for `delegate` message. - public var didChange: ControlEvent<()> { - return ControlEvent<()>(events: self.delegate.methodInvoked(#selector(UITextViewDelegate.textViewDidChange(_:))) - .map { _ in - return () - }) - } - - /// Reactive wrapper for `delegate` message. - public var didChangeSelection: ControlEvent<()> { - return ControlEvent<()>(events: self.delegate.methodInvoked(#selector(UITextViewDelegate.textViewDidChangeSelection(_:))) - .map { _ in - return () - }) - } - -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/iOS/WKWebView+Rx.swift b/Pods/RxCocoa/RxCocoa/iOS/WKWebView+Rx.swift deleted file mode 100644 index b3b4d8479..000000000 --- a/Pods/RxCocoa/RxCocoa/iOS/WKWebView+Rx.swift +++ /dev/null @@ -1,57 +0,0 @@ -// -// WKWebView+Rx.swift -// RxCocoa -// -// Created by Giuseppe Lanza on 14/02/2020. -// Copyright © 2020 Krunoslav Zaher. All rights reserved. -// - -#if os(iOS) || os(macOS) - -import RxSwift -import WebKit - -@available(iOS 8.0, OSX 10.10, OSXApplicationExtension 10.10, *) -extension Reactive where Base: WKWebView { - - /// Reactive wrapper for `navigationDelegate`. - /// For more information take a look at `DelegateProxyType` protocol documentation. - public var navigationDelegate: DelegateProxy { - RxWKNavigationDelegateProxy.proxy(for: base) - } - - /// Reactive wrapper for `navigationDelegate` message. - public var didCommit: Observable { - navigationDelegate - .methodInvoked(#selector(WKNavigationDelegate.webView(_:didCommit:))) - .map { a in try castOrThrow(WKNavigation.self, a[1]) } - } - - /// Reactive wrapper for `navigationDelegate` message. - public var didStartLoad: Observable { - navigationDelegate - .methodInvoked(#selector(WKNavigationDelegate.webView(_:didStartProvisionalNavigation:))) - .map { a in try castOrThrow(WKNavigation.self, a[1]) } - } - - /// Reactive wrapper for `navigationDelegate` message. - public var didFinishLoad: Observable { - navigationDelegate - .methodInvoked(#selector(WKNavigationDelegate.webView(_:didFinish:))) - .map { a in try castOrThrow(WKNavigation.self, a[1]) } - } - - /// Reactive wrapper for `navigationDelegate` message. - public var didFailLoad: Observable<(WKNavigation, Error)> { - navigationDelegate - .methodInvoked(#selector(WKNavigationDelegate.webView(_:didFail:withError:))) - .map { a in - ( - try castOrThrow(WKNavigation.self, a[1]), - try castOrThrow(Error.self, a[2]) - ) - } - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/macOS/NSButton+Rx.swift b/Pods/RxCocoa/RxCocoa/macOS/NSButton+Rx.swift deleted file mode 100644 index 7c223618f..000000000 --- a/Pods/RxCocoa/RxCocoa/macOS/NSButton+Rx.swift +++ /dev/null @@ -1,33 +0,0 @@ -// -// NSButton+Rx.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 5/17/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(macOS) - -import RxSwift -import Cocoa - -extension Reactive where Base: NSButton { - - /// Reactive wrapper for control event. - public var tap: ControlEvent { - self.controlEvent - } - - /// Reactive wrapper for `state` property`. - public var state: ControlProperty { - return self.base.rx.controlProperty( - getter: { control in - return control.state - }, setter: { (control: NSButton, state: NSControl.StateValue) in - control.state = state - } - ) - } -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/macOS/NSControl+Rx.swift b/Pods/RxCocoa/RxCocoa/macOS/NSControl+Rx.swift deleted file mode 100644 index 534f40cab..000000000 --- a/Pods/RxCocoa/RxCocoa/macOS/NSControl+Rx.swift +++ /dev/null @@ -1,87 +0,0 @@ -// -// NSControl+Rx.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 5/31/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(macOS) - -import Cocoa -import RxSwift - -private var rx_value_key: UInt8 = 0 -private var rx_control_events_key: UInt8 = 0 - -extension Reactive where Base: NSControl { - - /// Reactive wrapper for control event. - public var controlEvent: ControlEvent<()> { - MainScheduler.ensureRunningOnMainThread() - - let source = self.lazyInstanceObservable(&rx_control_events_key) { () -> Observable in - Observable.create { [weak control = self.base] observer in - MainScheduler.ensureRunningOnMainThread() - - guard let control = control else { - observer.on(.completed) - return Disposables.create() - } - - let observer = ControlTarget(control: control) { _ in - observer.on(.next(())) - } - - return observer - } - .take(until: self.deallocated) - .share() - } - - return ControlEvent(events: source) - } - - /// Creates a `ControlProperty` that is triggered by target/action pattern value updates. - /// - /// - parameter getter: Property value getter. - /// - parameter setter: Property value setter. - public func controlProperty( - getter: @escaping (Base) -> T, - setter: @escaping (Base, T) -> Void - ) -> ControlProperty { - MainScheduler.ensureRunningOnMainThread() - - let source = self.base.rx.lazyInstanceObservable(&rx_value_key) { () -> Observable<()> in - return Observable.create { [weak weakControl = self.base] (observer: AnyObserver<()>) in - guard let control = weakControl else { - observer.on(.completed) - return Disposables.create() - } - - observer.on(.next(())) - - let observer = ControlTarget(control: control) { _ in - if weakControl != nil { - observer.on(.next(())) - } - } - - return observer - } - .take(until: self.deallocated) - .share(replay: 1, scope: .whileConnected) - } - .flatMap { [weak base] _ -> Observable in - guard let control = base else { return Observable.empty() } - return Observable.just(getter(control)) - } - - let bindingObserver = Binder(self.base, binding: setter) - - return ControlProperty(values: source, valueSink: bindingObserver) - } -} - - -#endif diff --git a/Pods/RxCocoa/RxCocoa/macOS/NSSlider+Rx.swift b/Pods/RxCocoa/RxCocoa/macOS/NSSlider+Rx.swift deleted file mode 100644 index 2e5b19a85..000000000 --- a/Pods/RxCocoa/RxCocoa/macOS/NSSlider+Rx.swift +++ /dev/null @@ -1,30 +0,0 @@ -// -// NSSlider+Rx.swift -// RxCocoa -// -// Created by Junior B. on 24/05/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(macOS) - -import RxSwift -import Cocoa - -extension Reactive where Base: NSSlider { - - /// Reactive wrapper for `value` property. - public var value: ControlProperty { - return self.base.rx.controlProperty( - getter: { control -> Double in - return control.doubleValue - }, - setter: { control, value in - control.doubleValue = value - } - ) - } - -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/macOS/NSTextField+Rx.swift b/Pods/RxCocoa/RxCocoa/macOS/NSTextField+Rx.swift deleted file mode 100644 index ce69f9e9f..000000000 --- a/Pods/RxCocoa/RxCocoa/macOS/NSTextField+Rx.swift +++ /dev/null @@ -1,87 +0,0 @@ -// -// NSTextField+Rx.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 5/17/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(macOS) - -import Cocoa -import RxSwift - -/// Delegate proxy for `NSTextField`. -/// -/// For more information take a look at `DelegateProxyType`. -open class RxTextFieldDelegateProxy - : DelegateProxy - , DelegateProxyType - , NSTextFieldDelegate { - - /// Typed parent object. - public weak private(set) var textField: NSTextField? - - /// Initializes `RxTextFieldDelegateProxy` - /// - /// - parameter textField: Parent object for delegate proxy. - init(textField: NSTextField) { - self.textField = textField - super.init(parentObject: textField, delegateProxy: RxTextFieldDelegateProxy.self) - } - - public static func registerKnownImplementations() { - self.register { RxTextFieldDelegateProxy(textField: $0) } - } - - fileprivate let textSubject = PublishSubject() - - // MARK: Delegate methods - open func controlTextDidChange(_ notification: Notification) { - let textField: NSTextField = castOrFatalError(notification.object) - let nextValue = textField.stringValue - self.textSubject.on(.next(nextValue)) - _forwardToDelegate?.controlTextDidChange?(notification) - } - - // MARK: Delegate proxy methods - - /// For more information take a look at `DelegateProxyType`. - open class func currentDelegate(for object: ParentObject) -> NSTextFieldDelegate? { - object.delegate - } - - /// For more information take a look at `DelegateProxyType`. - open class func setCurrentDelegate(_ delegate: NSTextFieldDelegate?, to object: ParentObject) { - object.delegate = delegate - } - -} - -extension Reactive where Base: NSTextField { - - /// Reactive wrapper for `delegate`. - /// - /// For more information take a look at `DelegateProxyType` protocol documentation. - public var delegate: DelegateProxy { - RxTextFieldDelegateProxy.proxy(for: self.base) - } - - /// Reactive wrapper for `text` property. - public var text: ControlProperty { - let delegate = RxTextFieldDelegateProxy.proxy(for: self.base) - - let source = Observable.deferred { [weak textField = self.base] in - delegate.textSubject.startWith(textField?.stringValue) - }.take(until: self.deallocated) - - let observer = Binder(self.base) { (control, value: String?) in - control.stringValue = value ?? "" - } - - return ControlProperty(values: source, valueSink: observer.asObserver()) - } - -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/macOS/NSTextView+Rx.swift b/Pods/RxCocoa/RxCocoa/macOS/NSTextView+Rx.swift deleted file mode 100644 index c3134e4f5..000000000 --- a/Pods/RxCocoa/RxCocoa/macOS/NSTextView+Rx.swift +++ /dev/null @@ -1,94 +0,0 @@ -// -// NSTextView+Rx.swift -// RxCocoa -// -// Created by Cee on 8/5/18. -// Copyright © 2018 Krunoslav Zaher. All rights reserved. -// - -#if os(macOS) - -import Cocoa -import RxSwift - -/// Delegate proxy for `NSTextView`. -/// -/// For more information take a look at `DelegateProxyType`. -open class RxTextViewDelegateProxy: DelegateProxy, DelegateProxyType, NSTextViewDelegate { - - #if compiler(>=5.2) - /// Typed parent object. - /// - /// - note: Since Swift 5.2 and Xcode 11.4, Apple have suddenly - /// disallowed using `weak` for NSTextView. For more details - /// see this GitHub Issue: https://git.io/JvSRn - public private(set) var textView: NSTextView? - #else - /// Typed parent object. - public weak private(set) var textView: NSTextView? - #endif - - /// Initializes `RxTextViewDelegateProxy` - /// - /// - parameter textView: Parent object for delegate proxy. - init(textView: NSTextView) { - self.textView = textView - super.init(parentObject: textView, delegateProxy: RxTextViewDelegateProxy.self) - } - - public static func registerKnownImplementations() { - self.register { RxTextViewDelegateProxy(textView: $0) } - } - - fileprivate let textSubject = PublishSubject() - - // MARK: Delegate methods - - open func textDidChange(_ notification: Notification) { - let textView: NSTextView = castOrFatalError(notification.object) - let nextValue = textView.string - self.textSubject.on(.next(nextValue)) - self._forwardToDelegate?.textDidChange?(notification) - } - - // MARK: Delegate proxy methods - - /// For more information take a look at `DelegateProxyType`. - open class func currentDelegate(for object: ParentObject) -> NSTextViewDelegate? { - object.delegate - } - - /// For more information take a look at `DelegateProxyType`. - open class func setCurrentDelegate(_ delegate: NSTextViewDelegate?, to object: ParentObject) { - object.delegate = delegate - } - -} - -extension Reactive where Base: NSTextView { - - /// Reactive wrapper for `delegate`. - /// - /// For more information take a look at `DelegateProxyType` protocol documentation. - public var delegate: DelegateProxy { - RxTextViewDelegateProxy.proxy(for: self.base) - } - - /// Reactive wrapper for `string` property. - public var string: ControlProperty { - let delegate = RxTextViewDelegateProxy.proxy(for: self.base) - - let source = Observable.deferred { [weak textView = self.base] in - delegate.textSubject.startWith(textView?.string ?? "") - }.take(until: self.deallocated) - - let observer = Binder(self.base) { control, value in - control.string = value - } - - return ControlProperty(values: source, valueSink: observer.asObserver()) - } - -} - -#endif diff --git a/Pods/RxCocoa/RxCocoa/macOS/NSView+Rx.swift b/Pods/RxCocoa/RxCocoa/macOS/NSView+Rx.swift deleted file mode 100644 index f4256d119..000000000 --- a/Pods/RxCocoa/RxCocoa/macOS/NSView+Rx.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// NSView+Rx.swift -// RxCocoa -// -// Created by Krunoslav Zaher on 12/6/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(macOS) - import Cocoa - import RxSwift - - extension Reactive where Base: NSView { - /// Bindable sink for `alphaValue` property. - public var alpha: Binder { - return Binder(self.base) { view, value in - view.alphaValue = value - } - } - } -#endif diff --git a/Pods/RxRelay/LICENSE.md b/Pods/RxRelay/LICENSE.md deleted file mode 100644 index e32511b38..000000000 --- a/Pods/RxRelay/LICENSE.md +++ /dev/null @@ -1,9 +0,0 @@ -**The MIT License** -**Copyright © 2015 Krunoslav Zaher, Shai Mishali** -**All rights reserved.** - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Pods/RxRelay/README.md b/Pods/RxRelay/README.md deleted file mode 100644 index 20330166b..000000000 --- a/Pods/RxRelay/README.md +++ /dev/null @@ -1,254 +0,0 @@ -

-RxSwift Logo -
-
Build Status -Supported Platforms: iOS, macOS, tvOS, watchOS & Linux -
- - - -

- -Rx is a [generic abstraction of computation](https://youtu.be/looJcaeboBY) expressed through `Observable` interface, which lets you broadcast and subscribe to values and other events from an `Observable` stream. - -RxSwift is the Swift-specific implementation of the [Reactive Extensions](http://reactivex.io) standard. - -

RxSwift Observable Example of a price constantly changing and updating the app's UI

- -While this version aims to stay true to the original spirit and naming conventions of Rx, this projects also aims to provide a true Swift-first API for Rx APIs. - -Cross platform documentation can be found on [ReactiveX.io](http://reactivex.io/). - -Like other Rx implementation, RxSwift's intention is to enable easy composition of asynchronous operations and streams of data in the form of `Observable` objects and a suite of methods to transform and compose these pieces of asynchronous work. - -KVO observation, async operations, UI Events and other streams of data are all unified under [abstraction of sequence](Documentation/GettingStarted.md#observables-aka-sequences). This is the reason why Rx is so simple, elegant and powerful. - -## I came here because I want to ... - -###### ... understand - -* [why use rx?](Documentation/Why.md) -* [the basics, getting started with RxSwift](Documentation/GettingStarted.md) -* [traits](Documentation/Traits.md) - what are `Single`, `Completable`, `Maybe`, `Driver`, and `ControlProperty` ... and why do they exist? -* [testing](Documentation/UnitTests.md) -* [tips and common errors](Documentation/Tips.md) -* [debugging](Documentation/GettingStarted.md#debugging) -* [the math behind Rx](Documentation/MathBehindRx.md) -* [what are hot and cold observable sequences?](Documentation/HotAndColdObservables.md) - -###### ... install - -* Integrate RxSwift/RxCocoa with my app. [Installation Guide](#installation) - -###### ... hack around - -* with the example app. [Running Example App](Documentation/ExampleApp.md) -* with operators in playgrounds. [Playgrounds](Documentation/Playgrounds.md) - -###### ... interact - -* All of this is great, but it would be nice to talk with other people using RxSwift and exchange experiences.
[Join Slack Channel](http://slack.rxswift.org) -* Report a problem using the library. [Open an Issue With Bug Template](.github/ISSUE_TEMPLATE.md) -* Request a new feature. [Open an Issue With Feature Request Template](Documentation/NewFeatureRequestTemplate.md) -* Help out [Check out contribution guide](CONTRIBUTING.md) - -###### ... compare - -* [with Combine and ReactiveSwift](Documentation/ComparisonWithOtherLibraries.md). - -###### ... understand the structure - -RxSwift is as compositional as the asynchronous work it drives. The core unit is RxSwift itself, while other dependencies can be added for UI Work, testing, and more. - -It comprises five separate components depending on each other in the following way: - -```none -┌──────────────┐ ┌──────────────┐ -│ RxCocoa ├────▶ RxRelay │ -└───────┬──────┘ └──────┬───────┘ - │ │ -┌───────▼──────────────────▼───────┐ -│ RxSwift │ -└───────▲──────────────────▲───────┘ - │ │ -┌───────┴──────┐ ┌──────┴───────┐ -│ RxTest │ │ RxBlocking │ -└──────────────┘ └──────────────┘ -``` - -* **RxSwift**: The core of RxSwift, providing the Rx standard as (mostly) defined by [ReactiveX](https://reactivex.io). It has no other dependencies. -* **RxCocoa**: Provides Cocoa-specific capabilities for general iOS/macOS/watchOS & tvOS app development, such as Shared Sequences, Traits, and much more. It depends on both `RxSwift` and `RxRelay`. -* **RxRelay**: Provides `PublishRelay`, `BehaviorRelay` and `ReplayRelay`, three [simple wrappers around Subjects](https://github.com/ReactiveX/RxSwift/blob/main/Documentation/Subjects.md#relays). It depends on `RxSwift`. -* **RxTest** and **RxBlocking**: Provides testing capabilities for Rx-based systems. It depends on `RxSwift`. - -## Usage - - - - - - - - - - - - - - - - - - - -
Here's an exampleIn Action
Define search for GitHub repositories ...
-let searchResults = searchBar.rx.text.orEmpty
-    .throttle(.milliseconds(300), scheduler: MainScheduler.instance)
-    .distinctUntilChanged()
-    .flatMapLatest { query -> Observable<[Repository]> in
-        if query.isEmpty {
-            return .just([])
-        }
-        return searchGitHub(query)
-            .catchAndReturn([])
-    }
-    .observe(on: MainScheduler.instance)
... then bind the results to your tableview
-searchResults
-    .bind(to: tableView.rx.items(cellIdentifier: "Cell")) {
-        (index, repository: Repository, cell) in
-        cell.textLabel?.text = repository.name
-        cell.detailTextLabel?.text = repository.url
-    }
-    .disposed(by: disposeBag)
- - -## Requirements - -* Xcode 12.x -* Swift 5.x - -For Xcode 11 and below, [use RxSwift 5.x](https://github.com/ReactiveX/RxSwift/releases/tag/5.1.1). - -## Installation - -RxSwift doesn't contain any external dependencies. - -These are currently the supported installation options: - -### Manual - -Open Rx.xcworkspace, choose `RxExample` and hit run. This method will build everything and run the sample app - -### [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html) - -```ruby -# Podfile -use_frameworks! - -target 'YOUR_TARGET_NAME' do - pod 'RxSwift', '6.2.0' - pod 'RxCocoa', '6.2.0' -end - -# RxTest and RxBlocking make the most sense in the context of unit/integration tests -target 'YOUR_TESTING_TARGET' do - pod 'RxBlocking', '6.2.0' - pod 'RxTest', '6.2.0' -end -``` - -Replace `YOUR_TARGET_NAME` and then, in the `Podfile` directory, type: - -```bash -$ pod install -``` - -### XCFrameworks - -Each release starting with RxSwift 6 includes `*.xcframework` framework binaries. - -Simply drag the needed framework binaries to your **Frameworks, Libraries, and Embedded Content** section under your target's **General** tab. - -> **Note**: If you're using `RxCocoa`, be sure to also drag **RxCocoaRuntime.xcframework** before importing `RxCocoa`. - -XCFrameworks instructions - -### [Carthage](https://github.com/Carthage/Carthage) - -Add this to `Cartfile` - -``` -github "ReactiveX/RxSwift" "6.2.0" -``` - -```bash -$ carthage update -``` - -#### Carthage as a Static Library - -Carthage defaults to building RxSwift as a Dynamic Library. - -If you wish to build RxSwift as a Static Library using Carthage you may use the script below to manually modify the framework type before building with Carthage: - -```bash -carthage update RxSwift --platform iOS --no-build -sed -i -e 's/MACH_O_TYPE = mh_dylib/MACH_O_TYPE = staticlib/g' Carthage/Checkouts/RxSwift/Rx.xcodeproj/project.pbxproj -carthage build RxSwift --platform iOS -``` - -### [Swift Package Manager](https://github.com/apple/swift-package-manager) - -> **Note**: There is a critical cross-dependency bug affecting many projects including RxSwift in Swift Package Manager. We've [filed a bug (SR-12303)](https://bugs.swift.org/browse/SR-12303) in early 2020 but have no answer yet. Your mileage may vary. A partial workaround can be found [here](https://github.com/ReactiveX/RxSwift/issues/2127#issuecomment-717830502). - -Create a `Package.swift` file. - -```swift -// swift-tools-version:5.0 - -import PackageDescription - -let package = Package( - name: "RxTestProject", - dependencies: [ - .package(url: "https://github.com/ReactiveX/RxSwift.git", .exact("6.2.0")) - ], - targets: [ - .target(name: "RxTestProject", dependencies: ["RxSwift", "RxCocoa"]) - ] -) -``` - -```bash -$ swift build -``` - -To build or test a module with RxTest dependency, set `TEST=1`. - -```bash -$ TEST=1 swift test -``` - -### Manually using git submodules - -* Add RxSwift as a submodule - -```bash -$ git submodule add git@github.com:ReactiveX/RxSwift.git -``` - -* Drag `Rx.xcodeproj` into Project Navigator -* Go to `Project > Targets > Build Phases > Link Binary With Libraries`, click `+` and select `RxSwift`, `RxCocoa` and `RxRelay` targets - -## References - -* [http://reactivex.io/](http://reactivex.io/) -* [Reactive Extensions GitHub (GitHub)](https://github.com/Reactive-Extensions) -* [RxSwift RayWenderlich.com Book](https://store.raywenderlich.com/products/rxswift-reactive-programming-with-swift) -* [RxSwift: Debunking the myth of hard (YouTube)](https://www.youtube.com/watch?v=GdvLP0ZAhhc) -* [Boxue.io RxSwift Online Course](https://boxueio.com/series/rxswift-101) (Chinese 🇨🇳) -* [Expert to Expert: Brian Beckman and Erik Meijer - Inside the .NET Reactive Framework (Rx) (video)](https://youtu.be/looJcaeboBY) -* [Reactive Programming Overview (Jafar Husain from Netflix)](https://youtu.be/-8Y1-lE6NSA) -* [Subject/Observer is Dual to Iterator (paper)](http://csl.stanford.edu/~christos/pldi2010.fit/meijer.duality.pdf) -* [Rx standard sequence operators visualized (visualization tool)](http://rxmarbles.com/) -* [Haskell](https://www.haskell.org/) diff --git a/Pods/RxRelay/RxRelay/BehaviorRelay.swift b/Pods/RxRelay/RxRelay/BehaviorRelay.swift deleted file mode 100644 index e02fc8f5c..000000000 --- a/Pods/RxRelay/RxRelay/BehaviorRelay.swift +++ /dev/null @@ -1,42 +0,0 @@ -// -// BehaviorRelay.swift -// RxRelay -// -// Created by Krunoslav Zaher on 10/7/17. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - -/// BehaviorRelay is a wrapper for `BehaviorSubject`. -/// -/// Unlike `BehaviorSubject` it can't terminate with error or completed. -public final class BehaviorRelay: ObservableType { - private let subject: BehaviorSubject - - /// Accepts `event` and emits it to subscribers - public func accept(_ event: Element) { - self.subject.onNext(event) - } - - /// Current value of behavior subject - public var value: Element { - // this try! is ok because subject can't error out or be disposed - return try! self.subject.value() - } - - /// Initializes behavior relay with initial value. - public init(value: Element) { - self.subject = BehaviorSubject(value: value) - } - - /// Subscribes observer - public func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { - self.subject.subscribe(observer) - } - - /// - returns: Canonical interface for push style sequence - public func asObservable() -> Observable { - self.subject.asObservable() - } -} diff --git a/Pods/RxRelay/RxRelay/Observable+Bind.swift b/Pods/RxRelay/RxRelay/Observable+Bind.swift deleted file mode 100644 index 7a2efc7b0..000000000 --- a/Pods/RxRelay/RxRelay/Observable+Bind.swift +++ /dev/null @@ -1,149 +0,0 @@ -// -// Observable+Bind.swift -// RxRelay -// -// Created by Shai Mishali on 09/04/2019. -// Copyright © 2019 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - -extension ObservableType { - /** - Creates new subscription and sends elements to publish relay(s). - In case error occurs in debug mode, `fatalError` will be raised. - In case error occurs in release mode, `error` will be logged. - - parameter to: Target publish relays for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer. - */ - public func bind(to relays: PublishRelay...) -> Disposable { - bind(to: relays) - } - - /** - Creates new subscription and sends elements to publish relay(s). - - In case error occurs in debug mode, `fatalError` will be raised. - In case error occurs in release mode, `error` will be logged. - - - parameter to: Target publish relays for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer. - */ - public func bind(to relays: PublishRelay...) -> Disposable { - self.map { $0 as Element? }.bind(to: relays) - } - - /** - Creates new subscription and sends elements to publish relay(s). - In case error occurs in debug mode, `fatalError` will be raised. - In case error occurs in release mode, `error` will be logged. - - parameter to: Target publish relays for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer. - */ - private func bind(to relays: [PublishRelay]) -> Disposable { - subscribe { e in - switch e { - case let .next(element): - relays.forEach { - $0.accept(element) - } - case let .error(error): - rxFatalErrorInDebug("Binding error to publish relay: \(error)") - case .completed: - break - } - } - } - - /** - Creates new subscription and sends elements to behavior relay(s). - In case error occurs in debug mode, `fatalError` will be raised. - In case error occurs in release mode, `error` will be logged. - - parameter to: Target behavior relay for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer. - */ - public func bind(to relays: BehaviorRelay...) -> Disposable { - self.bind(to: relays) - } - - /** - Creates new subscription and sends elements to behavior relay(s). - - In case error occurs in debug mode, `fatalError` will be raised. - In case error occurs in release mode, `error` will be logged. - - - parameter to: Target behavior relay for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer. - */ - public func bind(to relays: BehaviorRelay...) -> Disposable { - self.map { $0 as Element? }.bind(to: relays) - } - - /** - Creates new subscription and sends elements to behavior relay(s). - In case error occurs in debug mode, `fatalError` will be raised. - In case error occurs in release mode, `error` will be logged. - - parameter to: Target behavior relay for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer. - */ - private func bind(to relays: [BehaviorRelay]) -> Disposable { - subscribe { e in - switch e { - case let .next(element): - relays.forEach { - $0.accept(element) - } - case let .error(error): - rxFatalErrorInDebug("Binding error to behavior relay: \(error)") - case .completed: - break - } - } - } - - /** - Creates new subscription and sends elements to replay relay(s). - In case error occurs in debug mode, `fatalError` will be raised. - In case error occurs in release mode, `error` will be logged. - - parameter to: Target replay relay for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer. - */ - public func bind(to relays: ReplayRelay...) -> Disposable { - self.bind(to: relays) - } - - /** - Creates new subscription and sends elements to replay relay(s). - - In case error occurs in debug mode, `fatalError` will be raised. - In case error occurs in release mode, `error` will be logged. - - - parameter to: Target replay relay for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer. - */ - public func bind(to relays: ReplayRelay...) -> Disposable { - self.map { $0 as Element? }.bind(to: relays) - } - - /** - Creates new subscription and sends elements to replay relay(s). - In case error occurs in debug mode, `fatalError` will be raised. - In case error occurs in release mode, `error` will be logged. - - parameter to: Target replay relay for sequence elements. - - returns: Disposable object that can be used to unsubscribe the observer. - */ - private func bind(to relays: [ReplayRelay]) -> Disposable { - subscribe { e in - switch e { - case let .next(element): - relays.forEach { - $0.accept(element) - } - case let .error(error): - rxFatalErrorInDebug("Binding error to behavior relay: \(error)") - case .completed: - break - } - } - } -} diff --git a/Pods/RxRelay/RxRelay/PublishRelay.swift b/Pods/RxRelay/RxRelay/PublishRelay.swift deleted file mode 100644 index a9c8ac428..000000000 --- a/Pods/RxRelay/RxRelay/PublishRelay.swift +++ /dev/null @@ -1,36 +0,0 @@ -// -// PublishRelay.swift -// RxRelay -// -// Created by Krunoslav Zaher on 3/28/15. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - -/// PublishRelay is a wrapper for `PublishSubject`. -/// -/// Unlike `PublishSubject` it can't terminate with error or completed. -public final class PublishRelay: ObservableType { - private let subject: PublishSubject - - // Accepts `event` and emits it to subscribers - public func accept(_ event: Element) { - self.subject.onNext(event) - } - - /// Initializes with internal empty subject. - public init() { - self.subject = PublishSubject() - } - - /// Subscribes observer - public func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { - self.subject.subscribe(observer) - } - - /// - returns: Canonical interface for push style sequence - public func asObservable() -> Observable { - self.subject.asObservable() - } -} diff --git a/Pods/RxRelay/RxRelay/ReplayRelay.swift b/Pods/RxRelay/RxRelay/ReplayRelay.swift deleted file mode 100644 index 3cc87cd09..000000000 --- a/Pods/RxRelay/RxRelay/ReplayRelay.swift +++ /dev/null @@ -1,50 +0,0 @@ -// -// ReplayRelay.swift -// RxRelay -// -// Created by Zsolt Kovacs on 12/22/19. -// Copyright © 2019 Krunoslav Zaher. All rights reserved. -// - -import RxSwift - -/// ReplayRelay is a wrapper for `ReplaySubject`. -/// -/// Unlike `ReplaySubject` it can't terminate with an error or complete. -public final class ReplayRelay: ObservableType { - private let subject: ReplaySubject - - // Accepts `event` and emits it to subscribers - public func accept(_ event: Element) { - self.subject.onNext(event) - } - - private init(subject: ReplaySubject) { - self.subject = subject - } - - /// Creates new instance of `ReplayRelay` that replays at most `bufferSize` last elements sent to it. - /// - /// - parameter bufferSize: Maximal number of elements to replay to observers after subscription. - /// - returns: New instance of replay relay. - public static func create(bufferSize: Int) -> ReplayRelay { - ReplayRelay(subject: ReplaySubject.create(bufferSize: bufferSize)) - } - - /// Creates a new instance of `ReplayRelay` that buffers all the sent to it. - /// To avoid filling up memory, developer needs to make sure that the use case will only ever store a 'reasonable' - /// number of elements. - public static func createUnbound() -> ReplayRelay { - ReplayRelay(subject: ReplaySubject.createUnbounded()) - } - - /// Subscribes observer - public func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { - self.subject.subscribe(observer) - } - - /// - returns: Canonical interface for push style sequence - public func asObservable() -> Observable { - self.subject.asObserver() - } -} diff --git a/Pods/RxRelay/RxRelay/Utils.swift b/Pods/RxRelay/RxRelay/Utils.swift deleted file mode 100644 index 5954fb980..000000000 --- a/Pods/RxRelay/RxRelay/Utils.swift +++ /dev/null @@ -1,17 +0,0 @@ -// -// Utils.swift -// RxRelay -// -// Created by Shai Mishali on 09/04/2019. -// Copyright © 2019 Krunoslav Zaher. All rights reserved. -// - -import Foundation - -func rxFatalErrorInDebug(_ lastMessage: @autoclosure () -> String, file: StaticString = #file, line: UInt = #line) { - #if DEBUG - fatalError(lastMessage(), file: file, line: line) - #else - print("\(file):\(line): \(lastMessage())") - #endif -} diff --git a/Pods/RxSwift/LICENSE.md b/Pods/RxSwift/LICENSE.md deleted file mode 100644 index e32511b38..000000000 --- a/Pods/RxSwift/LICENSE.md +++ /dev/null @@ -1,9 +0,0 @@ -**The MIT License** -**Copyright © 2015 Krunoslav Zaher, Shai Mishali** -**All rights reserved.** - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Pods/RxSwift/Platform/AtomicInt.swift b/Pods/RxSwift/Platform/AtomicInt.swift deleted file mode 100644 index 98479fd2c..000000000 --- a/Pods/RxSwift/Platform/AtomicInt.swift +++ /dev/null @@ -1,71 +0,0 @@ -// -// AtomicInt.swift -// Platform -// -// Created by Krunoslav Zaher on 10/28/18. -// Copyright © 2018 Krunoslav Zaher. All rights reserved. -// - -import Foundation - -final class AtomicInt: NSLock { - fileprivate var value: Int32 - public init(_ value: Int32 = 0) { - self.value = value - } -} - -@discardableResult -@inline(__always) -func add(_ this: AtomicInt, _ value: Int32) -> Int32 { - this.lock() - let oldValue = this.value - this.value += value - this.unlock() - return oldValue -} - -@discardableResult -@inline(__always) -func sub(_ this: AtomicInt, _ value: Int32) -> Int32 { - this.lock() - let oldValue = this.value - this.value -= value - this.unlock() - return oldValue -} - -@discardableResult -@inline(__always) -func fetchOr(_ this: AtomicInt, _ mask: Int32) -> Int32 { - this.lock() - let oldValue = this.value - this.value |= mask - this.unlock() - return oldValue -} - -@inline(__always) -func load(_ this: AtomicInt) -> Int32 { - this.lock() - let oldValue = this.value - this.unlock() - return oldValue -} - -@discardableResult -@inline(__always) -func increment(_ this: AtomicInt) -> Int32 { - add(this, 1) -} - -@discardableResult -@inline(__always) -func decrement(_ this: AtomicInt) -> Int32 { - sub(this, 1) -} - -@inline(__always) -func isFlagSet(_ this: AtomicInt, _ mask: Int32) -> Bool { - (load(this) & mask) != 0 -} diff --git a/Pods/RxSwift/Platform/DataStructures/Bag.swift b/Pods/RxSwift/Platform/DataStructures/Bag.swift deleted file mode 100644 index 5720a3b44..000000000 --- a/Pods/RxSwift/Platform/DataStructures/Bag.swift +++ /dev/null @@ -1,181 +0,0 @@ -// -// Bag.swift -// Platform -// -// Created by Krunoslav Zaher on 2/28/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import Swift - -let arrayDictionaryMaxSize = 30 - -struct BagKey { - /** - Unique identifier for object added to `Bag`. - - It's underlying type is UInt64. If we assume there in an idealized CPU that works at 4GHz, - it would take ~150 years of continuous running time for it to overflow. - */ - fileprivate let rawValue: UInt64 -} - -/** -Data structure that represents a bag of elements typed `T`. - -Single element can be stored multiple times. - -Time and space complexity of insertion and deletion is O(n). - -It is suitable for storing small number of elements. -*/ -struct Bag : CustomDebugStringConvertible { - /// Type of identifier for inserted elements. - typealias KeyType = BagKey - - typealias Entry = (key: BagKey, value: T) - - private var _nextKey: BagKey = BagKey(rawValue: 0) - - // data - - // first fill inline variables - var _key0: BagKey? - var _value0: T? - - // then fill "array dictionary" - var _pairs = ContiguousArray() - - // last is sparse dictionary - var _dictionary: [BagKey: T]? - - var _onlyFastPath = true - - /// Creates new empty `Bag`. - init() { - } - - /** - Inserts `value` into bag. - - - parameter element: Element to insert. - - returns: Key that can be used to remove element from bag. - */ - mutating func insert(_ element: T) -> BagKey { - let key = _nextKey - - _nextKey = BagKey(rawValue: _nextKey.rawValue &+ 1) - - if _key0 == nil { - _key0 = key - _value0 = element - return key - } - - _onlyFastPath = false - - if _dictionary != nil { - _dictionary![key] = element - return key - } - - if _pairs.count < arrayDictionaryMaxSize { - _pairs.append((key: key, value: element)) - return key - } - - _dictionary = [key: element] - - return key - } - - /// - returns: Number of elements in bag. - var count: Int { - let dictionaryCount: Int = _dictionary?.count ?? 0 - return (_value0 != nil ? 1 : 0) + _pairs.count + dictionaryCount - } - - /// Removes all elements from bag and clears capacity. - mutating func removeAll() { - _key0 = nil - _value0 = nil - - _pairs.removeAll(keepingCapacity: false) - _dictionary?.removeAll(keepingCapacity: false) - } - - /** - Removes element with a specific `key` from bag. - - - parameter key: Key that identifies element to remove from bag. - - returns: Element that bag contained, or nil in case element was already removed. - */ - mutating func removeKey(_ key: BagKey) -> T? { - if _key0 == key { - _key0 = nil - let value = _value0! - _value0 = nil - return value - } - - if let existingObject = _dictionary?.removeValue(forKey: key) { - return existingObject - } - - for i in 0 ..< _pairs.count where _pairs[i].key == key { - let value = _pairs[i].value - _pairs.remove(at: i) - return value - } - - return nil - } -} - -extension Bag { - /// A textual representation of `self`, suitable for debugging. - var debugDescription : String { - "\(self.count) elements in Bag" - } -} - -extension Bag { - /// Enumerates elements inside the bag. - /// - /// - parameter action: Enumeration closure. - func forEach(_ action: (T) -> Void) { - if _onlyFastPath { - if let value0 = _value0 { - action(value0) - } - return - } - - let value0 = _value0 - let dictionary = _dictionary - - if let value0 = value0 { - action(value0) - } - - for i in 0 ..< _pairs.count { - action(_pairs[i].value) - } - - if dictionary?.count ?? 0 > 0 { - for element in dictionary!.values { - action(element) - } - } - } -} - -extension BagKey: Hashable { - func hash(into hasher: inout Hasher) { - hasher.combine(rawValue) - } -} - -func ==(lhs: BagKey, rhs: BagKey) -> Bool { - lhs.rawValue == rhs.rawValue -} diff --git a/Pods/RxSwift/Platform/DataStructures/InfiniteSequence.swift b/Pods/RxSwift/Platform/DataStructures/InfiniteSequence.swift deleted file mode 100644 index 75d7bea7f..000000000 --- a/Pods/RxSwift/Platform/DataStructures/InfiniteSequence.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// InfiniteSequence.swift -// Platform -// -// Created by Krunoslav Zaher on 6/13/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// Sequence that repeats `repeatedValue` infinite number of times. -struct InfiniteSequence : Sequence { - typealias Iterator = AnyIterator - - private let repeatedValue: Element - - init(repeatedValue: Element) { - self.repeatedValue = repeatedValue - } - - func makeIterator() -> Iterator { - let repeatedValue = self.repeatedValue - return AnyIterator { repeatedValue } - } -} diff --git a/Pods/RxSwift/Platform/DataStructures/PriorityQueue.swift b/Pods/RxSwift/Platform/DataStructures/PriorityQueue.swift deleted file mode 100644 index 9ed856b91..000000000 --- a/Pods/RxSwift/Platform/DataStructures/PriorityQueue.swift +++ /dev/null @@ -1,111 +0,0 @@ -// -// PriorityQueue.swift -// Platform -// -// Created by Krunoslav Zaher on 12/27/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -struct PriorityQueue { - private let hasHigherPriority: (Element, Element) -> Bool - private let isEqual: (Element, Element) -> Bool - - private var elements = [Element]() - - init(hasHigherPriority: @escaping (Element, Element) -> Bool, isEqual: @escaping (Element, Element) -> Bool) { - self.hasHigherPriority = hasHigherPriority - self.isEqual = isEqual - } - - mutating func enqueue(_ element: Element) { - elements.append(element) - bubbleToHigherPriority(elements.count - 1) - } - - func peek() -> Element? { - elements.first - } - - var isEmpty: Bool { - elements.count == 0 - } - - mutating func dequeue() -> Element? { - guard let front = peek() else { - return nil - } - - removeAt(0) - - return front - } - - mutating func remove(_ element: Element) { - for i in 0 ..< elements.count { - if self.isEqual(elements[i], element) { - removeAt(i) - return - } - } - } - - private mutating func removeAt(_ index: Int) { - let removingLast = index == elements.count - 1 - if !removingLast { - elements.swapAt(index, elements.count - 1) - } - - _ = elements.popLast() - - if !removingLast { - bubbleToHigherPriority(index) - bubbleToLowerPriority(index) - } - } - - private mutating func bubbleToHigherPriority(_ initialUnbalancedIndex: Int) { - precondition(initialUnbalancedIndex >= 0) - precondition(initialUnbalancedIndex < elements.count) - - var unbalancedIndex = initialUnbalancedIndex - - while unbalancedIndex > 0 { - let parentIndex = (unbalancedIndex - 1) / 2 - guard self.hasHigherPriority(elements[unbalancedIndex], elements[parentIndex]) else { break } - elements.swapAt(unbalancedIndex, parentIndex) - unbalancedIndex = parentIndex - } - } - - private mutating func bubbleToLowerPriority(_ initialUnbalancedIndex: Int) { - precondition(initialUnbalancedIndex >= 0) - precondition(initialUnbalancedIndex < elements.count) - - var unbalancedIndex = initialUnbalancedIndex - while true { - let leftChildIndex = unbalancedIndex * 2 + 1 - let rightChildIndex = unbalancedIndex * 2 + 2 - - var highestPriorityIndex = unbalancedIndex - - if leftChildIndex < elements.count && self.hasHigherPriority(elements[leftChildIndex], elements[highestPriorityIndex]) { - highestPriorityIndex = leftChildIndex - } - - if rightChildIndex < elements.count && self.hasHigherPriority(elements[rightChildIndex], elements[highestPriorityIndex]) { - highestPriorityIndex = rightChildIndex - } - - guard highestPriorityIndex != unbalancedIndex else { break } - elements.swapAt(highestPriorityIndex, unbalancedIndex) - - unbalancedIndex = highestPriorityIndex - } - } -} - -extension PriorityQueue : CustomDebugStringConvertible { - var debugDescription: String { - elements.debugDescription - } -} diff --git a/Pods/RxSwift/Platform/DataStructures/Queue.swift b/Pods/RxSwift/Platform/DataStructures/Queue.swift deleted file mode 100644 index 625d4733e..000000000 --- a/Pods/RxSwift/Platform/DataStructures/Queue.swift +++ /dev/null @@ -1,148 +0,0 @@ -// -// Queue.swift -// Platform -// -// Created by Krunoslav Zaher on 3/21/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/** -Data structure that represents queue. - -Complexity of `enqueue`, `dequeue` is O(1) when number of operations is -averaged over N operations. - -Complexity of `peek` is O(1). -*/ -struct Queue: Sequence { - /// Type of generator. - typealias Generator = AnyIterator - - private let resizeFactor = 2 - - private var storage: ContiguousArray - private var innerCount = 0 - private var pushNextIndex = 0 - private let initialCapacity: Int - - /** - Creates new queue. - - - parameter capacity: Capacity of newly created queue. - */ - init(capacity: Int) { - initialCapacity = capacity - - storage = ContiguousArray(repeating: nil, count: capacity) - } - - private var dequeueIndex: Int { - let index = pushNextIndex - count - return index < 0 ? index + storage.count : index - } - - /// - returns: Is queue empty. - var isEmpty: Bool { count == 0 } - - /// - returns: Number of elements inside queue. - var count: Int { innerCount } - - /// - returns: Element in front of a list of elements to `dequeue`. - func peek() -> T { - precondition(count > 0) - - return storage[dequeueIndex]! - } - - mutating private func resizeTo(_ size: Int) { - var newStorage = ContiguousArray(repeating: nil, count: size) - - let count = self.count - - let dequeueIndex = self.dequeueIndex - let spaceToEndOfQueue = storage.count - dequeueIndex - - // first batch is from dequeue index to end of array - let countElementsInFirstBatch = Swift.min(count, spaceToEndOfQueue) - // second batch is wrapped from start of array to end of queue - let numberOfElementsInSecondBatch = count - countElementsInFirstBatch - - newStorage[0 ..< countElementsInFirstBatch] = storage[dequeueIndex ..< (dequeueIndex + countElementsInFirstBatch)] - newStorage[countElementsInFirstBatch ..< (countElementsInFirstBatch + numberOfElementsInSecondBatch)] = storage[0 ..< numberOfElementsInSecondBatch] - - self.innerCount = count - pushNextIndex = count - storage = newStorage - } - - /// Enqueues `element`. - /// - /// - parameter element: Element to enqueue. - mutating func enqueue(_ element: T) { - if count == storage.count { - resizeTo(Swift.max(storage.count, 1) * resizeFactor) - } - - storage[pushNextIndex] = element - pushNextIndex += 1 - innerCount += 1 - - if pushNextIndex >= storage.count { - pushNextIndex -= storage.count - } - } - - private mutating func dequeueElementOnly() -> T { - precondition(count > 0) - - let index = dequeueIndex - - defer { - storage[index] = nil - innerCount -= 1 - } - - return storage[index]! - } - - /// Dequeues element or throws an exception in case queue is empty. - /// - /// - returns: Dequeued element. - mutating func dequeue() -> T? { - if self.count == 0 { - return nil - } - - defer { - let downsizeLimit = storage.count / (resizeFactor * resizeFactor) - if count < downsizeLimit && downsizeLimit >= initialCapacity { - resizeTo(storage.count / resizeFactor) - } - } - - return dequeueElementOnly() - } - - /// - returns: Generator of contained elements. - func makeIterator() -> AnyIterator { - var i = dequeueIndex - var innerCount = count - - return AnyIterator { - if innerCount == 0 { - return nil - } - - defer { - innerCount -= 1 - i += 1 - } - - if i >= self.storage.count { - i -= self.storage.count - } - - return self.storage[i] - } - } -} diff --git a/Pods/RxSwift/Platform/DispatchQueue+Extensions.swift b/Pods/RxSwift/Platform/DispatchQueue+Extensions.swift deleted file mode 100644 index aaf24cae6..000000000 --- a/Pods/RxSwift/Platform/DispatchQueue+Extensions.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// DispatchQueue+Extensions.swift -// Platform -// -// Created by Krunoslav Zaher on 10/22/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -import Dispatch - -extension DispatchQueue { - private static var token: DispatchSpecificKey<()> = { - let key = DispatchSpecificKey<()>() - DispatchQueue.main.setSpecific(key: key, value: ()) - return key - }() - - static var isMain: Bool { - DispatchQueue.getSpecific(key: token) != nil - } -} diff --git a/Pods/RxSwift/Platform/Platform.Darwin.swift b/Pods/RxSwift/Platform/Platform.Darwin.swift deleted file mode 100644 index eacc19431..000000000 --- a/Pods/RxSwift/Platform/Platform.Darwin.swift +++ /dev/null @@ -1,35 +0,0 @@ -// -// Platform.Darwin.swift -// Platform -// -// Created by Krunoslav Zaher on 12/29/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) - - import Darwin - import Foundation - - extension Thread { - static func setThreadLocalStorageValue(_ value: T?, forKey key: NSCopying) { - let currentThread = Thread.current - let threadDictionary = currentThread.threadDictionary - - if let newValue = value { - threadDictionary[key] = newValue - } - else { - threadDictionary[key] = nil - } - } - - static func getThreadLocalStorageValueForKey(_ key: NSCopying) -> T? { - let currentThread = Thread.current - let threadDictionary = currentThread.threadDictionary - - return threadDictionary[key] as? T - } - } - -#endif diff --git a/Pods/RxSwift/Platform/Platform.Linux.swift b/Pods/RxSwift/Platform/Platform.Linux.swift deleted file mode 100644 index 52a3e3af8..000000000 --- a/Pods/RxSwift/Platform/Platform.Linux.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// Platform.Linux.swift -// Platform -// -// Created by Krunoslav Zaher on 12/29/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(Linux) - - import Foundation - - extension Thread { - - static func setThreadLocalStorageValue(_ value: T?, forKey key: String) { - if let newValue = value { - Thread.current.threadDictionary[key] = newValue - } - else { - Thread.current.threadDictionary[key] = nil - } - } - - static func getThreadLocalStorageValueForKey(_ key: String) -> T? { - let currentThread = Thread.current - let threadDictionary = currentThread.threadDictionary - - return threadDictionary[key] as? T - } - } - -#endif diff --git a/Pods/RxSwift/Platform/RecursiveLock.swift b/Pods/RxSwift/Platform/RecursiveLock.swift deleted file mode 100644 index 10b9bbb0b..000000000 --- a/Pods/RxSwift/Platform/RecursiveLock.swift +++ /dev/null @@ -1,34 +0,0 @@ -// -// RecursiveLock.swift -// Platform -// -// Created by Krunoslav Zaher on 12/18/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -import Foundation - -#if TRACE_RESOURCES - class RecursiveLock: NSRecursiveLock { - override init() { - _ = Resources.incrementTotal() - super.init() - } - - override func lock() { - super.lock() - _ = Resources.incrementTotal() - } - - override func unlock() { - super.unlock() - _ = Resources.decrementTotal() - } - - deinit { - _ = Resources.decrementTotal() - } - } -#else - typealias RecursiveLock = NSRecursiveLock -#endif diff --git a/Pods/RxSwift/README.md b/Pods/RxSwift/README.md deleted file mode 100644 index 20330166b..000000000 --- a/Pods/RxSwift/README.md +++ /dev/null @@ -1,254 +0,0 @@ -

-RxSwift Logo -
-Build Status -Supported Platforms: iOS, macOS, tvOS, watchOS & Linux -
- - - -

- -Rx is a [generic abstraction of computation](https://youtu.be/looJcaeboBY) expressed through `Observable` interface, which lets you broadcast and subscribe to values and other events from an `Observable` stream. - -RxSwift is the Swift-specific implementation of the [Reactive Extensions](http://reactivex.io) standard. - -

RxSwift Observable Example of a price constantly changing and updating the app's UI

- -While this version aims to stay true to the original spirit and naming conventions of Rx, this projects also aims to provide a true Swift-first API for Rx APIs. - -Cross platform documentation can be found on [ReactiveX.io](http://reactivex.io/). - -Like other Rx implementation, RxSwift's intention is to enable easy composition of asynchronous operations and streams of data in the form of `Observable` objects and a suite of methods to transform and compose these pieces of asynchronous work. - -KVO observation, async operations, UI Events and other streams of data are all unified under [abstraction of sequence](Documentation/GettingStarted.md#observables-aka-sequences). This is the reason why Rx is so simple, elegant and powerful. - -## I came here because I want to ... - -###### ... understand - -* [why use rx?](Documentation/Why.md) -* [the basics, getting started with RxSwift](Documentation/GettingStarted.md) -* [traits](Documentation/Traits.md) - what are `Single`, `Completable`, `Maybe`, `Driver`, and `ControlProperty` ... and why do they exist? -* [testing](Documentation/UnitTests.md) -* [tips and common errors](Documentation/Tips.md) -* [debugging](Documentation/GettingStarted.md#debugging) -* [the math behind Rx](Documentation/MathBehindRx.md) -* [what are hot and cold observable sequences?](Documentation/HotAndColdObservables.md) - -###### ... install - -* Integrate RxSwift/RxCocoa with my app. [Installation Guide](#installation) - -###### ... hack around - -* with the example app. [Running Example App](Documentation/ExampleApp.md) -* with operators in playgrounds. [Playgrounds](Documentation/Playgrounds.md) - -###### ... interact - -* All of this is great, but it would be nice to talk with other people using RxSwift and exchange experiences.
[Join Slack Channel](http://slack.rxswift.org) -* Report a problem using the library. [Open an Issue With Bug Template](.github/ISSUE_TEMPLATE.md) -* Request a new feature. [Open an Issue With Feature Request Template](Documentation/NewFeatureRequestTemplate.md) -* Help out [Check out contribution guide](CONTRIBUTING.md) - -###### ... compare - -* [with Combine and ReactiveSwift](Documentation/ComparisonWithOtherLibraries.md). - -###### ... understand the structure - -RxSwift is as compositional as the asynchronous work it drives. The core unit is RxSwift itself, while other dependencies can be added for UI Work, testing, and more. - -It comprises five separate components depending on each other in the following way: - -```none -┌──────────────┐ ┌──────────────┐ -│ RxCocoa ├────▶ RxRelay │ -└───────┬──────┘ └──────┬───────┘ - │ │ -┌───────▼──────────────────▼───────┐ -│ RxSwift │ -└───────▲──────────────────▲───────┘ - │ │ -┌───────┴──────┐ ┌──────┴───────┐ -│ RxTest │ │ RxBlocking │ -└──────────────┘ └──────────────┘ -``` - -* **RxSwift**: The core of RxSwift, providing the Rx standard as (mostly) defined by [ReactiveX](https://reactivex.io). It has no other dependencies. -* **RxCocoa**: Provides Cocoa-specific capabilities for general iOS/macOS/watchOS & tvOS app development, such as Shared Sequences, Traits, and much more. It depends on both `RxSwift` and `RxRelay`. -* **RxRelay**: Provides `PublishRelay`, `BehaviorRelay` and `ReplayRelay`, three [simple wrappers around Subjects](https://github.com/ReactiveX/RxSwift/blob/main/Documentation/Subjects.md#relays). It depends on `RxSwift`. -* **RxTest** and **RxBlocking**: Provides testing capabilities for Rx-based systems. It depends on `RxSwift`. - -## Usage - - - - - - - - - - - - - - - - - - - -
Here's an exampleIn Action
Define search for GitHub repositories ...
-let searchResults = searchBar.rx.text.orEmpty
-    .throttle(.milliseconds(300), scheduler: MainScheduler.instance)
-    .distinctUntilChanged()
-    .flatMapLatest { query -> Observable<[Repository]> in
-        if query.isEmpty {
-            return .just([])
-        }
-        return searchGitHub(query)
-            .catchAndReturn([])
-    }
-    .observe(on: MainScheduler.instance)
... then bind the results to your tableview
-searchResults
-    .bind(to: tableView.rx.items(cellIdentifier: "Cell")) {
-        (index, repository: Repository, cell) in
-        cell.textLabel?.text = repository.name
-        cell.detailTextLabel?.text = repository.url
-    }
-    .disposed(by: disposeBag)
- - -## Requirements - -* Xcode 12.x -* Swift 5.x - -For Xcode 11 and below, [use RxSwift 5.x](https://github.com/ReactiveX/RxSwift/releases/tag/5.1.1). - -## Installation - -RxSwift doesn't contain any external dependencies. - -These are currently the supported installation options: - -### Manual - -Open Rx.xcworkspace, choose `RxExample` and hit run. This method will build everything and run the sample app - -### [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html) - -```ruby -# Podfile -use_frameworks! - -target 'YOUR_TARGET_NAME' do - pod 'RxSwift', '6.2.0' - pod 'RxCocoa', '6.2.0' -end - -# RxTest and RxBlocking make the most sense in the context of unit/integration tests -target 'YOUR_TESTING_TARGET' do - pod 'RxBlocking', '6.2.0' - pod 'RxTest', '6.2.0' -end -``` - -Replace `YOUR_TARGET_NAME` and then, in the `Podfile` directory, type: - -```bash -$ pod install -``` - -### XCFrameworks - -Each release starting with RxSwift 6 includes `*.xcframework` framework binaries. - -Simply drag the needed framework binaries to your **Frameworks, Libraries, and Embedded Content** section under your target's **General** tab. - -> **Note**: If you're using `RxCocoa`, be sure to also drag **RxCocoaRuntime.xcframework** before importing `RxCocoa`. - -XCFrameworks instructions - -### [Carthage](https://github.com/Carthage/Carthage) - -Add this to `Cartfile` - -``` -github "ReactiveX/RxSwift" "6.2.0" -``` - -```bash -$ carthage update -``` - -#### Carthage as a Static Library - -Carthage defaults to building RxSwift as a Dynamic Library. - -If you wish to build RxSwift as a Static Library using Carthage you may use the script below to manually modify the framework type before building with Carthage: - -```bash -carthage update RxSwift --platform iOS --no-build -sed -i -e 's/MACH_O_TYPE = mh_dylib/MACH_O_TYPE = staticlib/g' Carthage/Checkouts/RxSwift/Rx.xcodeproj/project.pbxproj -carthage build RxSwift --platform iOS -``` - -### [Swift Package Manager](https://github.com/apple/swift-package-manager) - -> **Note**: There is a critical cross-dependency bug affecting many projects including RxSwift in Swift Package Manager. We've [filed a bug (SR-12303)](https://bugs.swift.org/browse/SR-12303) in early 2020 but have no answer yet. Your mileage may vary. A partial workaround can be found [here](https://github.com/ReactiveX/RxSwift/issues/2127#issuecomment-717830502). - -Create a `Package.swift` file. - -```swift -// swift-tools-version:5.0 - -import PackageDescription - -let package = Package( - name: "RxTestProject", - dependencies: [ - .package(url: "https://github.com/ReactiveX/RxSwift.git", .exact("6.2.0")) - ], - targets: [ - .target(name: "RxTestProject", dependencies: ["RxSwift", "RxCocoa"]) - ] -) -``` - -```bash -$ swift build -``` - -To build or test a module with RxTest dependency, set `TEST=1`. - -```bash -$ TEST=1 swift test -``` - -### Manually using git submodules - -* Add RxSwift as a submodule - -```bash -$ git submodule add git@github.com:ReactiveX/RxSwift.git -``` - -* Drag `Rx.xcodeproj` into Project Navigator -* Go to `Project > Targets > Build Phases > Link Binary With Libraries`, click `+` and select `RxSwift`, `RxCocoa` and `RxRelay` targets - -## References - -* [http://reactivex.io/](http://reactivex.io/) -* [Reactive Extensions GitHub (GitHub)](https://github.com/Reactive-Extensions) -* [RxSwift RayWenderlich.com Book](https://store.raywenderlich.com/products/rxswift-reactive-programming-with-swift) -* [RxSwift: Debunking the myth of hard (YouTube)](https://www.youtube.com/watch?v=GdvLP0ZAhhc) -* [Boxue.io RxSwift Online Course](https://boxueio.com/series/rxswift-101) (Chinese 🇨🇳) -* [Expert to Expert: Brian Beckman and Erik Meijer - Inside the .NET Reactive Framework (Rx) (video)](https://youtu.be/looJcaeboBY) -* [Reactive Programming Overview (Jafar Husain from Netflix)](https://youtu.be/-8Y1-lE6NSA) -* [Subject/Observer is Dual to Iterator (paper)](http://csl.stanford.edu/~christos/pldi2010.fit/meijer.duality.pdf) -* [Rx standard sequence operators visualized (visualization tool)](http://rxmarbles.com/) -* [Haskell](https://www.haskell.org/) diff --git a/Pods/RxSwift/RxSwift/AnyObserver.swift b/Pods/RxSwift/RxSwift/AnyObserver.swift deleted file mode 100644 index e92cc816e..000000000 --- a/Pods/RxSwift/RxSwift/AnyObserver.swift +++ /dev/null @@ -1,69 +0,0 @@ -// -// AnyObserver.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/28/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// A type-erased `ObserverType`. -/// -/// Forwards operations to an arbitrary underlying observer with the same `Element` type, hiding the specifics of the underlying observer type. -public struct AnyObserver : ObserverType { - /// Anonymous event handler type. - public typealias EventHandler = (Event) -> Void - - private let observer: EventHandler - - /// Construct an instance whose `on(event)` calls `eventHandler(event)` - /// - /// - parameter eventHandler: Event handler that observes sequences events. - public init(eventHandler: @escaping EventHandler) { - self.observer = eventHandler - } - - /// Construct an instance whose `on(event)` calls `observer.on(event)` - /// - /// - parameter observer: Observer that receives sequence events. - public init(_ observer: Observer) where Observer.Element == Element { - self.observer = observer.on - } - - /// Send `event` to this observer. - /// - /// - parameter event: Event instance. - public func on(_ event: Event) { - self.observer(event) - } - - /// Erases type of observer and returns canonical observer. - /// - /// - returns: type erased observer. - public func asObserver() -> AnyObserver { - self - } -} - -extension AnyObserver { - /// Collection of `AnyObserver`s - typealias s = Bag<(Event) -> Void> -} - -extension ObserverType { - /// Erases type of observer and returns canonical observer. - /// - /// - returns: type erased observer. - public func asObserver() -> AnyObserver { - AnyObserver(self) - } - - /// Transforms observer of type R to type E using custom transform method. - /// Each event sent to result observer is transformed and sent to `self`. - /// - /// - returns: observer that transforms events. - public func mapObserver(_ transform: @escaping (Result) throws -> Element) -> AnyObserver { - AnyObserver { e in - self.on(e.map(transform)) - } - } -} diff --git a/Pods/RxSwift/RxSwift/Binder.swift b/Pods/RxSwift/RxSwift/Binder.swift deleted file mode 100644 index 1aae09592..000000000 --- a/Pods/RxSwift/RxSwift/Binder.swift +++ /dev/null @@ -1,59 +0,0 @@ -// -// Binder.swift -// RxSwift -// -// Created by Krunoslav Zaher on 9/17/17. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -/** - Observer that enforces interface binding rules: - * can't bind errors (in debug builds binding of errors causes `fatalError` in release builds errors are being logged) - * ensures binding is performed on a specific scheduler - - `Binder` doesn't retain target and in case target is released, element isn't bound. - - By default it binds elements on main scheduler. - */ -public struct Binder: ObserverType { - public typealias Element = Value - - private let binding: (Event) -> Void - - /// Initializes `Binder` - /// - /// - parameter target: Target object. - /// - parameter scheduler: Scheduler used to bind the events. - /// - parameter binding: Binding logic. - public init(_ target: Target, scheduler: ImmediateSchedulerType = MainScheduler(), binding: @escaping (Target, Value) -> Void) { - weak var weakTarget = target - - self.binding = { event in - switch event { - case .next(let element): - _ = scheduler.schedule(element) { element in - if let target = weakTarget { - binding(target, element) - } - return Disposables.create() - } - case .error(let error): - rxFatalErrorInDebug("Binding error: \(error)") - case .completed: - break - } - } - } - - /// Binds next element to owner view as described in `binding`. - public func on(_ event: Event) { - self.binding(event) - } - - /// Erases type of observer. - /// - /// - returns: type erased observer. - public func asObserver() -> AnyObserver { - AnyObserver(eventHandler: self.on) - } -} diff --git a/Pods/RxSwift/RxSwift/Cancelable.swift b/Pods/RxSwift/RxSwift/Cancelable.swift deleted file mode 100644 index 1fa7a6772..000000000 --- a/Pods/RxSwift/RxSwift/Cancelable.swift +++ /dev/null @@ -1,13 +0,0 @@ -// -// Cancelable.swift -// RxSwift -// -// Created by Krunoslav Zaher on 3/12/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// Represents disposable resource with state tracking. -public protocol Cancelable : Disposable { - /// Was resource disposed. - var isDisposed: Bool { get } -} diff --git a/Pods/RxSwift/RxSwift/Concurrency/AsyncLock.swift b/Pods/RxSwift/RxSwift/Concurrency/AsyncLock.swift deleted file mode 100644 index 502597e93..000000000 --- a/Pods/RxSwift/RxSwift/Concurrency/AsyncLock.swift +++ /dev/null @@ -1,100 +0,0 @@ -// -// AsyncLock.swift -// RxSwift -// -// Created by Krunoslav Zaher on 3/21/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/** -In case nobody holds this lock, the work will be queued and executed immediately -on thread that is requesting lock. - -In case there is somebody currently holding that lock, action will be enqueued. -When owned of the lock finishes with it's processing, it will also execute -and pending work. - -That means that enqueued work could possibly be executed later on a different thread. -*/ -final class AsyncLock - : Disposable - , Lock - , SynchronizedDisposeType { - typealias Action = () -> Void - - private var _lock = SpinLock() - - private var queue: Queue = Queue(capacity: 0) - - private var isExecuting: Bool = false - private var hasFaulted: Bool = false - - // lock { - func lock() { - self._lock.lock() - } - - func unlock() { - self._lock.unlock() - } - // } - - private func enqueue(_ action: I) -> I? { - self.lock(); defer { self.unlock() } - if self.hasFaulted { - return nil - } - - if self.isExecuting { - self.queue.enqueue(action) - return nil - } - - self.isExecuting = true - - return action - } - - private func dequeue() -> I? { - self.lock(); defer { self.unlock() } - if !self.queue.isEmpty { - return self.queue.dequeue() - } - else { - self.isExecuting = false - return nil - } - } - - func invoke(_ action: I) { - let firstEnqueuedAction = self.enqueue(action) - - if let firstEnqueuedAction = firstEnqueuedAction { - firstEnqueuedAction.invoke() - } - else { - // action is enqueued, it's somebody else's concern now - return - } - - while true { - let nextAction = self.dequeue() - - if let nextAction = nextAction { - nextAction.invoke() - } - else { - return - } - } - } - - func dispose() { - self.synchronizedDispose() - } - - func synchronized_dispose() { - self.queue = Queue(capacity: 0) - self.hasFaulted = true - } -} diff --git a/Pods/RxSwift/RxSwift/Concurrency/Lock.swift b/Pods/RxSwift/RxSwift/Concurrency/Lock.swift deleted file mode 100644 index 7232f23f5..000000000 --- a/Pods/RxSwift/RxSwift/Concurrency/Lock.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// Lock.swift -// RxSwift -// -// Created by Krunoslav Zaher on 3/31/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -protocol Lock { - func lock() - func unlock() -} - -// https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20151214/000321.html -typealias SpinLock = RecursiveLock - -extension RecursiveLock : Lock { - @inline(__always) - final func performLocked(_ action: () -> T) -> T { - self.lock(); defer { self.unlock() } - return action() - } -} diff --git a/Pods/RxSwift/RxSwift/Concurrency/LockOwnerType.swift b/Pods/RxSwift/RxSwift/Concurrency/LockOwnerType.swift deleted file mode 100644 index 8a98007d1..000000000 --- a/Pods/RxSwift/RxSwift/Concurrency/LockOwnerType.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// LockOwnerType.swift -// RxSwift -// -// Created by Krunoslav Zaher on 10/25/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -protocol LockOwnerType: AnyObject, Lock { - var lock: RecursiveLock { get } -} - -extension LockOwnerType { - func lock() { self.lock.lock() } - func unlock() { self.lock.unlock() } -} diff --git a/Pods/RxSwift/RxSwift/Concurrency/SynchronizedDisposeType.swift b/Pods/RxSwift/RxSwift/Concurrency/SynchronizedDisposeType.swift deleted file mode 100644 index 527a2fbe8..000000000 --- a/Pods/RxSwift/RxSwift/Concurrency/SynchronizedDisposeType.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// SynchronizedDisposeType.swift -// RxSwift -// -// Created by Krunoslav Zaher on 10/25/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -protocol SynchronizedDisposeType: AnyObject, Disposable, Lock { - func synchronized_dispose() -} - -extension SynchronizedDisposeType { - func synchronizedDispose() { - self.lock(); defer { self.unlock() } - self.synchronized_dispose() - } -} diff --git a/Pods/RxSwift/RxSwift/Concurrency/SynchronizedOnType.swift b/Pods/RxSwift/RxSwift/Concurrency/SynchronizedOnType.swift deleted file mode 100644 index 19168d776..000000000 --- a/Pods/RxSwift/RxSwift/Concurrency/SynchronizedOnType.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// SynchronizedOnType.swift -// RxSwift -// -// Created by Krunoslav Zaher on 10/25/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -protocol SynchronizedOnType: AnyObject, ObserverType, Lock { - func synchronized_on(_ event: Event) -} - -extension SynchronizedOnType { - func synchronizedOn(_ event: Event) { - self.lock(); defer { self.unlock() } - self.synchronized_on(event) - } -} diff --git a/Pods/RxSwift/RxSwift/Concurrency/SynchronizedUnsubscribeType.swift b/Pods/RxSwift/RxSwift/Concurrency/SynchronizedUnsubscribeType.swift deleted file mode 100644 index 988b86f4d..000000000 --- a/Pods/RxSwift/RxSwift/Concurrency/SynchronizedUnsubscribeType.swift +++ /dev/null @@ -1,13 +0,0 @@ -// -// SynchronizedUnsubscribeType.swift -// RxSwift -// -// Created by Krunoslav Zaher on 10/25/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -protocol SynchronizedUnsubscribeType: AnyObject { - associatedtype DisposeKey - - func synchronizedUnsubscribe(_ disposeKey: DisposeKey) -} diff --git a/Pods/RxSwift/RxSwift/ConnectableObservableType.swift b/Pods/RxSwift/RxSwift/ConnectableObservableType.swift deleted file mode 100644 index 52bf93c56..000000000 --- a/Pods/RxSwift/RxSwift/ConnectableObservableType.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// ConnectableObservableType.swift -// RxSwift -// -// Created by Krunoslav Zaher on 3/1/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/** -Represents an observable sequence wrapper that can be connected and disconnected from its underlying observable sequence. -*/ -public protocol ConnectableObservableType : ObservableType { - /** - Connects the observable wrapper to its source. All subscribed observers will receive values from the underlying observable sequence as long as the connection is established. - - - returns: Disposable used to disconnect the observable wrapper from its source, causing subscribed observer to stop receiving values from the underlying observable sequence. - */ - func connect() -> Disposable -} diff --git a/Pods/RxSwift/RxSwift/Date+Dispatch.swift b/Pods/RxSwift/RxSwift/Date+Dispatch.swift deleted file mode 100644 index 90f70c560..000000000 --- a/Pods/RxSwift/RxSwift/Date+Dispatch.swift +++ /dev/null @@ -1,64 +0,0 @@ -// -// Date+Dispatch.swift -// RxSwift -// -// Created by Krunoslav Zaher on 4/14/19. -// Copyright © 2019 Krunoslav Zaher. All rights reserved. -// - -import Dispatch -import Foundation - -extension DispatchTimeInterval { - var convertToSecondsFactor: Double { - switch self { - case .nanoseconds: return 1_000_000_000.0 - case .microseconds: return 1_000_000.0 - case .milliseconds: return 1_000.0 - case .seconds: return 1.0 - case .never: fatalError() - @unknown default: fatalError() - } - } - - func map(_ transform: (Int, Double) -> Int) -> DispatchTimeInterval { - switch self { - case .nanoseconds(let value): return .nanoseconds(transform(value, 1_000_000_000.0)) - case .microseconds(let value): return .microseconds(transform(value, 1_000_000.0)) - case .milliseconds(let value): return .milliseconds(transform(value, 1_000.0)) - case .seconds(let value): return .seconds(transform(value, 1.0)) - case .never: return .never - @unknown default: fatalError() - } - } - - var isNow: Bool { - switch self { - case .nanoseconds(let value), .microseconds(let value), .milliseconds(let value), .seconds(let value): return value == 0 - case .never: return false - @unknown default: fatalError() - } - } - - internal func reduceWithSpanBetween(earlierDate: Date, laterDate: Date) -> DispatchTimeInterval { - return self.map { value, factor in - let interval = laterDate.timeIntervalSince(earlierDate) - let remainder = Double(value) - interval * factor - guard remainder > 0 else { return 0 } - return Int(remainder.rounded(.toNearestOrAwayFromZero)) - } - } -} - -extension Date { - - internal func addingDispatchInterval(_ dispatchInterval: DispatchTimeInterval) -> Date { - switch dispatchInterval { - case .nanoseconds(let value), .microseconds(let value), .milliseconds(let value), .seconds(let value): - return self.addingTimeInterval(TimeInterval(value) / dispatchInterval.convertToSecondsFactor) - case .never: return Date.distantFuture - @unknown default: fatalError() - } - } - -} diff --git a/Pods/RxSwift/RxSwift/Disposable.swift b/Pods/RxSwift/RxSwift/Disposable.swift deleted file mode 100644 index b79c77a75..000000000 --- a/Pods/RxSwift/RxSwift/Disposable.swift +++ /dev/null @@ -1,13 +0,0 @@ -// -// Disposable.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/8/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// Represents a disposable resource. -public protocol Disposable { - /// Dispose resource. - func dispose() -} diff --git a/Pods/RxSwift/RxSwift/Disposables/AnonymousDisposable.swift b/Pods/RxSwift/RxSwift/Disposables/AnonymousDisposable.swift deleted file mode 100644 index 591aafa5e..000000000 --- a/Pods/RxSwift/RxSwift/Disposables/AnonymousDisposable.swift +++ /dev/null @@ -1,59 +0,0 @@ -// -// AnonymousDisposable.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/15/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// Represents an Action-based disposable. -/// -/// When dispose method is called, disposal action will be dereferenced. -private final class AnonymousDisposable : DisposeBase, Cancelable { - public typealias DisposeAction = () -> Void - - private let disposed = AtomicInt(0) - private var disposeAction: DisposeAction? - - /// - returns: Was resource disposed. - public var isDisposed: Bool { - isFlagSet(self.disposed, 1) - } - - /// Constructs a new disposable with the given action used for disposal. - /// - /// - parameter disposeAction: Disposal action which will be run upon calling `dispose`. - private init(_ disposeAction: @escaping DisposeAction) { - self.disposeAction = disposeAction - super.init() - } - - // Non-deprecated version of the constructor, used by `Disposables.create(with:)` - fileprivate init(disposeAction: @escaping DisposeAction) { - self.disposeAction = disposeAction - super.init() - } - - /// Calls the disposal action if and only if the current instance hasn't been disposed yet. - /// - /// After invoking disposal action, disposal action will be dereferenced. - fileprivate func dispose() { - if fetchOr(self.disposed, 1) == 0 { - if let action = self.disposeAction { - self.disposeAction = nil - action() - } - } - } -} - -extension Disposables { - - /// Constructs a new disposable with the given action used for disposal. - /// - /// - parameter dispose: Disposal action which will be run upon calling `dispose`. - public static func create(with dispose: @escaping () -> Void) -> Cancelable { - AnonymousDisposable(disposeAction: dispose) - } - -} diff --git a/Pods/RxSwift/RxSwift/Disposables/BinaryDisposable.swift b/Pods/RxSwift/RxSwift/Disposables/BinaryDisposable.swift deleted file mode 100644 index a3d493708..000000000 --- a/Pods/RxSwift/RxSwift/Disposables/BinaryDisposable.swift +++ /dev/null @@ -1,53 +0,0 @@ -// -// BinaryDisposable.swift -// RxSwift -// -// Created by Krunoslav Zaher on 6/12/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// Represents two disposable resources that are disposed together. -private final class BinaryDisposable : DisposeBase, Cancelable { - - private let disposed = AtomicInt(0) - - // state - private var disposable1: Disposable? - private var disposable2: Disposable? - - /// - returns: Was resource disposed. - var isDisposed: Bool { - isFlagSet(self.disposed, 1) - } - - /// Constructs new binary disposable from two disposables. - /// - /// - parameter disposable1: First disposable - /// - parameter disposable2: Second disposable - init(_ disposable1: Disposable, _ disposable2: Disposable) { - self.disposable1 = disposable1 - self.disposable2 = disposable2 - super.init() - } - - /// Calls the disposal action if and only if the current instance hasn't been disposed yet. - /// - /// After invoking disposal action, disposal action will be dereferenced. - func dispose() { - if fetchOr(self.disposed, 1) == 0 { - self.disposable1?.dispose() - self.disposable2?.dispose() - self.disposable1 = nil - self.disposable2 = nil - } - } -} - -extension Disposables { - - /// Creates a disposable with the given disposables. - public static func create(_ disposable1: Disposable, _ disposable2: Disposable) -> Cancelable { - BinaryDisposable(disposable1, disposable2) - } - -} diff --git a/Pods/RxSwift/RxSwift/Disposables/BooleanDisposable.swift b/Pods/RxSwift/RxSwift/Disposables/BooleanDisposable.swift deleted file mode 100644 index c7d73e960..000000000 --- a/Pods/RxSwift/RxSwift/Disposables/BooleanDisposable.swift +++ /dev/null @@ -1,33 +0,0 @@ -// -// BooleanDisposable.swift -// RxSwift -// -// Created by Junior B. on 10/29/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// Represents a disposable resource that can be checked for disposal status. -public final class BooleanDisposable : Cancelable { - - internal static let BooleanDisposableTrue = BooleanDisposable(isDisposed: true) - private var disposed = false - - /// Initializes a new instance of the `BooleanDisposable` class - public init() { - } - - /// Initializes a new instance of the `BooleanDisposable` class with given value - public init(isDisposed: Bool) { - self.disposed = isDisposed - } - - /// - returns: Was resource disposed. - public var isDisposed: Bool { - self.disposed - } - - /// Sets the status to disposed, which can be observer through the `isDisposed` property. - public func dispose() { - self.disposed = true - } -} diff --git a/Pods/RxSwift/RxSwift/Disposables/CompositeDisposable.swift b/Pods/RxSwift/RxSwift/Disposables/CompositeDisposable.swift deleted file mode 100644 index bb4efe6ac..000000000 --- a/Pods/RxSwift/RxSwift/Disposables/CompositeDisposable.swift +++ /dev/null @@ -1,147 +0,0 @@ -// -// CompositeDisposable.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/20/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// Represents a group of disposable resources that are disposed together. -public final class CompositeDisposable : DisposeBase, Cancelable { - /// Key used to remove disposable from composite disposable - public struct DisposeKey { - fileprivate let key: BagKey - fileprivate init(key: BagKey) { - self.key = key - } - } - - private var lock = SpinLock() - - // state - private var disposables: Bag? = Bag() - - public var isDisposed: Bool { - self.lock.performLocked { self.disposables == nil } - } - - public override init() { - } - - /// Initializes a new instance of composite disposable with the specified number of disposables. - public init(_ disposable1: Disposable, _ disposable2: Disposable) { - // This overload is here to make sure we are using optimized version up to 4 arguments. - _ = self.disposables!.insert(disposable1) - _ = self.disposables!.insert(disposable2) - } - - /// Initializes a new instance of composite disposable with the specified number of disposables. - public init(_ disposable1: Disposable, _ disposable2: Disposable, _ disposable3: Disposable) { - // This overload is here to make sure we are using optimized version up to 4 arguments. - _ = self.disposables!.insert(disposable1) - _ = self.disposables!.insert(disposable2) - _ = self.disposables!.insert(disposable3) - } - - /// Initializes a new instance of composite disposable with the specified number of disposables. - public init(_ disposable1: Disposable, _ disposable2: Disposable, _ disposable3: Disposable, _ disposable4: Disposable, _ disposables: Disposable...) { - // This overload is here to make sure we are using optimized version up to 4 arguments. - _ = self.disposables!.insert(disposable1) - _ = self.disposables!.insert(disposable2) - _ = self.disposables!.insert(disposable3) - _ = self.disposables!.insert(disposable4) - - for disposable in disposables { - _ = self.disposables!.insert(disposable) - } - } - - /// Initializes a new instance of composite disposable with the specified number of disposables. - public init(disposables: [Disposable]) { - for disposable in disposables { - _ = self.disposables!.insert(disposable) - } - } - - /** - Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed. - - - parameter disposable: Disposable to add. - - returns: Key that can be used to remove disposable from composite disposable. In case dispose bag was already - disposed `nil` will be returned. - */ - public func insert(_ disposable: Disposable) -> DisposeKey? { - let key = self._insert(disposable) - - if key == nil { - disposable.dispose() - } - - return key - } - - private func _insert(_ disposable: Disposable) -> DisposeKey? { - self.lock.performLocked { - let bagKey = self.disposables?.insert(disposable) - return bagKey.map(DisposeKey.init) - } - } - - /// - returns: Gets the number of disposables contained in the `CompositeDisposable`. - public var count: Int { - self.lock.performLocked { self.disposables?.count ?? 0 } - } - - /// Removes and disposes the disposable identified by `disposeKey` from the CompositeDisposable. - /// - /// - parameter disposeKey: Key used to identify disposable to be removed. - public func remove(for disposeKey: DisposeKey) { - self._remove(for: disposeKey)?.dispose() - } - - private func _remove(for disposeKey: DisposeKey) -> Disposable? { - self.lock.performLocked { self.disposables?.removeKey(disposeKey.key) } - } - - /// Disposes all disposables in the group and removes them from the group. - public func dispose() { - if let disposables = self._dispose() { - disposeAll(in: disposables) - } - } - - private func _dispose() -> Bag? { - self.lock.performLocked { - let current = self.disposables - self.disposables = nil - return current - } - } -} - -extension Disposables { - - /// Creates a disposable with the given disposables. - public static func create(_ disposable1: Disposable, _ disposable2: Disposable, _ disposable3: Disposable) -> Cancelable { - CompositeDisposable(disposable1, disposable2, disposable3) - } - - /// Creates a disposable with the given disposables. - public static func create(_ disposable1: Disposable, _ disposable2: Disposable, _ disposable3: Disposable, _ disposables: Disposable ...) -> Cancelable { - var disposables = disposables - disposables.append(disposable1) - disposables.append(disposable2) - disposables.append(disposable3) - return CompositeDisposable(disposables: disposables) - } - - /// Creates a disposable with the given disposables. - public static func create(_ disposables: [Disposable]) -> Cancelable { - switch disposables.count { - case 2: - return Disposables.create(disposables[0], disposables[1]) - default: - return CompositeDisposable(disposables: disposables) - } - } -} diff --git a/Pods/RxSwift/RxSwift/Disposables/Disposables.swift b/Pods/RxSwift/RxSwift/Disposables/Disposables.swift deleted file mode 100644 index 8cd6e28c3..000000000 --- a/Pods/RxSwift/RxSwift/Disposables/Disposables.swift +++ /dev/null @@ -1,13 +0,0 @@ -// -// Disposables.swift -// RxSwift -// -// Created by Mohsen Ramezanpoor on 01/08/2016. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -/// A collection of utility methods for common disposable operations. -public struct Disposables { - private init() {} -} - diff --git a/Pods/RxSwift/RxSwift/Disposables/DisposeBag.swift b/Pods/RxSwift/RxSwift/Disposables/DisposeBag.swift deleted file mode 100644 index 1a673bcce..000000000 --- a/Pods/RxSwift/RxSwift/Disposables/DisposeBag.swift +++ /dev/null @@ -1,144 +0,0 @@ -// -// DisposeBag.swift -// RxSwift -// -// Created by Krunoslav Zaher on 3/25/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension Disposable { - /// Adds `self` to `bag` - /// - /// - parameter bag: `DisposeBag` to add `self` to. - public func disposed(by bag: DisposeBag) { - bag.insert(self) - } -} - -/** -Thread safe bag that disposes added disposables on `deinit`. - -This returns ARC (RAII) like resource management to `RxSwift`. - -In case contained disposables need to be disposed, just put a different dispose bag -or create a new one in its place. - - self.existingDisposeBag = DisposeBag() - -In case explicit disposal is necessary, there is also `CompositeDisposable`. -*/ -public final class DisposeBag: DisposeBase { - - private var lock = SpinLock() - - // state - private var disposables = [Disposable]() - private var isDisposed = false - - /// Constructs new empty dispose bag. - public override init() { - super.init() - } - - /// Adds `disposable` to be disposed when dispose bag is being deinited. - /// - /// - parameter disposable: Disposable to add. - public func insert(_ disposable: Disposable) { - self._insert(disposable)?.dispose() - } - - private func _insert(_ disposable: Disposable) -> Disposable? { - self.lock.performLocked { - if self.isDisposed { - return disposable - } - - self.disposables.append(disposable) - - return nil - } - } - - /// This is internal on purpose, take a look at `CompositeDisposable` instead. - private func dispose() { - let oldDisposables = self._dispose() - - for disposable in oldDisposables { - disposable.dispose() - } - } - - private func _dispose() -> [Disposable] { - self.lock.performLocked { - let disposables = self.disposables - - self.disposables.removeAll(keepingCapacity: false) - self.isDisposed = true - - return disposables - } - } - - deinit { - self.dispose() - } -} - -extension DisposeBag { - /// Convenience init allows a list of disposables to be gathered for disposal. - public convenience init(disposing disposables: Disposable...) { - self.init() - self.disposables += disposables - } - - /// Convenience init which utilizes a function builder to let you pass in a list of - /// disposables to make a DisposeBag of. - public convenience init(@DisposableBuilder builder: () -> [Disposable]) { - self.init(disposing: builder()) - } - - /// Convenience init allows an array of disposables to be gathered for disposal. - public convenience init(disposing disposables: [Disposable]) { - self.init() - self.disposables += disposables - } - - /// Convenience function allows a list of disposables to be gathered for disposal. - public func insert(_ disposables: Disposable...) { - self.insert(disposables) - } - - /// Convenience function allows a list of disposables to be gathered for disposal. - public func insert(@DisposableBuilder builder: () -> [Disposable]) { - self.insert(builder()) - } - - /// Convenience function allows an array of disposables to be gathered for disposal. - public func insert(_ disposables: [Disposable]) { - self.lock.performLocked { - if self.isDisposed { - disposables.forEach { $0.dispose() } - } else { - self.disposables += disposables - } - } - } - - /// A function builder accepting a list of Disposables and returning them as an array. - #if swift(>=5.4) - @resultBuilder - public struct DisposableBuilder { - public static func buildBlock(_ disposables: Disposable...) -> [Disposable] { - return disposables - } - } - #else - @_functionBuilder - public struct DisposableBuilder { - public static func buildBlock(_ disposables: Disposable...) -> [Disposable] { - return disposables - } - } - #endif - -} diff --git a/Pods/RxSwift/RxSwift/Disposables/DisposeBase.swift b/Pods/RxSwift/RxSwift/Disposables/DisposeBase.swift deleted file mode 100644 index 0d4b2fb7f..000000000 --- a/Pods/RxSwift/RxSwift/Disposables/DisposeBase.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// DisposeBase.swift -// RxSwift -// -// Created by Krunoslav Zaher on 4/4/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// Base class for all disposables. -public class DisposeBase { - init() { -#if TRACE_RESOURCES - _ = Resources.incrementTotal() -#endif - } - - deinit { -#if TRACE_RESOURCES - _ = Resources.decrementTotal() -#endif - } -} diff --git a/Pods/RxSwift/RxSwift/Disposables/NopDisposable.swift b/Pods/RxSwift/RxSwift/Disposables/NopDisposable.swift deleted file mode 100644 index dd436ba9c..000000000 --- a/Pods/RxSwift/RxSwift/Disposables/NopDisposable.swift +++ /dev/null @@ -1,30 +0,0 @@ -// -// NopDisposable.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/15/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// Represents a disposable that does nothing on disposal. -/// -/// Nop = No Operation -private struct NopDisposable : Disposable { - - fileprivate static let noOp: Disposable = NopDisposable() - - private init() { - - } - - /// Does nothing. - public func dispose() { - } -} - -extension Disposables { - /** - Creates a disposable that does nothing on disposal. - */ - static public func create() -> Disposable { NopDisposable.noOp } -} diff --git a/Pods/RxSwift/RxSwift/Disposables/RefCountDisposable.swift b/Pods/RxSwift/RxSwift/Disposables/RefCountDisposable.swift deleted file mode 100644 index a59f7789d..000000000 --- a/Pods/RxSwift/RxSwift/Disposables/RefCountDisposable.swift +++ /dev/null @@ -1,112 +0,0 @@ -// -// RefCountDisposable.swift -// RxSwift -// -// Created by Junior B. on 10/29/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed. -public final class RefCountDisposable : DisposeBase, Cancelable { - private var lock = SpinLock() - private var disposable = nil as Disposable? - private var primaryDisposed = false - private var count = 0 - - /// - returns: Was resource disposed. - public var isDisposed: Bool { - self.lock.performLocked { self.disposable == nil } - } - - /// Initializes a new instance of the `RefCountDisposable`. - public init(disposable: Disposable) { - self.disposable = disposable - super.init() - } - - /** - Holds a dependent disposable that when disposed decreases the refcount on the underlying disposable. - - When getter is called, a dependent disposable contributing to the reference count that manages the underlying disposable's lifetime is returned. - */ - public func retain() -> Disposable { - self.lock.performLocked { - if self.disposable != nil { - do { - _ = try incrementChecked(&self.count) - } catch { - rxFatalError("RefCountDisposable increment failed") - } - - return RefCountInnerDisposable(self) - } else { - return Disposables.create() - } - } - } - - /// Disposes the underlying disposable only when all dependent disposables have been disposed. - public func dispose() { - let oldDisposable: Disposable? = self.lock.performLocked { - if let oldDisposable = self.disposable, !self.primaryDisposed { - self.primaryDisposed = true - - if self.count == 0 { - self.disposable = nil - return oldDisposable - } - } - - return nil - } - - if let disposable = oldDisposable { - disposable.dispose() - } - } - - fileprivate func release() { - let oldDisposable: Disposable? = self.lock.performLocked { - if let oldDisposable = self.disposable { - do { - _ = try decrementChecked(&self.count) - } catch { - rxFatalError("RefCountDisposable decrement on release failed") - } - - guard self.count >= 0 else { - rxFatalError("RefCountDisposable counter is lower than 0") - } - - if self.primaryDisposed && self.count == 0 { - self.disposable = nil - return oldDisposable - } - } - - return nil - } - - if let disposable = oldDisposable { - disposable.dispose() - } - } -} - -internal final class RefCountInnerDisposable: DisposeBase, Disposable -{ - private let parent: RefCountDisposable - private let isDisposed = AtomicInt(0) - - init(_ parent: RefCountDisposable) { - self.parent = parent - super.init() - } - - internal func dispose() - { - if fetchOr(self.isDisposed, 1) == 0 { - self.parent.release() - } - } -} diff --git a/Pods/RxSwift/RxSwift/Disposables/ScheduledDisposable.swift b/Pods/RxSwift/RxSwift/Disposables/ScheduledDisposable.swift deleted file mode 100644 index 2cf997bca..000000000 --- a/Pods/RxSwift/RxSwift/Disposables/ScheduledDisposable.swift +++ /dev/null @@ -1,50 +0,0 @@ -// -// ScheduledDisposable.swift -// RxSwift -// -// Created by Krunoslav Zaher on 6/13/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -private let disposeScheduledDisposable: (ScheduledDisposable) -> Disposable = { sd in - sd.disposeInner() - return Disposables.create() -} - -/// Represents a disposable resource whose disposal invocation will be scheduled on the specified scheduler. -public final class ScheduledDisposable : Cancelable { - public let scheduler: ImmediateSchedulerType - - private let disposed = AtomicInt(0) - - // state - private var disposable: Disposable? - - /// - returns: Was resource disposed. - public var isDisposed: Bool { - isFlagSet(self.disposed, 1) - } - - /** - Initializes a new instance of the `ScheduledDisposable` that uses a `scheduler` on which to dispose the `disposable`. - - - parameter scheduler: Scheduler where the disposable resource will be disposed on. - - parameter disposable: Disposable resource to dispose on the given scheduler. - */ - public init(scheduler: ImmediateSchedulerType, disposable: Disposable) { - self.scheduler = scheduler - self.disposable = disposable - } - - /// Disposes the wrapped disposable on the provided scheduler. - public func dispose() { - _ = self.scheduler.schedule(self, action: disposeScheduledDisposable) - } - - func disposeInner() { - if fetchOr(self.disposed, 1) == 0 { - self.disposable!.dispose() - self.disposable = nil - } - } -} diff --git a/Pods/RxSwift/RxSwift/Disposables/SerialDisposable.swift b/Pods/RxSwift/RxSwift/Disposables/SerialDisposable.swift deleted file mode 100644 index ef4690d32..000000000 --- a/Pods/RxSwift/RxSwift/Disposables/SerialDisposable.swift +++ /dev/null @@ -1,73 +0,0 @@ -// -// SerialDisposable.swift -// RxSwift -// -// Created by Krunoslav Zaher on 3/12/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// Represents a disposable resource whose underlying disposable resource can be replaced by another disposable resource, causing automatic disposal of the previous underlying disposable resource. -public final class SerialDisposable : DisposeBase, Cancelable { - private var lock = SpinLock() - - // state - private var current = nil as Disposable? - private var disposed = false - - /// - returns: Was resource disposed. - public var isDisposed: Bool { - self.disposed - } - - /// Initializes a new instance of the `SerialDisposable`. - override public init() { - super.init() - } - - /** - Gets or sets the underlying disposable. - - Assigning this property disposes the previous disposable object. - - If the `SerialDisposable` has already been disposed, assignment to this property causes immediate disposal of the given disposable object. - */ - public var disposable: Disposable { - get { - self.lock.performLocked { - self.current ?? Disposables.create() - } - } - set (newDisposable) { - let disposable: Disposable? = self.lock.performLocked { - if self.isDisposed { - return newDisposable - } - else { - let toDispose = self.current - self.current = newDisposable - return toDispose - } - } - - if let disposable = disposable { - disposable.dispose() - } - } - } - - /// Disposes the underlying disposable as well as all future replacements. - public func dispose() { - self._dispose()?.dispose() - } - - private func _dispose() -> Disposable? { - self.lock.performLocked { - guard !self.isDisposed else { return nil } - - self.disposed = true - let current = self.current - self.current = nil - return current - } - } -} diff --git a/Pods/RxSwift/RxSwift/Disposables/SingleAssignmentDisposable.swift b/Pods/RxSwift/RxSwift/Disposables/SingleAssignmentDisposable.swift deleted file mode 100644 index d7307d680..000000000 --- a/Pods/RxSwift/RxSwift/Disposables/SingleAssignmentDisposable.swift +++ /dev/null @@ -1,70 +0,0 @@ -// -// SingleAssignmentDisposable.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/15/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/** -Represents a disposable resource which only allows a single assignment of its underlying disposable resource. - -If an underlying disposable resource has already been set, future attempts to set the underlying disposable resource will throw an exception. -*/ -public final class SingleAssignmentDisposable : DisposeBase, Cancelable { - - private enum DisposeState: Int32 { - case disposed = 1 - case disposableSet = 2 - } - - // state - private let state = AtomicInt(0) - private var disposable = nil as Disposable? - - /// - returns: A value that indicates whether the object is disposed. - public var isDisposed: Bool { - isFlagSet(self.state, DisposeState.disposed.rawValue) - } - - /// Initializes a new instance of the `SingleAssignmentDisposable`. - public override init() { - super.init() - } - - /// Gets or sets the underlying disposable. After disposal, the result of getting this property is undefined. - /// - /// **Throws exception if the `SingleAssignmentDisposable` has already been assigned to.** - public func setDisposable(_ disposable: Disposable) { - self.disposable = disposable - - let previousState = fetchOr(self.state, DisposeState.disposableSet.rawValue) - - if (previousState & DisposeState.disposableSet.rawValue) != 0 { - rxFatalError("oldState.disposable != nil") - } - - if (previousState & DisposeState.disposed.rawValue) != 0 { - disposable.dispose() - self.disposable = nil - } - } - - /// Disposes the underlying disposable. - public func dispose() { - let previousState = fetchOr(self.state, DisposeState.disposed.rawValue) - - if (previousState & DisposeState.disposed.rawValue) != 0 { - return - } - - if (previousState & DisposeState.disposableSet.rawValue) != 0 { - guard let disposable = self.disposable else { - rxFatalError("Disposable not set") - } - disposable.dispose() - self.disposable = nil - } - } - -} diff --git a/Pods/RxSwift/RxSwift/Disposables/SubscriptionDisposable.swift b/Pods/RxSwift/RxSwift/Disposables/SubscriptionDisposable.swift deleted file mode 100644 index a406c84cb..000000000 --- a/Pods/RxSwift/RxSwift/Disposables/SubscriptionDisposable.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// SubscriptionDisposable.swift -// RxSwift -// -// Created by Krunoslav Zaher on 10/25/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -struct SubscriptionDisposable : Disposable { - private let key: T.DisposeKey - private weak var owner: T? - - init(owner: T, key: T.DisposeKey) { - self.owner = owner - self.key = key - } - - func dispose() { - self.owner?.synchronizedUnsubscribe(self.key) - } -} diff --git a/Pods/RxSwift/RxSwift/Errors.swift b/Pods/RxSwift/RxSwift/Errors.swift deleted file mode 100644 index d2d2917e7..000000000 --- a/Pods/RxSwift/RxSwift/Errors.swift +++ /dev/null @@ -1,52 +0,0 @@ -// -// Errors.swift -// RxSwift -// -// Created by Krunoslav Zaher on 3/28/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -let RxErrorDomain = "RxErrorDomain" -let RxCompositeFailures = "RxCompositeFailures" - -/// Generic Rx error codes. -public enum RxError - : Swift.Error - , CustomDebugStringConvertible { - /// Unknown error occurred. - case unknown - /// Performing an action on disposed object. - case disposed(object: AnyObject) - /// Arithmetic overflow error. - case overflow - /// Argument out of range error. - case argumentOutOfRange - /// Sequence doesn't contain any elements. - case noElements - /// Sequence contains more than one element. - case moreThanOneElement - /// Timeout error. - case timeout -} - -extension RxError { - /// A textual representation of `self`, suitable for debugging. - public var debugDescription: String { - switch self { - case .unknown: - return "Unknown error occurred." - case .disposed(let object): - return "Object `\(object)` was already disposed." - case .overflow: - return "Arithmetic overflow occurred." - case .argumentOutOfRange: - return "Argument out of range." - case .noElements: - return "Sequence doesn't contain any elements." - case .moreThanOneElement: - return "Sequence contains more than one element." - case .timeout: - return "Sequence timeout." - } - } -} diff --git a/Pods/RxSwift/RxSwift/Event.swift b/Pods/RxSwift/RxSwift/Event.swift deleted file mode 100644 index 01861a858..000000000 --- a/Pods/RxSwift/RxSwift/Event.swift +++ /dev/null @@ -1,104 +0,0 @@ -// -// Event.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/8/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// Represents a sequence event. -/// -/// Sequence grammar: -/// **next\* (error | completed)** -@frozen public enum Event { - /// Next element is produced. - case next(Element) - - /// Sequence terminated with an error. - case error(Swift.Error) - - /// Sequence completed successfully. - case completed -} - -extension Event: CustomDebugStringConvertible { - /// Description of event. - public var debugDescription: String { - switch self { - case .next(let value): - return "next(\(value))" - case .error(let error): - return "error(\(error))" - case .completed: - return "completed" - } - } -} - -extension Event { - /// Is `completed` or `error` event. - public var isStopEvent: Bool { - switch self { - case .next: return false - case .error, .completed: return true - } - } - - /// If `next` event, returns element value. - public var element: Element? { - if case .next(let value) = self { - return value - } - return nil - } - - /// If `error` event, returns error. - public var error: Swift.Error? { - if case .error(let error) = self { - return error - } - return nil - } - - /// If `completed` event, returns `true`. - public var isCompleted: Bool { - if case .completed = self { - return true - } - return false - } -} - -extension Event { - /// Maps sequence elements using transform. If error happens during the transform, `.error` - /// will be returned as value. - public func map(_ transform: (Element) throws -> Result) -> Event { - do { - switch self { - case let .next(element): - return .next(try transform(element)) - case let .error(error): - return .error(error) - case .completed: - return .completed - } - } - catch let e { - return .error(e) - } - } -} - -/// A type that can be converted to `Event`. -public protocol EventConvertible { - /// Type of element in event - associatedtype Element - - /// Event representation of this instance - var event: Event { get } -} - -extension Event: EventConvertible { - /// Event representation of this instance - public var event: Event { self } -} diff --git a/Pods/RxSwift/RxSwift/Extensions/Bag+Rx.swift b/Pods/RxSwift/RxSwift/Extensions/Bag+Rx.swift deleted file mode 100644 index 97946837a..000000000 --- a/Pods/RxSwift/RxSwift/Extensions/Bag+Rx.swift +++ /dev/null @@ -1,50 +0,0 @@ -// -// Bag+Rx.swift -// RxSwift -// -// Created by Krunoslav Zaher on 10/19/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - - -// MARK: forEach - -@inline(__always) -func dispatch(_ bag: Bag<(Event) -> Void>, _ event: Event) { - bag._value0?(event) - - if bag._onlyFastPath { - return - } - - let pairs = bag._pairs - for i in 0 ..< pairs.count { - pairs[i].value(event) - } - - if let dictionary = bag._dictionary { - for element in dictionary.values { - element(event) - } - } -} - -/// Dispatches `dispose` to all disposables contained inside bag. -func disposeAll(in bag: Bag) { - bag._value0?.dispose() - - if bag._onlyFastPath { - return - } - - let pairs = bag._pairs - for i in 0 ..< pairs.count { - pairs[i].value.dispose() - } - - if let dictionary = bag._dictionary { - for element in dictionary.values { - element.dispose() - } - } -} diff --git a/Pods/RxSwift/RxSwift/GroupedObservable.swift b/Pods/RxSwift/RxSwift/GroupedObservable.swift deleted file mode 100644 index 189a8c46a..000000000 --- a/Pods/RxSwift/RxSwift/GroupedObservable.swift +++ /dev/null @@ -1,35 +0,0 @@ -// -// GroupedObservable.swift -// RxSwift -// -// Created by Tomi Koskinen on 01/12/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// Represents an observable sequence of elements that have a common key. -public struct GroupedObservable : ObservableType { - /// Gets the common key. - public let key: Key - - private let source: Observable - - /// Initializes grouped observable sequence with key and source observable sequence. - /// - /// - parameter key: Grouped observable sequence key - /// - parameter source: Observable sequence that represents sequence of elements for the key - /// - returns: Grouped observable sequence of elements for the specific key - public init(key: Key, source: Observable) { - self.key = key - self.source = source - } - - /// Subscribes `observer` to receive events for this sequence. - public func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { - self.source.subscribe(observer) - } - - /// Converts `self` to `Observable` sequence. - public func asObservable() -> Observable { - self.source - } -} diff --git a/Pods/RxSwift/RxSwift/ImmediateSchedulerType.swift b/Pods/RxSwift/RxSwift/ImmediateSchedulerType.swift deleted file mode 100644 index 954fbf04b..000000000 --- a/Pods/RxSwift/RxSwift/ImmediateSchedulerType.swift +++ /dev/null @@ -1,36 +0,0 @@ -// -// ImmediateSchedulerType.swift -// RxSwift -// -// Created by Krunoslav Zaher on 5/31/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// Represents an object that immediately schedules units of work. -public protocol ImmediateSchedulerType { - /** - Schedules an action to be executed immediately. - - - parameter state: State passed to the action to be executed. - - parameter action: Action to be executed. - - returns: The disposable object used to cancel the scheduled action (best effort). - */ - func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable -} - -extension ImmediateSchedulerType { - /** - Schedules an action to be executed recursively. - - - parameter state: State passed to the action to be executed. - - parameter action: Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state. - - returns: The disposable object used to cancel the scheduled action (best effort). - */ - public func scheduleRecursive(_ state: State, action: @escaping (_ state: State, _ recurse: (State) -> Void) -> Void) -> Disposable { - let recursiveScheduler = RecursiveImmediateScheduler(action: action, scheduler: self) - - recursiveScheduler.schedule(state) - - return Disposables.create(with: recursiveScheduler.dispose) - } -} diff --git a/Pods/RxSwift/RxSwift/Observable.swift b/Pods/RxSwift/RxSwift/Observable.swift deleted file mode 100644 index 93a3ed78f..000000000 --- a/Pods/RxSwift/RxSwift/Observable.swift +++ /dev/null @@ -1,31 +0,0 @@ -// -// Observable.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/8/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// A type-erased `ObservableType`. -/// -/// It represents a push style sequence. -public class Observable : ObservableType { - init() { -#if TRACE_RESOURCES - _ = Resources.incrementTotal() -#endif - } - - public func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { - rxAbstractMethod() - } - - public func asObservable() -> Observable { self } - - deinit { -#if TRACE_RESOURCES - _ = Resources.decrementTotal() -#endif - } -} - diff --git a/Pods/RxSwift/RxSwift/ObservableConvertibleType.swift b/Pods/RxSwift/RxSwift/ObservableConvertibleType.swift deleted file mode 100644 index 0f56a8165..000000000 --- a/Pods/RxSwift/RxSwift/ObservableConvertibleType.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// ObservableConvertibleType.swift -// RxSwift -// -// Created by Krunoslav Zaher on 9/17/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// Type that can be converted to observable sequence (`Observable`). -public protocol ObservableConvertibleType { - /// Type of elements in sequence. - associatedtype Element - - /// Converts `self` to `Observable` sequence. - /// - /// - returns: Observable sequence that represents `self`. - func asObservable() -> Observable -} diff --git a/Pods/RxSwift/RxSwift/ObservableType+Extensions.swift b/Pods/RxSwift/RxSwift/ObservableType+Extensions.swift deleted file mode 100644 index ac850c3ba..000000000 --- a/Pods/RxSwift/RxSwift/ObservableType+Extensions.swift +++ /dev/null @@ -1,174 +0,0 @@ -// -// ObservableType+Extensions.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/21/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if DEBUG - import Foundation -#endif - -extension ObservableType { - /** - Subscribes an event handler to an observable sequence. - - - parameter on: Action to invoke for each event in the observable sequence. - - returns: Subscription object used to unsubscribe from the observable sequence. - */ - public func subscribe(_ on: @escaping (Event) -> Void) -> Disposable { - let observer = AnonymousObserver { e in - on(e) - } - return self.asObservable().subscribe(observer) - } - - /** - Subscribes an element handler, an error handler, a completion handler and disposed handler to an observable sequence. - - Also, take in an object and provide an unretained, safe to use (i.e. not implicitly unwrapped), reference to it along with the events emitted by the sequence. - - - Note: If `object` can't be retained, none of the other closures will be invoked. - - - parameter object: The object to provide an unretained reference on. - - parameter onNext: Action to invoke for each element in the observable sequence. - - parameter onError: Action to invoke upon errored termination of the observable sequence. - - parameter onCompleted: Action to invoke upon graceful termination of the observable sequence. - - parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has - gracefully completed, errored, or if the generation is canceled by disposing subscription). - - returns: Subscription object used to unsubscribe from the observable sequence. - */ - public func subscribe( - with object: Object, - onNext: ((Object, Element) -> Void)? = nil, - onError: ((Object, Swift.Error) -> Void)? = nil, - onCompleted: ((Object) -> Void)? = nil, - onDisposed: ((Object) -> Void)? = nil - ) -> Disposable { - subscribe( - onNext: { [weak object] in - guard let object = object else { return } - onNext?(object, $0) - }, - onError: { [weak object] in - guard let object = object else { return } - onError?(object, $0) - }, - onCompleted: { [weak object] in - guard let object = object else { return } - onCompleted?(object) - }, - onDisposed: { [weak object] in - guard let object = object else { return } - onDisposed?(object) - } - ) - } - - /** - Subscribes an element handler, an error handler, a completion handler and disposed handler to an observable sequence. - - - parameter onNext: Action to invoke for each element in the observable sequence. - - parameter onError: Action to invoke upon errored termination of the observable sequence. - - parameter onCompleted: Action to invoke upon graceful termination of the observable sequence. - - parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has - gracefully completed, errored, or if the generation is canceled by disposing subscription). - - returns: Subscription object used to unsubscribe from the observable sequence. - */ - public func subscribe( - onNext: ((Element) -> Void)? = nil, - onError: ((Swift.Error) -> Void)? = nil, - onCompleted: (() -> Void)? = nil, - onDisposed: (() -> Void)? = nil - ) -> Disposable { - let disposable: Disposable - - if let disposed = onDisposed { - disposable = Disposables.create(with: disposed) - } - else { - disposable = Disposables.create() - } - - #if DEBUG - let synchronizationTracker = SynchronizationTracker() - #endif - - let callStack = Hooks.recordCallStackOnError ? Hooks.customCaptureSubscriptionCallstack() : [] - - let observer = AnonymousObserver { event in - - #if DEBUG - synchronizationTracker.register(synchronizationErrorMessage: .default) - defer { synchronizationTracker.unregister() } - #endif - - switch event { - case .next(let value): - onNext?(value) - case .error(let error): - if let onError = onError { - onError(error) - } - else { - Hooks.defaultErrorHandler(callStack, error) - } - disposable.dispose() - case .completed: - onCompleted?() - disposable.dispose() - } - } - return Disposables.create( - self.asObservable().subscribe(observer), - disposable - ) - } -} - -import Foundation - -extension Hooks { - public typealias DefaultErrorHandler = (_ subscriptionCallStack: [String], _ error: Error) -> Void - public typealias CustomCaptureSubscriptionCallstack = () -> [String] - - private static let lock = RecursiveLock() - private static var _defaultErrorHandler: DefaultErrorHandler = { subscriptionCallStack, error in - #if DEBUG - let serializedCallStack = subscriptionCallStack.joined(separator: "\n") - print("Unhandled error happened: \(error)") - if !serializedCallStack.isEmpty { - print("subscription called from:\n\(serializedCallStack)") - } - #endif - } - private static var _customCaptureSubscriptionCallstack: CustomCaptureSubscriptionCallstack = { - #if DEBUG - return Thread.callStackSymbols - #else - return [] - #endif - } - - /// Error handler called in case onError handler wasn't provided. - public static var defaultErrorHandler: DefaultErrorHandler { - get { - lock.performLocked { _defaultErrorHandler } - } - set { - lock.performLocked { _defaultErrorHandler = newValue } - } - } - - /// Subscription callstack block to fetch custom callstack information. - public static var customCaptureSubscriptionCallstack: CustomCaptureSubscriptionCallstack { - get { - lock.performLocked { _customCaptureSubscriptionCallstack } - } - set { - lock.performLocked { _customCaptureSubscriptionCallstack = newValue } - } - } -} - diff --git a/Pods/RxSwift/RxSwift/ObservableType.swift b/Pods/RxSwift/RxSwift/ObservableType.swift deleted file mode 100644 index 279bf7f46..000000000 --- a/Pods/RxSwift/RxSwift/ObservableType.swift +++ /dev/null @@ -1,45 +0,0 @@ -// -// ObservableType.swift -// RxSwift -// -// Created by Krunoslav Zaher on 8/8/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// Represents a push style sequence. -public protocol ObservableType: ObservableConvertibleType { - /** - Subscribes `observer` to receive events for this sequence. - - ### Grammar - - **Next\* (Error | Completed)?** - - * sequences can produce zero or more elements so zero or more `Next` events can be sent to `observer` - * once an `Error` or `Completed` event is sent, the sequence terminates and can't produce any other elements - - It is possible that events are sent from different threads, but no two events can be sent concurrently to - `observer`. - - ### Resource Management - - When sequence sends `Complete` or `Error` event all internal resources that compute sequence elements - will be freed. - - To cancel production of sequence elements and free resources immediately, call `dispose` on returned - subscription. - - - returns: Subscription for `observer` that can be used to cancel production of sequence elements and free resources. - */ - func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element -} - -extension ObservableType { - - /// Default implementation of converting `ObservableType` to `Observable`. - public func asObservable() -> Observable { - // temporary workaround - //return Observable.create(subscribe: self.subscribe) - Observable.create { o in self.subscribe(o) } - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/AddRef.swift b/Pods/RxSwift/RxSwift/Observables/AddRef.swift deleted file mode 100644 index a96dfcb03..000000000 --- a/Pods/RxSwift/RxSwift/Observables/AddRef.swift +++ /dev/null @@ -1,44 +0,0 @@ -// -// AddRef.swift -// RxSwift -// -// Created by Junior B. on 30/10/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -final class AddRefSink : Sink, ObserverType { - typealias Element = Observer.Element - - override init(observer: Observer, cancel: Cancelable) { - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - switch event { - case .next: - self.forwardOn(event) - case .completed, .error: - self.forwardOn(event) - self.dispose() - } - } -} - -final class AddRef : Producer { - - private let source: Observable - private let refCount: RefCountDisposable - - init(source: Observable, refCount: RefCountDisposable) { - self.source = source - self.refCount = refCount - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let releaseDisposable = self.refCount.retain() - let sink = AddRefSink(observer: observer, cancel: cancel) - let subscription = Disposables.create(releaseDisposable, self.source.subscribe(sink)) - - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Amb.swift b/Pods/RxSwift/RxSwift/Observables/Amb.swift deleted file mode 100644 index efc17a8d9..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Amb.swift +++ /dev/null @@ -1,157 +0,0 @@ -// -// Amb.swift -// RxSwift -// -// Created by Krunoslav Zaher on 6/14/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Propagates the observable sequence that reacts first. - - - seealso: [amb operator on reactivex.io](http://reactivex.io/documentation/operators/amb.html) - - - returns: An observable sequence that surfaces any of the given sequences, whichever reacted first. - */ - public static func amb(_ sequence: Sequence) -> Observable - where Sequence.Element == Observable { - sequence.reduce(Observable.never()) { a, o in - a.amb(o.asObservable()) - } - } -} - -extension ObservableType { - - /** - Propagates the observable sequence that reacts first. - - - seealso: [amb operator on reactivex.io](http://reactivex.io/documentation/operators/amb.html) - - - parameter right: Second observable sequence. - - returns: An observable sequence that surfaces either of the given sequences, whichever reacted first. - */ - public func amb - (_ right: O2) - -> Observable where O2.Element == Element { - Amb(left: self.asObservable(), right: right.asObservable()) - } -} - -private enum AmbState { - case neither - case left - case right -} - -final private class AmbObserver: ObserverType { - typealias Element = Observer.Element - typealias Parent = AmbSink - typealias This = AmbObserver - typealias Sink = (This, Event) -> Void - - private let parent: Parent - fileprivate var sink: Sink - fileprivate var cancel: Disposable - - init(parent: Parent, cancel: Disposable, sink: @escaping Sink) { -#if TRACE_RESOURCES - _ = Resources.incrementTotal() -#endif - - self.parent = parent - self.sink = sink - self.cancel = cancel - } - - func on(_ event: Event) { - self.sink(self, event) - if event.isStopEvent { - self.cancel.dispose() - } - } - - deinit { -#if TRACE_RESOURCES - _ = Resources.decrementTotal() -#endif - } -} - -final private class AmbSink: Sink { - typealias Element = Observer.Element - typealias Parent = Amb - typealias AmbObserverType = AmbObserver - - private let parent: Parent - - private let lock = RecursiveLock() - // state - private var choice = AmbState.neither - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - let subscription1 = SingleAssignmentDisposable() - let subscription2 = SingleAssignmentDisposable() - let disposeAll = Disposables.create(subscription1, subscription2) - - let forwardEvent = { (o: AmbObserverType, event: Event) -> Void in - self.forwardOn(event) - if event.isStopEvent { - self.dispose() - } - } - - let decide = { (o: AmbObserverType, event: Event, me: AmbState, otherSubscription: Disposable) in - self.lock.performLocked { - if self.choice == .neither { - self.choice = me - o.sink = forwardEvent - o.cancel = disposeAll - otherSubscription.dispose() - } - - if self.choice == me { - self.forwardOn(event) - if event.isStopEvent { - self.dispose() - } - } - } - } - - let sink1 = AmbObserver(parent: self, cancel: subscription1) { o, e in - decide(o, e, .left, subscription2) - } - - let sink2 = AmbObserver(parent: self, cancel: subscription1) { o, e in - decide(o, e, .right, subscription1) - } - - subscription1.setDisposable(self.parent.left.subscribe(sink1)) - subscription2.setDisposable(self.parent.right.subscribe(sink2)) - - return disposeAll - } -} - -final private class Amb: Producer { - fileprivate let left: Observable - fileprivate let right: Observable - - init(left: Observable, right: Observable) { - self.left = left - self.right = right - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = AmbSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/AsMaybe.swift b/Pods/RxSwift/RxSwift/Observables/AsMaybe.swift deleted file mode 100644 index 6fa625784..000000000 --- a/Pods/RxSwift/RxSwift/Observables/AsMaybe.swift +++ /dev/null @@ -1,48 +0,0 @@ -// -// AsMaybe.swift -// RxSwift -// -// Created by Krunoslav Zaher on 3/12/17. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -private final class AsMaybeSink : Sink, ObserverType { - typealias Element = Observer.Element - - private var element: Event? - - func on(_ event: Event) { - switch event { - case .next: - if self.element != nil { - self.forwardOn(.error(RxError.moreThanOneElement)) - self.dispose() - } - - self.element = event - case .error: - self.forwardOn(event) - self.dispose() - case .completed: - if let element = self.element { - self.forwardOn(element) - } - self.forwardOn(.completed) - self.dispose() - } - } -} - -final class AsMaybe: Producer { - private let source: Observable - - init(source: Observable) { - self.source = source - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = AsMaybeSink(observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/AsSingle.swift b/Pods/RxSwift/RxSwift/Observables/AsSingle.swift deleted file mode 100644 index b39932f12..000000000 --- a/Pods/RxSwift/RxSwift/Observables/AsSingle.swift +++ /dev/null @@ -1,51 +0,0 @@ -// -// AsSingle.swift -// RxSwift -// -// Created by Krunoslav Zaher on 3/12/17. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -private final class AsSingleSink : Sink, ObserverType { - typealias Element = Observer.Element - - private var element: Event? - - func on(_ event: Event) { - switch event { - case .next: - if self.element != nil { - self.forwardOn(.error(RxError.moreThanOneElement)) - self.dispose() - } - - self.element = event - case .error: - self.forwardOn(event) - self.dispose() - case .completed: - if let element = self.element { - self.forwardOn(element) - self.forwardOn(.completed) - } - else { - self.forwardOn(.error(RxError.noElements)) - } - self.dispose() - } - } -} - -final class AsSingle: Producer { - private let source: Observable - - init(source: Observable) { - self.source = source - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = AsSingleSink(observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Buffer.swift b/Pods/RxSwift/RxSwift/Observables/Buffer.swift deleted file mode 100644 index 087c4cf57..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Buffer.swift +++ /dev/null @@ -1,138 +0,0 @@ -// -// Buffer.swift -// RxSwift -// -// Created by Krunoslav Zaher on 9/13/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Projects each element of an observable sequence into a buffer that's sent out when either it's full or a given amount of time has elapsed, using the specified scheduler to run timers. - - A useful real-world analogy of this overload is the behavior of a ferry leaving the dock when all seats are taken, or at the scheduled time of departure, whichever event occurs first. - - - seealso: [buffer operator on reactivex.io](http://reactivex.io/documentation/operators/buffer.html) - - - parameter timeSpan: Maximum time length of a buffer. - - parameter count: Maximum element count of a buffer. - - parameter scheduler: Scheduler to run buffering timers on. - - returns: An observable sequence of buffers. - */ - public func buffer(timeSpan: RxTimeInterval, count: Int, scheduler: SchedulerType) - -> Observable<[Element]> { - BufferTimeCount(source: self.asObservable(), timeSpan: timeSpan, count: count, scheduler: scheduler) - } -} - -final private class BufferTimeCount: Producer<[Element]> { - - fileprivate let timeSpan: RxTimeInterval - fileprivate let count: Int - fileprivate let scheduler: SchedulerType - fileprivate let source: Observable - - init(source: Observable, timeSpan: RxTimeInterval, count: Int, scheduler: SchedulerType) { - self.source = source - self.timeSpan = timeSpan - self.count = count - self.scheduler = scheduler - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == [Element] { - let sink = BufferTimeCountSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - -final private class BufferTimeCountSink - : Sink - , LockOwnerType - , ObserverType - , SynchronizedOnType where Observer.Element == [Element] { - typealias Parent = BufferTimeCount - - private let parent: Parent - - let lock = RecursiveLock() - - // state - private let timerD = SerialDisposable() - private var buffer = [Element]() - private var windowID = 0 - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - self.createTimer(self.windowID) - return Disposables.create(timerD, parent.source.subscribe(self)) - } - - func startNewWindowAndSendCurrentOne() { - self.windowID = self.windowID &+ 1 - let windowID = self.windowID - - let buffer = self.buffer - self.buffer = [] - self.forwardOn(.next(buffer)) - - self.createTimer(windowID) - } - - func on(_ event: Event) { - self.synchronizedOn(event) - } - - func synchronized_on(_ event: Event) { - switch event { - case .next(let element): - self.buffer.append(element) - - if self.buffer.count == self.parent.count { - self.startNewWindowAndSendCurrentOne() - } - - case .error(let error): - self.buffer = [] - self.forwardOn(.error(error)) - self.dispose() - case .completed: - self.forwardOn(.next(self.buffer)) - self.forwardOn(.completed) - self.dispose() - } - } - - func createTimer(_ windowID: Int) { - if self.timerD.isDisposed { - return - } - - if self.windowID != windowID { - return - } - - let nextTimer = SingleAssignmentDisposable() - - self.timerD.disposable = nextTimer - - let disposable = self.parent.scheduler.scheduleRelative(windowID, dueTime: self.parent.timeSpan) { previousWindowID in - self.lock.performLocked { - if previousWindowID != self.windowID { - return - } - - self.startNewWindowAndSendCurrentOne() - } - - return Disposables.create() - } - - nextTimer.setDisposable(disposable) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Catch.swift b/Pods/RxSwift/RxSwift/Observables/Catch.swift deleted file mode 100644 index 2efd66062..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Catch.swift +++ /dev/null @@ -1,275 +0,0 @@ -// -// Catch.swift -// RxSwift -// -// Created by Krunoslav Zaher on 4/19/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Continues an observable sequence that is terminated by an error with the observable sequence produced by the handler. - - - seealso: [catch operator on reactivex.io](http://reactivex.io/documentation/operators/catch.html) - - - parameter handler: Error handler function, producing another observable sequence. - - returns: An observable sequence containing the source sequence's elements, followed by the elements produced by the handler's resulting observable sequence in case an error occurred. - */ - public func `catch`(_ handler: @escaping (Swift.Error) throws -> Observable) - -> Observable { - Catch(source: self.asObservable(), handler: handler) - } - - /** - Continues an observable sequence that is terminated by an error with the observable sequence produced by the handler. - - - seealso: [catch operator on reactivex.io](http://reactivex.io/documentation/operators/catch.html) - - - parameter handler: Error handler function, producing another observable sequence. - - returns: An observable sequence containing the source sequence's elements, followed by the elements produced by the handler's resulting observable sequence in case an error occurred. - */ - @available(*, deprecated, renamed: "catch(_:)") - public func catchError(_ handler: @escaping (Swift.Error) throws -> Observable) - -> Observable { - `catch`(handler) - } - - /** - Continues an observable sequence that is terminated by an error with a single element. - - - seealso: [catch operator on reactivex.io](http://reactivex.io/documentation/operators/catch.html) - - - parameter element: Last element in an observable sequence in case error occurs. - - returns: An observable sequence containing the source sequence's elements, followed by the `element` in case an error occurred. - */ - public func catchAndReturn(_ element: Element) - -> Observable { - Catch(source: self.asObservable(), handler: { _ in Observable.just(element) }) - } - - /** - Continues an observable sequence that is terminated by an error with a single element. - - - seealso: [catch operator on reactivex.io](http://reactivex.io/documentation/operators/catch.html) - - - parameter element: Last element in an observable sequence in case error occurs. - - returns: An observable sequence containing the source sequence's elements, followed by the `element` in case an error occurred. - */ - @available(*, deprecated, renamed: "catchAndReturn(_:)") - public func catchErrorJustReturn(_ element: Element) - -> Observable { - catchAndReturn(element) - } -} - -extension ObservableType { - /** - Continues an observable sequence that is terminated by an error with the next observable sequence. - - - seealso: [catch operator on reactivex.io](http://reactivex.io/documentation/operators/catch.html) - - - returns: An observable sequence containing elements from consecutive source sequences until a source sequence terminates successfully. - */ - @available(*, deprecated, renamed: "catch(onSuccess:onFailure:onDisposed:)") - public static func catchError(_ sequence: Sequence) -> Observable - where Sequence.Element == Observable { - `catch`(sequence: sequence) - } - - /** - Continues an observable sequence that is terminated by an error with the next observable sequence. - - - seealso: [catch operator on reactivex.io](http://reactivex.io/documentation/operators/catch.html) - - - returns: An observable sequence containing elements from consecutive source sequences until a source sequence terminates successfully. - */ - public static func `catch`(sequence: Sequence) -> Observable - where Sequence.Element == Observable { - CatchSequence(sources: sequence) - } -} - -extension ObservableType { - - /** - Repeats the source observable sequence until it successfully terminates. - - **This could potentially create an infinite sequence.** - - - seealso: [retry operator on reactivex.io](http://reactivex.io/documentation/operators/retry.html) - - - returns: Observable sequence to repeat until it successfully terminates. - */ - public func retry() -> Observable { - CatchSequence(sources: InfiniteSequence(repeatedValue: self.asObservable())) - } - - /** - Repeats the source observable sequence the specified number of times in case of an error or until it successfully terminates. - - If you encounter an error and want it to retry once, then you must use `retry(2)` - - - seealso: [retry operator on reactivex.io](http://reactivex.io/documentation/operators/retry.html) - - - parameter maxAttemptCount: Maximum number of times to repeat the sequence. - - returns: An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully. - */ - public func retry(_ maxAttemptCount: Int) - -> Observable { - CatchSequence(sources: Swift.repeatElement(self.asObservable(), count: maxAttemptCount)) - } -} - -// catch with callback - -final private class CatchSinkProxy: ObserverType { - typealias Element = Observer.Element - typealias Parent = CatchSink - - private let parent: Parent - - init(parent: Parent) { - self.parent = parent - } - - func on(_ event: Event) { - self.parent.forwardOn(event) - - switch event { - case .next: - break - case .error, .completed: - self.parent.dispose() - } - } -} - -final private class CatchSink: Sink, ObserverType { - typealias Element = Observer.Element - typealias Parent = Catch - - private let parent: Parent - private let subscription = SerialDisposable() - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - let d1 = SingleAssignmentDisposable() - self.subscription.disposable = d1 - d1.setDisposable(self.parent.source.subscribe(self)) - - return self.subscription - } - - func on(_ event: Event) { - switch event { - case .next: - self.forwardOn(event) - case .completed: - self.forwardOn(event) - self.dispose() - case .error(let error): - do { - let catchSequence = try self.parent.handler(error) - - let observer = CatchSinkProxy(parent: self) - - self.subscription.disposable = catchSequence.subscribe(observer) - } - catch let e { - self.forwardOn(.error(e)) - self.dispose() - } - } - } -} - -final private class Catch: Producer { - typealias Handler = (Swift.Error) throws -> Observable - - fileprivate let source: Observable - fileprivate let handler: Handler - - init(source: Observable, handler: @escaping Handler) { - self.source = source - self.handler = handler - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = CatchSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - -// catch enumerable - -final private class CatchSequenceSink - : TailRecursiveSink - , ObserverType where Sequence.Element: ObservableConvertibleType, Sequence.Element.Element == Observer.Element { - typealias Element = Observer.Element - typealias Parent = CatchSequence - - private var lastError: Swift.Error? - - override init(observer: Observer, cancel: Cancelable) { - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - switch event { - case .next: - self.forwardOn(event) - case .error(let error): - self.lastError = error - self.schedule(.moveNext) - case .completed: - self.forwardOn(event) - self.dispose() - } - } - - override func subscribeToNext(_ source: Observable) -> Disposable { - source.subscribe(self) - } - - override func done() { - if let lastError = self.lastError { - self.forwardOn(.error(lastError)) - } - else { - self.forwardOn(.completed) - } - - self.dispose() - } - - override func extract(_ observable: Observable) -> SequenceGenerator? { - if let onError = observable as? CatchSequence { - return (onError.sources.makeIterator(), nil) - } - else { - return nil - } - } -} - -final private class CatchSequence: Producer where Sequence.Element: ObservableConvertibleType { - typealias Element = Sequence.Element.Element - - let sources: Sequence - - init(sources: Sequence) { - self.sources = sources - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = CatchSequenceSink(observer: observer, cancel: cancel) - let subscription = sink.run((self.sources.makeIterator(), nil)) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/CombineLatest+Collection.swift b/Pods/RxSwift/RxSwift/Observables/CombineLatest+Collection.swift deleted file mode 100644 index 4350851c2..000000000 --- a/Pods/RxSwift/RxSwift/Observables/CombineLatest+Collection.swift +++ /dev/null @@ -1,165 +0,0 @@ -// -// CombineLatest+Collection.swift -// RxSwift -// -// Created by Krunoslav Zaher on 8/29/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element. - - - seealso: [combinelatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html) - - - parameter resultSelector: Function to invoke whenever any of the sources produces an element. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func combineLatest(_ collection: Collection, resultSelector: @escaping ([Collection.Element.Element]) throws -> Element) -> Observable - where Collection.Element: ObservableType { - CombineLatestCollectionType(sources: collection, resultSelector: resultSelector) - } - - /** - Merges the specified observable sequences into one observable sequence whenever any of the observable sequences produces an element. - - - seealso: [combinelatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html) - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func combineLatest(_ collection: Collection) -> Observable<[Element]> - where Collection.Element: ObservableType, Collection.Element.Element == Element { - CombineLatestCollectionType(sources: collection, resultSelector: { $0 }) - } -} - -final private class CombineLatestCollectionTypeSink - : Sink where Collection.Element: ObservableConvertibleType { - typealias Result = Observer.Element - typealias Parent = CombineLatestCollectionType - typealias SourceElement = Collection.Element.Element - - let parent: Parent - - let lock = RecursiveLock() - - // state - var numberOfValues = 0 - var values: [SourceElement?] - var isDone: [Bool] - var numberOfDone = 0 - var subscriptions: [SingleAssignmentDisposable] - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - self.values = [SourceElement?](repeating: nil, count: parent.count) - self.isDone = [Bool](repeating: false, count: parent.count) - self.subscriptions = [SingleAssignmentDisposable]() - self.subscriptions.reserveCapacity(parent.count) - - for _ in 0 ..< parent.count { - self.subscriptions.append(SingleAssignmentDisposable()) - } - - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event, atIndex: Int) { - self.lock.lock(); defer { self.lock.unlock() } - switch event { - case .next(let element): - if self.values[atIndex] == nil { - self.numberOfValues += 1 - } - - self.values[atIndex] = element - - if self.numberOfValues < self.parent.count { - let numberOfOthersThatAreDone = self.numberOfDone - (self.isDone[atIndex] ? 1 : 0) - if numberOfOthersThatAreDone == self.parent.count - 1 { - self.forwardOn(.completed) - self.dispose() - } - return - } - - do { - let result = try self.parent.resultSelector(self.values.map { $0! }) - self.forwardOn(.next(result)) - } - catch let error { - self.forwardOn(.error(error)) - self.dispose() - } - - case .error(let error): - self.forwardOn(.error(error)) - self.dispose() - case .completed: - if self.isDone[atIndex] { - return - } - - self.isDone[atIndex] = true - self.numberOfDone += 1 - - if self.numberOfDone == self.parent.count { - self.forwardOn(.completed) - self.dispose() - } - else { - self.subscriptions[atIndex].dispose() - } - } - } - - func run() -> Disposable { - var j = 0 - for i in self.parent.sources { - let index = j - let source = i.asObservable() - let disposable = source.subscribe(AnyObserver { event in - self.on(event, atIndex: index) - }) - - self.subscriptions[j].setDisposable(disposable) - - j += 1 - } - - if self.parent.sources.isEmpty { - do { - let result = try self.parent.resultSelector([]) - self.forwardOn(.next(result)) - self.forwardOn(.completed) - self.dispose() - } - catch let error { - self.forwardOn(.error(error)) - self.dispose() - } - } - - return Disposables.create(subscriptions) - } -} - -final private class CombineLatestCollectionType: Producer where Collection.Element: ObservableConvertibleType { - typealias ResultSelector = ([Collection.Element.Element]) throws -> Result - - let sources: Collection - let resultSelector: ResultSelector - let count: Int - - init(sources: Collection, resultSelector: @escaping ResultSelector) { - self.sources = sources - self.resultSelector = resultSelector - self.count = self.sources.count - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { - let sink = CombineLatestCollectionTypeSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/CombineLatest+arity.swift b/Pods/RxSwift/RxSwift/Observables/CombineLatest+arity.swift deleted file mode 100644 index e69bbab4a..000000000 --- a/Pods/RxSwift/RxSwift/Observables/CombineLatest+arity.swift +++ /dev/null @@ -1,843 +0,0 @@ -// This file is autogenerated. Take a look at `Preprocessor` target in RxSwift project -// -// CombineLatest+arity.swift -// RxSwift -// -// Created by Krunoslav Zaher on 4/22/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - - - -// 2 - -extension ObservableType { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element. - - - seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html) - - - parameter resultSelector: Function to invoke whenever any of the sources produces an element. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, resultSelector: @escaping (O1.Element, O2.Element) throws -> Element) - -> Observable { - return CombineLatest2( - source1: source1.asObservable(), source2: source2.asObservable(), - resultSelector: resultSelector - ) - } -} - -extension ObservableType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of tuples whenever any of the observable sequences produces an element. - - - seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html) - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2) - -> Observable<(O1.Element, O2.Element)> { - return CombineLatest2( - source1: source1.asObservable(), source2: source2.asObservable(), - resultSelector: { ($0, $1) } - ) - } -} - -final class CombineLatestSink2_ : CombineLatestSink { - typealias Result = Observer.Element - typealias Parent = CombineLatest2 - - let parent: Parent - - var latestElement1: E1! = nil - var latestElement2: E2! = nil - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(arity: 2, observer: observer, cancel: cancel) - } - - func run() -> Disposable { - let subscription1 = SingleAssignmentDisposable() - let subscription2 = SingleAssignmentDisposable() - - let observer1 = CombineLatestObserver(lock: self.lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self.latestElement1 = e }, this: subscription1) - let observer2 = CombineLatestObserver(lock: self.lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self.latestElement2 = e }, this: subscription2) - - subscription1.setDisposable(self.parent.source1.subscribe(observer1)) - subscription2.setDisposable(self.parent.source2.subscribe(observer2)) - - return Disposables.create([ - subscription1, - subscription2 - ]) - } - - override func getResult() throws -> Result { - try self.parent.resultSelector(self.latestElement1, self.latestElement2) - } -} - -final class CombineLatest2 : Producer { - typealias ResultSelector = (E1, E2) throws -> Result - - let source1: Observable - let source2: Observable - - let resultSelector: ResultSelector - - init(source1: Observable, source2: Observable, resultSelector: @escaping ResultSelector) { - self.source1 = source1 - self.source2 = source2 - - self.resultSelector = resultSelector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { - let sink = CombineLatestSink2_(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - - - -// 3 - -extension ObservableType { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element. - - - seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html) - - - parameter resultSelector: Function to invoke whenever any of the sources produces an element. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, resultSelector: @escaping (O1.Element, O2.Element, O3.Element) throws -> Element) - -> Observable { - return CombineLatest3( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), - resultSelector: resultSelector - ) - } -} - -extension ObservableType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of tuples whenever any of the observable sequences produces an element. - - - seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html) - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3) - -> Observable<(O1.Element, O2.Element, O3.Element)> { - return CombineLatest3( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), - resultSelector: { ($0, $1, $2) } - ) - } -} - -final class CombineLatestSink3_ : CombineLatestSink { - typealias Result = Observer.Element - typealias Parent = CombineLatest3 - - let parent: Parent - - var latestElement1: E1! = nil - var latestElement2: E2! = nil - var latestElement3: E3! = nil - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(arity: 3, observer: observer, cancel: cancel) - } - - func run() -> Disposable { - let subscription1 = SingleAssignmentDisposable() - let subscription2 = SingleAssignmentDisposable() - let subscription3 = SingleAssignmentDisposable() - - let observer1 = CombineLatestObserver(lock: self.lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self.latestElement1 = e }, this: subscription1) - let observer2 = CombineLatestObserver(lock: self.lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self.latestElement2 = e }, this: subscription2) - let observer3 = CombineLatestObserver(lock: self.lock, parent: self, index: 2, setLatestValue: { (e: E3) -> Void in self.latestElement3 = e }, this: subscription3) - - subscription1.setDisposable(self.parent.source1.subscribe(observer1)) - subscription2.setDisposable(self.parent.source2.subscribe(observer2)) - subscription3.setDisposable(self.parent.source3.subscribe(observer3)) - - return Disposables.create([ - subscription1, - subscription2, - subscription3 - ]) - } - - override func getResult() throws -> Result { - try self.parent.resultSelector(self.latestElement1, self.latestElement2, self.latestElement3) - } -} - -final class CombineLatest3 : Producer { - typealias ResultSelector = (E1, E2, E3) throws -> Result - - let source1: Observable - let source2: Observable - let source3: Observable - - let resultSelector: ResultSelector - - init(source1: Observable, source2: Observable, source3: Observable, resultSelector: @escaping ResultSelector) { - self.source1 = source1 - self.source2 = source2 - self.source3 = source3 - - self.resultSelector = resultSelector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { - let sink = CombineLatestSink3_(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - - - -// 4 - -extension ObservableType { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element. - - - seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html) - - - parameter resultSelector: Function to invoke whenever any of the sources produces an element. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element) throws -> Element) - -> Observable { - return CombineLatest4( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), - resultSelector: resultSelector - ) - } -} - -extension ObservableType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of tuples whenever any of the observable sequences produces an element. - - - seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html) - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4) - -> Observable<(O1.Element, O2.Element, O3.Element, O4.Element)> { - return CombineLatest4( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), - resultSelector: { ($0, $1, $2, $3) } - ) - } -} - -final class CombineLatestSink4_ : CombineLatestSink { - typealias Result = Observer.Element - typealias Parent = CombineLatest4 - - let parent: Parent - - var latestElement1: E1! = nil - var latestElement2: E2! = nil - var latestElement3: E3! = nil - var latestElement4: E4! = nil - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(arity: 4, observer: observer, cancel: cancel) - } - - func run() -> Disposable { - let subscription1 = SingleAssignmentDisposable() - let subscription2 = SingleAssignmentDisposable() - let subscription3 = SingleAssignmentDisposable() - let subscription4 = SingleAssignmentDisposable() - - let observer1 = CombineLatestObserver(lock: self.lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self.latestElement1 = e }, this: subscription1) - let observer2 = CombineLatestObserver(lock: self.lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self.latestElement2 = e }, this: subscription2) - let observer3 = CombineLatestObserver(lock: self.lock, parent: self, index: 2, setLatestValue: { (e: E3) -> Void in self.latestElement3 = e }, this: subscription3) - let observer4 = CombineLatestObserver(lock: self.lock, parent: self, index: 3, setLatestValue: { (e: E4) -> Void in self.latestElement4 = e }, this: subscription4) - - subscription1.setDisposable(self.parent.source1.subscribe(observer1)) - subscription2.setDisposable(self.parent.source2.subscribe(observer2)) - subscription3.setDisposable(self.parent.source3.subscribe(observer3)) - subscription4.setDisposable(self.parent.source4.subscribe(observer4)) - - return Disposables.create([ - subscription1, - subscription2, - subscription3, - subscription4 - ]) - } - - override func getResult() throws -> Result { - try self.parent.resultSelector(self.latestElement1, self.latestElement2, self.latestElement3, self.latestElement4) - } -} - -final class CombineLatest4 : Producer { - typealias ResultSelector = (E1, E2, E3, E4) throws -> Result - - let source1: Observable - let source2: Observable - let source3: Observable - let source4: Observable - - let resultSelector: ResultSelector - - init(source1: Observable, source2: Observable, source3: Observable, source4: Observable, resultSelector: @escaping ResultSelector) { - self.source1 = source1 - self.source2 = source2 - self.source3 = source3 - self.source4 = source4 - - self.resultSelector = resultSelector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { - let sink = CombineLatestSink4_(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - - - -// 5 - -extension ObservableType { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element. - - - seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html) - - - parameter resultSelector: Function to invoke whenever any of the sources produces an element. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element) throws -> Element) - -> Observable { - return CombineLatest5( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), - resultSelector: resultSelector - ) - } -} - -extension ObservableType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of tuples whenever any of the observable sequences produces an element. - - - seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html) - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5) - -> Observable<(O1.Element, O2.Element, O3.Element, O4.Element, O5.Element)> { - return CombineLatest5( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), - resultSelector: { ($0, $1, $2, $3, $4) } - ) - } -} - -final class CombineLatestSink5_ : CombineLatestSink { - typealias Result = Observer.Element - typealias Parent = CombineLatest5 - - let parent: Parent - - var latestElement1: E1! = nil - var latestElement2: E2! = nil - var latestElement3: E3! = nil - var latestElement4: E4! = nil - var latestElement5: E5! = nil - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(arity: 5, observer: observer, cancel: cancel) - } - - func run() -> Disposable { - let subscription1 = SingleAssignmentDisposable() - let subscription2 = SingleAssignmentDisposable() - let subscription3 = SingleAssignmentDisposable() - let subscription4 = SingleAssignmentDisposable() - let subscription5 = SingleAssignmentDisposable() - - let observer1 = CombineLatestObserver(lock: self.lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self.latestElement1 = e }, this: subscription1) - let observer2 = CombineLatestObserver(lock: self.lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self.latestElement2 = e }, this: subscription2) - let observer3 = CombineLatestObserver(lock: self.lock, parent: self, index: 2, setLatestValue: { (e: E3) -> Void in self.latestElement3 = e }, this: subscription3) - let observer4 = CombineLatestObserver(lock: self.lock, parent: self, index: 3, setLatestValue: { (e: E4) -> Void in self.latestElement4 = e }, this: subscription4) - let observer5 = CombineLatestObserver(lock: self.lock, parent: self, index: 4, setLatestValue: { (e: E5) -> Void in self.latestElement5 = e }, this: subscription5) - - subscription1.setDisposable(self.parent.source1.subscribe(observer1)) - subscription2.setDisposable(self.parent.source2.subscribe(observer2)) - subscription3.setDisposable(self.parent.source3.subscribe(observer3)) - subscription4.setDisposable(self.parent.source4.subscribe(observer4)) - subscription5.setDisposable(self.parent.source5.subscribe(observer5)) - - return Disposables.create([ - subscription1, - subscription2, - subscription3, - subscription4, - subscription5 - ]) - } - - override func getResult() throws -> Result { - try self.parent.resultSelector(self.latestElement1, self.latestElement2, self.latestElement3, self.latestElement4, self.latestElement5) - } -} - -final class CombineLatest5 : Producer { - typealias ResultSelector = (E1, E2, E3, E4, E5) throws -> Result - - let source1: Observable - let source2: Observable - let source3: Observable - let source4: Observable - let source5: Observable - - let resultSelector: ResultSelector - - init(source1: Observable, source2: Observable, source3: Observable, source4: Observable, source5: Observable, resultSelector: @escaping ResultSelector) { - self.source1 = source1 - self.source2 = source2 - self.source3 = source3 - self.source4 = source4 - self.source5 = source5 - - self.resultSelector = resultSelector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { - let sink = CombineLatestSink5_(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - - - -// 6 - -extension ObservableType { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element. - - - seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html) - - - parameter resultSelector: Function to invoke whenever any of the sources produces an element. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element) throws -> Element) - -> Observable { - return CombineLatest6( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), - resultSelector: resultSelector - ) - } -} - -extension ObservableType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of tuples whenever any of the observable sequences produces an element. - - - seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html) - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6) - -> Observable<(O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element)> { - return CombineLatest6( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), - resultSelector: { ($0, $1, $2, $3, $4, $5) } - ) - } -} - -final class CombineLatestSink6_ : CombineLatestSink { - typealias Result = Observer.Element - typealias Parent = CombineLatest6 - - let parent: Parent - - var latestElement1: E1! = nil - var latestElement2: E2! = nil - var latestElement3: E3! = nil - var latestElement4: E4! = nil - var latestElement5: E5! = nil - var latestElement6: E6! = nil - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(arity: 6, observer: observer, cancel: cancel) - } - - func run() -> Disposable { - let subscription1 = SingleAssignmentDisposable() - let subscription2 = SingleAssignmentDisposable() - let subscription3 = SingleAssignmentDisposable() - let subscription4 = SingleAssignmentDisposable() - let subscription5 = SingleAssignmentDisposable() - let subscription6 = SingleAssignmentDisposable() - - let observer1 = CombineLatestObserver(lock: self.lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self.latestElement1 = e }, this: subscription1) - let observer2 = CombineLatestObserver(lock: self.lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self.latestElement2 = e }, this: subscription2) - let observer3 = CombineLatestObserver(lock: self.lock, parent: self, index: 2, setLatestValue: { (e: E3) -> Void in self.latestElement3 = e }, this: subscription3) - let observer4 = CombineLatestObserver(lock: self.lock, parent: self, index: 3, setLatestValue: { (e: E4) -> Void in self.latestElement4 = e }, this: subscription4) - let observer5 = CombineLatestObserver(lock: self.lock, parent: self, index: 4, setLatestValue: { (e: E5) -> Void in self.latestElement5 = e }, this: subscription5) - let observer6 = CombineLatestObserver(lock: self.lock, parent: self, index: 5, setLatestValue: { (e: E6) -> Void in self.latestElement6 = e }, this: subscription6) - - subscription1.setDisposable(self.parent.source1.subscribe(observer1)) - subscription2.setDisposable(self.parent.source2.subscribe(observer2)) - subscription3.setDisposable(self.parent.source3.subscribe(observer3)) - subscription4.setDisposable(self.parent.source4.subscribe(observer4)) - subscription5.setDisposable(self.parent.source5.subscribe(observer5)) - subscription6.setDisposable(self.parent.source6.subscribe(observer6)) - - return Disposables.create([ - subscription1, - subscription2, - subscription3, - subscription4, - subscription5, - subscription6 - ]) - } - - override func getResult() throws -> Result { - try self.parent.resultSelector(self.latestElement1, self.latestElement2, self.latestElement3, self.latestElement4, self.latestElement5, self.latestElement6) - } -} - -final class CombineLatest6 : Producer { - typealias ResultSelector = (E1, E2, E3, E4, E5, E6) throws -> Result - - let source1: Observable - let source2: Observable - let source3: Observable - let source4: Observable - let source5: Observable - let source6: Observable - - let resultSelector: ResultSelector - - init(source1: Observable, source2: Observable, source3: Observable, source4: Observable, source5: Observable, source6: Observable, resultSelector: @escaping ResultSelector) { - self.source1 = source1 - self.source2 = source2 - self.source3 = source3 - self.source4 = source4 - self.source5 = source5 - self.source6 = source6 - - self.resultSelector = resultSelector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { - let sink = CombineLatestSink6_(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - - - -// 7 - -extension ObservableType { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element. - - - seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html) - - - parameter resultSelector: Function to invoke whenever any of the sources produces an element. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element) throws -> Element) - -> Observable { - return CombineLatest7( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), source7: source7.asObservable(), - resultSelector: resultSelector - ) - } -} - -extension ObservableType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of tuples whenever any of the observable sequences produces an element. - - - seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html) - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7) - -> Observable<(O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element)> { - return CombineLatest7( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), source7: source7.asObservable(), - resultSelector: { ($0, $1, $2, $3, $4, $5, $6) } - ) - } -} - -final class CombineLatestSink7_ : CombineLatestSink { - typealias Result = Observer.Element - typealias Parent = CombineLatest7 - - let parent: Parent - - var latestElement1: E1! = nil - var latestElement2: E2! = nil - var latestElement3: E3! = nil - var latestElement4: E4! = nil - var latestElement5: E5! = nil - var latestElement6: E6! = nil - var latestElement7: E7! = nil - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(arity: 7, observer: observer, cancel: cancel) - } - - func run() -> Disposable { - let subscription1 = SingleAssignmentDisposable() - let subscription2 = SingleAssignmentDisposable() - let subscription3 = SingleAssignmentDisposable() - let subscription4 = SingleAssignmentDisposable() - let subscription5 = SingleAssignmentDisposable() - let subscription6 = SingleAssignmentDisposable() - let subscription7 = SingleAssignmentDisposable() - - let observer1 = CombineLatestObserver(lock: self.lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self.latestElement1 = e }, this: subscription1) - let observer2 = CombineLatestObserver(lock: self.lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self.latestElement2 = e }, this: subscription2) - let observer3 = CombineLatestObserver(lock: self.lock, parent: self, index: 2, setLatestValue: { (e: E3) -> Void in self.latestElement3 = e }, this: subscription3) - let observer4 = CombineLatestObserver(lock: self.lock, parent: self, index: 3, setLatestValue: { (e: E4) -> Void in self.latestElement4 = e }, this: subscription4) - let observer5 = CombineLatestObserver(lock: self.lock, parent: self, index: 4, setLatestValue: { (e: E5) -> Void in self.latestElement5 = e }, this: subscription5) - let observer6 = CombineLatestObserver(lock: self.lock, parent: self, index: 5, setLatestValue: { (e: E6) -> Void in self.latestElement6 = e }, this: subscription6) - let observer7 = CombineLatestObserver(lock: self.lock, parent: self, index: 6, setLatestValue: { (e: E7) -> Void in self.latestElement7 = e }, this: subscription7) - - subscription1.setDisposable(self.parent.source1.subscribe(observer1)) - subscription2.setDisposable(self.parent.source2.subscribe(observer2)) - subscription3.setDisposable(self.parent.source3.subscribe(observer3)) - subscription4.setDisposable(self.parent.source4.subscribe(observer4)) - subscription5.setDisposable(self.parent.source5.subscribe(observer5)) - subscription6.setDisposable(self.parent.source6.subscribe(observer6)) - subscription7.setDisposable(self.parent.source7.subscribe(observer7)) - - return Disposables.create([ - subscription1, - subscription2, - subscription3, - subscription4, - subscription5, - subscription6, - subscription7 - ]) - } - - override func getResult() throws -> Result { - try self.parent.resultSelector(self.latestElement1, self.latestElement2, self.latestElement3, self.latestElement4, self.latestElement5, self.latestElement6, self.latestElement7) - } -} - -final class CombineLatest7 : Producer { - typealias ResultSelector = (E1, E2, E3, E4, E5, E6, E7) throws -> Result - - let source1: Observable - let source2: Observable - let source3: Observable - let source4: Observable - let source5: Observable - let source6: Observable - let source7: Observable - - let resultSelector: ResultSelector - - init(source1: Observable, source2: Observable, source3: Observable, source4: Observable, source5: Observable, source6: Observable, source7: Observable, resultSelector: @escaping ResultSelector) { - self.source1 = source1 - self.source2 = source2 - self.source3 = source3 - self.source4 = source4 - self.source5 = source5 - self.source6 = source6 - self.source7 = source7 - - self.resultSelector = resultSelector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { - let sink = CombineLatestSink7_(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - - - -// 8 - -extension ObservableType { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever any of the observable sequences produces an element. - - - seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html) - - - parameter resultSelector: Function to invoke whenever any of the sources produces an element. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, _ source8: O8, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element, O8.Element) throws -> Element) - -> Observable { - return CombineLatest8( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), source7: source7.asObservable(), source8: source8.asObservable(), - resultSelector: resultSelector - ) - } -} - -extension ObservableType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of tuples whenever any of the observable sequences produces an element. - - - seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html) - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func combineLatest - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, _ source8: O8) - -> Observable<(O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element, O8.Element)> { - return CombineLatest8( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), source7: source7.asObservable(), source8: source8.asObservable(), - resultSelector: { ($0, $1, $2, $3, $4, $5, $6, $7) } - ) - } -} - -final class CombineLatestSink8_ : CombineLatestSink { - typealias Result = Observer.Element - typealias Parent = CombineLatest8 - - let parent: Parent - - var latestElement1: E1! = nil - var latestElement2: E2! = nil - var latestElement3: E3! = nil - var latestElement4: E4! = nil - var latestElement5: E5! = nil - var latestElement6: E6! = nil - var latestElement7: E7! = nil - var latestElement8: E8! = nil - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(arity: 8, observer: observer, cancel: cancel) - } - - func run() -> Disposable { - let subscription1 = SingleAssignmentDisposable() - let subscription2 = SingleAssignmentDisposable() - let subscription3 = SingleAssignmentDisposable() - let subscription4 = SingleAssignmentDisposable() - let subscription5 = SingleAssignmentDisposable() - let subscription6 = SingleAssignmentDisposable() - let subscription7 = SingleAssignmentDisposable() - let subscription8 = SingleAssignmentDisposable() - - let observer1 = CombineLatestObserver(lock: self.lock, parent: self, index: 0, setLatestValue: { (e: E1) -> Void in self.latestElement1 = e }, this: subscription1) - let observer2 = CombineLatestObserver(lock: self.lock, parent: self, index: 1, setLatestValue: { (e: E2) -> Void in self.latestElement2 = e }, this: subscription2) - let observer3 = CombineLatestObserver(lock: self.lock, parent: self, index: 2, setLatestValue: { (e: E3) -> Void in self.latestElement3 = e }, this: subscription3) - let observer4 = CombineLatestObserver(lock: self.lock, parent: self, index: 3, setLatestValue: { (e: E4) -> Void in self.latestElement4 = e }, this: subscription4) - let observer5 = CombineLatestObserver(lock: self.lock, parent: self, index: 4, setLatestValue: { (e: E5) -> Void in self.latestElement5 = e }, this: subscription5) - let observer6 = CombineLatestObserver(lock: self.lock, parent: self, index: 5, setLatestValue: { (e: E6) -> Void in self.latestElement6 = e }, this: subscription6) - let observer7 = CombineLatestObserver(lock: self.lock, parent: self, index: 6, setLatestValue: { (e: E7) -> Void in self.latestElement7 = e }, this: subscription7) - let observer8 = CombineLatestObserver(lock: self.lock, parent: self, index: 7, setLatestValue: { (e: E8) -> Void in self.latestElement8 = e }, this: subscription8) - - subscription1.setDisposable(self.parent.source1.subscribe(observer1)) - subscription2.setDisposable(self.parent.source2.subscribe(observer2)) - subscription3.setDisposable(self.parent.source3.subscribe(observer3)) - subscription4.setDisposable(self.parent.source4.subscribe(observer4)) - subscription5.setDisposable(self.parent.source5.subscribe(observer5)) - subscription6.setDisposable(self.parent.source6.subscribe(observer6)) - subscription7.setDisposable(self.parent.source7.subscribe(observer7)) - subscription8.setDisposable(self.parent.source8.subscribe(observer8)) - - return Disposables.create([ - subscription1, - subscription2, - subscription3, - subscription4, - subscription5, - subscription6, - subscription7, - subscription8 - ]) - } - - override func getResult() throws -> Result { - try self.parent.resultSelector(self.latestElement1, self.latestElement2, self.latestElement3, self.latestElement4, self.latestElement5, self.latestElement6, self.latestElement7, self.latestElement8) - } -} - -final class CombineLatest8 : Producer { - typealias ResultSelector = (E1, E2, E3, E4, E5, E6, E7, E8) throws -> Result - - let source1: Observable - let source2: Observable - let source3: Observable - let source4: Observable - let source5: Observable - let source6: Observable - let source7: Observable - let source8: Observable - - let resultSelector: ResultSelector - - init(source1: Observable, source2: Observable, source3: Observable, source4: Observable, source5: Observable, source6: Observable, source7: Observable, source8: Observable, resultSelector: @escaping ResultSelector) { - self.source1 = source1 - self.source2 = source2 - self.source3 = source3 - self.source4 = source4 - self.source5 = source5 - self.source6 = source6 - self.source7 = source7 - self.source8 = source8 - - self.resultSelector = resultSelector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { - let sink = CombineLatestSink8_(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - - diff --git a/Pods/RxSwift/RxSwift/Observables/CombineLatest.swift b/Pods/RxSwift/RxSwift/Observables/CombineLatest.swift deleted file mode 100644 index caa025640..000000000 --- a/Pods/RxSwift/RxSwift/Observables/CombineLatest.swift +++ /dev/null @@ -1,131 +0,0 @@ -// -// CombineLatest.swift -// RxSwift -// -// Created by Krunoslav Zaher on 3/21/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -protocol CombineLatestProtocol: AnyObject { - func next(_ index: Int) - func fail(_ error: Swift.Error) - func done(_ index: Int) -} - -class CombineLatestSink - : Sink - , CombineLatestProtocol { - typealias Element = Observer.Element - - let lock = RecursiveLock() - - private let arity: Int - private var numberOfValues = 0 - private var numberOfDone = 0 - private var hasValue: [Bool] - private var isDone: [Bool] - - init(arity: Int, observer: Observer, cancel: Cancelable) { - self.arity = arity - self.hasValue = [Bool](repeating: false, count: arity) - self.isDone = [Bool](repeating: false, count: arity) - - super.init(observer: observer, cancel: cancel) - } - - func getResult() throws -> Element { - rxAbstractMethod() - } - - func next(_ index: Int) { - if !self.hasValue[index] { - self.hasValue[index] = true - self.numberOfValues += 1 - } - - if self.numberOfValues == self.arity { - do { - let result = try self.getResult() - self.forwardOn(.next(result)) - } - catch let e { - self.forwardOn(.error(e)) - self.dispose() - } - } - else { - var allOthersDone = true - - for i in 0 ..< self.arity { - if i != index && !self.isDone[i] { - allOthersDone = false - break - } - } - - if allOthersDone { - self.forwardOn(.completed) - self.dispose() - } - } - } - - func fail(_ error: Swift.Error) { - self.forwardOn(.error(error)) - self.dispose() - } - - func done(_ index: Int) { - if self.isDone[index] { - return - } - - self.isDone[index] = true - self.numberOfDone += 1 - - if self.numberOfDone == self.arity { - self.forwardOn(.completed) - self.dispose() - } - } -} - -final class CombineLatestObserver - : ObserverType - , LockOwnerType - , SynchronizedOnType { - typealias ValueSetter = (Element) -> Void - - private let parent: CombineLatestProtocol - - let lock: RecursiveLock - private let index: Int - private let this: Disposable - private let setLatestValue: ValueSetter - - init(lock: RecursiveLock, parent: CombineLatestProtocol, index: Int, setLatestValue: @escaping ValueSetter, this: Disposable) { - self.lock = lock - self.parent = parent - self.index = index - self.this = this - self.setLatestValue = setLatestValue - } - - func on(_ event: Event) { - self.synchronizedOn(event) - } - - func synchronized_on(_ event: Event) { - switch event { - case .next(let value): - self.setLatestValue(value) - self.parent.next(self.index) - case .error(let error): - self.this.dispose() - self.parent.fail(error) - case .completed: - self.this.dispose() - self.parent.done(self.index) - } - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/CompactMap.swift b/Pods/RxSwift/RxSwift/Observables/CompactMap.swift deleted file mode 100644 index 7dbcdfbe9..000000000 --- a/Pods/RxSwift/RxSwift/Observables/CompactMap.swift +++ /dev/null @@ -1,76 +0,0 @@ -// -// CompactMap.swift -// RxSwift -// -// Created by Michael Long on 04/09/2019. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Projects each element of an observable sequence into an optional form and filters all optional results. - - - parameter transform: A transform function to apply to each source element and which returns an element or nil. - - returns: An observable sequence whose elements are the result of filtering the transform function for each element of the source. - - */ - public func compactMap(_ transform: @escaping (Element) throws -> Result?) - -> Observable { - CompactMap(source: self.asObservable(), transform: transform) - } -} - -final private class CompactMapSink: Sink, ObserverType { - typealias Transform = (SourceType) throws -> ResultType? - - typealias ResultType = Observer.Element - typealias Element = SourceType - - private let transform: Transform - - init(transform: @escaping Transform, observer: Observer, cancel: Cancelable) { - self.transform = transform - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - switch event { - case .next(let element): - do { - if let mappedElement = try self.transform(element) { - self.forwardOn(.next(mappedElement)) - } - } - catch let e { - self.forwardOn(.error(e)) - self.dispose() - } - case .error(let error): - self.forwardOn(.error(error)) - self.dispose() - case .completed: - self.forwardOn(.completed) - self.dispose() - } - } -} - -final private class CompactMap: Producer { - typealias Transform = (SourceType) throws -> ResultType? - - private let source: Observable - - private let transform: Transform - - init(source: Observable, transform: @escaping Transform) { - self.source = source - self.transform = transform - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == ResultType { - let sink = CompactMapSink(transform: self.transform, observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Concat.swift b/Pods/RxSwift/RxSwift/Observables/Concat.swift deleted file mode 100644 index b2fb1a2e5..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Concat.swift +++ /dev/null @@ -1,131 +0,0 @@ -// -// Concat.swift -// RxSwift -// -// Created by Krunoslav Zaher on 3/21/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Concatenates the second observable sequence to `self` upon successful termination of `self`. - - - seealso: [concat operator on reactivex.io](http://reactivex.io/documentation/operators/concat.html) - - - parameter second: Second observable sequence. - - returns: An observable sequence that contains the elements of `self`, followed by those of the second sequence. - */ - public func concat(_ second: Source) -> Observable where Source.Element == Element { - Observable.concat([self.asObservable(), second.asObservable()]) - } -} - -extension ObservableType { - /** - Concatenates all observable sequences in the given sequence, as long as the previous observable sequence terminated successfully. - - This operator has tail recursive optimizations that will prevent stack overflow. - - Optimizations will be performed in cases equivalent to following: - - [1, [2, [3, .....].concat()].concat].concat() - - - seealso: [concat operator on reactivex.io](http://reactivex.io/documentation/operators/concat.html) - - - returns: An observable sequence that contains the elements of each given sequence, in sequential order. - */ - public static func concat(_ sequence: Sequence) -> Observable - where Sequence.Element == Observable { - return Concat(sources: sequence, count: nil) - } - - /** - Concatenates all observable sequences in the given collection, as long as the previous observable sequence terminated successfully. - - This operator has tail recursive optimizations that will prevent stack overflow. - - Optimizations will be performed in cases equivalent to following: - - [1, [2, [3, .....].concat()].concat].concat() - - - seealso: [concat operator on reactivex.io](http://reactivex.io/documentation/operators/concat.html) - - - returns: An observable sequence that contains the elements of each given sequence, in sequential order. - */ - public static func concat(_ collection: Collection) -> Observable - where Collection.Element == Observable { - return Concat(sources: collection, count: Int64(collection.count)) - } - - /** - Concatenates all observable sequences in the given collection, as long as the previous observable sequence terminated successfully. - - This operator has tail recursive optimizations that will prevent stack overflow. - - Optimizations will be performed in cases equivalent to following: - - [1, [2, [3, .....].concat()].concat].concat() - - - seealso: [concat operator on reactivex.io](http://reactivex.io/documentation/operators/concat.html) - - - returns: An observable sequence that contains the elements of each given sequence, in sequential order. - */ - public static func concat(_ sources: Observable ...) -> Observable { - Concat(sources: sources, count: Int64(sources.count)) - } -} - -final private class ConcatSink - : TailRecursiveSink - , ObserverType where Sequence.Element: ObservableConvertibleType, Sequence.Element.Element == Observer.Element { - typealias Element = Observer.Element - - override init(observer: Observer, cancel: Cancelable) { - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event){ - switch event { - case .next: - self.forwardOn(event) - case .error: - self.forwardOn(event) - self.dispose() - case .completed: - self.schedule(.moveNext) - } - } - - override func subscribeToNext(_ source: Observable) -> Disposable { - source.subscribe(self) - } - - override func extract(_ observable: Observable) -> SequenceGenerator? { - if let source = observable as? Concat { - return (source.sources.makeIterator(), source.count) - } - else { - return nil - } - } -} - -final private class Concat: Producer where Sequence.Element: ObservableConvertibleType { - typealias Element = Sequence.Element.Element - - fileprivate let sources: Sequence - fileprivate let count: IntMax? - - init(sources: Sequence, count: IntMax?) { - self.sources = sources - self.count = count - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = ConcatSink(observer: observer, cancel: cancel) - let subscription = sink.run((self.sources.makeIterator(), self.count)) - return (sink: sink, subscription: subscription) - } -} - diff --git a/Pods/RxSwift/RxSwift/Observables/Create.swift b/Pods/RxSwift/RxSwift/Observables/Create.swift deleted file mode 100644 index ca81442ce..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Create.swift +++ /dev/null @@ -1,78 +0,0 @@ -// -// Create.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/8/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - // MARK: create - - /** - Creates an observable sequence from a specified subscribe method implementation. - - - seealso: [create operator on reactivex.io](http://reactivex.io/documentation/operators/create.html) - - - parameter subscribe: Implementation of the resulting observable sequence's `subscribe` method. - - returns: The observable sequence with the specified implementation for the `subscribe` method. - */ - public static func create(_ subscribe: @escaping (AnyObserver) -> Disposable) -> Observable { - AnonymousObservable(subscribe) - } -} - -final private class AnonymousObservableSink: Sink, ObserverType { - typealias Element = Observer.Element - typealias Parent = AnonymousObservable - - // state - private let isStopped = AtomicInt(0) - - #if DEBUG - private let synchronizationTracker = SynchronizationTracker() - #endif - - override init(observer: Observer, cancel: Cancelable) { - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - #if DEBUG - self.synchronizationTracker.register(synchronizationErrorMessage: .default) - defer { self.synchronizationTracker.unregister() } - #endif - switch event { - case .next: - if load(self.isStopped) == 1 { - return - } - self.forwardOn(event) - case .error, .completed: - if fetchOr(self.isStopped, 1) == 0 { - self.forwardOn(event) - self.dispose() - } - } - } - - func run(_ parent: Parent) -> Disposable { - parent.subscribeHandler(AnyObserver(self)) - } -} - -final private class AnonymousObservable: Producer { - typealias SubscribeHandler = (AnyObserver) -> Disposable - - let subscribeHandler: SubscribeHandler - - init(_ subscribeHandler: @escaping SubscribeHandler) { - self.subscribeHandler = subscribeHandler - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = AnonymousObservableSink(observer: observer, cancel: cancel) - let subscription = sink.run(self) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Debounce.swift b/Pods/RxSwift/RxSwift/Observables/Debounce.swift deleted file mode 100644 index dfab00454..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Debounce.swift +++ /dev/null @@ -1,119 +0,0 @@ -// -// Debounce.swift -// RxSwift -// -// Created by Krunoslav Zaher on 9/11/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Ignores elements from an observable sequence which are followed by another element within a specified relative time duration, using the specified scheduler to run throttling timers. - - - seealso: [debounce operator on reactivex.io](http://reactivex.io/documentation/operators/debounce.html) - - - parameter dueTime: Throttling duration for each element. - - parameter scheduler: Scheduler to run the throttle timers on. - - returns: The throttled sequence. - */ - public func debounce(_ dueTime: RxTimeInterval, scheduler: SchedulerType) - -> Observable { - return Debounce(source: self.asObservable(), dueTime: dueTime, scheduler: scheduler) - } -} - -final private class DebounceSink - : Sink - , ObserverType - , LockOwnerType - , SynchronizedOnType { - typealias Element = Observer.Element - typealias ParentType = Debounce - - private let parent: ParentType - - let lock = RecursiveLock() - - // state - private var id = 0 as UInt64 - private var value: Element? - - let cancellable = SerialDisposable() - - init(parent: ParentType, observer: Observer, cancel: Cancelable) { - self.parent = parent - - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - let subscription = self.parent.source.subscribe(self) - - return Disposables.create(subscription, cancellable) - } - - func on(_ event: Event) { - self.synchronizedOn(event) - } - - func synchronized_on(_ event: Event) { - switch event { - case .next(let element): - self.id = self.id &+ 1 - let currentId = self.id - self.value = element - - - let scheduler = self.parent.scheduler - let dueTime = self.parent.dueTime - - let d = SingleAssignmentDisposable() - self.cancellable.disposable = d - d.setDisposable(scheduler.scheduleRelative(currentId, dueTime: dueTime, action: self.propagate)) - case .error: - self.value = nil - self.forwardOn(event) - self.dispose() - case .completed: - if let value = self.value { - self.value = nil - self.forwardOn(.next(value)) - } - self.forwardOn(.completed) - self.dispose() - } - } - - func propagate(_ currentId: UInt64) -> Disposable { - self.lock.performLocked { - let originalValue = self.value - - if let value = originalValue, self.id == currentId { - self.value = nil - self.forwardOn(.next(value)) - } - - return Disposables.create() - } - } -} - -final private class Debounce: Producer { - fileprivate let source: Observable - fileprivate let dueTime: RxTimeInterval - fileprivate let scheduler: SchedulerType - - init(source: Observable, dueTime: RxTimeInterval, scheduler: SchedulerType) { - self.source = source - self.dueTime = dueTime - self.scheduler = scheduler - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = DebounceSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } - -} diff --git a/Pods/RxSwift/RxSwift/Observables/Debug.swift b/Pods/RxSwift/RxSwift/Observables/Debug.swift deleted file mode 100644 index 762e394fc..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Debug.swift +++ /dev/null @@ -1,102 +0,0 @@ -// -// Debug.swift -// RxSwift -// -// Created by Krunoslav Zaher on 5/2/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import Foundation - -extension ObservableType { - - /** - Prints received events for all observers on standard output. - - - seealso: [do operator on reactivex.io](http://reactivex.io/documentation/operators/do.html) - - - parameter identifier: Identifier that is printed together with event description to standard output. - - parameter trimOutput: Should output be trimmed to max 40 characters. - - returns: An observable sequence whose events are printed to standard output. - */ - public func debug(_ identifier: String? = nil, trimOutput: Bool = false, file: String = #file, line: UInt = #line, function: String = #function) - -> Observable { - return Debug(source: self, identifier: identifier, trimOutput: trimOutput, file: file, line: line, function: function) - } -} - -private let dateFormat = "yyyy-MM-dd HH:mm:ss.SSS" - -private func logEvent(_ identifier: String, dateFormat: DateFormatter, content: String) { - print("\(dateFormat.string(from: Date())): \(identifier) -> \(content)") -} - -final private class DebugSink: Sink, ObserverType where Observer.Element == Source.Element { - typealias Element = Observer.Element - typealias Parent = Debug - - private let parent: Parent - private let timestampFormatter = DateFormatter() - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - self.timestampFormatter.dateFormat = dateFormat - - logEvent(self.parent.identifier, dateFormat: self.timestampFormatter, content: "subscribed") - - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - let maxEventTextLength = 40 - let eventText = "\(event)" - - let eventNormalized = (eventText.count > maxEventTextLength) && self.parent.trimOutput - ? String(eventText.prefix(maxEventTextLength / 2)) + "..." + String(eventText.suffix(maxEventTextLength / 2)) - : eventText - - logEvent(self.parent.identifier, dateFormat: self.timestampFormatter, content: "Event \(eventNormalized)") - - self.forwardOn(event) - if event.isStopEvent { - self.dispose() - } - } - - override func dispose() { - if !self.isDisposed { - logEvent(self.parent.identifier, dateFormat: self.timestampFormatter, content: "isDisposed") - } - super.dispose() - } -} - -final private class Debug: Producer { - fileprivate let identifier: String - fileprivate let trimOutput: Bool - private let source: Source - - init(source: Source, identifier: String?, trimOutput: Bool, file: String, line: UInt, function: String) { - self.trimOutput = trimOutput - if let identifier = identifier { - self.identifier = identifier - } - else { - let trimmedFile: String - if let lastIndex = file.lastIndex(of: "/") { - trimmedFile = String(file[file.index(after: lastIndex) ..< file.endIndex]) - } - else { - trimmedFile = file - } - self.identifier = "\(trimmedFile):\(line) (\(function))" - } - self.source = source - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Source.Element { - let sink = DebugSink(parent: self, observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Decode.swift b/Pods/RxSwift/RxSwift/Observables/Decode.swift deleted file mode 100644 index 8bc73425d..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Decode.swift +++ /dev/null @@ -1,34 +0,0 @@ -// -// Decode.swift -// RxSwift -// -// Created by Shai Mishali on 24/07/2020. -// Copyright © 2020 Krunoslav Zaher. All rights reserved. -// - -import Foundation - -public extension ObservableType where Element == Data { - /// Attempt to decode the emitted `Data` using a provided decoder. - /// - /// - parameter type: A `Decodable`-conforming type to attempt to decode to - /// - parameter decoder: A capable decoder, e.g. `JSONDecoder` or `PropertyListDecoder` - /// - /// - note: If using a custom decoder, it must conform to the `DataDecoder` protocol. - /// - /// - returns: An `Observable` of the decoded type - func decode(type: Item.Type, - decoder: Decoder) -> Observable { - map { try decoder.decode(type, from: $0) } - } -} - -/// Represents an entity capable of decoding raw `Data` -/// into a concrete `Decodable` type -public protocol DataDecoder { - func decode(_ type: Item.Type, from data: Data) throws -> Item -} - -extension JSONDecoder: DataDecoder {} -extension PropertyListDecoder: DataDecoder {} diff --git a/Pods/RxSwift/RxSwift/Observables/DefaultIfEmpty.swift b/Pods/RxSwift/RxSwift/Observables/DefaultIfEmpty.swift deleted file mode 100644 index 8d133d8f8..000000000 --- a/Pods/RxSwift/RxSwift/Observables/DefaultIfEmpty.swift +++ /dev/null @@ -1,66 +0,0 @@ -// -// DefaultIfEmpty.swift -// RxSwift -// -// Created by sergdort on 23/12/2016. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Emits elements from the source observable sequence, or a default element if the source observable sequence is empty. - - - seealso: [DefaultIfEmpty operator on reactivex.io](http://reactivex.io/documentation/operators/defaultifempty.html) - - - parameter default: Default element to be sent if the source does not emit any elements - - returns: An observable sequence which emits default element end completes in case the original sequence is empty - */ - public func ifEmpty(default: Element) -> Observable { - DefaultIfEmpty(source: self.asObservable(), default: `default`) - } -} - -final private class DefaultIfEmptySink: Sink, ObserverType { - typealias Element = Observer.Element - private let `default`: Element - private var isEmpty = true - - init(default: Element, observer: Observer, cancel: Cancelable) { - self.default = `default` - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - switch event { - case .next: - self.isEmpty = false - self.forwardOn(event) - case .error: - self.forwardOn(event) - self.dispose() - case .completed: - if self.isEmpty { - self.forwardOn(.next(self.default)) - } - self.forwardOn(.completed) - self.dispose() - } - } -} - -final private class DefaultIfEmpty: Producer { - private let source: Observable - private let `default`: SourceType - - init(source: Observable, `default`: SourceType) { - self.source = source - self.default = `default` - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == SourceType { - let sink = DefaultIfEmptySink(default: self.default, observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Deferred.swift b/Pods/RxSwift/RxSwift/Observables/Deferred.swift deleted file mode 100644 index b81cb1669..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Deferred.swift +++ /dev/null @@ -1,75 +0,0 @@ -// -// Deferred.swift -// RxSwift -// -// Created by Krunoslav Zaher on 4/19/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes. - - - seealso: [defer operator on reactivex.io](http://reactivex.io/documentation/operators/defer.html) - - - parameter observableFactory: Observable factory function to invoke for each observer that subscribes to the resulting sequence. - - returns: An observable sequence whose observers trigger an invocation of the given observable factory function. - */ - public static func deferred(_ observableFactory: @escaping () throws -> Observable) - -> Observable { - Deferred(observableFactory: observableFactory) - } -} - -final private class DeferredSink: Sink, ObserverType where Source.Element == Observer.Element { - typealias Element = Observer.Element - - private let observableFactory: () throws -> Source - - init(observableFactory: @escaping () throws -> Source, observer: Observer, cancel: Cancelable) { - self.observableFactory = observableFactory - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - do { - let result = try self.observableFactory() - return result.subscribe(self) - } - catch let e { - self.forwardOn(.error(e)) - self.dispose() - return Disposables.create() - } - } - - func on(_ event: Event) { - self.forwardOn(event) - - switch event { - case .next: - break - case .error: - self.dispose() - case .completed: - self.dispose() - } - } -} - -final private class Deferred: Producer { - typealias Factory = () throws -> Source - - private let observableFactory : Factory - - init(observableFactory: @escaping Factory) { - self.observableFactory = observableFactory - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) - where Observer.Element == Source.Element { - let sink = DeferredSink(observableFactory: self.observableFactory, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Delay.swift b/Pods/RxSwift/RxSwift/Observables/Delay.swift deleted file mode 100644 index 9f71c32d0..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Delay.swift +++ /dev/null @@ -1,174 +0,0 @@ -// -// Delay.swift -// RxSwift -// -// Created by tarunon on 2016/02/09. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -import Foundation - -extension ObservableType { - - /** - Returns an observable sequence by the source observable sequence shifted forward in time by a specified delay. Error events from the source observable sequence are not delayed. - - - seealso: [delay operator on reactivex.io](http://reactivex.io/documentation/operators/delay.html) - - - parameter dueTime: Relative time shift of the source by. - - parameter scheduler: Scheduler to run the subscription delay timer on. - - returns: the source Observable shifted in time by the specified delay. - */ - public func delay(_ dueTime: RxTimeInterval, scheduler: SchedulerType) - -> Observable { - return Delay(source: self.asObservable(), dueTime: dueTime, scheduler: scheduler) - } -} - -final private class DelaySink - : Sink - , ObserverType { - typealias Element = Observer.Element - typealias Source = Observable - typealias DisposeKey = Bag.KeyType - - private let lock = RecursiveLock() - - private let dueTime: RxTimeInterval - private let scheduler: SchedulerType - - private let sourceSubscription = SingleAssignmentDisposable() - private let cancelable = SerialDisposable() - - // is scheduled some action - private var active = false - // is "run loop" on different scheduler running - private var running = false - private var errorEvent: Event? - - // state - private var queue = Queue<(eventTime: RxTime, event: Event)>(capacity: 0) - - init(observer: Observer, dueTime: RxTimeInterval, scheduler: SchedulerType, cancel: Cancelable) { - self.dueTime = dueTime - self.scheduler = scheduler - super.init(observer: observer, cancel: cancel) - } - - // All of these complications in this method are caused by the fact that - // error should be propagated immediately. Error can be potentially received on different - // scheduler so this process needs to be synchronized somehow. - // - // Another complication is that scheduler is potentially concurrent so internal queue is used. - func drainQueue(state: (), scheduler: AnyRecursiveScheduler<()>) { - self.lock.lock() - let hasFailed = self.errorEvent != nil - if !hasFailed { - self.running = true - } - self.lock.unlock() - - if hasFailed { - return - } - - var ranAtLeastOnce = false - - while true { - self.lock.lock() - let errorEvent = self.errorEvent - - let eventToForwardImmediately = ranAtLeastOnce ? nil : self.queue.dequeue()?.event - let nextEventToScheduleOriginalTime: Date? = ranAtLeastOnce && !self.queue.isEmpty ? self.queue.peek().eventTime : nil - - if errorEvent == nil { - if eventToForwardImmediately != nil { - } - else if nextEventToScheduleOriginalTime != nil { - self.running = false - } - else { - self.running = false - self.active = false - } - } - self.lock.unlock() - - if let errorEvent = errorEvent { - self.forwardOn(errorEvent) - self.dispose() - return - } - else { - if let eventToForwardImmediately = eventToForwardImmediately { - ranAtLeastOnce = true - self.forwardOn(eventToForwardImmediately) - if case .completed = eventToForwardImmediately { - self.dispose() - return - } - } - else if let nextEventToScheduleOriginalTime = nextEventToScheduleOriginalTime { - scheduler.schedule((), dueTime: self.dueTime.reduceWithSpanBetween(earlierDate: nextEventToScheduleOriginalTime, laterDate: self.scheduler.now)) - return - } - else { - return - } - } - } - } - - func on(_ event: Event) { - if event.isStopEvent { - self.sourceSubscription.dispose() - } - - switch event { - case .error: - self.lock.lock() - let shouldSendImmediately = !self.running - self.queue = Queue(capacity: 0) - self.errorEvent = event - self.lock.unlock() - - if shouldSendImmediately { - self.forwardOn(event) - self.dispose() - } - default: - self.lock.lock() - let shouldSchedule = !self.active - self.active = true - self.queue.enqueue((self.scheduler.now, event)) - self.lock.unlock() - - if shouldSchedule { - self.cancelable.disposable = self.scheduler.scheduleRecursive((), dueTime: self.dueTime, action: self.drainQueue) - } - } - } - - func run(source: Observable) -> Disposable { - self.sourceSubscription.setDisposable(source.subscribe(self)) - return Disposables.create(sourceSubscription, cancelable) - } -} - -final private class Delay: Producer { - private let source: Observable - private let dueTime: RxTimeInterval - private let scheduler: SchedulerType - - init(source: Observable, dueTime: RxTimeInterval, scheduler: SchedulerType) { - self.source = source - self.dueTime = dueTime - self.scheduler = scheduler - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = DelaySink(observer: observer, dueTime: self.dueTime, scheduler: self.scheduler, cancel: cancel) - let subscription = sink.run(source: self.source) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/DelaySubscription.swift b/Pods/RxSwift/RxSwift/Observables/DelaySubscription.swift deleted file mode 100644 index fd8c4951f..000000000 --- a/Pods/RxSwift/RxSwift/Observables/DelaySubscription.swift +++ /dev/null @@ -1,58 +0,0 @@ -// -// DelaySubscription.swift -// RxSwift -// -// Created by Krunoslav Zaher on 6/14/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Time shifts the observable sequence by delaying the subscription with the specified relative time duration, using the specified scheduler to run timers. - - - seealso: [delay operator on reactivex.io](http://reactivex.io/documentation/operators/delay.html) - - - parameter dueTime: Relative time shift of the subscription. - - parameter scheduler: Scheduler to run the subscription delay timer on. - - returns: Time-shifted sequence. - */ - public func delaySubscription(_ dueTime: RxTimeInterval, scheduler: SchedulerType) - -> Observable { - DelaySubscription(source: self.asObservable(), dueTime: dueTime, scheduler: scheduler) - } -} - -final private class DelaySubscriptionSink - : Sink, ObserverType { - typealias Element = Observer.Element - - func on(_ event: Event) { - self.forwardOn(event) - if event.isStopEvent { - self.dispose() - } - } - -} - -final private class DelaySubscription: Producer { - private let source: Observable - private let dueTime: RxTimeInterval - private let scheduler: SchedulerType - - init(source: Observable, dueTime: RxTimeInterval, scheduler: SchedulerType) { - self.source = source - self.dueTime = dueTime - self.scheduler = scheduler - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = DelaySubscriptionSink(observer: observer, cancel: cancel) - let subscription = self.scheduler.scheduleRelative((), dueTime: self.dueTime) { _ in - return self.source.subscribe(sink) - } - - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Dematerialize.swift b/Pods/RxSwift/RxSwift/Observables/Dematerialize.swift deleted file mode 100644 index 2ccd54620..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Dematerialize.swift +++ /dev/null @@ -1,51 +0,0 @@ -// -// Dematerialize.swift -// RxSwift -// -// Created by Jamie Pinkham on 3/13/17. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType where Element: EventConvertible { - /** - Convert any previously materialized Observable into it's original form. - - seealso: [materialize operator on reactivex.io](http://reactivex.io/documentation/operators/materialize-dematerialize.html) - - returns: The dematerialized observable sequence. - */ - public func dematerialize() -> Observable { - Dematerialize(source: self.asObservable()) - } - -} - -private final class DematerializeSink: Sink, ObserverType where Observer.Element == T.Element { - fileprivate func on(_ event: Event) { - switch event { - case .next(let element): - self.forwardOn(element.event) - if element.event.isStopEvent { - self.dispose() - } - case .completed: - self.forwardOn(.completed) - self.dispose() - case .error(let error): - self.forwardOn(.error(error)) - self.dispose() - } - } -} - -final private class Dematerialize: Producer { - private let source: Observable - - init(source: Observable) { - self.source = source - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == T.Element { - let sink = DematerializeSink(observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/DistinctUntilChanged.swift b/Pods/RxSwift/RxSwift/Observables/DistinctUntilChanged.swift deleted file mode 100644 index c127b5aa5..000000000 --- a/Pods/RxSwift/RxSwift/Observables/DistinctUntilChanged.swift +++ /dev/null @@ -1,137 +0,0 @@ -// -// DistinctUntilChanged.swift -// RxSwift -// -// Created by Krunoslav Zaher on 3/15/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType where Element: Equatable { - - /** - Returns an observable sequence that contains only distinct contiguous elements according to equality operator. - - - seealso: [distinct operator on reactivex.io](http://reactivex.io/documentation/operators/distinct.html) - - - returns: An observable sequence only containing the distinct contiguous elements, based on equality operator, from the source sequence. - */ - public func distinctUntilChanged() - -> Observable { - self.distinctUntilChanged({ $0 }, comparer: { ($0 == $1) }) - } -} - -extension ObservableType { - /** - Returns an observable sequence that contains only distinct contiguous elements according to the `keySelector`. - - - seealso: [distinct operator on reactivex.io](http://reactivex.io/documentation/operators/distinct.html) - - - parameter keySelector: A function to compute the comparison key for each element. - - returns: An observable sequence only containing the distinct contiguous elements, based on a computed key value, from the source sequence. - */ - public func distinctUntilChanged(_ keySelector: @escaping (Element) throws -> Key) - -> Observable { - self.distinctUntilChanged(keySelector, comparer: { $0 == $1 }) - } - - /** - Returns an observable sequence that contains only distinct contiguous elements according to the `comparer`. - - - seealso: [distinct operator on reactivex.io](http://reactivex.io/documentation/operators/distinct.html) - - - parameter comparer: Equality comparer for computed key values. - - returns: An observable sequence only containing the distinct contiguous elements, based on `comparer`, from the source sequence. - */ - public func distinctUntilChanged(_ comparer: @escaping (Element, Element) throws -> Bool) - -> Observable { - self.distinctUntilChanged({ $0 }, comparer: comparer) - } - - /** - Returns an observable sequence that contains only distinct contiguous elements according to the keySelector and the comparer. - - - seealso: [distinct operator on reactivex.io](http://reactivex.io/documentation/operators/distinct.html) - - - parameter keySelector: A function to compute the comparison key for each element. - - parameter comparer: Equality comparer for computed key values. - - returns: An observable sequence only containing the distinct contiguous elements, based on a computed key value and the comparer, from the source sequence. - */ - public func distinctUntilChanged(_ keySelector: @escaping (Element) throws -> K, comparer: @escaping (K, K) throws -> Bool) - -> Observable { - return DistinctUntilChanged(source: self.asObservable(), selector: keySelector, comparer: comparer) - } - - /** - Returns an observable sequence that contains only contiguous elements with distinct values in the provided key path on each object. - - - seealso: [distinct operator on reactivex.io](http://reactivex.io/documentation/operators/distinct.html) - - - returns: An observable sequence only containing the distinct contiguous elements, based on equality operator on the provided key path - */ - public func distinctUntilChanged(at keyPath: KeyPath) -> - Observable { - self.distinctUntilChanged { $0[keyPath: keyPath] == $1[keyPath: keyPath] } - } -} - -final private class DistinctUntilChangedSink: Sink, ObserverType { - typealias Element = Observer.Element - - private let parent: DistinctUntilChanged - private var currentKey: Key? - - init(parent: DistinctUntilChanged, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - switch event { - case .next(let value): - do { - let key = try self.parent.selector(value) - var areEqual = false - if let currentKey = self.currentKey { - areEqual = try self.parent.comparer(currentKey, key) - } - - if areEqual { - return - } - - self.currentKey = key - - self.forwardOn(event) - } - catch let error { - self.forwardOn(.error(error)) - self.dispose() - } - case .error, .completed: - self.forwardOn(event) - self.dispose() - } - } -} - -final private class DistinctUntilChanged: Producer { - typealias KeySelector = (Element) throws -> Key - typealias EqualityComparer = (Key, Key) throws -> Bool - - private let source: Observable - fileprivate let selector: KeySelector - fileprivate let comparer: EqualityComparer - - init(source: Observable, selector: @escaping KeySelector, comparer: @escaping EqualityComparer) { - self.source = source - self.selector = selector - self.comparer = comparer - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = DistinctUntilChangedSink(parent: self, observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Do.swift b/Pods/RxSwift/RxSwift/Observables/Do.swift deleted file mode 100644 index 3c8c68b3d..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Do.swift +++ /dev/null @@ -1,112 +0,0 @@ -// -// Do.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/21/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Invokes an action for each event in the observable sequence, and propagates all observer messages through the result sequence. - - - seealso: [do operator on reactivex.io](http://reactivex.io/documentation/operators/do.html) - - - parameter onNext: Action to invoke for each element in the observable sequence. - - parameter afterNext: Action to invoke for each element after the observable has passed an onNext event along to its downstream. - - parameter onError: Action to invoke upon errored termination of the observable sequence. - - parameter afterError: Action to invoke after errored termination of the observable sequence. - - parameter onCompleted: Action to invoke upon graceful termination of the observable sequence. - - parameter afterCompleted: Action to invoke after graceful termination of the observable sequence. - - parameter onSubscribe: Action to invoke before subscribing to source observable sequence. - - parameter onSubscribed: Action to invoke after subscribing to source observable sequence. - - parameter onDispose: Action to invoke after subscription to source observable has been disposed for any reason. It can be either because sequence terminates for some reason or observer subscription being disposed. - - returns: The source sequence with the side-effecting behavior applied. - */ - public func `do`(onNext: ((Element) throws -> Void)? = nil, afterNext: ((Element) throws -> Void)? = nil, onError: ((Swift.Error) throws -> Void)? = nil, afterError: ((Swift.Error) throws -> Void)? = nil, onCompleted: (() throws -> Void)? = nil, afterCompleted: (() throws -> Void)? = nil, onSubscribe: (() -> Void)? = nil, onSubscribed: (() -> Void)? = nil, onDispose: (() -> Void)? = nil) - -> Observable { - return Do(source: self.asObservable(), eventHandler: { e in - switch e { - case .next(let element): - try onNext?(element) - case .error(let e): - try onError?(e) - case .completed: - try onCompleted?() - } - }, afterEventHandler: { e in - switch e { - case .next(let element): - try afterNext?(element) - case .error(let e): - try afterError?(e) - case .completed: - try afterCompleted?() - } - }, onSubscribe: onSubscribe, onSubscribed: onSubscribed, onDispose: onDispose) - } -} - -final private class DoSink: Sink, ObserverType { - typealias Element = Observer.Element - typealias EventHandler = (Event) throws -> Void - typealias AfterEventHandler = (Event) throws -> Void - - private let eventHandler: EventHandler - private let afterEventHandler: AfterEventHandler - - init(eventHandler: @escaping EventHandler, afterEventHandler: @escaping AfterEventHandler, observer: Observer, cancel: Cancelable) { - self.eventHandler = eventHandler - self.afterEventHandler = afterEventHandler - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - do { - try self.eventHandler(event) - self.forwardOn(event) - try self.afterEventHandler(event) - if event.isStopEvent { - self.dispose() - } - } - catch let error { - self.forwardOn(.error(error)) - self.dispose() - } - } -} - -final private class Do: Producer { - typealias EventHandler = (Event) throws -> Void - typealias AfterEventHandler = (Event) throws -> Void - - private let source: Observable - private let eventHandler: EventHandler - private let afterEventHandler: AfterEventHandler - private let onSubscribe: (() -> Void)? - private let onSubscribed: (() -> Void)? - private let onDispose: (() -> Void)? - - init(source: Observable, eventHandler: @escaping EventHandler, afterEventHandler: @escaping AfterEventHandler, onSubscribe: (() -> Void)?, onSubscribed: (() -> Void)?, onDispose: (() -> Void)?) { - self.source = source - self.eventHandler = eventHandler - self.afterEventHandler = afterEventHandler - self.onSubscribe = onSubscribe - self.onSubscribed = onSubscribed - self.onDispose = onDispose - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - self.onSubscribe?() - let sink = DoSink(eventHandler: self.eventHandler, afterEventHandler: self.afterEventHandler, observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - self.onSubscribed?() - let onDispose = self.onDispose - let allSubscriptions = Disposables.create { - subscription.dispose() - onDispose?() - } - return (sink: sink, subscription: allSubscriptions) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/ElementAt.swift b/Pods/RxSwift/RxSwift/Observables/ElementAt.swift deleted file mode 100644 index 3f09c7087..000000000 --- a/Pods/RxSwift/RxSwift/Observables/ElementAt.swift +++ /dev/null @@ -1,105 +0,0 @@ -// -// ElementAt.swift -// RxSwift -// -// Created by Junior B. on 21/10/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Returns a sequence emitting only element _n_ emitted by an Observable - - - seealso: [elementAt operator on reactivex.io](http://reactivex.io/documentation/operators/elementat.html) - - - parameter index: The index of the required element (starting from 0). - - returns: An observable sequence that emits the desired element as its own sole emission. - */ - @available(*, deprecated, renamed: "element(at:)") - public func elementAt(_ index: Int) - -> Observable { - element(at: index) - } - - /** - Returns a sequence emitting only element _n_ emitted by an Observable - - - seealso: [elementAt operator on reactivex.io](http://reactivex.io/documentation/operators/elementat.html) - - - parameter index: The index of the required element (starting from 0). - - returns: An observable sequence that emits the desired element as its own sole emission. - */ - public func element(at index: Int) - -> Observable { - ElementAt(source: self.asObservable(), index: index, throwOnEmpty: true) - } -} - -final private class ElementAtSink: Sink, ObserverType { - typealias SourceType = Observer.Element - typealias Parent = ElementAt - - let parent: Parent - var i: Int - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - self.i = parent.index - - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - switch event { - case .next: - - if self.i == 0 { - self.forwardOn(event) - self.forwardOn(.completed) - self.dispose() - } - - do { - _ = try decrementChecked(&self.i) - } catch let e { - self.forwardOn(.error(e)) - self.dispose() - return - } - - case .error(let e): - self.forwardOn(.error(e)) - self.dispose() - case .completed: - if self.parent.throwOnEmpty { - self.forwardOn(.error(RxError.argumentOutOfRange)) - } else { - self.forwardOn(.completed) - } - - self.dispose() - } - } -} - -final private class ElementAt: Producer { - let source: Observable - let throwOnEmpty: Bool - let index: Int - - init(source: Observable, index: Int, throwOnEmpty: Bool) { - if index < 0 { - rxFatalError("index can't be negative") - } - - self.source = source - self.index = index - self.throwOnEmpty = throwOnEmpty - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == SourceType { - let sink = ElementAtSink(parent: self, observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Empty.swift b/Pods/RxSwift/RxSwift/Observables/Empty.swift deleted file mode 100644 index 9ca596594..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Empty.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// Empty.swift -// RxSwift -// -// Created by Krunoslav Zaher on 8/30/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Returns an empty observable sequence, using the specified scheduler to send out the single `Completed` message. - - - seealso: [empty operator on reactivex.io](http://reactivex.io/documentation/operators/empty-never-throw.html) - - - returns: An observable sequence with no elements. - */ - public static func empty() -> Observable { - EmptyProducer() - } -} - -final private class EmptyProducer: Producer { - override func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { - observer.on(.completed) - return Disposables.create() - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Enumerated.swift b/Pods/RxSwift/RxSwift/Observables/Enumerated.swift deleted file mode 100644 index ef8a0ff02..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Enumerated.swift +++ /dev/null @@ -1,61 +0,0 @@ -// -// Enumerated.swift -// RxSwift -// -// Created by Krunoslav Zaher on 8/6/17. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Enumerates the elements of an observable sequence. - - - seealso: [map operator on reactivex.io](http://reactivex.io/documentation/operators/map.html) - - - returns: An observable sequence that contains tuples of source sequence elements and their indexes. - */ - public func enumerated() - -> Observable<(index: Int, element: Element)> { - Enumerated(source: self.asObservable()) - } -} - -final private class EnumeratedSink: Sink, ObserverType where Observer.Element == (index: Int, element: Element) { - var index = 0 - - func on(_ event: Event) { - switch event { - case .next(let value): - do { - let nextIndex = try incrementChecked(&self.index) - let next = (index: nextIndex, element: value) - self.forwardOn(.next(next)) - } - catch let e { - self.forwardOn(.error(e)) - self.dispose() - } - case .completed: - self.forwardOn(.completed) - self.dispose() - case .error(let error): - self.forwardOn(.error(error)) - self.dispose() - } - } -} - -final private class Enumerated: Producer<(index: Int, element: Element)> { - private let source: Observable - - init(source: Observable) { - self.source = source - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == (index: Int, element: Element) { - let sink = EnumeratedSink(observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Error.swift b/Pods/RxSwift/RxSwift/Observables/Error.swift deleted file mode 100644 index 2e722d670..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Error.swift +++ /dev/null @@ -1,33 +0,0 @@ -// -// Error.swift -// RxSwift -// -// Created by Krunoslav Zaher on 8/30/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Returns an observable sequence that terminates with an `error`. - - - seealso: [throw operator on reactivex.io](http://reactivex.io/documentation/operators/empty-never-throw.html) - - - returns: The observable sequence that terminates with specified error. - */ - public static func error(_ error: Swift.Error) -> Observable { - ErrorProducer(error: error) - } -} - -final private class ErrorProducer: Producer { - private let error: Swift.Error - - init(error: Swift.Error) { - self.error = error - } - - override func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { - observer.on(.error(self.error)) - return Disposables.create() - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Filter.swift b/Pods/RxSwift/RxSwift/Observables/Filter.swift deleted file mode 100644 index 61d3ce793..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Filter.swift +++ /dev/null @@ -1,86 +0,0 @@ -// -// Filter.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/17/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Filters the elements of an observable sequence based on a predicate. - - - seealso: [filter operator on reactivex.io](http://reactivex.io/documentation/operators/filter.html) - - - parameter predicate: A function to test each source element for a condition. - - returns: An observable sequence that contains elements from the input sequence that satisfy the condition. - */ - public func filter(_ predicate: @escaping (Element) throws -> Bool) - -> Observable { - Filter(source: self.asObservable(), predicate: predicate) - } -} - -extension ObservableType { - /** - Skips elements and completes (or errors) when the observable sequence completes (or errors). Equivalent to filter that always returns false. - - - seealso: [ignoreElements operator on reactivex.io](http://reactivex.io/documentation/operators/ignoreelements.html) - - - returns: An observable sequence that skips all elements of the source sequence. - */ - public func ignoreElements() - -> Observable { - self.flatMap { _ in Observable.empty() } - } -} - -final private class FilterSink: Sink, ObserverType { - typealias Predicate = (Element) throws -> Bool - typealias Element = Observer.Element - - private let predicate: Predicate - - init(predicate: @escaping Predicate, observer: Observer, cancel: Cancelable) { - self.predicate = predicate - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - switch event { - case .next(let value): - do { - let satisfies = try self.predicate(value) - if satisfies { - self.forwardOn(.next(value)) - } - } - catch let e { - self.forwardOn(.error(e)) - self.dispose() - } - case .completed, .error: - self.forwardOn(event) - self.dispose() - } - } -} - -final private class Filter: Producer { - typealias Predicate = (Element) throws -> Bool - - private let source: Observable - private let predicate: Predicate - - init(source: Observable, predicate: @escaping Predicate) { - self.source = source - self.predicate = predicate - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = FilterSink(predicate: self.predicate, observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/First.swift b/Pods/RxSwift/RxSwift/Observables/First.swift deleted file mode 100644 index 001411485..000000000 --- a/Pods/RxSwift/RxSwift/Observables/First.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// First.swift -// RxSwift -// -// Created by Krunoslav Zaher on 7/31/17. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -private final class FirstSink : Sink, ObserverType where Observer.Element == Element? { - typealias Parent = First - - func on(_ event: Event) { - switch event { - case .next(let value): - self.forwardOn(.next(value)) - self.forwardOn(.completed) - self.dispose() - case .error(let error): - self.forwardOn(.error(error)) - self.dispose() - case .completed: - self.forwardOn(.next(nil)) - self.forwardOn(.completed) - self.dispose() - } - } -} - -final class First: Producer { - private let source: Observable - - init(source: Observable) { - self.source = source - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element? { - let sink = FirstSink(observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Generate.swift b/Pods/RxSwift/RxSwift/Observables/Generate.swift deleted file mode 100644 index 7b924b381..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Generate.swift +++ /dev/null @@ -1,87 +0,0 @@ -// -// Generate.swift -// RxSwift -// -// Created by Krunoslav Zaher on 9/2/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Generates an observable sequence by running a state-driven loop producing the sequence's elements, using the specified scheduler - to run the loop send out observer messages. - - - seealso: [create operator on reactivex.io](http://reactivex.io/documentation/operators/create.html) - - - parameter initialState: Initial state. - - parameter condition: Condition to terminate generation (upon returning `false`). - - parameter iterate: Iteration step function. - - parameter scheduler: Scheduler on which to run the generator loop. - - returns: The generated sequence. - */ - public static func generate(initialState: Element, condition: @escaping (Element) throws -> Bool, scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance, iterate: @escaping (Element) throws -> Element) -> Observable { - Generate(initialState: initialState, condition: condition, iterate: iterate, resultSelector: { $0 }, scheduler: scheduler) - } -} - -final private class GenerateSink: Sink { - typealias Parent = Generate - - private let parent: Parent - - private var state: Sequence - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - self.state = parent.initialState - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - return self.parent.scheduler.scheduleRecursive(true) { isFirst, recurse -> Void in - do { - if !isFirst { - self.state = try self.parent.iterate(self.state) - } - - if try self.parent.condition(self.state) { - let result = try self.parent.resultSelector(self.state) - self.forwardOn(.next(result)) - - recurse(false) - } - else { - self.forwardOn(.completed) - self.dispose() - } - } - catch let error { - self.forwardOn(.error(error)) - self.dispose() - } - } - } -} - -final private class Generate: Producer { - fileprivate let initialState: Sequence - fileprivate let condition: (Sequence) throws -> Bool - fileprivate let iterate: (Sequence) throws -> Sequence - fileprivate let resultSelector: (Sequence) throws -> Element - fileprivate let scheduler: ImmediateSchedulerType - - init(initialState: Sequence, condition: @escaping (Sequence) throws -> Bool, iterate: @escaping (Sequence) throws -> Sequence, resultSelector: @escaping (Sequence) throws -> Element, scheduler: ImmediateSchedulerType) { - self.initialState = initialState - self.condition = condition - self.iterate = iterate - self.resultSelector = resultSelector - self.scheduler = scheduler - super.init() - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = GenerateSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/GroupBy.swift b/Pods/RxSwift/RxSwift/Observables/GroupBy.swift deleted file mode 100644 index 88cbda767..000000000 --- a/Pods/RxSwift/RxSwift/Observables/GroupBy.swift +++ /dev/null @@ -1,133 +0,0 @@ -// -// GroupBy.swift -// RxSwift -// -// Created by Tomi Koskinen on 01/12/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /* - Groups the elements of an observable sequence according to a specified key selector function. - - - seealso: [groupBy operator on reactivex.io](http://reactivex.io/documentation/operators/groupby.html) - - - parameter keySelector: A function to extract the key for each element. - - returns: A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value. - */ - public func groupBy(keySelector: @escaping (Element) throws -> Key) - -> Observable> { - GroupBy(source: self.asObservable(), selector: keySelector) - } -} - -final private class GroupedObservableImpl: Observable { - private var subject: PublishSubject - private var refCount: RefCountDisposable - - init(subject: PublishSubject, refCount: RefCountDisposable) { - self.subject = subject - self.refCount = refCount - } - - override public func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { - let release = self.refCount.retain() - let subscription = self.subject.subscribe(observer) - return Disposables.create(release, subscription) - } -} - - -final private class GroupBySink - : Sink - , ObserverType where Observer.Element == GroupedObservable { - typealias ResultType = Observer.Element - typealias Parent = GroupBy - - private let parent: Parent - private let subscription = SingleAssignmentDisposable() - private var refCountDisposable: RefCountDisposable! - private var groupedSubjectTable: [Key: PublishSubject] - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - self.groupedSubjectTable = [Key: PublishSubject]() - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - self.refCountDisposable = RefCountDisposable(disposable: self.subscription) - - self.subscription.setDisposable(self.parent.source.subscribe(self)) - - return self.refCountDisposable - } - - private func onGroupEvent(key: Key, value: Element) { - if let writer = self.groupedSubjectTable[key] { - writer.on(.next(value)) - } else { - let writer = PublishSubject() - self.groupedSubjectTable[key] = writer - - let group = GroupedObservable( - key: key, - source: GroupedObservableImpl(subject: writer, refCount: refCountDisposable) - ) - - self.forwardOn(.next(group)) - writer.on(.next(value)) - } - } - - final func on(_ event: Event) { - switch event { - case let .next(value): - do { - let groupKey = try self.parent.selector(value) - self.onGroupEvent(key: groupKey, value: value) - } - catch let e { - self.error(e) - return - } - case let .error(e): - self.error(e) - case .completed: - self.forwardOnGroups(event: .completed) - self.forwardOn(.completed) - self.subscription.dispose() - self.dispose() - } - } - - final func error(_ error: Swift.Error) { - self.forwardOnGroups(event: .error(error)) - self.forwardOn(.error(error)) - self.subscription.dispose() - self.dispose() - } - - final func forwardOnGroups(event: Event) { - for writer in self.groupedSubjectTable.values { - writer.on(event) - } - } -} - -final private class GroupBy: Producer> { - typealias KeySelector = (Element) throws -> Key - - fileprivate let source: Observable - fileprivate let selector: KeySelector - - init(source: Observable, selector: @escaping KeySelector) { - self.source = source - self.selector = selector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == GroupedObservable { - let sink = GroupBySink(parent: self, observer: observer, cancel: cancel) - return (sink: sink, subscription: sink.run()) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Just.swift b/Pods/RxSwift/RxSwift/Observables/Just.swift deleted file mode 100644 index 93490837f..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Just.swift +++ /dev/null @@ -1,87 +0,0 @@ -// -// Just.swift -// RxSwift -// -// Created by Krunoslav Zaher on 8/30/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Returns an observable sequence that contains a single element. - - - seealso: [just operator on reactivex.io](http://reactivex.io/documentation/operators/just.html) - - - parameter element: Single element in the resulting observable sequence. - - returns: An observable sequence containing the single specified element. - */ - public static func just(_ element: Element) -> Observable { - Just(element: element) - } - - /** - Returns an observable sequence that contains a single element. - - - seealso: [just operator on reactivex.io](http://reactivex.io/documentation/operators/just.html) - - - parameter element: Single element in the resulting observable sequence. - - parameter scheduler: Scheduler to send the single element on. - - returns: An observable sequence containing the single specified element. - */ - public static func just(_ element: Element, scheduler: ImmediateSchedulerType) -> Observable { - JustScheduled(element: element, scheduler: scheduler) - } -} - -final private class JustScheduledSink: Sink { - typealias Parent = JustScheduled - - private let parent: Parent - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - let scheduler = self.parent.scheduler - return scheduler.schedule(self.parent.element) { element in - self.forwardOn(.next(element)) - return scheduler.schedule(()) { _ in - self.forwardOn(.completed) - self.dispose() - return Disposables.create() - } - } - } -} - -final private class JustScheduled: Producer { - fileprivate let scheduler: ImmediateSchedulerType - fileprivate let element: Element - - init(element: Element, scheduler: ImmediateSchedulerType) { - self.scheduler = scheduler - self.element = element - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = JustScheduledSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - -final private class Just: Producer { - private let element: Element - - init(element: Element) { - self.element = element - } - - override func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { - observer.on(.next(self.element)) - observer.on(.completed) - return Disposables.create() - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Map.swift b/Pods/RxSwift/RxSwift/Observables/Map.swift deleted file mode 100644 index 0691273cc..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Map.swift +++ /dev/null @@ -1,77 +0,0 @@ -// -// Map.swift -// RxSwift -// -// Created by Krunoslav Zaher on 3/15/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Projects each element of an observable sequence into a new form. - - - seealso: [map operator on reactivex.io](http://reactivex.io/documentation/operators/map.html) - - - parameter transform: A transform function to apply to each source element. - - returns: An observable sequence whose elements are the result of invoking the transform function on each element of source. - - */ - public func map(_ transform: @escaping (Element) throws -> Result) - -> Observable { - Map(source: self.asObservable(), transform: transform) - } -} - -final private class MapSink: Sink, ObserverType { - typealias Transform = (SourceType) throws -> ResultType - - typealias ResultType = Observer.Element - typealias Element = SourceType - - private let transform: Transform - - init(transform: @escaping Transform, observer: Observer, cancel: Cancelable) { - self.transform = transform - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - switch event { - case .next(let element): - do { - let mappedElement = try self.transform(element) - self.forwardOn(.next(mappedElement)) - } - catch let e { - self.forwardOn(.error(e)) - self.dispose() - } - case .error(let error): - self.forwardOn(.error(error)) - self.dispose() - case .completed: - self.forwardOn(.completed) - self.dispose() - } - } -} - -final private class Map: Producer { - typealias Transform = (SourceType) throws -> ResultType - - private let source: Observable - - private let transform: Transform - - init(source: Observable, transform: @escaping Transform) { - self.source = source - self.transform = transform - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == ResultType { - let sink = MapSink(transform: self.transform, observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Materialize.swift b/Pods/RxSwift/RxSwift/Observables/Materialize.swift deleted file mode 100644 index e2577be5d..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Materialize.swift +++ /dev/null @@ -1,44 +0,0 @@ -// -// Materialize.swift -// RxSwift -// -// Created by sergdort on 08/03/2017. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Convert any Observable into an Observable of its events. - - seealso: [materialize operator on reactivex.io](http://reactivex.io/documentation/operators/materialize-dematerialize.html) - - returns: An observable sequence that wraps events in an Event. The returned Observable never errors, but it does complete after observing all of the events of the underlying Observable. - */ - public func materialize() -> Observable> { - Materialize(source: self.asObservable()) - } -} - -private final class MaterializeSink: Sink, ObserverType where Observer.Element == Event { - - func on(_ event: Event) { - self.forwardOn(.next(event)) - if event.isStopEvent { - self.forwardOn(.completed) - self.dispose() - } - } -} - -final private class Materialize: Producer> { - private let source: Observable - - init(source: Observable) { - self.source = source - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = MaterializeSink(observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Merge.swift b/Pods/RxSwift/RxSwift/Observables/Merge.swift deleted file mode 100644 index 51a646291..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Merge.swift +++ /dev/null @@ -1,600 +0,0 @@ -// -// Merge.swift -// RxSwift -// -// Created by Krunoslav Zaher on 3/28/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Projects each element of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence. - - - seealso: [flatMap operator on reactivex.io](http://reactivex.io/documentation/operators/flatmap.html) - - - parameter selector: A transform function to apply to each element. - - returns: An observable sequence whose elements are the result of invoking the one-to-many transform function on each element of the input sequence. - */ - public func flatMap(_ selector: @escaping (Element) throws -> Source) - -> Observable { - return FlatMap(source: self.asObservable(), selector: selector) - } - -} - -extension ObservableType { - - /** - Projects each element of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence. - If element is received while there is some projected observable sequence being merged it will simply be ignored. - - - seealso: [flatMapFirst operator on reactivex.io](http://reactivex.io/documentation/operators/flatmap.html) - - - parameter selector: A transform function to apply to element that was observed while no observable is executing in parallel. - - returns: An observable sequence whose elements are the result of invoking the one-to-many transform function on each element of the input sequence that was received while no other sequence was being calculated. - */ - public func flatMapFirst(_ selector: @escaping (Element) throws -> Source) - -> Observable { - return FlatMapFirst(source: self.asObservable(), selector: selector) - } -} - -extension ObservableType where Element: ObservableConvertibleType { - - /** - Merges elements from all observable sequences in the given enumerable sequence into a single observable sequence. - - - seealso: [merge operator on reactivex.io](http://reactivex.io/documentation/operators/merge.html) - - - returns: The observable sequence that merges the elements of the observable sequences. - */ - public func merge() -> Observable { - Merge(source: self.asObservable()) - } - - /** - Merges elements from all inner observable sequences into a single observable sequence, limiting the number of concurrent subscriptions to inner sequences. - - - seealso: [merge operator on reactivex.io](http://reactivex.io/documentation/operators/merge.html) - - - parameter maxConcurrent: Maximum number of inner observable sequences being subscribed to concurrently. - - returns: The observable sequence that merges the elements of the inner sequences. - */ - public func merge(maxConcurrent: Int) - -> Observable { - MergeLimited(source: self.asObservable(), maxConcurrent: maxConcurrent) - } -} - -extension ObservableType where Element: ObservableConvertibleType { - - /** - Concatenates all inner observable sequences, as long as the previous observable sequence terminated successfully. - - - seealso: [concat operator on reactivex.io](http://reactivex.io/documentation/operators/concat.html) - - - returns: An observable sequence that contains the elements of each observed inner sequence, in sequential order. - */ - public func concat() -> Observable { - self.merge(maxConcurrent: 1) - } -} - -extension ObservableType { - /** - Merges elements from all observable sequences from collection into a single observable sequence. - - - seealso: [merge operator on reactivex.io](http://reactivex.io/documentation/operators/merge.html) - - - parameter sources: Collection of observable sequences to merge. - - returns: The observable sequence that merges the elements of the observable sequences. - */ - public static func merge(_ sources: Collection) -> Observable where Collection.Element == Observable { - MergeArray(sources: Array(sources)) - } - - /** - Merges elements from all observable sequences from array into a single observable sequence. - - - seealso: [merge operator on reactivex.io](http://reactivex.io/documentation/operators/merge.html) - - - parameter sources: Array of observable sequences to merge. - - returns: The observable sequence that merges the elements of the observable sequences. - */ - public static func merge(_ sources: [Observable]) -> Observable { - MergeArray(sources: sources) - } - - /** - Merges elements from all observable sequences into a single observable sequence. - - - seealso: [merge operator on reactivex.io](http://reactivex.io/documentation/operators/merge.html) - - - parameter sources: Collection of observable sequences to merge. - - returns: The observable sequence that merges the elements of the observable sequences. - */ - public static func merge(_ sources: Observable...) -> Observable { - MergeArray(sources: sources) - } -} - -// MARK: concatMap - -extension ObservableType { - /** - Projects each element of an observable sequence to an observable sequence and concatenates the resulting observable sequences into one observable sequence. - - - seealso: [concat operator on reactivex.io](http://reactivex.io/documentation/operators/concat.html) - - - returns: An observable sequence that contains the elements of each observed inner sequence, in sequential order. - */ - - public func concatMap(_ selector: @escaping (Element) throws -> Source) - -> Observable { - return ConcatMap(source: self.asObservable(), selector: selector) - } -} - -private final class MergeLimitedSinkIter - : ObserverType - , LockOwnerType - , SynchronizedOnType where SourceSequence.Element == Observer.Element { - typealias Element = Observer.Element - typealias DisposeKey = CompositeDisposable.DisposeKey - typealias Parent = MergeLimitedSink - - private let parent: Parent - private let disposeKey: DisposeKey - - var lock: RecursiveLock { - self.parent.lock - } - - init(parent: Parent, disposeKey: DisposeKey) { - self.parent = parent - self.disposeKey = disposeKey - } - - func on(_ event: Event) { - self.synchronizedOn(event) - } - - func synchronized_on(_ event: Event) { - switch event { - case .next: - self.parent.forwardOn(event) - case .error: - self.parent.forwardOn(event) - self.parent.dispose() - case .completed: - self.parent.group.remove(for: self.disposeKey) - if let next = self.parent.queue.dequeue() { - self.parent.subscribe(next, group: self.parent.group) - } - else { - self.parent.activeCount -= 1 - - if self.parent.stopped && self.parent.activeCount == 0 { - self.parent.forwardOn(.completed) - self.parent.dispose() - } - } - } - } -} - -private final class ConcatMapSink: MergeLimitedSink where Observer.Element == SourceSequence.Element { - typealias Selector = (SourceElement) throws -> SourceSequence - - private let selector: Selector - - init(selector: @escaping Selector, observer: Observer, cancel: Cancelable) { - self.selector = selector - super.init(maxConcurrent: 1, observer: observer, cancel: cancel) - } - - override func performMap(_ element: SourceElement) throws -> SourceSequence { - try self.selector(element) - } -} - -private final class MergeLimitedBasicSink: MergeLimitedSink where Observer.Element == SourceSequence.Element { - - override func performMap(_ element: SourceSequence) throws -> SourceSequence { - element - } -} - -private class MergeLimitedSink - : Sink - , ObserverType where Observer.Element == SourceSequence.Element { - typealias QueueType = Queue - - let maxConcurrent: Int - - let lock = RecursiveLock() - - // state - var stopped = false - var activeCount = 0 - var queue = QueueType(capacity: 2) - - let sourceSubscription = SingleAssignmentDisposable() - let group = CompositeDisposable() - - init(maxConcurrent: Int, observer: Observer, cancel: Cancelable) { - self.maxConcurrent = maxConcurrent - super.init(observer: observer, cancel: cancel) - } - - func run(_ source: Observable) -> Disposable { - _ = self.group.insert(self.sourceSubscription) - - let disposable = source.subscribe(self) - self.sourceSubscription.setDisposable(disposable) - return self.group - } - - func subscribe(_ innerSource: SourceSequence, group: CompositeDisposable) { - let subscription = SingleAssignmentDisposable() - - let key = group.insert(subscription) - - if let key = key { - let observer = MergeLimitedSinkIter(parent: self, disposeKey: key) - - let disposable = innerSource.asObservable().subscribe(observer) - subscription.setDisposable(disposable) - } - } - - func performMap(_ element: SourceElement) throws -> SourceSequence { - rxAbstractMethod() - } - - @inline(__always) - final private func nextElementArrived(element: SourceElement) -> SourceSequence? { - self.lock.performLocked { - let subscribe: Bool - if self.activeCount < self.maxConcurrent { - self.activeCount += 1 - subscribe = true - } - else { - do { - let value = try self.performMap(element) - self.queue.enqueue(value) - } catch { - self.forwardOn(.error(error)) - self.dispose() - } - subscribe = false - } - - if subscribe { - do { - return try self.performMap(element) - } catch { - self.forwardOn(.error(error)) - self.dispose() - } - } - - return nil - } - } - - func on(_ event: Event) { - switch event { - case .next(let element): - if let sequence = self.nextElementArrived(element: element) { - self.subscribe(sequence, group: self.group) - } - case .error(let error): - self.lock.performLocked { - self.forwardOn(.error(error)) - self.dispose() - } - case .completed: - self.lock.performLocked { - if self.activeCount == 0 { - self.forwardOn(.completed) - self.dispose() - } - else { - self.sourceSubscription.dispose() - } - - self.stopped = true - } - } - } -} - -final private class MergeLimited: Producer { - private let source: Observable - private let maxConcurrent: Int - - init(source: Observable, maxConcurrent: Int) { - self.source = source - self.maxConcurrent = maxConcurrent - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == SourceSequence.Element { - let sink = MergeLimitedBasicSink(maxConcurrent: self.maxConcurrent, observer: observer, cancel: cancel) - let subscription = sink.run(self.source) - return (sink: sink, subscription: subscription) - } -} - -// MARK: Merge - -private final class MergeBasicSink : MergeSink where Observer.Element == Source.Element { - override func performMap(_ element: Source) throws -> Source { - element - } -} - -// MARK: flatMap - -private final class FlatMapSink : MergeSink where Observer.Element == SourceSequence.Element { - typealias Selector = (SourceElement) throws -> SourceSequence - - private let selector: Selector - - init(selector: @escaping Selector, observer: Observer, cancel: Cancelable) { - self.selector = selector - super.init(observer: observer, cancel: cancel) - } - - override func performMap(_ element: SourceElement) throws -> SourceSequence { - try self.selector(element) - } -} - -// MARK: FlatMapFirst - -private final class FlatMapFirstSink : MergeSink where Observer.Element == SourceSequence.Element { - typealias Selector = (SourceElement) throws -> SourceSequence - - private let selector: Selector - - override var subscribeNext: Bool { - self.activeCount == 0 - } - - init(selector: @escaping Selector, observer: Observer, cancel: Cancelable) { - self.selector = selector - super.init(observer: observer, cancel: cancel) - } - - override func performMap(_ element: SourceElement) throws -> SourceSequence { - try self.selector(element) - } -} - -private final class MergeSinkIter : ObserverType where Observer.Element == SourceSequence.Element { - typealias Parent = MergeSink - typealias DisposeKey = CompositeDisposable.DisposeKey - typealias Element = Observer.Element - - private let parent: Parent - private let disposeKey: DisposeKey - - init(parent: Parent, disposeKey: DisposeKey) { - self.parent = parent - self.disposeKey = disposeKey - } - - func on(_ event: Event) { - self.parent.lock.performLocked { - switch event { - case .next(let value): - self.parent.forwardOn(.next(value)) - case .error(let error): - self.parent.forwardOn(.error(error)) - self.parent.dispose() - case .completed: - self.parent.group.remove(for: self.disposeKey) - self.parent.activeCount -= 1 - self.parent.checkCompleted() - } - } - } -} - - -private class MergeSink - : Sink - , ObserverType where Observer.Element == SourceSequence.Element { - typealias ResultType = Observer.Element - typealias Element = SourceElement - - let lock = RecursiveLock() - - var subscribeNext: Bool { - true - } - - // state - let group = CompositeDisposable() - let sourceSubscription = SingleAssignmentDisposable() - - var activeCount = 0 - var stopped = false - - override init(observer: Observer, cancel: Cancelable) { - super.init(observer: observer, cancel: cancel) - } - - func performMap(_ element: SourceElement) throws -> SourceSequence { - rxAbstractMethod() - } - - @inline(__always) - final private func nextElementArrived(element: SourceElement) -> SourceSequence? { - self.lock.performLocked { - if !self.subscribeNext { - return nil - } - - do { - let value = try self.performMap(element) - self.activeCount += 1 - return value - } - catch let e { - self.forwardOn(.error(e)) - self.dispose() - return nil - } - } - } - - func on(_ event: Event) { - switch event { - case .next(let element): - if let value = self.nextElementArrived(element: element) { - self.subscribeInner(value.asObservable()) - } - case .error(let error): - self.lock.performLocked { - self.forwardOn(.error(error)) - self.dispose() - } - case .completed: - self.lock.performLocked { - self.stopped = true - self.sourceSubscription.dispose() - self.checkCompleted() - } - } - } - - func subscribeInner(_ source: Observable) { - let iterDisposable = SingleAssignmentDisposable() - if let disposeKey = self.group.insert(iterDisposable) { - let iter = MergeSinkIter(parent: self, disposeKey: disposeKey) - let subscription = source.subscribe(iter) - iterDisposable.setDisposable(subscription) - } - } - - func run(_ sources: [Observable]) -> Disposable { - self.activeCount += sources.count - - for source in sources { - self.subscribeInner(source) - } - - self.stopped = true - - self.checkCompleted() - - return self.group - } - - @inline(__always) - func checkCompleted() { - if self.stopped && self.activeCount == 0 { - self.forwardOn(.completed) - self.dispose() - } - } - - func run(_ source: Observable) -> Disposable { - _ = self.group.insert(self.sourceSubscription) - - let subscription = source.subscribe(self) - self.sourceSubscription.setDisposable(subscription) - - return self.group - } -} - -// MARK: Producers - -final private class FlatMap: Producer { - typealias Selector = (SourceElement) throws -> SourceSequence - - private let source: Observable - - private let selector: Selector - - init(source: Observable, selector: @escaping Selector) { - self.source = source - self.selector = selector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == SourceSequence.Element { - let sink = FlatMapSink(selector: self.selector, observer: observer, cancel: cancel) - let subscription = sink.run(self.source) - return (sink: sink, subscription: subscription) - } -} - -final private class FlatMapFirst: Producer { - typealias Selector = (SourceElement) throws -> SourceSequence - - private let source: Observable - - private let selector: Selector - - init(source: Observable, selector: @escaping Selector) { - self.source = source - self.selector = selector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == SourceSequence.Element { - let sink = FlatMapFirstSink(selector: self.selector, observer: observer, cancel: cancel) - let subscription = sink.run(self.source) - return (sink: sink, subscription: subscription) - } -} - -final class ConcatMap: Producer { - typealias Selector = (SourceElement) throws -> SourceSequence - - private let source: Observable - private let selector: Selector - - init(source: Observable, selector: @escaping Selector) { - self.source = source - self.selector = selector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == SourceSequence.Element { - let sink = ConcatMapSink(selector: self.selector, observer: observer, cancel: cancel) - let subscription = sink.run(self.source) - return (sink: sink, subscription: subscription) - } -} - -final class Merge : Producer { - private let source: Observable - - init(source: Observable) { - self.source = source - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == SourceSequence.Element { - let sink = MergeBasicSink(observer: observer, cancel: cancel) - let subscription = sink.run(self.source) - return (sink: sink, subscription: subscription) - } -} - -final private class MergeArray: Producer { - private let sources: [Observable] - - init(sources: [Observable]) { - self.sources = sources - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = MergeBasicSink, Observer>(observer: observer, cancel: cancel) - let subscription = sink.run(self.sources) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Multicast.swift b/Pods/RxSwift/RxSwift/Observables/Multicast.swift deleted file mode 100644 index 1ebcf0212..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Multicast.swift +++ /dev/null @@ -1,405 +0,0 @@ -// -// Multicast.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/27/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/** - Represents an observable wrapper that can be connected and disconnected from its underlying observable sequence. - */ -public class ConnectableObservable - : Observable - , ConnectableObservableType { - - /** - Connects the observable wrapper to its source. All subscribed observers will receive values from the underlying observable sequence as long as the connection is established. - - - returns: Disposable used to disconnect the observable wrapper from its source, causing subscribed observer to stop receiving values from the underlying observable sequence. - */ - public func connect() -> Disposable { - rxAbstractMethod() - } -} - -extension ObservableType { - - /** - Multicasts the source sequence notifications through an instantiated subject into all uses of the sequence within a selector function. - - Each subscription to the resulting sequence causes a separate multicast invocation, exposing the sequence resulting from the selector function's invocation. - - For specializations with fixed subject types, see `publish` and `replay`. - - - seealso: [multicast operator on reactivex.io](http://reactivex.io/documentation/operators/publish.html) - - - parameter subjectSelector: Factory function to create an intermediate subject through which the source sequence's elements will be multicast to the selector function. - - parameter selector: Selector function which can use the multicasted source sequence subject to the policies enforced by the created subject. - - returns: An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function. - */ - public func multicast(_ subjectSelector: @escaping () throws -> Subject, selector: @escaping (Observable) throws -> Observable) - -> Observable where Subject.Observer.Element == Element { - return Multicast( - source: self.asObservable(), - subjectSelector: subjectSelector, - selector: selector - ) - } -} - -extension ObservableType { - - /** - Returns a connectable observable sequence that shares a single subscription to the underlying sequence. - - This operator is a specialization of `multicast` using a `PublishSubject`. - - - seealso: [publish operator on reactivex.io](http://reactivex.io/documentation/operators/publish.html) - - - returns: A connectable observable sequence that shares a single subscription to the underlying sequence. - */ - public func publish() -> ConnectableObservable { - self.multicast { PublishSubject() } - } -} - -extension ObservableType { - - /** - Returns a connectable observable sequence that shares a single subscription to the underlying sequence replaying bufferSize elements. - - This operator is a specialization of `multicast` using a `ReplaySubject`. - - - seealso: [replay operator on reactivex.io](http://reactivex.io/documentation/operators/replay.html) - - - parameter bufferSize: Maximum element count of the replay buffer. - - returns: A connectable observable sequence that shares a single subscription to the underlying sequence. - */ - public func replay(_ bufferSize: Int) - -> ConnectableObservable { - self.multicast { ReplaySubject.create(bufferSize: bufferSize) } - } - - /** - Returns a connectable observable sequence that shares a single subscription to the underlying sequence replaying all elements. - - This operator is a specialization of `multicast` using a `ReplaySubject`. - - - seealso: [replay operator on reactivex.io](http://reactivex.io/documentation/operators/replay.html) - - - returns: A connectable observable sequence that shares a single subscription to the underlying sequence. - */ - public func replayAll() - -> ConnectableObservable { - self.multicast { ReplaySubject.createUnbounded() } - } -} - -extension ConnectableObservableType { - - /** - Returns an observable sequence that stays connected to the source as long as there is at least one subscription to the observable sequence. - - - seealso: [refCount operator on reactivex.io](http://reactivex.io/documentation/operators/refcount.html) - - - returns: An observable sequence that stays connected to the source as long as there is at least one subscription to the observable sequence. - */ - public func refCount() -> Observable { - RefCount(source: self) - } -} - -extension ObservableType { - - /** - Multicasts the source sequence notifications through the specified subject to the resulting connectable observable. - - Upon connection of the connectable observable, the subject is subscribed to the source exactly one, and messages are forwarded to the observers registered with the connectable observable. - - For specializations with fixed subject types, see `publish` and `replay`. - - - seealso: [multicast operator on reactivex.io](http://reactivex.io/documentation/operators/publish.html) - - - parameter subject: Subject to push source elements into. - - returns: A connectable observable sequence that upon connection causes the source sequence to push results into the specified subject. - */ - public func multicast(_ subject: Subject) - -> ConnectableObservable where Subject.Observer.Element == Element { - ConnectableObservableAdapter(source: self.asObservable(), makeSubject: { subject }) - } - - /** - Multicasts the source sequence notifications through an instantiated subject to the resulting connectable observable. - - Upon connection of the connectable observable, the subject is subscribed to the source exactly one, and messages are forwarded to the observers registered with the connectable observable. - - Subject is cleared on connection disposal or in case source sequence produces terminal event. - - - seealso: [multicast operator on reactivex.io](http://reactivex.io/documentation/operators/publish.html) - - - parameter makeSubject: Factory function used to instantiate a subject for each connection. - - returns: A connectable observable sequence that upon connection causes the source sequence to push results into the specified subject. - */ - public func multicast(makeSubject: @escaping () -> Subject) - -> ConnectableObservable where Subject.Observer.Element == Element { - ConnectableObservableAdapter(source: self.asObservable(), makeSubject: makeSubject) - } -} - -final private class Connection: ObserverType, Disposable { - typealias Element = Subject.Observer.Element - - private var lock: RecursiveLock - // state - private var parent: ConnectableObservableAdapter? - private var subscription : Disposable? - private var subjectObserver: Subject.Observer - - private let disposed = AtomicInt(0) - - init(parent: ConnectableObservableAdapter, subjectObserver: Subject.Observer, lock: RecursiveLock, subscription: Disposable) { - self.parent = parent - self.subscription = subscription - self.lock = lock - self.subjectObserver = subjectObserver - } - - func on(_ event: Event) { - if isFlagSet(self.disposed, 1) { - return - } - if event.isStopEvent { - self.dispose() - } - self.subjectObserver.on(event) - } - - func dispose() { - lock.lock(); defer { lock.unlock() } - fetchOr(self.disposed, 1) - guard let parent = self.parent else { - return - } - - if parent.connection === self { - parent.connection = nil - parent.subject = nil - } - self.parent = nil - - self.subscription?.dispose() - self.subscription = nil - } -} - -final private class ConnectableObservableAdapter - : ConnectableObservable { - typealias ConnectionType = Connection - - private let source: Observable - private let makeSubject: () -> Subject - - fileprivate let lock = RecursiveLock() - fileprivate var subject: Subject? - - // state - fileprivate var connection: ConnectionType? - - init(source: Observable, makeSubject: @escaping () -> Subject) { - self.source = source - self.makeSubject = makeSubject - self.subject = nil - self.connection = nil - } - - override func connect() -> Disposable { - return self.lock.performLocked { - if let connection = self.connection { - return connection - } - - let singleAssignmentDisposable = SingleAssignmentDisposable() - let connection = Connection(parent: self, subjectObserver: self.lazySubject.asObserver(), lock: self.lock, subscription: singleAssignmentDisposable) - self.connection = connection - let subscription = self.source.subscribe(connection) - singleAssignmentDisposable.setDisposable(subscription) - return connection - } - } - - private var lazySubject: Subject { - if let subject = self.subject { - return subject - } - - let subject = self.makeSubject() - self.subject = subject - return subject - } - - override func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Subject.Element { - self.lazySubject.subscribe(observer) - } -} - -final private class RefCountSink - : Sink - , ObserverType where ConnectableSource.Element == Observer.Element { - typealias Element = Observer.Element - typealias Parent = RefCount - - private let parent: Parent - - private var connectionIdSnapshot: Int64 = -1 - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - let subscription = self.parent.source.subscribe(self) - self.parent.lock.lock(); defer { self.parent.lock.unlock() } - - self.connectionIdSnapshot = self.parent.connectionId - - if self.isDisposed { - return Disposables.create() - } - - if self.parent.count == 0 { - self.parent.count = 1 - self.parent.connectableSubscription = self.parent.source.connect() - } - else { - self.parent.count += 1 - } - - return Disposables.create { - subscription.dispose() - self.parent.lock.lock(); defer { self.parent.lock.unlock() } - if self.parent.connectionId != self.connectionIdSnapshot { - return - } - if self.parent.count == 1 { - self.parent.count = 0 - guard let connectableSubscription = self.parent.connectableSubscription else { - return - } - - connectableSubscription.dispose() - self.parent.connectableSubscription = nil - } - else if self.parent.count > 1 { - self.parent.count -= 1 - } - else { - rxFatalError("Something went wrong with RefCount disposing mechanism") - } - } - } - - func on(_ event: Event) { - switch event { - case .next: - self.forwardOn(event) - case .error, .completed: - self.parent.lock.lock() - if self.parent.connectionId == self.connectionIdSnapshot { - let connection = self.parent.connectableSubscription - defer { connection?.dispose() } - self.parent.count = 0 - self.parent.connectionId = self.parent.connectionId &+ 1 - self.parent.connectableSubscription = nil - } - self.parent.lock.unlock() - self.forwardOn(event) - self.dispose() - } - } -} - -final private class RefCount: Producer { - fileprivate let lock = RecursiveLock() - - // state - fileprivate var count = 0 - fileprivate var connectionId: Int64 = 0 - fileprivate var connectableSubscription = nil as Disposable? - - fileprivate let source: ConnectableSource - - init(source: ConnectableSource) { - self.source = source - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) - where Observer.Element == ConnectableSource.Element { - let sink = RefCountSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - -final private class MulticastSink: Sink, ObserverType { - typealias Element = Observer.Element - typealias ResultType = Element - typealias MutlicastType = Multicast - - private let parent: MutlicastType - - init(parent: MutlicastType, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - do { - let subject = try self.parent.subjectSelector() - let connectable = ConnectableObservableAdapter(source: self.parent.source, makeSubject: { subject }) - - let observable = try self.parent.selector(connectable) - - let subscription = observable.subscribe(self) - let connection = connectable.connect() - - return Disposables.create(subscription, connection) - } - catch let e { - self.forwardOn(.error(e)) - self.dispose() - return Disposables.create() - } - } - - func on(_ event: Event) { - self.forwardOn(event) - switch event { - case .next: break - case .error, .completed: - self.dispose() - } - } -} - -final private class Multicast: Producer { - typealias SubjectSelectorType = () throws -> Subject - typealias SelectorType = (Observable) throws -> Observable - - fileprivate let source: Observable - fileprivate let subjectSelector: SubjectSelectorType - fileprivate let selector: SelectorType - - init(source: Observable, subjectSelector: @escaping SubjectSelectorType, selector: @escaping SelectorType) { - self.source = source - self.subjectSelector = subjectSelector - self.selector = selector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { - let sink = MulticastSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Never.swift b/Pods/RxSwift/RxSwift/Observables/Never.swift deleted file mode 100644 index 7b456eed9..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Never.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// Never.swift -// RxSwift -// -// Created by Krunoslav Zaher on 8/30/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Returns a non-terminating observable sequence, which can be used to denote an infinite duration. - - - seealso: [never operator on reactivex.io](http://reactivex.io/documentation/operators/empty-never-throw.html) - - - returns: An observable sequence whose observers will never get called. - */ - public static func never() -> Observable { - NeverProducer() - } -} - -final private class NeverProducer: Producer { - override func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { - Disposables.create() - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/ObserveOn.swift b/Pods/RxSwift/RxSwift/Observables/ObserveOn.swift deleted file mode 100644 index 6b8689e1e..000000000 --- a/Pods/RxSwift/RxSwift/Observables/ObserveOn.swift +++ /dev/null @@ -1,243 +0,0 @@ -// -// ObserveOn.swift -// RxSwift -// -// Created by Krunoslav Zaher on 7/25/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Wraps the source sequence in order to run its observer callbacks on the specified scheduler. - - This only invokes observer callbacks on a `scheduler`. In case the subscription and/or unsubscription - actions have side-effects that require to be run on a scheduler, use `subscribeOn`. - - - seealso: [observeOn operator on reactivex.io](http://reactivex.io/documentation/operators/observeon.html) - - - parameter scheduler: Scheduler to notify observers on. - - returns: The source sequence whose observations happen on the specified scheduler. - */ - public func observe(on scheduler: ImmediateSchedulerType) - -> Observable { - guard let serialScheduler = scheduler as? SerialDispatchQueueScheduler else { - return ObserveOn(source: self.asObservable(), scheduler: scheduler) - } - - return ObserveOnSerialDispatchQueue(source: self.asObservable(), - scheduler: serialScheduler) - } - - /** - Wraps the source sequence in order to run its observer callbacks on the specified scheduler. - - This only invokes observer callbacks on a `scheduler`. In case the subscription and/or unsubscription - actions have side-effects that require to be run on a scheduler, use `subscribeOn`. - - - seealso: [observeOn operator on reactivex.io](http://reactivex.io/documentation/operators/observeon.html) - - - parameter scheduler: Scheduler to notify observers on. - - returns: The source sequence whose observations happen on the specified scheduler. - */ - @available(*, deprecated, renamed: "observe(on:)") - public func observeOn(_ scheduler: ImmediateSchedulerType) - -> Observable { - observe(on: scheduler) - } -} - -final private class ObserveOn: Producer { - let scheduler: ImmediateSchedulerType - let source: Observable - - init(source: Observable, scheduler: ImmediateSchedulerType) { - self.scheduler = scheduler - self.source = source - -#if TRACE_RESOURCES - _ = Resources.incrementTotal() -#endif - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = ObserveOnSink(scheduler: self.scheduler, observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } - -#if TRACE_RESOURCES - deinit { - _ = Resources.decrementTotal() - } -#endif -} - -enum ObserveOnState : Int32 { - // pump is not running - case stopped = 0 - // pump is running - case running = 1 -} - -final private class ObserveOnSink: ObserverBase { - typealias Element = Observer.Element - - let scheduler: ImmediateSchedulerType - - var lock = SpinLock() - let observer: Observer - - // state - var state = ObserveOnState.stopped - var queue = Queue>(capacity: 10) - - let scheduleDisposable = SerialDisposable() - let cancel: Cancelable - - init(scheduler: ImmediateSchedulerType, observer: Observer, cancel: Cancelable) { - self.scheduler = scheduler - self.observer = observer - self.cancel = cancel - } - - override func onCore(_ event: Event) { - let shouldStart = self.lock.performLocked { () -> Bool in - self.queue.enqueue(event) - - switch self.state { - case .stopped: - self.state = .running - return true - case .running: - return false - } - } - - if shouldStart { - self.scheduleDisposable.disposable = self.scheduler.scheduleRecursive((), action: self.run) - } - } - - func run(_ state: (), _ recurse: (()) -> Void) { - let (nextEvent, observer) = self.lock.performLocked { () -> (Event?, Observer) in - if !self.queue.isEmpty { - return (self.queue.dequeue(), self.observer) - } - else { - self.state = .stopped - return (nil, self.observer) - } - } - - if let nextEvent = nextEvent, !self.cancel.isDisposed { - observer.on(nextEvent) - if nextEvent.isStopEvent { - self.dispose() - } - } - else { - return - } - - let shouldContinue = self.shouldContinue_synchronized() - - if shouldContinue { - recurse(()) - } - } - - func shouldContinue_synchronized() -> Bool { - self.lock.performLocked { - let isEmpty = self.queue.isEmpty - if isEmpty { self.state = .stopped } - return !isEmpty - } - } - - override func dispose() { - super.dispose() - - self.cancel.dispose() - self.scheduleDisposable.dispose() - } -} - -#if TRACE_RESOURCES - private let numberOfSerialDispatchObservables = AtomicInt(0) - extension Resources { - /** - Counts number of `SerialDispatchQueueObservables`. - - Purposed for unit tests. - */ - public static var numberOfSerialDispatchQueueObservables: Int32 { - return load(numberOfSerialDispatchObservables) - } - } -#endif - -final private class ObserveOnSerialDispatchQueueSink: ObserverBase { - let scheduler: SerialDispatchQueueScheduler - let observer: Observer - - let cancel: Cancelable - - var cachedScheduleLambda: (((sink: ObserveOnSerialDispatchQueueSink, event: Event)) -> Disposable)! - - init(scheduler: SerialDispatchQueueScheduler, observer: Observer, cancel: Cancelable) { - self.scheduler = scheduler - self.observer = observer - self.cancel = cancel - super.init() - - self.cachedScheduleLambda = { pair in - guard !cancel.isDisposed else { return Disposables.create() } - - pair.sink.observer.on(pair.event) - - if pair.event.isStopEvent { - pair.sink.dispose() - } - - return Disposables.create() - } - } - - override func onCore(_ event: Event) { - _ = self.scheduler.schedule((self, event), action: self.cachedScheduleLambda!) - } - - override func dispose() { - super.dispose() - - self.cancel.dispose() - } -} - -final private class ObserveOnSerialDispatchQueue: Producer { - let scheduler: SerialDispatchQueueScheduler - let source: Observable - - init(source: Observable, scheduler: SerialDispatchQueueScheduler) { - self.scheduler = scheduler - self.source = source - - #if TRACE_RESOURCES - _ = Resources.incrementTotal() - _ = increment(numberOfSerialDispatchObservables) - #endif - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = ObserveOnSerialDispatchQueueSink(scheduler: self.scheduler, observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } - - #if TRACE_RESOURCES - deinit { - _ = Resources.decrementTotal() - _ = decrement(numberOfSerialDispatchObservables) - } - #endif -} diff --git a/Pods/RxSwift/RxSwift/Observables/Optional.swift b/Pods/RxSwift/RxSwift/Observables/Optional.swift deleted file mode 100644 index 64f8f1fdd..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Optional.swift +++ /dev/null @@ -1,95 +0,0 @@ -// -// Optional.swift -// RxSwift -// -// Created by tarunon on 2016/12/13. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Converts a optional to an observable sequence. - - - seealso: [from operator on reactivex.io](http://reactivex.io/documentation/operators/from.html) - - - parameter optional: Optional element in the resulting observable sequence. - - returns: An observable sequence containing the wrapped value or not from given optional. - */ - public static func from(optional: Element?) -> Observable { - ObservableOptional(optional: optional) - } - - /** - Converts a optional to an observable sequence. - - - seealso: [from operator on reactivex.io](http://reactivex.io/documentation/operators/from.html) - - - parameter optional: Optional element in the resulting observable sequence. - - parameter scheduler: Scheduler to send the optional element on. - - returns: An observable sequence containing the wrapped value or not from given optional. - */ - public static func from(optional: Element?, scheduler: ImmediateSchedulerType) -> Observable { - ObservableOptionalScheduled(optional: optional, scheduler: scheduler) - } -} - -final private class ObservableOptionalScheduledSink: Sink { - typealias Element = Observer.Element - typealias Parent = ObservableOptionalScheduled - - private let parent: Parent - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - return self.parent.scheduler.schedule(self.parent.optional) { (optional: Element?) -> Disposable in - if let next = optional { - self.forwardOn(.next(next)) - return self.parent.scheduler.schedule(()) { _ in - self.forwardOn(.completed) - self.dispose() - return Disposables.create() - } - } else { - self.forwardOn(.completed) - self.dispose() - return Disposables.create() - } - } - } -} - -final private class ObservableOptionalScheduled: Producer { - fileprivate let optional: Element? - fileprivate let scheduler: ImmediateSchedulerType - - init(optional: Element?, scheduler: ImmediateSchedulerType) { - self.optional = optional - self.scheduler = scheduler - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = ObservableOptionalScheduledSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - -final private class ObservableOptional: Producer { - private let optional: Element? - - init(optional: Element?) { - self.optional = optional - } - - override func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { - if let element = self.optional { - observer.on(.next(element)) - } - observer.on(.completed) - return Disposables.create() - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Producer.swift b/Pods/RxSwift/RxSwift/Observables/Producer.swift deleted file mode 100644 index e611930a5..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Producer.swift +++ /dev/null @@ -1,92 +0,0 @@ -// -// Producer.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/20/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -class Producer: Observable { - override init() { - super.init() - } - - override func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { - if !CurrentThreadScheduler.isScheduleRequired { - // The returned disposable needs to release all references once it was disposed. - let disposer = SinkDisposer() - let sinkAndSubscription = self.run(observer, cancel: disposer) - disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription) - - return disposer - } - else { - return CurrentThreadScheduler.instance.schedule(()) { _ in - let disposer = SinkDisposer() - let sinkAndSubscription = self.run(observer, cancel: disposer) - disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription) - - return disposer - } - } - } - - func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - rxAbstractMethod() - } -} - -private final class SinkDisposer: Cancelable { - private enum DisposeState: Int32 { - case disposed = 1 - case sinkAndSubscriptionSet = 2 - } - - private let state = AtomicInt(0) - private var sink: Disposable? - private var subscription: Disposable? - - var isDisposed: Bool { - isFlagSet(self.state, DisposeState.disposed.rawValue) - } - - func setSinkAndSubscription(sink: Disposable, subscription: Disposable) { - self.sink = sink - self.subscription = subscription - - let previousState = fetchOr(self.state, DisposeState.sinkAndSubscriptionSet.rawValue) - if (previousState & DisposeState.sinkAndSubscriptionSet.rawValue) != 0 { - rxFatalError("Sink and subscription were already set") - } - - if (previousState & DisposeState.disposed.rawValue) != 0 { - sink.dispose() - subscription.dispose() - self.sink = nil - self.subscription = nil - } - } - - func dispose() { - let previousState = fetchOr(self.state, DisposeState.disposed.rawValue) - - if (previousState & DisposeState.disposed.rawValue) != 0 { - return - } - - if (previousState & DisposeState.sinkAndSubscriptionSet.rawValue) != 0 { - guard let sink = self.sink else { - rxFatalError("Sink not set") - } - guard let subscription = self.subscription else { - rxFatalError("Subscription not set") - } - - sink.dispose() - subscription.dispose() - - self.sink = nil - self.subscription = nil - } - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Range.swift b/Pods/RxSwift/RxSwift/Observables/Range.swift deleted file mode 100644 index 245353249..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Range.swift +++ /dev/null @@ -1,73 +0,0 @@ -// -// Range.swift -// RxSwift -// -// Created by Krunoslav Zaher on 9/13/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType where Element: RxAbstractInteger { - /** - Generates an observable sequence of integral numbers within a specified range, using the specified scheduler to generate and send out observer messages. - - - seealso: [range operator on reactivex.io](http://reactivex.io/documentation/operators/range.html) - - - parameter start: The value of the first integer in the sequence. - - parameter count: The number of sequential integers to generate. - - parameter scheduler: Scheduler to run the generator loop on. - - returns: An observable sequence that contains a range of sequential integral numbers. - */ - public static func range(start: Element, count: Element, scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable { - RangeProducer(start: start, count: count, scheduler: scheduler) - } -} - -final private class RangeProducer: Producer { - fileprivate let start: Element - fileprivate let count: Element - fileprivate let scheduler: ImmediateSchedulerType - - init(start: Element, count: Element, scheduler: ImmediateSchedulerType) { - guard count >= 0 else { - rxFatalError("count can't be negative") - } - - guard start &+ (count - 1) >= start || count == 0 else { - rxFatalError("overflow of count") - } - - self.start = start - self.count = count - self.scheduler = scheduler - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = RangeSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - -final private class RangeSink: Sink where Observer.Element: RxAbstractInteger { - typealias Parent = RangeProducer - - private let parent: Parent - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - return self.parent.scheduler.scheduleRecursive(0 as Observer.Element) { i, recurse in - if i < self.parent.count { - self.forwardOn(.next(self.parent.start + i)) - recurse(i + 1) - } - else { - self.forwardOn(.completed) - self.dispose() - } - } - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Reduce.swift b/Pods/RxSwift/RxSwift/Observables/Reduce.swift deleted file mode 100644 index d5fab3478..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Reduce.swift +++ /dev/null @@ -1,109 +0,0 @@ -// -// Reduce.swift -// RxSwift -// -// Created by Krunoslav Zaher on 4/1/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - - -extension ObservableType { - /** - Applies an `accumulator` function over an observable sequence, returning the result of the aggregation as a single element in the result sequence. The specified `seed` value is used as the initial accumulator value. - - For aggregation behavior with incremental intermediate results, see `scan`. - - - seealso: [reduce operator on reactivex.io](http://reactivex.io/documentation/operators/reduce.html) - - - parameter seed: The initial accumulator value. - - parameter accumulator: A accumulator function to be invoked on each element. - - parameter mapResult: A function to transform the final accumulator value into the result value. - - returns: An observable sequence containing a single element with the final accumulator value. - */ - public func reduce(_ seed: A, accumulator: @escaping (A, Element) throws -> A, mapResult: @escaping (A) throws -> Result) - -> Observable { - Reduce(source: self.asObservable(), seed: seed, accumulator: accumulator, mapResult: mapResult) - } - - /** - Applies an `accumulator` function over an observable sequence, returning the result of the aggregation as a single element in the result sequence. The specified `seed` value is used as the initial accumulator value. - - For aggregation behavior with incremental intermediate results, see `scan`. - - - seealso: [reduce operator on reactivex.io](http://reactivex.io/documentation/operators/reduce.html) - - - parameter seed: The initial accumulator value. - - parameter accumulator: A accumulator function to be invoked on each element. - - returns: An observable sequence containing a single element with the final accumulator value. - */ - public func reduce(_ seed: A, accumulator: @escaping (A, Element) throws -> A) - -> Observable { - Reduce(source: self.asObservable(), seed: seed, accumulator: accumulator, mapResult: { $0 }) - } -} - -final private class ReduceSink: Sink, ObserverType { - typealias ResultType = Observer.Element - typealias Parent = Reduce - - private let parent: Parent - private var accumulation: AccumulateType - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - self.accumulation = parent.seed - - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - switch event { - case .next(let value): - do { - self.accumulation = try self.parent.accumulator(self.accumulation, value) - } - catch let e { - self.forwardOn(.error(e)) - self.dispose() - } - case .error(let e): - self.forwardOn(.error(e)) - self.dispose() - case .completed: - do { - let result = try self.parent.mapResult(self.accumulation) - self.forwardOn(.next(result)) - self.forwardOn(.completed) - self.dispose() - } - catch let e { - self.forwardOn(.error(e)) - self.dispose() - } - } - } -} - -final private class Reduce: Producer { - typealias AccumulatorType = (AccumulateType, SourceType) throws -> AccumulateType - typealias ResultSelectorType = (AccumulateType) throws -> ResultType - - private let source: Observable - fileprivate let seed: AccumulateType - fileprivate let accumulator: AccumulatorType - fileprivate let mapResult: ResultSelectorType - - init(source: Observable, seed: AccumulateType, accumulator: @escaping AccumulatorType, mapResult: @escaping ResultSelectorType) { - self.source = source - self.seed = seed - self.accumulator = accumulator - self.mapResult = mapResult - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == ResultType { - let sink = ReduceSink(parent: self, observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} - diff --git a/Pods/RxSwift/RxSwift/Observables/Repeat.swift b/Pods/RxSwift/RxSwift/Observables/Repeat.swift deleted file mode 100644 index 69a3ba02e..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Repeat.swift +++ /dev/null @@ -1,57 +0,0 @@ -// -// Repeat.swift -// RxSwift -// -// Created by Krunoslav Zaher on 9/13/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Generates an observable sequence that repeats the given element infinitely, using the specified scheduler to send out observer messages. - - - seealso: [repeat operator on reactivex.io](http://reactivex.io/documentation/operators/repeat.html) - - - parameter element: Element to repeat. - - parameter scheduler: Scheduler to run the producer loop on. - - returns: An observable sequence that repeats the given element infinitely. - */ - public static func repeatElement(_ element: Element, scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable { - RepeatElement(element: element, scheduler: scheduler) - } -} - -final private class RepeatElement: Producer { - fileprivate let element: Element - fileprivate let scheduler: ImmediateSchedulerType - - init(element: Element, scheduler: ImmediateSchedulerType) { - self.element = element - self.scheduler = scheduler - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = RepeatElementSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - - return (sink: sink, subscription: subscription) - } -} - -final private class RepeatElementSink: Sink { - typealias Parent = RepeatElement - - private let parent: Parent - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - return self.parent.scheduler.scheduleRecursive(self.parent.element) { e, recurse in - self.forwardOn(.next(e)) - recurse(e) - } - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/RetryWhen.swift b/Pods/RxSwift/RxSwift/Observables/RetryWhen.swift deleted file mode 100644 index 52a27091b..000000000 --- a/Pods/RxSwift/RxSwift/Observables/RetryWhen.swift +++ /dev/null @@ -1,211 +0,0 @@ -// -// RetryWhen.swift -// RxSwift -// -// Created by Junior B. on 06/10/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Repeats the source observable sequence on error when the notifier emits a next value. - If the source observable errors and the notifier completes, it will complete the source sequence. - - - seealso: [retry operator on reactivex.io](http://reactivex.io/documentation/operators/retry.html) - - - parameter notificationHandler: A handler that is passed an observable sequence of errors raised by the source observable and returns and observable that either continues, completes or errors. This behavior is then applied to the source observable. - - returns: An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully or is notified to error or complete. - */ - public func retry(when notificationHandler: @escaping (Observable) -> TriggerObservable) - -> Observable { - RetryWhenSequence(sources: InfiniteSequence(repeatedValue: self.asObservable()), notificationHandler: notificationHandler) - } - - /** - Repeats the source observable sequence on error when the notifier emits a next value. - If the source observable errors and the notifier completes, it will complete the source sequence. - - - seealso: [retry operator on reactivex.io](http://reactivex.io/documentation/operators/retry.html) - - - parameter notificationHandler: A handler that is passed an observable sequence of errors raised by the source observable and returns and observable that either continues, completes or errors. This behavior is then applied to the source observable. - - returns: An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully or is notified to error or complete. - */ - @available(*, deprecated, renamed: "retry(when:)") - public func retryWhen(_ notificationHandler: @escaping (Observable) -> TriggerObservable) - -> Observable { - retry(when: notificationHandler) - } - - /** - Repeats the source observable sequence on error when the notifier emits a next value. - If the source observable errors and the notifier completes, it will complete the source sequence. - - - seealso: [retry operator on reactivex.io](http://reactivex.io/documentation/operators/retry.html) - - - parameter notificationHandler: A handler that is passed an observable sequence of errors raised by the source observable and returns and observable that either continues, completes or errors. This behavior is then applied to the source observable. - - returns: An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully or is notified to error or complete. - */ - public func retry(when notificationHandler: @escaping (Observable) -> TriggerObservable) - -> Observable { - RetryWhenSequence(sources: InfiniteSequence(repeatedValue: self.asObservable()), notificationHandler: notificationHandler) - } - - /** - Repeats the source observable sequence on error when the notifier emits a next value. - If the source observable errors and the notifier completes, it will complete the source sequence. - - - seealso: [retry operator on reactivex.io](http://reactivex.io/documentation/operators/retry.html) - - - parameter notificationHandler: A handler that is passed an observable sequence of errors raised by the source observable and returns and observable that either continues, completes or errors. This behavior is then applied to the source observable. - - returns: An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully or is notified to error or complete. - */ - @available(*, deprecated, renamed: "retry(when:)") - public func retryWhen(_ notificationHandler: @escaping (Observable) -> TriggerObservable) - -> Observable { - RetryWhenSequence(sources: InfiniteSequence(repeatedValue: self.asObservable()), notificationHandler: notificationHandler) - } -} - -final private class RetryTriggerSink - : ObserverType where Sequence.Element: ObservableType, Sequence.Element.Element == Observer.Element { - typealias Element = TriggerObservable.Element - - typealias Parent = RetryWhenSequenceSinkIter - - private let parent: Parent - - init(parent: Parent) { - self.parent = parent - } - - func on(_ event: Event) { - switch event { - case .next: - self.parent.parent.lastError = nil - self.parent.parent.schedule(.moveNext) - case .error(let e): - self.parent.parent.forwardOn(.error(e)) - self.parent.parent.dispose() - case .completed: - self.parent.parent.forwardOn(.completed) - self.parent.parent.dispose() - } - } -} - -final private class RetryWhenSequenceSinkIter - : ObserverType - , Disposable where Sequence.Element: ObservableType, Sequence.Element.Element == Observer.Element { - typealias Element = Observer.Element - typealias Parent = RetryWhenSequenceSink - - fileprivate let parent: Parent - private let errorHandlerSubscription = SingleAssignmentDisposable() - private let subscription: Disposable - - init(parent: Parent, subscription: Disposable) { - self.parent = parent - self.subscription = subscription - } - - func on(_ event: Event) { - switch event { - case .next: - self.parent.forwardOn(event) - case .error(let error): - self.parent.lastError = error - - if let failedWith = error as? Error { - // dispose current subscription - self.subscription.dispose() - - let errorHandlerSubscription = self.parent.notifier.subscribe(RetryTriggerSink(parent: self)) - self.errorHandlerSubscription.setDisposable(errorHandlerSubscription) - self.parent.errorSubject.on(.next(failedWith)) - } - else { - self.parent.forwardOn(.error(error)) - self.parent.dispose() - } - case .completed: - self.parent.forwardOn(event) - self.parent.dispose() - } - } - - final func dispose() { - self.subscription.dispose() - self.errorHandlerSubscription.dispose() - } -} - -final private class RetryWhenSequenceSink - : TailRecursiveSink where Sequence.Element: ObservableType, Sequence.Element.Element == Observer.Element { - typealias Element = Observer.Element - typealias Parent = RetryWhenSequence - - let lock = RecursiveLock() - - private let parent: Parent - - fileprivate var lastError: Swift.Error? - fileprivate let errorSubject = PublishSubject() - private let handler: Observable - fileprivate let notifier = PublishSubject() - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - self.handler = parent.notificationHandler(self.errorSubject).asObservable() - super.init(observer: observer, cancel: cancel) - } - - override func done() { - if let lastError = self.lastError { - self.forwardOn(.error(lastError)) - self.lastError = nil - } - else { - self.forwardOn(.completed) - } - - self.dispose() - } - - override func extract(_ observable: Observable) -> SequenceGenerator? { - // It is important to always return `nil` here because there are sideffects in the `run` method - // that are dependant on particular `retryWhen` operator so single operator stack can't be reused in this - // case. - return nil - } - - override func subscribeToNext(_ source: Observable) -> Disposable { - let subscription = SingleAssignmentDisposable() - let iter = RetryWhenSequenceSinkIter(parent: self, subscription: subscription) - subscription.setDisposable(source.subscribe(iter)) - return iter - } - - override func run(_ sources: SequenceGenerator) -> Disposable { - let triggerSubscription = self.handler.subscribe(self.notifier.asObserver()) - let superSubscription = super.run(sources) - return Disposables.create(superSubscription, triggerSubscription) - } -} - -final private class RetryWhenSequence: Producer where Sequence.Element: ObservableType { - typealias Element = Sequence.Element.Element - - private let sources: Sequence - fileprivate let notificationHandler: (Observable) -> TriggerObservable - - init(sources: Sequence, notificationHandler: @escaping (Observable) -> TriggerObservable) { - self.sources = sources - self.notificationHandler = notificationHandler - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = RetryWhenSequenceSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run((self.sources.makeIterator(), nil)) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Sample.swift b/Pods/RxSwift/RxSwift/Observables/Sample.swift deleted file mode 100644 index 9301c9af7..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Sample.swift +++ /dev/null @@ -1,139 +0,0 @@ -// -// Sample.swift -// RxSwift -// -// Created by Krunoslav Zaher on 5/1/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Samples the source observable sequence using a sampler observable sequence producing sampling ticks. - - Upon each sampling tick, the latest element (if any) in the source sequence during the last sampling interval is sent to the resulting sequence. - - **In case there were no new elements between sampler ticks, you may provide a default value to be emitted, instead - to the resulting sequence otherwise no element is sent.** - - - seealso: [sample operator on reactivex.io](http://reactivex.io/documentation/operators/sample.html) - - - parameter sampler: Sampling tick sequence. - - parameter defaultValue: a value to return if there are no new elements between sampler ticks - - returns: Sampled observable sequence. - */ - public func sample(_ sampler: Source, defaultValue: Element? = nil) - -> Observable { - return Sample(source: self.asObservable(), sampler: sampler.asObservable(), defaultValue: defaultValue) - } -} - -final private class SamplerSink - : ObserverType - , LockOwnerType - , SynchronizedOnType { - typealias Element = SampleType - - typealias Parent = SampleSequenceSink - - private let parent: Parent - - var lock: RecursiveLock { - self.parent.lock - } - - init(parent: Parent) { - self.parent = parent - } - - func on(_ event: Event) { - self.synchronizedOn(event) - } - - func synchronized_on(_ event: Event) { - switch event { - case .next, .completed: - if let element = parent.element ?? self.parent.defaultValue { - self.parent.element = nil - self.parent.forwardOn(.next(element)) - } - - if self.parent.atEnd { - self.parent.forwardOn(.completed) - self.parent.dispose() - } - case .error(let e): - self.parent.forwardOn(.error(e)) - self.parent.dispose() - } - } -} - -final private class SampleSequenceSink - : Sink - , ObserverType - , LockOwnerType - , SynchronizedOnType { - typealias Element = Observer.Element - typealias Parent = Sample - - fileprivate let parent: Parent - fileprivate let defaultValue: Element? - - let lock = RecursiveLock() - - // state - fileprivate var element = nil as Element? - fileprivate var atEnd = false - - private let sourceSubscription = SingleAssignmentDisposable() - - init(parent: Parent, observer: Observer, cancel: Cancelable, defaultValue: Element? = nil) { - self.parent = parent - self.defaultValue = defaultValue - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - self.sourceSubscription.setDisposable(self.parent.source.subscribe(self)) - let samplerSubscription = self.parent.sampler.subscribe(SamplerSink(parent: self)) - - return Disposables.create(sourceSubscription, samplerSubscription) - } - - func on(_ event: Event) { - self.synchronizedOn(event) - } - - func synchronized_on(_ event: Event) { - switch event { - case .next(let element): - self.element = element - case .error: - self.forwardOn(event) - self.dispose() - case .completed: - self.atEnd = true - self.sourceSubscription.dispose() - } - } - -} - -final private class Sample: Producer { - fileprivate let source: Observable - fileprivate let sampler: Observable - fileprivate let defaultValue: Element? - - init(source: Observable, sampler: Observable, defaultValue: Element? = nil) { - self.source = source - self.sampler = sampler - self.defaultValue = defaultValue - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = SampleSequenceSink(parent: self, observer: observer, cancel: cancel, defaultValue: self.defaultValue) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Scan.swift b/Pods/RxSwift/RxSwift/Observables/Scan.swift deleted file mode 100644 index ecf69c80c..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Scan.swift +++ /dev/null @@ -1,100 +0,0 @@ -// -// Scan.swift -// RxSwift -// -// Created by Krunoslav Zaher on 6/14/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Applies an accumulator function over an observable sequence and returns each intermediate result. The specified seed value is used as the initial accumulator value. - - For aggregation behavior with no intermediate results, see `reduce`. - - - seealso: [scan operator on reactivex.io](http://reactivex.io/documentation/operators/scan.html) - - - parameter seed: The initial accumulator value. - - parameter accumulator: An accumulator function to be invoked on each element. - - returns: An observable sequence containing the accumulated values. - */ - public func scan(into seed: A, accumulator: @escaping (inout A, Element) throws -> Void) - -> Observable { - Scan(source: self.asObservable(), seed: seed, accumulator: accumulator) - } - - /** - Applies an accumulator function over an observable sequence and returns each intermediate result. The specified seed value is used as the initial accumulator value. - - For aggregation behavior with no intermediate results, see `reduce`. - - - seealso: [scan operator on reactivex.io](http://reactivex.io/documentation/operators/scan.html) - - - parameter seed: The initial accumulator value. - - parameter accumulator: An accumulator function to be invoked on each element. - - returns: An observable sequence containing the accumulated values. - */ - public func scan(_ seed: A, accumulator: @escaping (A, Element) throws -> A) - -> Observable { - return Scan(source: self.asObservable(), seed: seed) { acc, element in - let currentAcc = acc - acc = try accumulator(currentAcc, element) - } - } -} - -final private class ScanSink: Sink, ObserverType { - typealias Accumulate = Observer.Element - typealias Parent = Scan - - private let parent: Parent - private var accumulate: Accumulate - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - self.accumulate = parent.seed - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - switch event { - case .next(let element): - do { - try self.parent.accumulator(&self.accumulate, element) - self.forwardOn(.next(self.accumulate)) - } - catch let error { - self.forwardOn(.error(error)) - self.dispose() - } - case .error(let error): - self.forwardOn(.error(error)) - self.dispose() - case .completed: - self.forwardOn(.completed) - self.dispose() - } - } - -} - -final private class Scan: Producer { - typealias Accumulator = (inout Accumulate, Element) throws -> Void - - private let source: Observable - fileprivate let seed: Accumulate - fileprivate let accumulator: Accumulator - - init(source: Observable, seed: Accumulate, accumulator: @escaping Accumulator) { - self.source = source - self.seed = seed - self.accumulator = accumulator - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Accumulate { - let sink = ScanSink(parent: self, observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Sequence.swift b/Pods/RxSwift/RxSwift/Observables/Sequence.swift deleted file mode 100644 index c6d10896e..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Sequence.swift +++ /dev/null @@ -1,89 +0,0 @@ -// -// Sequence.swift -// RxSwift -// -// Created by Krunoslav Zaher on 11/14/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - // MARK: of - - /** - This method creates a new Observable instance with a variable number of elements. - - - seealso: [from operator on reactivex.io](http://reactivex.io/documentation/operators/from.html) - - - parameter elements: Elements to generate. - - parameter scheduler: Scheduler to send elements on. If `nil`, elements are sent immediately on subscription. - - returns: The observable sequence whose elements are pulled from the given arguments. - */ - public static func of(_ elements: Element ..., scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable { - ObservableSequence(elements: elements, scheduler: scheduler) - } -} - -extension ObservableType { - /** - Converts an array to an observable sequence. - - - seealso: [from operator on reactivex.io](http://reactivex.io/documentation/operators/from.html) - - - returns: The observable sequence whose elements are pulled from the given enumerable sequence. - */ - public static func from(_ array: [Element], scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable { - ObservableSequence(elements: array, scheduler: scheduler) - } - - /** - Converts a sequence to an observable sequence. - - - seealso: [from operator on reactivex.io](http://reactivex.io/documentation/operators/from.html) - - - returns: The observable sequence whose elements are pulled from the given enumerable sequence. - */ - public static func from(_ sequence: Sequence, scheduler: ImmediateSchedulerType = CurrentThreadScheduler.instance) -> Observable where Sequence.Element == Element { - ObservableSequence(elements: sequence, scheduler: scheduler) - } -} - -final private class ObservableSequenceSink: Sink where Sequence.Element == Observer.Element { - typealias Parent = ObservableSequence - - private let parent: Parent - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - return self.parent.scheduler.scheduleRecursive(self.parent.elements.makeIterator()) { iterator, recurse in - var mutableIterator = iterator - if let next = mutableIterator.next() { - self.forwardOn(.next(next)) - recurse(mutableIterator) - } - else { - self.forwardOn(.completed) - self.dispose() - } - } - } -} - -final private class ObservableSequence: Producer { - fileprivate let elements: Sequence - fileprivate let scheduler: ImmediateSchedulerType - - init(elements: Sequence, scheduler: ImmediateSchedulerType) { - self.elements = elements - self.scheduler = scheduler - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = ObservableSequenceSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/ShareReplayScope.swift b/Pods/RxSwift/RxSwift/Observables/ShareReplayScope.swift deleted file mode 100644 index 59d440dc3..000000000 --- a/Pods/RxSwift/RxSwift/Observables/ShareReplayScope.swift +++ /dev/null @@ -1,443 +0,0 @@ -// -// ShareReplayScope.swift -// RxSwift -// -// Created by Krunoslav Zaher on 5/28/17. -// Copyright © 2017 Krunoslav Zaher. All rights reserved. -// - -/// Subject lifetime scope -public enum SubjectLifetimeScope { - /** - **Each connection will have it's own subject instance to store replay events.** - **Connections will be isolated from each another.** - - Configures the underlying implementation to behave equivalent to. - - ``` - source.multicast(makeSubject: { MySubject() }).refCount() - ``` - - **This is the recommended default.** - - This has the following consequences: - * `retry` or `concat` operators will function as expected because terminating the sequence will clear internal state. - * Each connection to source observable sequence will use it's own subject. - * When the number of subscribers drops from 1 to 0 and connection to source sequence is disposed, subject will be cleared. - - - ``` - let xs = Observable.deferred { () -> Observable in - print("Performing work ...") - return Observable.just(Date().timeIntervalSince1970) - } - .share(replay: 1, scope: .whileConnected) - - _ = xs.subscribe(onNext: { print("next \($0)") }, onCompleted: { print("completed\n") }) - _ = xs.subscribe(onNext: { print("next \($0)") }, onCompleted: { print("completed\n") }) - _ = xs.subscribe(onNext: { print("next \($0)") }, onCompleted: { print("completed\n") }) - - ``` - - Notice how time interval is different and `Performing work ...` is printed each time) - - ``` - Performing work ... - next 1495998900.82141 - completed - - Performing work ... - next 1495998900.82359 - completed - - Performing work ... - next 1495998900.82444 - completed - - - ``` - - */ - case whileConnected - - /** - **One subject will store replay events for all connections to source.** - **Connections won't be isolated from each another.** - - Configures the underlying implementation behave equivalent to. - - ``` - source.multicast(MySubject()).refCount() - ``` - - This has the following consequences: - * Using `retry` or `concat` operators after this operator usually isn't advised. - * Each connection to source observable sequence will share the same subject. - * After number of subscribers drops from 1 to 0 and connection to source observable sequence is dispose, this operator will - continue holding a reference to the same subject. - If at some later moment a new observer initiates a new connection to source it can potentially receive - some of the stale events received during previous connection. - * After source sequence terminates any new observer will always immediately receive replayed elements and terminal event. - No new subscriptions to source observable sequence will be attempted. - - ``` - let xs = Observable.deferred { () -> Observable in - print("Performing work ...") - return Observable.just(Date().timeIntervalSince1970) - } - .share(replay: 1, scope: .forever) - - _ = xs.subscribe(onNext: { print("next \($0)") }, onCompleted: { print("completed\n") }) - _ = xs.subscribe(onNext: { print("next \($0)") }, onCompleted: { print("completed\n") }) - _ = xs.subscribe(onNext: { print("next \($0)") }, onCompleted: { print("completed\n") }) - ``` - - Notice how time interval is the same, replayed, and `Performing work ...` is printed only once - - ``` - Performing work ... - next 1495999013.76356 - completed - - next 1495999013.76356 - completed - - next 1495999013.76356 - completed - ``` - - */ - case forever -} - -extension ObservableType { - - /** - Returns an observable sequence that **shares a single subscription to the underlying sequence**, and immediately upon subscription replays elements in buffer. - - This operator is equivalent to: - * `.whileConnected` - ``` - // Each connection will have it's own subject instance to store replay events. - // Connections will be isolated from each another. - source.multicast(makeSubject: { Replay.create(bufferSize: replay) }).refCount() - ``` - * `.forever` - ``` - // One subject will store replay events for all connections to source. - // Connections won't be isolated from each another. - source.multicast(Replay.create(bufferSize: replay)).refCount() - ``` - - It uses optimized versions of the operators for most common operations. - - - parameter replay: Maximum element count of the replay buffer. - - parameter scope: Lifetime scope of sharing subject. For more information see `SubjectLifetimeScope` enum. - - - seealso: [shareReplay operator on reactivex.io](http://reactivex.io/documentation/operators/replay.html) - - - returns: An observable sequence that contains the elements of a sequence produced by multicasting the source sequence. - */ - public func share(replay: Int = 0, scope: SubjectLifetimeScope = .whileConnected) - -> Observable { - switch scope { - case .forever: - switch replay { - case 0: return self.multicast(PublishSubject()).refCount() - default: return self.multicast(ReplaySubject.create(bufferSize: replay)).refCount() - } - case .whileConnected: - switch replay { - case 0: return ShareWhileConnected(source: self.asObservable()) - case 1: return ShareReplay1WhileConnected(source: self.asObservable()) - default: return self.multicast(makeSubject: { ReplaySubject.create(bufferSize: replay) }).refCount() - } - } - } -} - -private final class ShareReplay1WhileConnectedConnection - : ObserverType - , SynchronizedUnsubscribeType { - typealias Observers = AnyObserver.s - typealias DisposeKey = Observers.KeyType - - typealias Parent = ShareReplay1WhileConnected - private let parent: Parent - private let subscription = SingleAssignmentDisposable() - - private let lock: RecursiveLock - private var disposed: Bool = false - fileprivate var observers = Observers() - private var element: Element? - - init(parent: Parent, lock: RecursiveLock) { - self.parent = parent - self.lock = lock - - #if TRACE_RESOURCES - _ = Resources.incrementTotal() - #endif - } - - final func on(_ event: Event) { - let observers = self.lock.performLocked { self.synchronized_on(event) } - dispatch(observers, event) - } - - final private func synchronized_on(_ event: Event) -> Observers { - if self.disposed { - return Observers() - } - - switch event { - case .next(let element): - self.element = element - return self.observers - case .error, .completed: - let observers = self.observers - self.synchronized_dispose() - return observers - } - } - - final func connect() { - self.subscription.setDisposable(self.parent.source.subscribe(self)) - } - - final func synchronized_subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { - self.lock.performLocked { - if let element = self.element { - observer.on(.next(element)) - } - - let disposeKey = self.observers.insert(observer.on) - - return SubscriptionDisposable(owner: self, key: disposeKey) - } - } - - final private func synchronized_dispose() { - self.disposed = true - if self.parent.connection === self { - self.parent.connection = nil - } - self.observers = Observers() - } - - final func synchronizedUnsubscribe(_ disposeKey: DisposeKey) { - if self.lock.performLocked({ self.synchronized_unsubscribe(disposeKey) }) { - self.subscription.dispose() - } - } - - @inline(__always) - final private func synchronized_unsubscribe(_ disposeKey: DisposeKey) -> Bool { - // if already unsubscribed, just return - if self.observers.removeKey(disposeKey) == nil { - return false - } - - if self.observers.count == 0 { - self.synchronized_dispose() - return true - } - - return false - } - - #if TRACE_RESOURCES - deinit { - _ = Resources.decrementTotal() - } - #endif -} - -// optimized version of share replay for most common case -final private class ShareReplay1WhileConnected - : Observable { - - fileprivate typealias Connection = ShareReplay1WhileConnectedConnection - - fileprivate let source: Observable - - private let lock = RecursiveLock() - - fileprivate var connection: Connection? - - init(source: Observable) { - self.source = source - } - - override func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { - self.lock.lock() - let connection = self.synchronized_subscribe(observer) - let count = connection.observers.count - - let disposable = connection.synchronized_subscribe(observer) - self.lock.unlock() - - if count == 0 { - connection.connect() - } - - return disposable - } - - @inline(__always) - private func synchronized_subscribe(_ observer: Observer) -> Connection where Observer.Element == Element { - let connection: Connection - - if let existingConnection = self.connection { - connection = existingConnection - } - else { - connection = ShareReplay1WhileConnectedConnection( - parent: self, - lock: self.lock) - self.connection = connection - } - - return connection - } -} - -private final class ShareWhileConnectedConnection - : ObserverType - , SynchronizedUnsubscribeType { - typealias Observers = AnyObserver.s - typealias DisposeKey = Observers.KeyType - - typealias Parent = ShareWhileConnected - private let parent: Parent - private let subscription = SingleAssignmentDisposable() - - private let lock: RecursiveLock - private var disposed: Bool = false - fileprivate var observers = Observers() - - init(parent: Parent, lock: RecursiveLock) { - self.parent = parent - self.lock = lock - - #if TRACE_RESOURCES - _ = Resources.incrementTotal() - #endif - } - - final func on(_ event: Event) { - let observers = self.lock.performLocked { self.synchronized_on(event) } - dispatch(observers, event) - } - - final private func synchronized_on(_ event: Event) -> Observers { - if self.disposed { - return Observers() - } - - switch event { - case .next: - return self.observers - case .error, .completed: - let observers = self.observers - self.synchronized_dispose() - return observers - } - } - - final func connect() { - self.subscription.setDisposable(self.parent.source.subscribe(self)) - } - - final func synchronized_subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { - self.lock.performLocked { - let disposeKey = self.observers.insert(observer.on) - - return SubscriptionDisposable(owner: self, key: disposeKey) - } - } - - final private func synchronized_dispose() { - self.disposed = true - if self.parent.connection === self { - self.parent.connection = nil - } - self.observers = Observers() - } - - final func synchronizedUnsubscribe(_ disposeKey: DisposeKey) { - if self.lock.performLocked({ self.synchronized_unsubscribe(disposeKey) }) { - self.subscription.dispose() - } - } - - @inline(__always) - final private func synchronized_unsubscribe(_ disposeKey: DisposeKey) -> Bool { - // if already unsubscribed, just return - if self.observers.removeKey(disposeKey) == nil { - return false - } - - if self.observers.count == 0 { - self.synchronized_dispose() - return true - } - - return false - } - - #if TRACE_RESOURCES - deinit { - _ = Resources.decrementTotal() - } - #endif -} - -// optimized version of share replay for most common case -final private class ShareWhileConnected - : Observable { - - fileprivate typealias Connection = ShareWhileConnectedConnection - - fileprivate let source: Observable - - private let lock = RecursiveLock() - - fileprivate var connection: Connection? - - init(source: Observable) { - self.source = source - } - - override func subscribe(_ observer: Observer) -> Disposable where Observer.Element == Element { - self.lock.lock() - let connection = self.synchronized_subscribe(observer) - let count = connection.observers.count - - let disposable = connection.synchronized_subscribe(observer) - self.lock.unlock() - - if count == 0 { - connection.connect() - } - - return disposable - } - - @inline(__always) - private func synchronized_subscribe(_ observer: Observer) -> Connection where Observer.Element == Element { - let connection: Connection - - if let existingConnection = self.connection { - connection = existingConnection - } - else { - connection = ShareWhileConnectedConnection( - parent: self, - lock: self.lock) - self.connection = connection - } - - return connection - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/SingleAsync.swift b/Pods/RxSwift/RxSwift/Observables/SingleAsync.swift deleted file mode 100644 index 04e221764..000000000 --- a/Pods/RxSwift/RxSwift/Observables/SingleAsync.swift +++ /dev/null @@ -1,104 +0,0 @@ -// -// SingleAsync.swift -// RxSwift -// -// Created by Junior B. on 09/11/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - The single operator is similar to first, but throws a `RxError.noElements` or `RxError.moreThanOneElement` - if the source Observable does not emit exactly one element before successfully completing. - - - seealso: [single operator on reactivex.io](http://reactivex.io/documentation/operators/first.html) - - - returns: An observable sequence that emits a single element or throws an exception if more (or none) of them are emitted. - */ - public func single() - -> Observable { - SingleAsync(source: self.asObservable()) - } - - /** - The single operator is similar to first, but throws a `RxError.NoElements` or `RxError.MoreThanOneElement` - if the source Observable does not emit exactly one element before successfully completing. - - - seealso: [single operator on reactivex.io](http://reactivex.io/documentation/operators/first.html) - - - parameter predicate: A function to test each source element for a condition. - - returns: An observable sequence that emits a single element or throws an exception if more (or none) of them are emitted. - */ - public func single(_ predicate: @escaping (Element) throws -> Bool) - -> Observable { - SingleAsync(source: self.asObservable(), predicate: predicate) - } -} - -private final class SingleAsyncSink : Sink, ObserverType { - typealias Element = Observer.Element - typealias Parent = SingleAsync - - private let parent: Parent - private var seenValue: Bool = false - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - switch event { - case .next(let value): - do { - let forward = try self.parent.predicate?(value) ?? true - if !forward { - return - } - } - catch let error { - self.forwardOn(.error(error as Swift.Error)) - self.dispose() - return - } - - if self.seenValue { - self.forwardOn(.error(RxError.moreThanOneElement)) - self.dispose() - return - } - - self.seenValue = true - self.forwardOn(.next(value)) - case .error: - self.forwardOn(event) - self.dispose() - case .completed: - if self.seenValue { - self.forwardOn(.completed) - } else { - self.forwardOn(.error(RxError.noElements)) - } - self.dispose() - } - } -} - -final class SingleAsync: Producer { - typealias Predicate = (Element) throws -> Bool - - private let source: Observable - fileprivate let predicate: Predicate? - - init(source: Observable, predicate: Predicate? = nil) { - self.source = source - self.predicate = predicate - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = SingleAsyncSink(parent: self, observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Sink.swift b/Pods/RxSwift/RxSwift/Observables/Sink.swift deleted file mode 100644 index ed4fec01e..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Sink.swift +++ /dev/null @@ -1,75 +0,0 @@ -// -// Sink.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/19/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -class Sink: Disposable { - fileprivate let observer: Observer - fileprivate let cancel: Cancelable - private let disposed = AtomicInt(0) - - #if DEBUG - private let synchronizationTracker = SynchronizationTracker() - #endif - - init(observer: Observer, cancel: Cancelable) { -#if TRACE_RESOURCES - _ = Resources.incrementTotal() -#endif - self.observer = observer - self.cancel = cancel - } - - final func forwardOn(_ event: Event) { - #if DEBUG - self.synchronizationTracker.register(synchronizationErrorMessage: .default) - defer { self.synchronizationTracker.unregister() } - #endif - if isFlagSet(self.disposed, 1) { - return - } - self.observer.on(event) - } - - final func forwarder() -> SinkForward { - SinkForward(forward: self) - } - - final var isDisposed: Bool { - isFlagSet(self.disposed, 1) - } - - func dispose() { - fetchOr(self.disposed, 1) - self.cancel.dispose() - } - - deinit { -#if TRACE_RESOURCES - _ = Resources.decrementTotal() -#endif - } -} - -final class SinkForward: ObserverType { - typealias Element = Observer.Element - - private let forward: Sink - - init(forward: Sink) { - self.forward = forward - } - - final func on(_ event: Event) { - switch event { - case .next: - self.forward.observer.on(event) - case .error, .completed: - self.forward.observer.on(event) - self.forward.cancel.dispose() - } - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Skip.swift b/Pods/RxSwift/RxSwift/Observables/Skip.swift deleted file mode 100644 index 5856f3744..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Skip.swift +++ /dev/null @@ -1,158 +0,0 @@ -// -// Skip.swift -// RxSwift -// -// Created by Krunoslav Zaher on 6/25/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Bypasses a specified number of elements in an observable sequence and then returns the remaining elements. - - - seealso: [skip operator on reactivex.io](http://reactivex.io/documentation/operators/skip.html) - - - parameter count: The number of elements to skip before returning the remaining elements. - - returns: An observable sequence that contains the elements that occur after the specified index in the input sequence. - */ - public func skip(_ count: Int) - -> Observable { - SkipCount(source: self.asObservable(), count: count) - } -} - -extension ObservableType { - - /** - Skips elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers. - - - seealso: [skip operator on reactivex.io](http://reactivex.io/documentation/operators/skip.html) - - - parameter duration: Duration for skipping elements from the start of the sequence. - - parameter scheduler: Scheduler to run the timer on. - - returns: An observable sequence with the elements skipped during the specified duration from the start of the source sequence. - */ - public func skip(_ duration: RxTimeInterval, scheduler: SchedulerType) - -> Observable { - SkipTime(source: self.asObservable(), duration: duration, scheduler: scheduler) - } -} - -// count version - -final private class SkipCountSink: Sink, ObserverType { - typealias Element = Observer.Element - typealias Parent = SkipCount - - let parent: Parent - - var remaining: Int - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - self.remaining = parent.count - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - switch event { - case .next(let value): - - if self.remaining <= 0 { - self.forwardOn(.next(value)) - } - else { - self.remaining -= 1 - } - case .error: - self.forwardOn(event) - self.dispose() - case .completed: - self.forwardOn(event) - self.dispose() - } - } - -} - -final private class SkipCount: Producer { - let source: Observable - let count: Int - - init(source: Observable, count: Int) { - self.source = source - self.count = count - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = SkipCountSink(parent: self, observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - - return (sink: sink, subscription: subscription) - } -} - -// time version - -final private class SkipTimeSink: Sink, ObserverType where Observer.Element == Element { - typealias Parent = SkipTime - - let parent: Parent - - // state - var open = false - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - switch event { - case .next(let value): - if self.open { - self.forwardOn(.next(value)) - } - case .error: - self.forwardOn(event) - self.dispose() - case .completed: - self.forwardOn(event) - self.dispose() - } - } - - func tick() { - self.open = true - } - - func run() -> Disposable { - let disposeTimer = self.parent.scheduler.scheduleRelative((), dueTime: self.parent.duration) { _ in - self.tick() - return Disposables.create() - } - - let disposeSubscription = self.parent.source.subscribe(self) - - return Disposables.create(disposeTimer, disposeSubscription) - } -} - -final private class SkipTime: Producer { - let source: Observable - let duration: RxTimeInterval - let scheduler: SchedulerType - - init(source: Observable, duration: RxTimeInterval, scheduler: SchedulerType) { - self.source = source - self.scheduler = scheduler - self.duration = duration - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = SkipTimeSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/SkipUntil.swift b/Pods/RxSwift/RxSwift/Observables/SkipUntil.swift deleted file mode 100644 index c8fe19340..000000000 --- a/Pods/RxSwift/RxSwift/Observables/SkipUntil.swift +++ /dev/null @@ -1,152 +0,0 @@ -// -// SkipUntil.swift -// RxSwift -// -// Created by Yury Korolev on 10/3/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Returns the elements from the source observable sequence that are emitted after the other observable sequence produces an element. - - - seealso: [skipUntil operator on reactivex.io](http://reactivex.io/documentation/operators/skipuntil.html) - - - parameter other: Observable sequence that starts propagation of elements of the source sequence. - - returns: An observable sequence containing the elements of the source sequence that are emitted after the other sequence emits an item. - */ - public func skip(until other: Source) - -> Observable { - SkipUntil(source: self.asObservable(), other: other.asObservable()) - } - - /** - Returns the elements from the source observable sequence that are emitted after the other observable sequence produces an element. - - - seealso: [skipUntil operator on reactivex.io](http://reactivex.io/documentation/operators/skipuntil.html) - - - parameter other: Observable sequence that starts propagation of elements of the source sequence. - - returns: An observable sequence containing the elements of the source sequence that are emitted after the other sequence emits an item. - */ - @available(*, deprecated, renamed: "skip(until:)") - public func skipUntil(_ other: Source) - -> Observable { - skip(until: other) - } -} - -final private class SkipUntilSinkOther - : ObserverType - , LockOwnerType - , SynchronizedOnType { - typealias Parent = SkipUntilSink - typealias Element = Other - - private let parent: Parent - - var lock: RecursiveLock { - self.parent.lock - } - - let subscription = SingleAssignmentDisposable() - - init(parent: Parent) { - self.parent = parent - #if TRACE_RESOURCES - _ = Resources.incrementTotal() - #endif - } - - func on(_ event: Event) { - self.synchronizedOn(event) - } - - func synchronized_on(_ event: Event) { - switch event { - case .next: - self.parent.forwardElements = true - self.subscription.dispose() - case .error(let e): - self.parent.forwardOn(.error(e)) - self.parent.dispose() - case .completed: - self.subscription.dispose() - } - } - - #if TRACE_RESOURCES - deinit { - _ = Resources.decrementTotal() - } - #endif - -} - - -final private class SkipUntilSink - : Sink - , ObserverType - , LockOwnerType - , SynchronizedOnType { - typealias Element = Observer.Element - typealias Parent = SkipUntil - - let lock = RecursiveLock() - private let parent: Parent - fileprivate var forwardElements = false - - private let sourceSubscription = SingleAssignmentDisposable() - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - self.synchronizedOn(event) - } - - func synchronized_on(_ event: Event) { - switch event { - case .next: - if self.forwardElements { - self.forwardOn(event) - } - case .error: - self.forwardOn(event) - self.dispose() - case .completed: - if self.forwardElements { - self.forwardOn(event) - } - self.dispose() - } - } - - func run() -> Disposable { - let sourceSubscription = self.parent.source.subscribe(self) - let otherObserver = SkipUntilSinkOther(parent: self) - let otherSubscription = self.parent.other.subscribe(otherObserver) - self.sourceSubscription.setDisposable(sourceSubscription) - otherObserver.subscription.setDisposable(otherSubscription) - - return Disposables.create(sourceSubscription, otherObserver.subscription) - } -} - -final private class SkipUntil: Producer { - - fileprivate let source: Observable - fileprivate let other: Observable - - init(source: Observable, other: Observable) { - self.source = source - self.other = other - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = SkipUntilSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/SkipWhile.swift b/Pods/RxSwift/RxSwift/Observables/SkipWhile.swift deleted file mode 100644 index a62f88ddd..000000000 --- a/Pods/RxSwift/RxSwift/Observables/SkipWhile.swift +++ /dev/null @@ -1,87 +0,0 @@ -// -// SkipWhile.swift -// RxSwift -// -// Created by Yury Korolev on 10/9/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements. - - - seealso: [skipWhile operator on reactivex.io](http://reactivex.io/documentation/operators/skipwhile.html) - - - parameter predicate: A function to test each element for a condition. - - returns: An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate. - */ - public func skip(while predicate: @escaping (Element) throws -> Bool) -> Observable { - SkipWhile(source: self.asObservable(), predicate: predicate) - } - - /** - Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements. - - - seealso: [skipWhile operator on reactivex.io](http://reactivex.io/documentation/operators/skipwhile.html) - - - parameter predicate: A function to test each element for a condition. - - returns: An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate. - */ - @available(*, deprecated, renamed: "skip(while:)") - public func skipWhile(_ predicate: @escaping (Element) throws -> Bool) -> Observable { - SkipWhile(source: self.asObservable(), predicate: predicate) - } -} - -final private class SkipWhileSink: Sink, ObserverType { - typealias Element = Observer.Element - typealias Parent = SkipWhile - - private let parent: Parent - private var running = false - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - switch event { - case .next(let value): - if !self.running { - do { - self.running = try !self.parent.predicate(value) - } catch let e { - self.forwardOn(.error(e)) - self.dispose() - return - } - } - - if self.running { - self.forwardOn(.next(value)) - } - case .error, .completed: - self.forwardOn(event) - self.dispose() - } - } -} - -final private class SkipWhile: Producer { - typealias Predicate = (Element) throws -> Bool - - private let source: Observable - fileprivate let predicate: Predicate - - init(source: Observable, predicate: @escaping Predicate) { - self.source = source - self.predicate = predicate - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = SkipWhileSink(parent: self, observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/StartWith.swift b/Pods/RxSwift/RxSwift/Observables/StartWith.swift deleted file mode 100644 index 13fb31d33..000000000 --- a/Pods/RxSwift/RxSwift/Observables/StartWith.swift +++ /dev/null @@ -1,42 +0,0 @@ -// -// StartWith.swift -// RxSwift -// -// Created by Krunoslav Zaher on 4/6/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Prepends a sequence of values to an observable sequence. - - - seealso: [startWith operator on reactivex.io](http://reactivex.io/documentation/operators/startwith.html) - - - parameter elements: Elements to prepend to the specified sequence. - - returns: The source sequence prepended with the specified values. - */ - public func startWith(_ elements: Element ...) - -> Observable { - return StartWith(source: self.asObservable(), elements: elements) - } -} - -final private class StartWith: Producer { - let elements: [Element] - let source: Observable - - init(source: Observable, elements: [Element]) { - self.source = source - self.elements = elements - super.init() - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - for e in self.elements { - observer.on(.next(e)) - } - - return (sink: Disposables.create(), subscription: self.source.subscribe(observer)) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/SubscribeOn.swift b/Pods/RxSwift/RxSwift/Observables/SubscribeOn.swift deleted file mode 100644 index e8e41d9cf..000000000 --- a/Pods/RxSwift/RxSwift/Observables/SubscribeOn.swift +++ /dev/null @@ -1,103 +0,0 @@ -// -// SubscribeOn.swift -// RxSwift -// -// Created by Krunoslav Zaher on 6/14/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Wraps the source sequence in order to run its subscription and unsubscription logic on the specified - scheduler. - - This operation is not commonly used. - - This only performs the side-effects of subscription and unsubscription on the specified scheduler. - - In order to invoke observer callbacks on a `scheduler`, use `observeOn`. - - - seealso: [subscribeOn operator on reactivex.io](http://reactivex.io/documentation/operators/subscribeon.html) - - - parameter scheduler: Scheduler to perform subscription and unsubscription actions on. - - returns: The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler. - */ - public func subscribe(on scheduler: ImmediateSchedulerType) - -> Observable { - SubscribeOn(source: self, scheduler: scheduler) - } - - /** - Wraps the source sequence in order to run its subscription and unsubscription logic on the specified - scheduler. - - This operation is not commonly used. - - This only performs the side-effects of subscription and unsubscription on the specified scheduler. - - In order to invoke observer callbacks on a `scheduler`, use `observeOn`. - - - seealso: [subscribeOn operator on reactivex.io](http://reactivex.io/documentation/operators/subscribeon.html) - - - parameter scheduler: Scheduler to perform subscription and unsubscription actions on. - - returns: The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler. - */ - @available(*, deprecated, renamed: "subscribe(on:)") - public func subscribeOn(_ scheduler: ImmediateSchedulerType) - -> Observable { - subscribe(on: scheduler) - } -} - -final private class SubscribeOnSink: Sink, ObserverType where Ob.Element == Observer.Element { - typealias Element = Observer.Element - typealias Parent = SubscribeOn - - let parent: Parent - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - self.forwardOn(event) - - if event.isStopEvent { - self.dispose() - } - } - - func run() -> Disposable { - let disposeEverything = SerialDisposable() - let cancelSchedule = SingleAssignmentDisposable() - - disposeEverything.disposable = cancelSchedule - - let disposeSchedule = self.parent.scheduler.schedule(()) { _ -> Disposable in - let subscription = self.parent.source.subscribe(self) - disposeEverything.disposable = ScheduledDisposable(scheduler: self.parent.scheduler, disposable: subscription) - return Disposables.create() - } - - cancelSchedule.setDisposable(disposeSchedule) - - return disposeEverything - } -} - -final private class SubscribeOn: Producer { - let source: Ob - let scheduler: ImmediateSchedulerType - - init(source: Ob, scheduler: ImmediateSchedulerType) { - self.source = source - self.scheduler = scheduler - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Ob.Element { - let sink = SubscribeOnSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Switch.swift b/Pods/RxSwift/RxSwift/Observables/Switch.swift deleted file mode 100644 index 5aa60b97a..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Switch.swift +++ /dev/null @@ -1,251 +0,0 @@ -// -// Switch.swift -// RxSwift -// -// Created by Krunoslav Zaher on 3/12/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Projects each element of an observable sequence into a new sequence of observable sequences and then - transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence. - - It is a combination of `map` + `switchLatest` operator - - - seealso: [flatMapLatest operator on reactivex.io](http://reactivex.io/documentation/operators/flatmap.html) - - - parameter selector: A transform function to apply to each element. - - returns: An observable sequence whose elements are the result of invoking the transform function on each element of source producing an - Observable of Observable sequences and that at any point in time produces the elements of the most recent inner observable sequence that has been received. - */ - public func flatMapLatest(_ selector: @escaping (Element) throws -> Source) - -> Observable { - return FlatMapLatest(source: self.asObservable(), selector: selector) - } - - /** - Projects each element of an observable sequence into a new sequence of observable sequences and then - transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence. - - It is a combination of `map` + `switchLatest` operator - - - seealso: [flatMapLatest operator on reactivex.io](http://reactivex.io/documentation/operators/flatmap.html) - - - parameter selector: A transform function to apply to each element. - - returns: An observable sequence whose elements are the result of invoking the transform function on each element of source producing an - Observable of Observable sequences and that at any point in time produces the elements of the most recent inner observable sequence that has been received. - */ - public func flatMapLatest(_ selector: @escaping (Element) throws -> Source) - -> Infallible { - return Infallible(flatMapLatest(selector)) - } -} - -extension ObservableType where Element: ObservableConvertibleType { - - /** - Transforms an observable sequence of observable sequences into an observable sequence - producing values only from the most recent observable sequence. - - Each time a new inner observable sequence is received, unsubscribe from the - previous inner observable sequence. - - - seealso: [switch operator on reactivex.io](http://reactivex.io/documentation/operators/switch.html) - - - returns: The observable sequence that at any point in time produces the elements of the most recent inner observable sequence that has been received. - */ - public func switchLatest() -> Observable { - Switch(source: self.asObservable()) - } -} - -private class SwitchSink - : Sink - , ObserverType where Source.Element == Observer.Element { - typealias Element = SourceType - - private let subscriptions: SingleAssignmentDisposable = SingleAssignmentDisposable() - private let innerSubscription: SerialDisposable = SerialDisposable() - - let lock = RecursiveLock() - - // state - fileprivate var stopped = false - fileprivate var latest = 0 - fileprivate var hasLatest = false - - override init(observer: Observer, cancel: Cancelable) { - super.init(observer: observer, cancel: cancel) - } - - func run(_ source: Observable) -> Disposable { - let subscription = source.subscribe(self) - self.subscriptions.setDisposable(subscription) - return Disposables.create(subscriptions, innerSubscription) - } - - func performMap(_ element: SourceType) throws -> Source { - rxAbstractMethod() - } - - @inline(__always) - final private func nextElementArrived(element: Element) -> (Int, Observable)? { - self.lock.lock(); defer { self.lock.unlock() } - - do { - let observable = try self.performMap(element).asObservable() - self.hasLatest = true - self.latest = self.latest &+ 1 - return (self.latest, observable) - } - catch let error { - self.forwardOn(.error(error)) - self.dispose() - } - - return nil - } - - func on(_ event: Event) { - switch event { - case .next(let element): - if let (latest, observable) = self.nextElementArrived(element: element) { - let d = SingleAssignmentDisposable() - self.innerSubscription.disposable = d - - let observer = SwitchSinkIter(parent: self, id: latest, this: d) - let disposable = observable.subscribe(observer) - d.setDisposable(disposable) - } - case .error(let error): - self.lock.lock(); defer { self.lock.unlock() } - self.forwardOn(.error(error)) - self.dispose() - case .completed: - self.lock.lock(); defer { self.lock.unlock() } - self.stopped = true - - self.subscriptions.dispose() - - if !self.hasLatest { - self.forwardOn(.completed) - self.dispose() - } - } - } -} - -final private class SwitchSinkIter - : ObserverType - , LockOwnerType - , SynchronizedOnType where Source.Element == Observer.Element { - typealias Element = Source.Element - typealias Parent = SwitchSink - - private let parent: Parent - private let id: Int - private let this: Disposable - - var lock: RecursiveLock { - self.parent.lock - } - - init(parent: Parent, id: Int, this: Disposable) { - self.parent = parent - self.id = id - self.this = this - } - - func on(_ event: Event) { - self.synchronizedOn(event) - } - - func synchronized_on(_ event: Event) { - switch event { - case .next: break - case .error, .completed: - self.this.dispose() - } - - if self.parent.latest != self.id { - return - } - - switch event { - case .next: - self.parent.forwardOn(event) - case .error: - self.parent.forwardOn(event) - self.parent.dispose() - case .completed: - self.parent.hasLatest = false - if self.parent.stopped { - self.parent.forwardOn(event) - self.parent.dispose() - } - } - } -} - -// MARK: Specializations - -final private class SwitchIdentitySink: SwitchSink - where Observer.Element == Source.Element { - override init(observer: Observer, cancel: Cancelable) { - super.init(observer: observer, cancel: cancel) - } - - override func performMap(_ element: Source) throws -> Source { - element - } -} - -final private class MapSwitchSink: SwitchSink where Observer.Element == Source.Element { - typealias Selector = (SourceType) throws -> Source - - private let selector: Selector - - init(selector: @escaping Selector, observer: Observer, cancel: Cancelable) { - self.selector = selector - super.init(observer: observer, cancel: cancel) - } - - override func performMap(_ element: SourceType) throws -> Source { - try self.selector(element) - } -} - -// MARK: Producers - -final private class Switch: Producer { - private let source: Observable - - init(source: Observable) { - self.source = source - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Source.Element { - let sink = SwitchIdentitySink(observer: observer, cancel: cancel) - let subscription = sink.run(self.source) - return (sink: sink, subscription: subscription) - } -} - -final private class FlatMapLatest: Producer { - typealias Selector = (SourceType) throws -> Source - - private let source: Observable - private let selector: Selector - - init(source: Observable, selector: @escaping Selector) { - self.source = source - self.selector = selector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Source.Element { - let sink = MapSwitchSink(selector: self.selector, observer: observer, cancel: cancel) - let subscription = sink.run(self.source) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/SwitchIfEmpty.swift b/Pods/RxSwift/RxSwift/Observables/SwitchIfEmpty.swift deleted file mode 100644 index a8827c455..000000000 --- a/Pods/RxSwift/RxSwift/Observables/SwitchIfEmpty.swift +++ /dev/null @@ -1,104 +0,0 @@ -// -// SwitchIfEmpty.swift -// RxSwift -// -// Created by sergdort on 23/12/2016. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Returns the elements of the specified sequence or `switchTo` sequence if the sequence is empty. - - - seealso: [DefaultIfEmpty operator on reactivex.io](http://reactivex.io/documentation/operators/defaultifempty.html) - - - parameter switchTo: Observable sequence being returned when source sequence is empty. - - returns: Observable sequence that contains elements from switchTo sequence if source is empty, otherwise returns source sequence elements. - */ - public func ifEmpty(switchTo other: Observable) -> Observable { - SwitchIfEmpty(source: self.asObservable(), ifEmpty: other) - } -} - -final private class SwitchIfEmpty: Producer { - - private let source: Observable - private let ifEmpty: Observable - - init(source: Observable, ifEmpty: Observable) { - self.source = source - self.ifEmpty = ifEmpty - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = SwitchIfEmptySink(ifEmpty: self.ifEmpty, - observer: observer, - cancel: cancel) - let subscription = sink.run(self.source.asObservable()) - - return (sink: sink, subscription: subscription) - } -} - -final private class SwitchIfEmptySink: Sink - , ObserverType { - typealias Element = Observer.Element - - private let ifEmpty: Observable - private var isEmpty = true - private let ifEmptySubscription = SingleAssignmentDisposable() - - init(ifEmpty: Observable, observer: Observer, cancel: Cancelable) { - self.ifEmpty = ifEmpty - super.init(observer: observer, cancel: cancel) - } - - func run(_ source: Observable) -> Disposable { - let subscription = source.subscribe(self) - return Disposables.create(subscription, ifEmptySubscription) - } - - func on(_ event: Event) { - switch event { - case .next: - self.isEmpty = false - self.forwardOn(event) - case .error: - self.forwardOn(event) - self.dispose() - case .completed: - guard self.isEmpty else { - self.forwardOn(.completed) - self.dispose() - return - } - let ifEmptySink = SwitchIfEmptySinkIter(parent: self) - self.ifEmptySubscription.setDisposable(self.ifEmpty.subscribe(ifEmptySink)) - } - } -} - -final private class SwitchIfEmptySinkIter - : ObserverType { - typealias Element = Observer.Element - typealias Parent = SwitchIfEmptySink - - private let parent: Parent - - init(parent: Parent) { - self.parent = parent - } - - func on(_ event: Event) { - switch event { - case .next: - self.parent.forwardOn(event) - case .error: - self.parent.forwardOn(event) - self.parent.dispose() - case .completed: - self.parent.forwardOn(event) - self.parent.dispose() - } - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Take.swift b/Pods/RxSwift/RxSwift/Observables/Take.swift deleted file mode 100644 index e5746880f..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Take.swift +++ /dev/null @@ -1,193 +0,0 @@ -// -// Take.swift -// RxSwift -// -// Created by Krunoslav Zaher on 6/12/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Returns a specified number of contiguous elements from the start of an observable sequence. - - - seealso: [take operator on reactivex.io](http://reactivex.io/documentation/operators/take.html) - - - parameter count: The number of elements to return. - - returns: An observable sequence that contains the specified number of elements from the start of the input sequence. - */ - public func take(_ count: Int) - -> Observable { - if count == 0 { - return Observable.empty() - } - else { - return TakeCount(source: self.asObservable(), count: count) - } - } -} - -extension ObservableType { - /** - Takes elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers. - - - seealso: [take operator on reactivex.io](http://reactivex.io/documentation/operators/take.html) - - - parameter duration: Duration for taking elements from the start of the sequence. - - parameter scheduler: Scheduler to run the timer on. - - returns: An observable sequence with the elements taken during the specified duration from the start of the source sequence. - */ - public func take(for duration: RxTimeInterval, scheduler: SchedulerType) - -> Observable { - TakeTime(source: self.asObservable(), duration: duration, scheduler: scheduler) - } - - /** - Takes elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers. - - - seealso: [take operator on reactivex.io](http://reactivex.io/documentation/operators/take.html) - - - parameter duration: Duration for taking elements from the start of the sequence. - - parameter scheduler: Scheduler to run the timer on. - - returns: An observable sequence with the elements taken during the specified duration from the start of the source sequence. - */ - @available(*, deprecated, renamed: "take(for:scheduler:)") - public func take(_ duration: RxTimeInterval, scheduler: SchedulerType) - -> Observable { - take(for: duration, scheduler: scheduler) - } -} - -// count version - -final private class TakeCountSink: Sink, ObserverType { - typealias Element = Observer.Element - typealias Parent = TakeCount - - private let parent: Parent - - private var remaining: Int - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - self.remaining = parent.count - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - switch event { - case .next(let value): - - if self.remaining > 0 { - self.remaining -= 1 - - self.forwardOn(.next(value)) - - if self.remaining == 0 { - self.forwardOn(.completed) - self.dispose() - } - } - case .error: - self.forwardOn(event) - self.dispose() - case .completed: - self.forwardOn(event) - self.dispose() - } - } - -} - -final private class TakeCount: Producer { - private let source: Observable - fileprivate let count: Int - - init(source: Observable, count: Int) { - if count < 0 { - rxFatalError("count can't be negative") - } - self.source = source - self.count = count - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = TakeCountSink(parent: self, observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} - -// time version - -final private class TakeTimeSink - : Sink - , LockOwnerType - , ObserverType - , SynchronizedOnType where Observer.Element == Element { - typealias Parent = TakeTime - - private let parent: Parent - - let lock = RecursiveLock() - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - self.synchronizedOn(event) - } - - func synchronized_on(_ event: Event) { - switch event { - case .next(let value): - self.forwardOn(.next(value)) - case .error: - self.forwardOn(event) - self.dispose() - case .completed: - self.forwardOn(event) - self.dispose() - } - } - - func tick() { - self.lock.performLocked { - self.forwardOn(.completed) - self.dispose() - } - } - - func run() -> Disposable { - let disposeTimer = self.parent.scheduler.scheduleRelative((), dueTime: self.parent.duration) { _ in - self.tick() - return Disposables.create() - } - - let disposeSubscription = self.parent.source.subscribe(self) - - return Disposables.create(disposeTimer, disposeSubscription) - } -} - -final private class TakeTime: Producer { - typealias TimeInterval = RxTimeInterval - - fileprivate let source: Observable - fileprivate let duration: TimeInterval - fileprivate let scheduler: SchedulerType - - init(source: Observable, duration: TimeInterval, scheduler: SchedulerType) { - self.source = source - self.scheduler = scheduler - self.duration = duration - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = TakeTimeSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/TakeLast.swift b/Pods/RxSwift/RxSwift/Observables/TakeLast.swift deleted file mode 100644 index 91833872d..000000000 --- a/Pods/RxSwift/RxSwift/Observables/TakeLast.swift +++ /dev/null @@ -1,78 +0,0 @@ -// -// TakeLast.swift -// RxSwift -// -// Created by Tomi Koskinen on 25/10/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Returns a specified number of contiguous elements from the end of an observable sequence. - - This operator accumulates a buffer with a length enough to store elements count elements. Upon completion of the source sequence, this buffer is drained on the result sequence. This causes the elements to be delayed. - - - seealso: [takeLast operator on reactivex.io](http://reactivex.io/documentation/operators/takelast.html) - - - parameter count: Number of elements to take from the end of the source sequence. - - returns: An observable sequence containing the specified number of elements from the end of the source sequence. - */ - public func takeLast(_ count: Int) - -> Observable { - TakeLast(source: self.asObservable(), count: count) - } -} - -final private class TakeLastSink: Sink, ObserverType { - typealias Element = Observer.Element - typealias Parent = TakeLast - - private let parent: Parent - - private var elements: Queue - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - self.elements = Queue(capacity: parent.count + 1) - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - switch event { - case .next(let value): - self.elements.enqueue(value) - if self.elements.count > self.parent.count { - _ = self.elements.dequeue() - } - case .error: - self.forwardOn(event) - self.dispose() - case .completed: - for e in self.elements { - self.forwardOn(.next(e)) - } - self.forwardOn(.completed) - self.dispose() - } - } -} - -final private class TakeLast: Producer { - private let source: Observable - fileprivate let count: Int - - init(source: Observable, count: Int) { - if count < 0 { - rxFatalError("count can't be negative") - } - self.source = source - self.count = count - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = TakeLastSink(parent: self, observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/TakeWithPredicate.swift b/Pods/RxSwift/RxSwift/Observables/TakeWithPredicate.swift deleted file mode 100644 index 6c28d19ba..000000000 --- a/Pods/RxSwift/RxSwift/Observables/TakeWithPredicate.swift +++ /dev/null @@ -1,285 +0,0 @@ -// -// TakeWithPredicate.swift -// RxSwift -// -// Created by Krunoslav Zaher on 6/7/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Returns the elements from the source observable sequence until the other observable sequence produces an element. - - - seealso: [takeUntil operator on reactivex.io](http://reactivex.io/documentation/operators/takeuntil.html) - - - parameter other: Observable sequence that terminates propagation of elements of the source sequence. - - returns: An observable sequence containing the elements of the source sequence up to the point the other sequence interrupted further propagation. - */ - public func take(until other: Source) - -> Observable { - TakeUntil(source: self.asObservable(), other: other.asObservable()) - } - - /** - Returns elements from an observable sequence until the specified condition is true. - - - seealso: [takeUntil operator on reactivex.io](http://reactivex.io/documentation/operators/takeuntil.html) - - - parameter predicate: A function to test each element for a condition. - - parameter behavior: Whether or not to include the last element matching the predicate. Defaults to `exclusive`. - - - returns: An observable sequence that contains the elements from the input sequence that occur before the element at which the test passes. - */ - public func take(until predicate: @escaping (Element) throws -> Bool, - behavior: TakeBehavior = .exclusive) - -> Observable { - TakeUntilPredicate(source: self.asObservable(), - behavior: behavior, - predicate: predicate) - } - - /** - Returns elements from an observable sequence as long as a specified condition is true. - - - seealso: [takeWhile operator on reactivex.io](http://reactivex.io/documentation/operators/takewhile.html) - - - parameter predicate: A function to test each element for a condition. - - returns: An observable sequence that contains the elements from the input sequence that occur before the element at which the test no longer passes. - */ - public func take(while predicate: @escaping (Element) throws -> Bool, - behavior: TakeBehavior = .exclusive) - -> Observable { - take(until: { try !predicate($0) }, behavior: behavior) - } - - /** - Returns the elements from the source observable sequence until the other observable sequence produces an element. - - - seealso: [takeUntil operator on reactivex.io](http://reactivex.io/documentation/operators/takeuntil.html) - - - parameter other: Observable sequence that terminates propagation of elements of the source sequence. - - returns: An observable sequence containing the elements of the source sequence up to the point the other sequence interrupted further propagation. - */ - @available(*, deprecated, renamed: "take(until:)") - public func takeUntil(_ other: Source) - -> Observable { - take(until: other) - } - - /** - Returns elements from an observable sequence until the specified condition is true. - - - seealso: [takeUntil operator on reactivex.io](http://reactivex.io/documentation/operators/takeuntil.html) - - - parameter behavior: Whether or not to include the last element matching the predicate. - - parameter predicate: A function to test each element for a condition. - - returns: An observable sequence that contains the elements from the input sequence that occur before the element at which the test passes. - */ - @available(*, deprecated, renamed: "take(until:behavior:)") - public func takeUntil(_ behavior: TakeBehavior, - predicate: @escaping (Element) throws -> Bool) - -> Observable { - take(until: predicate, behavior: behavior) - } - - /** - Returns elements from an observable sequence as long as a specified condition is true. - - - seealso: [takeWhile operator on reactivex.io](http://reactivex.io/documentation/operators/takewhile.html) - - - parameter predicate: A function to test each element for a condition. - - returns: An observable sequence that contains the elements from the input sequence that occur before the element at which the test no longer passes. - */ - @available(*, deprecated, renamed: "take(while:)") - public func takeWhile(_ predicate: @escaping (Element) throws -> Bool) - -> Observable { - take(until: { try !predicate($0) }, behavior: .exclusive) - } -} - -/// Behaviors for the take operator family. -public enum TakeBehavior { - /// Include the last element matching the predicate. - case inclusive - - /// Exclude the last element matching the predicate. - case exclusive -} - -// MARK: - TakeUntil Observable -final private class TakeUntilSinkOther - : ObserverType - , LockOwnerType - , SynchronizedOnType { - typealias Parent = TakeUntilSink - typealias Element = Other - - private let parent: Parent - - var lock: RecursiveLock { - self.parent.lock - } - - fileprivate let subscription = SingleAssignmentDisposable() - - init(parent: Parent) { - self.parent = parent -#if TRACE_RESOURCES - _ = Resources.incrementTotal() -#endif - } - - func on(_ event: Event) { - self.synchronizedOn(event) - } - - func synchronized_on(_ event: Event) { - switch event { - case .next: - self.parent.forwardOn(.completed) - self.parent.dispose() - case .error(let e): - self.parent.forwardOn(.error(e)) - self.parent.dispose() - case .completed: - self.subscription.dispose() - } - } - -#if TRACE_RESOURCES - deinit { - _ = Resources.decrementTotal() - } -#endif -} - -final private class TakeUntilSink - : Sink - , LockOwnerType - , ObserverType - , SynchronizedOnType { - typealias Element = Observer.Element - typealias Parent = TakeUntil - - private let parent: Parent - - let lock = RecursiveLock() - - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - self.synchronizedOn(event) - } - - func synchronized_on(_ event: Event) { - switch event { - case .next: - self.forwardOn(event) - case .error: - self.forwardOn(event) - self.dispose() - case .completed: - self.forwardOn(event) - self.dispose() - } - } - - func run() -> Disposable { - let otherObserver = TakeUntilSinkOther(parent: self) - let otherSubscription = self.parent.other.subscribe(otherObserver) - otherObserver.subscription.setDisposable(otherSubscription) - let sourceSubscription = self.parent.source.subscribe(self) - - return Disposables.create(sourceSubscription, otherObserver.subscription) - } -} - -final private class TakeUntil: Producer { - - fileprivate let source: Observable - fileprivate let other: Observable - - init(source: Observable, other: Observable) { - self.source = source - self.other = other - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = TakeUntilSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - -// MARK: - TakeUntil Predicate -final private class TakeUntilPredicateSink - : Sink, ObserverType { - typealias Element = Observer.Element - typealias Parent = TakeUntilPredicate - - private let parent: Parent - private var running = true - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - switch event { - case .next(let value): - if !self.running { - return - } - - do { - self.running = try !self.parent.predicate(value) - } catch let e { - self.forwardOn(.error(e)) - self.dispose() - return - } - - if self.running { - self.forwardOn(.next(value)) - } else { - if self.parent.behavior == .inclusive { - self.forwardOn(.next(value)) - } - - self.forwardOn(.completed) - self.dispose() - } - case .error, .completed: - self.forwardOn(event) - self.dispose() - } - } - -} - -final private class TakeUntilPredicate: Producer { - typealias Predicate = (Element) throws -> Bool - - private let source: Observable - fileprivate let predicate: Predicate - fileprivate let behavior: TakeBehavior - - init(source: Observable, - behavior: TakeBehavior, - predicate: @escaping Predicate) { - self.source = source - self.behavior = behavior - self.predicate = predicate - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = TakeUntilPredicateSink(parent: self, observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Throttle.swift b/Pods/RxSwift/RxSwift/Observables/Throttle.swift deleted file mode 100644 index 86152a837..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Throttle.swift +++ /dev/null @@ -1,160 +0,0 @@ -// -// Throttle.swift -// RxSwift -// -// Created by Krunoslav Zaher on 3/22/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import Foundation - -extension ObservableType { - - /** - Returns an Observable that emits the first and the latest item emitted by the source Observable during sequential time windows of a specified duration. - - This operator makes sure that no two elements are emitted in less then dueTime. - - - seealso: [debounce operator on reactivex.io](http://reactivex.io/documentation/operators/debounce.html) - - - parameter dueTime: Throttling duration for each element. - - parameter latest: Should latest element received in a dueTime wide time window since last element emission be emitted. - - parameter scheduler: Scheduler to run the throttle timers on. - - returns: The throttled sequence. - */ - public func throttle(_ dueTime: RxTimeInterval, latest: Bool = true, scheduler: SchedulerType) - -> Observable { - Throttle(source: self.asObservable(), dueTime: dueTime, latest: latest, scheduler: scheduler) - } -} - -final private class ThrottleSink - : Sink - , ObserverType - , LockOwnerType - , SynchronizedOnType { - typealias Element = Observer.Element - typealias ParentType = Throttle - - private let parent: ParentType - - let lock = RecursiveLock() - - // state - private var lastUnsentElement: Element? - private var lastSentTime: Date? - private var completed: Bool = false - - let cancellable = SerialDisposable() - - init(parent: ParentType, observer: Observer, cancel: Cancelable) { - self.parent = parent - - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - let subscription = self.parent.source.subscribe(self) - - return Disposables.create(subscription, cancellable) - } - - func on(_ event: Event) { - self.synchronizedOn(event) - } - - func synchronized_on(_ event: Event) { - switch event { - case .next(let element): - let now = self.parent.scheduler.now - - let reducedScheduledTime: RxTimeInterval - - if let lastSendingTime = self.lastSentTime { - reducedScheduledTime = self.parent.dueTime.reduceWithSpanBetween(earlierDate: lastSendingTime, laterDate: now) - } - else { - reducedScheduledTime = .nanoseconds(0) - } - - if reducedScheduledTime.isNow { - self.sendNow(element: element) - return - } - - if !self.parent.latest { - return - } - - let isThereAlreadyInFlightRequest = self.lastUnsentElement != nil - - self.lastUnsentElement = element - - if isThereAlreadyInFlightRequest { - return - } - - let scheduler = self.parent.scheduler - - let d = SingleAssignmentDisposable() - self.cancellable.disposable = d - - d.setDisposable(scheduler.scheduleRelative(0, dueTime: reducedScheduledTime, action: self.propagate)) - case .error: - self.lastUnsentElement = nil - self.forwardOn(event) - self.dispose() - case .completed: - if self.lastUnsentElement != nil { - self.completed = true - } - else { - self.forwardOn(.completed) - self.dispose() - } - } - } - - private func sendNow(element: Element) { - self.lastUnsentElement = nil - self.forwardOn(.next(element)) - // in case element processing takes a while, this should give some more room - self.lastSentTime = self.parent.scheduler.now - } - - func propagate(_: Int) -> Disposable { - self.lock.performLocked { - if let lastUnsentElement = self.lastUnsentElement { - self.sendNow(element: lastUnsentElement) - } - - if self.completed { - self.forwardOn(.completed) - self.dispose() - } - } - - return Disposables.create() - } -} - -final private class Throttle: Producer { - fileprivate let source: Observable - fileprivate let dueTime: RxTimeInterval - fileprivate let latest: Bool - fileprivate let scheduler: SchedulerType - - init(source: Observable, dueTime: RxTimeInterval, latest: Bool, scheduler: SchedulerType) { - self.source = source - self.dueTime = dueTime - self.latest = latest - self.scheduler = scheduler - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = ThrottleSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } - -} diff --git a/Pods/RxSwift/RxSwift/Observables/Timeout.swift b/Pods/RxSwift/RxSwift/Observables/Timeout.swift deleted file mode 100644 index efcc7917d..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Timeout.swift +++ /dev/null @@ -1,151 +0,0 @@ -// -// Timeout.swift -// RxSwift -// -// Created by Tomi Koskinen on 13/11/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Applies a timeout policy for each element in the observable sequence. If the next element isn't received within the specified timeout duration starting from its predecessor, a TimeoutError is propagated to the observer. - - - seealso: [timeout operator on reactivex.io](http://reactivex.io/documentation/operators/timeout.html) - - - parameter dueTime: Maximum duration between values before a timeout occurs. - - parameter scheduler: Scheduler to run the timeout timer on. - - returns: An observable sequence with a `RxError.timeout` in case of a timeout. - */ - public func timeout(_ dueTime: RxTimeInterval, scheduler: SchedulerType) - -> Observable { - return Timeout(source: self.asObservable(), dueTime: dueTime, other: Observable.error(RxError.timeout), scheduler: scheduler) - } - - /** - Applies a timeout policy for each element in the observable sequence, using the specified scheduler to run timeout timers. If the next element isn't received within the specified timeout duration starting from its predecessor, the other observable sequence is used to produce future messages from that point on. - - - seealso: [timeout operator on reactivex.io](http://reactivex.io/documentation/operators/timeout.html) - - - parameter dueTime: Maximum duration between values before a timeout occurs. - - parameter other: Sequence to return in case of a timeout. - - parameter scheduler: Scheduler to run the timeout timer on. - - returns: The source sequence switching to the other sequence in case of a timeout. - */ - public func timeout(_ dueTime: RxTimeInterval, other: Source, scheduler: SchedulerType) - -> Observable where Element == Source.Element { - return Timeout(source: self.asObservable(), dueTime: dueTime, other: other.asObservable(), scheduler: scheduler) - } -} - -final private class TimeoutSink: Sink, LockOwnerType, ObserverType { - typealias Element = Observer.Element - typealias Parent = Timeout - - private let parent: Parent - - let lock = RecursiveLock() - - private let timerD = SerialDisposable() - private let subscription = SerialDisposable() - - private var id = 0 - private var switched = false - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - let original = SingleAssignmentDisposable() - self.subscription.disposable = original - - self.createTimeoutTimer() - - original.setDisposable(self.parent.source.subscribe(self)) - - return Disposables.create(subscription, timerD) - } - - func on(_ event: Event) { - switch event { - case .next: - var onNextWins = false - - self.lock.performLocked { - onNextWins = !self.switched - if onNextWins { - self.id = self.id &+ 1 - } - } - - if onNextWins { - self.forwardOn(event) - self.createTimeoutTimer() - } - case .error, .completed: - var onEventWins = false - - self.lock.performLocked { - onEventWins = !self.switched - if onEventWins { - self.id = self.id &+ 1 - } - } - - if onEventWins { - self.forwardOn(event) - self.dispose() - } - } - } - - private func createTimeoutTimer() { - if self.timerD.isDisposed { - return - } - - let nextTimer = SingleAssignmentDisposable() - self.timerD.disposable = nextTimer - - let disposeSchedule = self.parent.scheduler.scheduleRelative(self.id, dueTime: self.parent.dueTime) { state in - - var timerWins = false - - self.lock.performLocked { - self.switched = (state == self.id) - timerWins = self.switched - } - - if timerWins { - self.subscription.disposable = self.parent.other.subscribe(self.forwarder()) - } - - return Disposables.create() - } - - nextTimer.setDisposable(disposeSchedule) - } -} - - -final private class Timeout: Producer { - fileprivate let source: Observable - fileprivate let dueTime: RxTimeInterval - fileprivate let other: Observable - fileprivate let scheduler: SchedulerType - - init(source: Observable, dueTime: RxTimeInterval, other: Observable, scheduler: SchedulerType) { - self.source = source - self.dueTime = dueTime - self.other = other - self.scheduler = scheduler - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = TimeoutSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Timer.swift b/Pods/RxSwift/RxSwift/Observables/Timer.swift deleted file mode 100644 index 30bbdf67d..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Timer.swift +++ /dev/null @@ -1,117 +0,0 @@ -// -// Timer.swift -// RxSwift -// -// Created by Krunoslav Zaher on 6/7/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType where Element: RxAbstractInteger { - /** - Returns an observable sequence that produces a value after each period, using the specified scheduler to run timers and to send out observer messages. - - - seealso: [interval operator on reactivex.io](http://reactivex.io/documentation/operators/interval.html) - - - parameter period: Period for producing the values in the resulting sequence. - - parameter scheduler: Scheduler to run the timer on. - - returns: An observable sequence that produces a value after each period. - */ - public static func interval(_ period: RxTimeInterval, scheduler: SchedulerType) - -> Observable { - return Timer( - dueTime: period, - period: period, - scheduler: scheduler - ) - } -} - -extension ObservableType where Element: RxAbstractInteger { - /** - Returns an observable sequence that periodically produces a value after the specified initial relative due time has elapsed, using the specified scheduler to run timers. - - - seealso: [timer operator on reactivex.io](http://reactivex.io/documentation/operators/timer.html) - - - parameter dueTime: Relative time at which to produce the first value. - - parameter period: Period to produce subsequent values. - - parameter scheduler: Scheduler to run timers on. - - returns: An observable sequence that produces a value after due time has elapsed and then each period. - */ - public static func timer(_ dueTime: RxTimeInterval, period: RxTimeInterval? = nil, scheduler: SchedulerType) - -> Observable { - return Timer( - dueTime: dueTime, - period: period, - scheduler: scheduler - ) - } -} - -import Foundation - -final private class TimerSink : Sink where Observer.Element : RxAbstractInteger { - typealias Parent = Timer - - private let parent: Parent - private let lock = RecursiveLock() - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - return self.parent.scheduler.schedulePeriodic(0 as Observer.Element, startAfter: self.parent.dueTime, period: self.parent.period!) { state in - self.lock.performLocked { - self.forwardOn(.next(state)) - return state &+ 1 - } - } - } -} - -final private class TimerOneOffSink: Sink where Observer.Element: RxAbstractInteger { - typealias Parent = Timer - - private let parent: Parent - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - return self.parent.scheduler.scheduleRelative(self, dueTime: self.parent.dueTime) { [unowned self] _ -> Disposable in - self.forwardOn(.next(0)) - self.forwardOn(.completed) - self.dispose() - - return Disposables.create() - } - } -} - -final private class Timer: Producer { - fileprivate let scheduler: SchedulerType - fileprivate let dueTime: RxTimeInterval - fileprivate let period: RxTimeInterval? - - init(dueTime: RxTimeInterval, period: RxTimeInterval?, scheduler: SchedulerType) { - self.scheduler = scheduler - self.dueTime = dueTime - self.period = period - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - if self.period != nil { - let sink = TimerSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } - else { - let sink = TimerOneOffSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/ToArray.swift b/Pods/RxSwift/RxSwift/Observables/ToArray.swift deleted file mode 100644 index 76c7370aa..000000000 --- a/Pods/RxSwift/RxSwift/Observables/ToArray.swift +++ /dev/null @@ -1,64 +0,0 @@ -// -// ToArray.swift -// RxSwift -// -// Created by Junior B. on 20/10/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Converts an Observable into a Single that emits the whole sequence as a single array and then terminates. - - For aggregation behavior see `reduce`. - - - seealso: [toArray operator on reactivex.io](http://reactivex.io/documentation/operators/to.html) - - - returns: A Single sequence containing all the emitted elements as array. - */ - public func toArray() - -> Single<[Element]> { - PrimitiveSequence(raw: ToArray(source: self.asObservable())) - } -} - -final private class ToArraySink: Sink, ObserverType where Observer.Element == [SourceType] { - typealias Parent = ToArray - - let parent: Parent - var list = [SourceType]() - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event) { - switch event { - case .next(let value): - self.list.append(value) - case .error(let e): - self.forwardOn(.error(e)) - self.dispose() - case .completed: - self.forwardOn(.next(self.list)) - self.forwardOn(.completed) - self.dispose() - } - } -} - -final private class ToArray: Producer<[SourceType]> { - let source: Observable - - init(source: Observable) { - self.source = source - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == [SourceType] { - let sink = ToArraySink(parent: self, observer: observer, cancel: cancel) - let subscription = self.source.subscribe(sink) - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Using.swift b/Pods/RxSwift/RxSwift/Observables/Using.swift deleted file mode 100644 index ca48d2fb8..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Using.swift +++ /dev/null @@ -1,90 +0,0 @@ -// -// Using.swift -// RxSwift -// -// Created by Yury Korolev on 10/15/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Constructs an observable sequence that depends on a resource object, whose lifetime is tied to the resulting observable sequence's lifetime. - - - seealso: [using operator on reactivex.io](http://reactivex.io/documentation/operators/using.html) - - - parameter resourceFactory: Factory function to obtain a resource object. - - parameter observableFactory: Factory function to obtain an observable sequence that depends on the obtained resource. - - returns: An observable sequence whose lifetime controls the lifetime of the dependent resource object. - */ - public static func using(_ resourceFactory: @escaping () throws -> Resource, observableFactory: @escaping (Resource) throws -> Observable) -> Observable { - Using(resourceFactory: resourceFactory, observableFactory: observableFactory) - } -} - -final private class UsingSink: Sink, ObserverType { - typealias SourceType = Observer.Element - typealias Parent = Using - - private let parent: Parent - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - var disposable = Disposables.create() - - do { - let resource = try self.parent.resourceFactory() - disposable = resource - let source = try self.parent.observableFactory(resource) - - return Disposables.create( - source.subscribe(self), - disposable - ) - } catch let error { - return Disposables.create( - Observable.error(error).subscribe(self), - disposable - ) - } - } - - func on(_ event: Event) { - switch event { - case let .next(value): - self.forwardOn(.next(value)) - case let .error(error): - self.forwardOn(.error(error)) - self.dispose() - case .completed: - self.forwardOn(.completed) - self.dispose() - } - } -} - -final private class Using: Producer { - - typealias Element = SourceType - - typealias ResourceFactory = () throws -> ResourceType - typealias ObservableFactory = (ResourceType) throws -> Observable - - fileprivate let resourceFactory: ResourceFactory - fileprivate let observableFactory: ObservableFactory - - - init(resourceFactory: @escaping ResourceFactory, observableFactory: @escaping ObservableFactory) { - self.resourceFactory = resourceFactory - self.observableFactory = observableFactory - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element { - let sink = UsingSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Window.swift b/Pods/RxSwift/RxSwift/Observables/Window.swift deleted file mode 100644 index b2a37a5c4..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Window.swift +++ /dev/null @@ -1,168 +0,0 @@ -// -// Window.swift -// RxSwift -// -// Created by Junior B. on 29/10/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Projects each element of an observable sequence into a window that is completed when either it’s full or a given amount of time has elapsed. - - - seealso: [window operator on reactivex.io](http://reactivex.io/documentation/operators/window.html) - - - parameter timeSpan: Maximum time length of a window. - - parameter count: Maximum element count of a window. - - parameter scheduler: Scheduler to run windowing timers on. - - returns: An observable sequence of windows (instances of `Observable`). - */ - public func window(timeSpan: RxTimeInterval, count: Int, scheduler: SchedulerType) - -> Observable> { - return WindowTimeCount(source: self.asObservable(), timeSpan: timeSpan, count: count, scheduler: scheduler) - } -} - -final private class WindowTimeCountSink - : Sink - , ObserverType - , LockOwnerType - , SynchronizedOnType where Observer.Element == Observable { - typealias Parent = WindowTimeCount - - private let parent: Parent - - let lock = RecursiveLock() - - private var subject = PublishSubject() - private var count = 0 - private var windowId = 0 - - private let timerD = SerialDisposable() - private let refCountDisposable: RefCountDisposable - private let groupDisposable = CompositeDisposable() - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - - _ = self.groupDisposable.insert(self.timerD) - - self.refCountDisposable = RefCountDisposable(disposable: self.groupDisposable) - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - - self.forwardOn(.next(AddRef(source: self.subject, refCount: self.refCountDisposable).asObservable())) - self.createTimer(self.windowId) - - _ = self.groupDisposable.insert(self.parent.source.subscribe(self)) - return self.refCountDisposable - } - - func startNewWindowAndCompleteCurrentOne() { - self.subject.on(.completed) - self.subject = PublishSubject() - - self.forwardOn(.next(AddRef(source: self.subject, refCount: self.refCountDisposable).asObservable())) - } - - func on(_ event: Event) { - self.synchronizedOn(event) - } - - func synchronized_on(_ event: Event) { - var newWindow = false - var newId = 0 - - switch event { - case .next(let element): - self.subject.on(.next(element)) - - do { - _ = try incrementChecked(&self.count) - } catch let e { - self.subject.on(.error(e as Swift.Error)) - self.dispose() - } - - if self.count == self.parent.count { - newWindow = true - self.count = 0 - self.windowId += 1 - newId = self.windowId - self.startNewWindowAndCompleteCurrentOne() - } - - case .error(let error): - self.subject.on(.error(error)) - self.forwardOn(.error(error)) - self.dispose() - case .completed: - self.subject.on(.completed) - self.forwardOn(.completed) - self.dispose() - } - - if newWindow { - self.createTimer(newId) - } - } - - func createTimer(_ windowId: Int) { - if self.timerD.isDisposed { - return - } - - if self.windowId != windowId { - return - } - - let nextTimer = SingleAssignmentDisposable() - - self.timerD.disposable = nextTimer - - let scheduledRelative = self.parent.scheduler.scheduleRelative(windowId, dueTime: self.parent.timeSpan) { previousWindowId in - - var newId = 0 - - self.lock.performLocked { - if previousWindowId != self.windowId { - return - } - - self.count = 0 - self.windowId = self.windowId &+ 1 - newId = self.windowId - self.startNewWindowAndCompleteCurrentOne() - } - - self.createTimer(newId) - - return Disposables.create() - } - - nextTimer.setDisposable(scheduledRelative) - } -} - -final private class WindowTimeCount: Producer> { - fileprivate let timeSpan: RxTimeInterval - fileprivate let count: Int - fileprivate let scheduler: SchedulerType - fileprivate let source: Observable - - init(source: Observable, timeSpan: RxTimeInterval, count: Int, scheduler: SchedulerType) { - self.source = source - self.timeSpan = timeSpan - self.count = count - self.scheduler = scheduler - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Observable { - let sink = WindowTimeCountSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/WithLatestFrom.swift b/Pods/RxSwift/RxSwift/Observables/WithLatestFrom.swift deleted file mode 100644 index d2868121a..000000000 --- a/Pods/RxSwift/RxSwift/Observables/WithLatestFrom.swift +++ /dev/null @@ -1,151 +0,0 @@ -// -// WithLatestFrom.swift -// RxSwift -// -// Created by Yury Korolev on 10/19/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - - /** - Merges two observable sequences into one observable sequence by combining each element from self with the latest element from the second source, if any. - - - seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html) - - note: Elements emitted by self before the second source has emitted any values will be omitted. - - - parameter second: Second observable source. - - parameter resultSelector: Function to invoke for each element from the self combined with the latest element from the second source, if any. - - returns: An observable sequence containing the result of combining each element of the self with the latest element from the second source, if any, using the specified result selector function. - */ - public func withLatestFrom(_ second: Source, resultSelector: @escaping (Element, Source.Element) throws -> ResultType) -> Observable { - WithLatestFrom(first: self.asObservable(), second: second.asObservable(), resultSelector: resultSelector) - } - - /** - Merges two observable sequences into one observable sequence by using latest element from the second sequence every time when `self` emits an element. - - - seealso: [combineLatest operator on reactivex.io](http://reactivex.io/documentation/operators/combinelatest.html) - - note: Elements emitted by self before the second source has emitted any values will be omitted. - - - parameter second: Second observable source. - - returns: An observable sequence containing the result of combining each element of the self with the latest element from the second source, if any, using the specified result selector function. - */ - public func withLatestFrom(_ second: Source) -> Observable { - WithLatestFrom(first: self.asObservable(), second: second.asObservable(), resultSelector: { $1 }) - } -} - -final private class WithLatestFromSink - : Sink - , ObserverType - , LockOwnerType - , SynchronizedOnType { - typealias ResultType = Observer.Element - typealias Parent = WithLatestFrom - typealias Element = FirstType - - private let parent: Parent - - fileprivate var lock = RecursiveLock() - fileprivate var latest: SecondType? - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - - super.init(observer: observer, cancel: cancel) - } - - func run() -> Disposable { - let sndSubscription = SingleAssignmentDisposable() - let sndO = WithLatestFromSecond(parent: self, disposable: sndSubscription) - - sndSubscription.setDisposable(self.parent.second.subscribe(sndO)) - let fstSubscription = self.parent.first.subscribe(self) - - return Disposables.create(fstSubscription, sndSubscription) - } - - func on(_ event: Event) { - self.synchronizedOn(event) - } - - func synchronized_on(_ event: Event) { - switch event { - case let .next(value): - guard let latest = self.latest else { return } - do { - let res = try self.parent.resultSelector(value, latest) - - self.forwardOn(.next(res)) - } catch let e { - self.forwardOn(.error(e)) - self.dispose() - } - case .completed: - self.forwardOn(.completed) - self.dispose() - case let .error(error): - self.forwardOn(.error(error)) - self.dispose() - } - } -} - -final private class WithLatestFromSecond - : ObserverType - , LockOwnerType - , SynchronizedOnType { - - typealias ResultType = Observer.Element - typealias Parent = WithLatestFromSink - typealias Element = SecondType - - private let parent: Parent - private let disposable: Disposable - - var lock: RecursiveLock { - self.parent.lock - } - - init(parent: Parent, disposable: Disposable) { - self.parent = parent - self.disposable = disposable - } - - func on(_ event: Event) { - self.synchronizedOn(event) - } - - func synchronized_on(_ event: Event) { - switch event { - case let .next(value): - self.parent.latest = value - case .completed: - self.disposable.dispose() - case let .error(error): - self.parent.forwardOn(.error(error)) - self.parent.dispose() - } - } -} - -final private class WithLatestFrom: Producer { - typealias ResultSelector = (FirstType, SecondType) throws -> ResultType - - fileprivate let first: Observable - fileprivate let second: Observable - fileprivate let resultSelector: ResultSelector - - init(first: Observable, second: Observable, resultSelector: @escaping ResultSelector) { - self.first = first - self.second = second - self.resultSelector = resultSelector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == ResultType { - let sink = WithLatestFromSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/WithUnretained.swift b/Pods/RxSwift/RxSwift/Observables/WithUnretained.swift deleted file mode 100644 index 4dc2eadff..000000000 --- a/Pods/RxSwift/RxSwift/Observables/WithUnretained.swift +++ /dev/null @@ -1,58 +0,0 @@ -// -// WithUnretained.swift -// RxSwift -// -// Created by Vincent Pradeilles on 01/01/2021. -// Copyright © 2020 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence. - - In the case the provided object cannot be retained successfully, the seqeunce will complete. - - - note: Be careful when using this operator in a sequence that has a buffer or replay, for example `share(replay: 1)`, as the sharing buffer will also include the provided object, which could potentially cause a retain cycle. - - - parameter obj: The object to provide an unretained reference on. - - parameter resultSelector: A function to combine the unretained referenced on `obj` and the value of the observable sequence. - - returns: An observable sequence that contains the result of `resultSelector` being called with an unretained reference on `obj` and the values of the original sequence. - */ - public func withUnretained( - _ obj: Object, - resultSelector: @escaping (Object, Element) -> Out - ) -> Observable { - map { [weak obj] element -> Out in - guard let obj = obj else { throw UnretainedError.failedRetaining } - - return resultSelector(obj, element) - } - .catch{ error -> Observable in - guard let unretainedError = error as? UnretainedError, - unretainedError == .failedRetaining else { - return .error(error) - } - - return .empty() - } - } - - - /** - Provides an unretained, safe to use (i.e. not implicitly unwrapped), reference to an object along with the events emitted by the sequence. - - In the case the provided object cannot be retained successfully, the seqeunce will complete. - - - note: Be careful when using this operator in a sequence that has a buffer or replay, for example `share(replay: 1)`, as the sharing buffer will also include the provided object, which could potentially cause a retain cycle. - - - parameter obj: The object to provide an unretained reference on. - - returns: An observable sequence of tuples that contains both an unretained reference on `obj` and the values of the original sequence. - */ - public func withUnretained(_ obj: Object) -> Observable<(Object, Element)> { - return withUnretained(obj) { ($0, $1) } - } -} - -private enum UnretainedError: Swift.Error { - case failedRetaining -} diff --git a/Pods/RxSwift/RxSwift/Observables/Zip+Collection.swift b/Pods/RxSwift/RxSwift/Observables/Zip+Collection.swift deleted file mode 100644 index 2d7f8877c..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Zip+Collection.swift +++ /dev/null @@ -1,168 +0,0 @@ -// -// Zip+Collection.swift -// RxSwift -// -// Created by Krunoslav Zaher on 8/30/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -extension ObservableType { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index. - - - seealso: [zip operator on reactivex.io](http://reactivex.io/documentation/operators/zip.html) - - - parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func zip(_ collection: Collection, resultSelector: @escaping ([Collection.Element.Element]) throws -> Element) -> Observable - where Collection.Element: ObservableType { - ZipCollectionType(sources: collection, resultSelector: resultSelector) - } - - /** - Merges the specified observable sequences into one observable sequence whenever all of the observable sequences have produced an element at a corresponding index. - - - seealso: [zip operator on reactivex.io](http://reactivex.io/documentation/operators/zip.html) - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func zip(_ collection: Collection) -> Observable<[Element]> - where Collection.Element: ObservableType, Collection.Element.Element == Element { - ZipCollectionType(sources: collection, resultSelector: { $0 }) - } - -} - -final private class ZipCollectionTypeSink - : Sink where Collection.Element: ObservableConvertibleType { - typealias Result = Observer.Element - typealias Parent = ZipCollectionType - typealias SourceElement = Collection.Element.Element - - private let parent: Parent - - private let lock = RecursiveLock() - - // state - private var numberOfValues = 0 - private var values: [Queue] - private var isDone: [Bool] - private var numberOfDone = 0 - private var subscriptions: [SingleAssignmentDisposable] - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - self.values = [Queue](repeating: Queue(capacity: 4), count: parent.count) - self.isDone = [Bool](repeating: false, count: parent.count) - self.subscriptions = [SingleAssignmentDisposable]() - self.subscriptions.reserveCapacity(parent.count) - - for _ in 0 ..< parent.count { - self.subscriptions.append(SingleAssignmentDisposable()) - } - - super.init(observer: observer, cancel: cancel) - } - - func on(_ event: Event, atIndex: Int) { - self.lock.lock(); defer { self.lock.unlock() } - switch event { - case .next(let element): - self.values[atIndex].enqueue(element) - - if self.values[atIndex].count == 1 { - self.numberOfValues += 1 - } - - if self.numberOfValues < self.parent.count { - if self.numberOfDone == self.parent.count - 1 { - self.forwardOn(.completed) - self.dispose() - } - return - } - - do { - var arguments = [SourceElement]() - arguments.reserveCapacity(self.parent.count) - - // recalculate number of values - self.numberOfValues = 0 - - for i in 0 ..< self.values.count { - arguments.append(self.values[i].dequeue()!) - if !self.values[i].isEmpty { - self.numberOfValues += 1 - } - } - - let result = try self.parent.resultSelector(arguments) - self.forwardOn(.next(result)) - } - catch let error { - self.forwardOn(.error(error)) - self.dispose() - } - - case .error(let error): - self.forwardOn(.error(error)) - self.dispose() - case .completed: - if self.isDone[atIndex] { - return - } - - self.isDone[atIndex] = true - self.numberOfDone += 1 - - if self.numberOfDone == self.parent.count { - self.forwardOn(.completed) - self.dispose() - } - else { - self.subscriptions[atIndex].dispose() - } - } - } - - func run() -> Disposable { - var j = 0 - for i in self.parent.sources { - let index = j - let source = i.asObservable() - - let disposable = source.subscribe(AnyObserver { event in - self.on(event, atIndex: index) - }) - self.subscriptions[j].setDisposable(disposable) - j += 1 - } - - if self.parent.sources.isEmpty { - self.forwardOn(.completed) - } - - return Disposables.create(subscriptions) - } -} - -final private class ZipCollectionType: Producer where Collection.Element: ObservableConvertibleType { - typealias ResultSelector = ([Collection.Element.Element]) throws -> Result - - let sources: Collection - let resultSelector: ResultSelector - let count: Int - - init(sources: Collection, resultSelector: @escaping ResultSelector) { - self.sources = sources - self.resultSelector = resultSelector - self.count = self.sources.count - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { - let sink = ZipCollectionTypeSink(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} diff --git a/Pods/RxSwift/RxSwift/Observables/Zip+arity.swift b/Pods/RxSwift/RxSwift/Observables/Zip+arity.swift deleted file mode 100644 index b6d876d1d..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Zip+arity.swift +++ /dev/null @@ -1,934 +0,0 @@ -// This file is autogenerated. Take a look at `Preprocessor` target in RxSwift project -// -// Zip+arity.swift -// RxSwift -// -// Created by Krunoslav Zaher on 5/23/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - - - -// 2 - -extension ObservableType { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index. - - - seealso: [zip operator on reactivex.io](http://reactivex.io/documentation/operators/zip.html) - - - parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func zip - (_ source1: O1, _ source2: O2, resultSelector: @escaping (O1.Element, O2.Element) throws -> Element) - -> Observable { - return Zip2( - source1: source1.asObservable(), source2: source2.asObservable(), - resultSelector: resultSelector - ) - } -} - -extension ObservableType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of tuples whenever all of the observable sequences have produced an element at a corresponding index. - - - seealso: [zip operator on reactivex.io](http://reactivex.io/documentation/operators/zip.html) - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func zip - (_ source1: O1, _ source2: O2) - -> Observable<(O1.Element, O2.Element)> { - return Zip2( - source1: source1.asObservable(), source2: source2.asObservable(), - resultSelector: { ($0, $1) } - ) - } -} - -final class ZipSink2_ : ZipSink { - typealias Result = Observer.Element - typealias Parent = Zip2 - - let parent: Parent - - var values1: Queue = Queue(capacity: 2) - var values2: Queue = Queue(capacity: 2) - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(arity: 2, observer: observer, cancel: cancel) - } - - override func hasElements(_ index: Int) -> Bool { - switch index { - case 0: return !self.values1.isEmpty - case 1: return !self.values2.isEmpty - - default: - rxFatalError("Unhandled case (Function)") - } - } - - func run() -> Disposable { - let subscription1 = SingleAssignmentDisposable() - let subscription2 = SingleAssignmentDisposable() - - let observer1 = ZipObserver(lock: self.lock, parent: self, index: 0, setNextValue: { self.values1.enqueue($0) }, this: subscription1) - let observer2 = ZipObserver(lock: self.lock, parent: self, index: 1, setNextValue: { self.values2.enqueue($0) }, this: subscription2) - - subscription1.setDisposable(self.parent.source1.subscribe(observer1)) - subscription2.setDisposable(self.parent.source2.subscribe(observer2)) - - return Disposables.create([ - subscription1, - subscription2 - ]) - } - - override func getResult() throws -> Result { - try self.parent.resultSelector(self.values1.dequeue()!, self.values2.dequeue()!) - } -} - -final class Zip2 : Producer { - typealias ResultSelector = (E1, E2) throws -> Result - - let source1: Observable - let source2: Observable - - let resultSelector: ResultSelector - - init(source1: Observable, source2: Observable, resultSelector: @escaping ResultSelector) { - self.source1 = source1 - self.source2 = source2 - - self.resultSelector = resultSelector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { - let sink = ZipSink2_(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - - - -// 3 - -extension ObservableType { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index. - - - seealso: [zip operator on reactivex.io](http://reactivex.io/documentation/operators/zip.html) - - - parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, resultSelector: @escaping (O1.Element, O2.Element, O3.Element) throws -> Element) - -> Observable { - return Zip3( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), - resultSelector: resultSelector - ) - } -} - -extension ObservableType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of tuples whenever all of the observable sequences have produced an element at a corresponding index. - - - seealso: [zip operator on reactivex.io](http://reactivex.io/documentation/operators/zip.html) - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3) - -> Observable<(O1.Element, O2.Element, O3.Element)> { - return Zip3( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), - resultSelector: { ($0, $1, $2) } - ) - } -} - -final class ZipSink3_ : ZipSink { - typealias Result = Observer.Element - typealias Parent = Zip3 - - let parent: Parent - - var values1: Queue = Queue(capacity: 2) - var values2: Queue = Queue(capacity: 2) - var values3: Queue = Queue(capacity: 2) - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(arity: 3, observer: observer, cancel: cancel) - } - - override func hasElements(_ index: Int) -> Bool { - switch index { - case 0: return !self.values1.isEmpty - case 1: return !self.values2.isEmpty - case 2: return !self.values3.isEmpty - - default: - rxFatalError("Unhandled case (Function)") - } - } - - func run() -> Disposable { - let subscription1 = SingleAssignmentDisposable() - let subscription2 = SingleAssignmentDisposable() - let subscription3 = SingleAssignmentDisposable() - - let observer1 = ZipObserver(lock: self.lock, parent: self, index: 0, setNextValue: { self.values1.enqueue($0) }, this: subscription1) - let observer2 = ZipObserver(lock: self.lock, parent: self, index: 1, setNextValue: { self.values2.enqueue($0) }, this: subscription2) - let observer3 = ZipObserver(lock: self.lock, parent: self, index: 2, setNextValue: { self.values3.enqueue($0) }, this: subscription3) - - subscription1.setDisposable(self.parent.source1.subscribe(observer1)) - subscription2.setDisposable(self.parent.source2.subscribe(observer2)) - subscription3.setDisposable(self.parent.source3.subscribe(observer3)) - - return Disposables.create([ - subscription1, - subscription2, - subscription3 - ]) - } - - override func getResult() throws -> Result { - try self.parent.resultSelector(self.values1.dequeue()!, self.values2.dequeue()!, self.values3.dequeue()!) - } -} - -final class Zip3 : Producer { - typealias ResultSelector = (E1, E2, E3) throws -> Result - - let source1: Observable - let source2: Observable - let source3: Observable - - let resultSelector: ResultSelector - - init(source1: Observable, source2: Observable, source3: Observable, resultSelector: @escaping ResultSelector) { - self.source1 = source1 - self.source2 = source2 - self.source3 = source3 - - self.resultSelector = resultSelector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { - let sink = ZipSink3_(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - - - -// 4 - -extension ObservableType { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index. - - - seealso: [zip operator on reactivex.io](http://reactivex.io/documentation/operators/zip.html) - - - parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element) throws -> Element) - -> Observable { - return Zip4( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), - resultSelector: resultSelector - ) - } -} - -extension ObservableType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of tuples whenever all of the observable sequences have produced an element at a corresponding index. - - - seealso: [zip operator on reactivex.io](http://reactivex.io/documentation/operators/zip.html) - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4) - -> Observable<(O1.Element, O2.Element, O3.Element, O4.Element)> { - return Zip4( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), - resultSelector: { ($0, $1, $2, $3) } - ) - } -} - -final class ZipSink4_ : ZipSink { - typealias Result = Observer.Element - typealias Parent = Zip4 - - let parent: Parent - - var values1: Queue = Queue(capacity: 2) - var values2: Queue = Queue(capacity: 2) - var values3: Queue = Queue(capacity: 2) - var values4: Queue = Queue(capacity: 2) - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(arity: 4, observer: observer, cancel: cancel) - } - - override func hasElements(_ index: Int) -> Bool { - switch index { - case 0: return !self.values1.isEmpty - case 1: return !self.values2.isEmpty - case 2: return !self.values3.isEmpty - case 3: return !self.values4.isEmpty - - default: - rxFatalError("Unhandled case (Function)") - } - } - - func run() -> Disposable { - let subscription1 = SingleAssignmentDisposable() - let subscription2 = SingleAssignmentDisposable() - let subscription3 = SingleAssignmentDisposable() - let subscription4 = SingleAssignmentDisposable() - - let observer1 = ZipObserver(lock: self.lock, parent: self, index: 0, setNextValue: { self.values1.enqueue($0) }, this: subscription1) - let observer2 = ZipObserver(lock: self.lock, parent: self, index: 1, setNextValue: { self.values2.enqueue($0) }, this: subscription2) - let observer3 = ZipObserver(lock: self.lock, parent: self, index: 2, setNextValue: { self.values3.enqueue($0) }, this: subscription3) - let observer4 = ZipObserver(lock: self.lock, parent: self, index: 3, setNextValue: { self.values4.enqueue($0) }, this: subscription4) - - subscription1.setDisposable(self.parent.source1.subscribe(observer1)) - subscription2.setDisposable(self.parent.source2.subscribe(observer2)) - subscription3.setDisposable(self.parent.source3.subscribe(observer3)) - subscription4.setDisposable(self.parent.source4.subscribe(observer4)) - - return Disposables.create([ - subscription1, - subscription2, - subscription3, - subscription4 - ]) - } - - override func getResult() throws -> Result { - try self.parent.resultSelector(self.values1.dequeue()!, self.values2.dequeue()!, self.values3.dequeue()!, self.values4.dequeue()!) - } -} - -final class Zip4 : Producer { - typealias ResultSelector = (E1, E2, E3, E4) throws -> Result - - let source1: Observable - let source2: Observable - let source3: Observable - let source4: Observable - - let resultSelector: ResultSelector - - init(source1: Observable, source2: Observable, source3: Observable, source4: Observable, resultSelector: @escaping ResultSelector) { - self.source1 = source1 - self.source2 = source2 - self.source3 = source3 - self.source4 = source4 - - self.resultSelector = resultSelector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { - let sink = ZipSink4_(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - - - -// 5 - -extension ObservableType { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index. - - - seealso: [zip operator on reactivex.io](http://reactivex.io/documentation/operators/zip.html) - - - parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element) throws -> Element) - -> Observable { - return Zip5( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), - resultSelector: resultSelector - ) - } -} - -extension ObservableType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of tuples whenever all of the observable sequences have produced an element at a corresponding index. - - - seealso: [zip operator on reactivex.io](http://reactivex.io/documentation/operators/zip.html) - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5) - -> Observable<(O1.Element, O2.Element, O3.Element, O4.Element, O5.Element)> { - return Zip5( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), - resultSelector: { ($0, $1, $2, $3, $4) } - ) - } -} - -final class ZipSink5_ : ZipSink { - typealias Result = Observer.Element - typealias Parent = Zip5 - - let parent: Parent - - var values1: Queue = Queue(capacity: 2) - var values2: Queue = Queue(capacity: 2) - var values3: Queue = Queue(capacity: 2) - var values4: Queue = Queue(capacity: 2) - var values5: Queue = Queue(capacity: 2) - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(arity: 5, observer: observer, cancel: cancel) - } - - override func hasElements(_ index: Int) -> Bool { - switch index { - case 0: return !self.values1.isEmpty - case 1: return !self.values2.isEmpty - case 2: return !self.values3.isEmpty - case 3: return !self.values4.isEmpty - case 4: return !self.values5.isEmpty - - default: - rxFatalError("Unhandled case (Function)") - } - } - - func run() -> Disposable { - let subscription1 = SingleAssignmentDisposable() - let subscription2 = SingleAssignmentDisposable() - let subscription3 = SingleAssignmentDisposable() - let subscription4 = SingleAssignmentDisposable() - let subscription5 = SingleAssignmentDisposable() - - let observer1 = ZipObserver(lock: self.lock, parent: self, index: 0, setNextValue: { self.values1.enqueue($0) }, this: subscription1) - let observer2 = ZipObserver(lock: self.lock, parent: self, index: 1, setNextValue: { self.values2.enqueue($0) }, this: subscription2) - let observer3 = ZipObserver(lock: self.lock, parent: self, index: 2, setNextValue: { self.values3.enqueue($0) }, this: subscription3) - let observer4 = ZipObserver(lock: self.lock, parent: self, index: 3, setNextValue: { self.values4.enqueue($0) }, this: subscription4) - let observer5 = ZipObserver(lock: self.lock, parent: self, index: 4, setNextValue: { self.values5.enqueue($0) }, this: subscription5) - - subscription1.setDisposable(self.parent.source1.subscribe(observer1)) - subscription2.setDisposable(self.parent.source2.subscribe(observer2)) - subscription3.setDisposable(self.parent.source3.subscribe(observer3)) - subscription4.setDisposable(self.parent.source4.subscribe(observer4)) - subscription5.setDisposable(self.parent.source5.subscribe(observer5)) - - return Disposables.create([ - subscription1, - subscription2, - subscription3, - subscription4, - subscription5 - ]) - } - - override func getResult() throws -> Result { - try self.parent.resultSelector(self.values1.dequeue()!, self.values2.dequeue()!, self.values3.dequeue()!, self.values4.dequeue()!, self.values5.dequeue()!) - } -} - -final class Zip5 : Producer { - typealias ResultSelector = (E1, E2, E3, E4, E5) throws -> Result - - let source1: Observable - let source2: Observable - let source3: Observable - let source4: Observable - let source5: Observable - - let resultSelector: ResultSelector - - init(source1: Observable, source2: Observable, source3: Observable, source4: Observable, source5: Observable, resultSelector: @escaping ResultSelector) { - self.source1 = source1 - self.source2 = source2 - self.source3 = source3 - self.source4 = source4 - self.source5 = source5 - - self.resultSelector = resultSelector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { - let sink = ZipSink5_(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - - - -// 6 - -extension ObservableType { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index. - - - seealso: [zip operator on reactivex.io](http://reactivex.io/documentation/operators/zip.html) - - - parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element) throws -> Element) - -> Observable { - return Zip6( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), - resultSelector: resultSelector - ) - } -} - -extension ObservableType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of tuples whenever all of the observable sequences have produced an element at a corresponding index. - - - seealso: [zip operator on reactivex.io](http://reactivex.io/documentation/operators/zip.html) - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6) - -> Observable<(O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element)> { - return Zip6( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), - resultSelector: { ($0, $1, $2, $3, $4, $5) } - ) - } -} - -final class ZipSink6_ : ZipSink { - typealias Result = Observer.Element - typealias Parent = Zip6 - - let parent: Parent - - var values1: Queue = Queue(capacity: 2) - var values2: Queue = Queue(capacity: 2) - var values3: Queue = Queue(capacity: 2) - var values4: Queue = Queue(capacity: 2) - var values5: Queue = Queue(capacity: 2) - var values6: Queue = Queue(capacity: 2) - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(arity: 6, observer: observer, cancel: cancel) - } - - override func hasElements(_ index: Int) -> Bool { - switch index { - case 0: return !self.values1.isEmpty - case 1: return !self.values2.isEmpty - case 2: return !self.values3.isEmpty - case 3: return !self.values4.isEmpty - case 4: return !self.values5.isEmpty - case 5: return !self.values6.isEmpty - - default: - rxFatalError("Unhandled case (Function)") - } - } - - func run() -> Disposable { - let subscription1 = SingleAssignmentDisposable() - let subscription2 = SingleAssignmentDisposable() - let subscription3 = SingleAssignmentDisposable() - let subscription4 = SingleAssignmentDisposable() - let subscription5 = SingleAssignmentDisposable() - let subscription6 = SingleAssignmentDisposable() - - let observer1 = ZipObserver(lock: self.lock, parent: self, index: 0, setNextValue: { self.values1.enqueue($0) }, this: subscription1) - let observer2 = ZipObserver(lock: self.lock, parent: self, index: 1, setNextValue: { self.values2.enqueue($0) }, this: subscription2) - let observer3 = ZipObserver(lock: self.lock, parent: self, index: 2, setNextValue: { self.values3.enqueue($0) }, this: subscription3) - let observer4 = ZipObserver(lock: self.lock, parent: self, index: 3, setNextValue: { self.values4.enqueue($0) }, this: subscription4) - let observer5 = ZipObserver(lock: self.lock, parent: self, index: 4, setNextValue: { self.values5.enqueue($0) }, this: subscription5) - let observer6 = ZipObserver(lock: self.lock, parent: self, index: 5, setNextValue: { self.values6.enqueue($0) }, this: subscription6) - - subscription1.setDisposable(self.parent.source1.subscribe(observer1)) - subscription2.setDisposable(self.parent.source2.subscribe(observer2)) - subscription3.setDisposable(self.parent.source3.subscribe(observer3)) - subscription4.setDisposable(self.parent.source4.subscribe(observer4)) - subscription5.setDisposable(self.parent.source5.subscribe(observer5)) - subscription6.setDisposable(self.parent.source6.subscribe(observer6)) - - return Disposables.create([ - subscription1, - subscription2, - subscription3, - subscription4, - subscription5, - subscription6 - ]) - } - - override func getResult() throws -> Result { - try self.parent.resultSelector(self.values1.dequeue()!, self.values2.dequeue()!, self.values3.dequeue()!, self.values4.dequeue()!, self.values5.dequeue()!, self.values6.dequeue()!) - } -} - -final class Zip6 : Producer { - typealias ResultSelector = (E1, E2, E3, E4, E5, E6) throws -> Result - - let source1: Observable - let source2: Observable - let source3: Observable - let source4: Observable - let source5: Observable - let source6: Observable - - let resultSelector: ResultSelector - - init(source1: Observable, source2: Observable, source3: Observable, source4: Observable, source5: Observable, source6: Observable, resultSelector: @escaping ResultSelector) { - self.source1 = source1 - self.source2 = source2 - self.source3 = source3 - self.source4 = source4 - self.source5 = source5 - self.source6 = source6 - - self.resultSelector = resultSelector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { - let sink = ZipSink6_(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - - - -// 7 - -extension ObservableType { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index. - - - seealso: [zip operator on reactivex.io](http://reactivex.io/documentation/operators/zip.html) - - - parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element) throws -> Element) - -> Observable { - return Zip7( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), source7: source7.asObservable(), - resultSelector: resultSelector - ) - } -} - -extension ObservableType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of tuples whenever all of the observable sequences have produced an element at a corresponding index. - - - seealso: [zip operator on reactivex.io](http://reactivex.io/documentation/operators/zip.html) - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7) - -> Observable<(O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element)> { - return Zip7( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), source7: source7.asObservable(), - resultSelector: { ($0, $1, $2, $3, $4, $5, $6) } - ) - } -} - -final class ZipSink7_ : ZipSink { - typealias Result = Observer.Element - typealias Parent = Zip7 - - let parent: Parent - - var values1: Queue = Queue(capacity: 2) - var values2: Queue = Queue(capacity: 2) - var values3: Queue = Queue(capacity: 2) - var values4: Queue = Queue(capacity: 2) - var values5: Queue = Queue(capacity: 2) - var values6: Queue = Queue(capacity: 2) - var values7: Queue = Queue(capacity: 2) - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(arity: 7, observer: observer, cancel: cancel) - } - - override func hasElements(_ index: Int) -> Bool { - switch index { - case 0: return !self.values1.isEmpty - case 1: return !self.values2.isEmpty - case 2: return !self.values3.isEmpty - case 3: return !self.values4.isEmpty - case 4: return !self.values5.isEmpty - case 5: return !self.values6.isEmpty - case 6: return !self.values7.isEmpty - - default: - rxFatalError("Unhandled case (Function)") - } - } - - func run() -> Disposable { - let subscription1 = SingleAssignmentDisposable() - let subscription2 = SingleAssignmentDisposable() - let subscription3 = SingleAssignmentDisposable() - let subscription4 = SingleAssignmentDisposable() - let subscription5 = SingleAssignmentDisposable() - let subscription6 = SingleAssignmentDisposable() - let subscription7 = SingleAssignmentDisposable() - - let observer1 = ZipObserver(lock: self.lock, parent: self, index: 0, setNextValue: { self.values1.enqueue($0) }, this: subscription1) - let observer2 = ZipObserver(lock: self.lock, parent: self, index: 1, setNextValue: { self.values2.enqueue($0) }, this: subscription2) - let observer3 = ZipObserver(lock: self.lock, parent: self, index: 2, setNextValue: { self.values3.enqueue($0) }, this: subscription3) - let observer4 = ZipObserver(lock: self.lock, parent: self, index: 3, setNextValue: { self.values4.enqueue($0) }, this: subscription4) - let observer5 = ZipObserver(lock: self.lock, parent: self, index: 4, setNextValue: { self.values5.enqueue($0) }, this: subscription5) - let observer6 = ZipObserver(lock: self.lock, parent: self, index: 5, setNextValue: { self.values6.enqueue($0) }, this: subscription6) - let observer7 = ZipObserver(lock: self.lock, parent: self, index: 6, setNextValue: { self.values7.enqueue($0) }, this: subscription7) - - subscription1.setDisposable(self.parent.source1.subscribe(observer1)) - subscription2.setDisposable(self.parent.source2.subscribe(observer2)) - subscription3.setDisposable(self.parent.source3.subscribe(observer3)) - subscription4.setDisposable(self.parent.source4.subscribe(observer4)) - subscription5.setDisposable(self.parent.source5.subscribe(observer5)) - subscription6.setDisposable(self.parent.source6.subscribe(observer6)) - subscription7.setDisposable(self.parent.source7.subscribe(observer7)) - - return Disposables.create([ - subscription1, - subscription2, - subscription3, - subscription4, - subscription5, - subscription6, - subscription7 - ]) - } - - override func getResult() throws -> Result { - try self.parent.resultSelector(self.values1.dequeue()!, self.values2.dequeue()!, self.values3.dequeue()!, self.values4.dequeue()!, self.values5.dequeue()!, self.values6.dequeue()!, self.values7.dequeue()!) - } -} - -final class Zip7 : Producer { - typealias ResultSelector = (E1, E2, E3, E4, E5, E6, E7) throws -> Result - - let source1: Observable - let source2: Observable - let source3: Observable - let source4: Observable - let source5: Observable - let source6: Observable - let source7: Observable - - let resultSelector: ResultSelector - - init(source1: Observable, source2: Observable, source3: Observable, source4: Observable, source5: Observable, source6: Observable, source7: Observable, resultSelector: @escaping ResultSelector) { - self.source1 = source1 - self.source2 = source2 - self.source3 = source3 - self.source4 = source4 - self.source5 = source5 - self.source6 = source6 - self.source7 = source7 - - self.resultSelector = resultSelector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { - let sink = ZipSink7_(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - - - -// 8 - -extension ObservableType { - /** - Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index. - - - seealso: [zip operator on reactivex.io](http://reactivex.io/documentation/operators/zip.html) - - - parameter resultSelector: Function to invoke for each series of elements at corresponding indexes in the sources. - - returns: An observable sequence containing the result of combining elements of the sources using the specified result selector function. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, _ source8: O8, resultSelector: @escaping (O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element, O8.Element) throws -> Element) - -> Observable { - return Zip8( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), source7: source7.asObservable(), source8: source8.asObservable(), - resultSelector: resultSelector - ) - } -} - -extension ObservableType where Element == Any { - /** - Merges the specified observable sequences into one observable sequence of tuples whenever all of the observable sequences have produced an element at a corresponding index. - - - seealso: [zip operator on reactivex.io](http://reactivex.io/documentation/operators/zip.html) - - - returns: An observable sequence containing the result of combining elements of the sources. - */ - public static func zip - (_ source1: O1, _ source2: O2, _ source3: O3, _ source4: O4, _ source5: O5, _ source6: O6, _ source7: O7, _ source8: O8) - -> Observable<(O1.Element, O2.Element, O3.Element, O4.Element, O5.Element, O6.Element, O7.Element, O8.Element)> { - return Zip8( - source1: source1.asObservable(), source2: source2.asObservable(), source3: source3.asObservable(), source4: source4.asObservable(), source5: source5.asObservable(), source6: source6.asObservable(), source7: source7.asObservable(), source8: source8.asObservable(), - resultSelector: { ($0, $1, $2, $3, $4, $5, $6, $7) } - ) - } -} - -final class ZipSink8_ : ZipSink { - typealias Result = Observer.Element - typealias Parent = Zip8 - - let parent: Parent - - var values1: Queue = Queue(capacity: 2) - var values2: Queue = Queue(capacity: 2) - var values3: Queue = Queue(capacity: 2) - var values4: Queue = Queue(capacity: 2) - var values5: Queue = Queue(capacity: 2) - var values6: Queue = Queue(capacity: 2) - var values7: Queue = Queue(capacity: 2) - var values8: Queue = Queue(capacity: 2) - - init(parent: Parent, observer: Observer, cancel: Cancelable) { - self.parent = parent - super.init(arity: 8, observer: observer, cancel: cancel) - } - - override func hasElements(_ index: Int) -> Bool { - switch index { - case 0: return !self.values1.isEmpty - case 1: return !self.values2.isEmpty - case 2: return !self.values3.isEmpty - case 3: return !self.values4.isEmpty - case 4: return !self.values5.isEmpty - case 5: return !self.values6.isEmpty - case 6: return !self.values7.isEmpty - case 7: return !self.values8.isEmpty - - default: - rxFatalError("Unhandled case (Function)") - } - } - - func run() -> Disposable { - let subscription1 = SingleAssignmentDisposable() - let subscription2 = SingleAssignmentDisposable() - let subscription3 = SingleAssignmentDisposable() - let subscription4 = SingleAssignmentDisposable() - let subscription5 = SingleAssignmentDisposable() - let subscription6 = SingleAssignmentDisposable() - let subscription7 = SingleAssignmentDisposable() - let subscription8 = SingleAssignmentDisposable() - - let observer1 = ZipObserver(lock: self.lock, parent: self, index: 0, setNextValue: { self.values1.enqueue($0) }, this: subscription1) - let observer2 = ZipObserver(lock: self.lock, parent: self, index: 1, setNextValue: { self.values2.enqueue($0) }, this: subscription2) - let observer3 = ZipObserver(lock: self.lock, parent: self, index: 2, setNextValue: { self.values3.enqueue($0) }, this: subscription3) - let observer4 = ZipObserver(lock: self.lock, parent: self, index: 3, setNextValue: { self.values4.enqueue($0) }, this: subscription4) - let observer5 = ZipObserver(lock: self.lock, parent: self, index: 4, setNextValue: { self.values5.enqueue($0) }, this: subscription5) - let observer6 = ZipObserver(lock: self.lock, parent: self, index: 5, setNextValue: { self.values6.enqueue($0) }, this: subscription6) - let observer7 = ZipObserver(lock: self.lock, parent: self, index: 6, setNextValue: { self.values7.enqueue($0) }, this: subscription7) - let observer8 = ZipObserver(lock: self.lock, parent: self, index: 7, setNextValue: { self.values8.enqueue($0) }, this: subscription8) - - subscription1.setDisposable(self.parent.source1.subscribe(observer1)) - subscription2.setDisposable(self.parent.source2.subscribe(observer2)) - subscription3.setDisposable(self.parent.source3.subscribe(observer3)) - subscription4.setDisposable(self.parent.source4.subscribe(observer4)) - subscription5.setDisposable(self.parent.source5.subscribe(observer5)) - subscription6.setDisposable(self.parent.source6.subscribe(observer6)) - subscription7.setDisposable(self.parent.source7.subscribe(observer7)) - subscription8.setDisposable(self.parent.source8.subscribe(observer8)) - - return Disposables.create([ - subscription1, - subscription2, - subscription3, - subscription4, - subscription5, - subscription6, - subscription7, - subscription8 - ]) - } - - override func getResult() throws -> Result { - try self.parent.resultSelector(self.values1.dequeue()!, self.values2.dequeue()!, self.values3.dequeue()!, self.values4.dequeue()!, self.values5.dequeue()!, self.values6.dequeue()!, self.values7.dequeue()!, self.values8.dequeue()!) - } -} - -final class Zip8 : Producer { - typealias ResultSelector = (E1, E2, E3, E4, E5, E6, E7, E8) throws -> Result - - let source1: Observable - let source2: Observable - let source3: Observable - let source4: Observable - let source5: Observable - let source6: Observable - let source7: Observable - let source8: Observable - - let resultSelector: ResultSelector - - init(source1: Observable, source2: Observable, source3: Observable, source4: Observable, source5: Observable, source6: Observable, source7: Observable, source8: Observable, resultSelector: @escaping ResultSelector) { - self.source1 = source1 - self.source2 = source2 - self.source3 = source3 - self.source4 = source4 - self.source5 = source5 - self.source6 = source6 - self.source7 = source7 - self.source8 = source8 - - self.resultSelector = resultSelector - } - - override func run(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Result { - let sink = ZipSink8_(parent: self, observer: observer, cancel: cancel) - let subscription = sink.run() - return (sink: sink, subscription: subscription) - } -} - - diff --git a/Pods/RxSwift/RxSwift/Observables/Zip.swift b/Pods/RxSwift/RxSwift/Observables/Zip.swift deleted file mode 100644 index 328a40ef7..000000000 --- a/Pods/RxSwift/RxSwift/Observables/Zip.swift +++ /dev/null @@ -1,135 +0,0 @@ -// -// Zip.swift -// RxSwift -// -// Created by Krunoslav Zaher on 5/23/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -protocol ZipSinkProtocol: AnyObject { - func next(_ index: Int) - func fail(_ error: Swift.Error) - func done(_ index: Int) -} - -class ZipSink : Sink, ZipSinkProtocol { - typealias Element = Observer.Element - - let arity: Int - - let lock = RecursiveLock() - - // state - private var isDone: [Bool] - - init(arity: Int, observer: Observer, cancel: Cancelable) { - self.isDone = [Bool](repeating: false, count: arity) - self.arity = arity - - super.init(observer: observer, cancel: cancel) - } - - func getResult() throws -> Element { - rxAbstractMethod() - } - - func hasElements(_ index: Int) -> Bool { - rxAbstractMethod() - } - - func next(_ index: Int) { - var hasValueAll = true - - for i in 0 ..< self.arity { - if !self.hasElements(i) { - hasValueAll = false - break - } - } - - if hasValueAll { - do { - let result = try self.getResult() - self.forwardOn(.next(result)) - } - catch let e { - self.forwardOn(.error(e)) - self.dispose() - } - } - } - - func fail(_ error: Swift.Error) { - self.forwardOn(.error(error)) - self.dispose() - } - - func done(_ index: Int) { - self.isDone[index] = true - - var allDone = true - - for done in self.isDone where !done { - allDone = false - break - } - - if allDone { - self.forwardOn(.completed) - self.dispose() - } - } -} - -final class ZipObserver - : ObserverType - , LockOwnerType - , SynchronizedOnType { - typealias ValueSetter = (Element) -> Void - - private var parent: ZipSinkProtocol? - - let lock: RecursiveLock - - // state - private let index: Int - private let this: Disposable - private let setNextValue: ValueSetter - - init(lock: RecursiveLock, parent: ZipSinkProtocol, index: Int, setNextValue: @escaping ValueSetter, this: Disposable) { - self.lock = lock - self.parent = parent - self.index = index - self.this = this - self.setNextValue = setNextValue - } - - func on(_ event: Event) { - self.synchronizedOn(event) - } - - func synchronized_on(_ event: Event) { - if self.parent != nil { - switch event { - case .next: - break - case .error: - self.this.dispose() - case .completed: - self.this.dispose() - } - } - - if let parent = self.parent { - switch event { - case .next(let value): - self.setNextValue(value) - parent.next(self.index) - case .error(let error): - parent.fail(error) - case .completed: - parent.done(self.index) - } - } - } -} diff --git a/Pods/RxSwift/RxSwift/ObserverType.swift b/Pods/RxSwift/RxSwift/ObserverType.swift deleted file mode 100644 index b7a66480e..000000000 --- a/Pods/RxSwift/RxSwift/ObserverType.swift +++ /dev/null @@ -1,40 +0,0 @@ -// -// ObserverType.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/8/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// Supports push-style iteration over an observable sequence. -public protocol ObserverType { - /// The type of elements in sequence that observer can observe. - associatedtype Element - - /// Notify observer about sequence event. - /// - /// - parameter event: Event that occurred. - func on(_ event: Event) -} - -/// Convenience API extensions to provide alternate next, error, completed events -extension ObserverType { - - /// Convenience method equivalent to `on(.next(element: Element))` - /// - /// - parameter element: Next element to send to observer(s) - public func onNext(_ element: Element) { - self.on(.next(element)) - } - - /// Convenience method equivalent to `on(.completed)` - public func onCompleted() { - self.on(.completed) - } - - /// Convenience method equivalent to `on(.error(Swift.Error))` - /// - parameter error: Swift.Error to send to observer(s) - public func onError(_ error: Swift.Error) { - self.on(.error(error)) - } -} diff --git a/Pods/RxSwift/RxSwift/Observers/AnonymousObserver.swift b/Pods/RxSwift/RxSwift/Observers/AnonymousObserver.swift deleted file mode 100644 index cbb42dc82..000000000 --- a/Pods/RxSwift/RxSwift/Observers/AnonymousObserver.swift +++ /dev/null @@ -1,30 +0,0 @@ -// -// AnonymousObserver.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/8/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -final class AnonymousObserver: ObserverBase { - typealias EventHandler = (Event) -> Void - - private let eventHandler : EventHandler - - init(_ eventHandler: @escaping EventHandler) { -#if TRACE_RESOURCES - _ = Resources.incrementTotal() -#endif - self.eventHandler = eventHandler - } - - override func onCore(_ event: Event) { - self.eventHandler(event) - } - -#if TRACE_RESOURCES - deinit { - _ = Resources.decrementTotal() - } -#endif -} diff --git a/Pods/RxSwift/RxSwift/Observers/ObserverBase.swift b/Pods/RxSwift/RxSwift/Observers/ObserverBase.swift deleted file mode 100644 index 48e09868b..000000000 --- a/Pods/RxSwift/RxSwift/Observers/ObserverBase.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// ObserverBase.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/15/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -class ObserverBase : Disposable, ObserverType { - private let isStopped = AtomicInt(0) - - func on(_ event: Event) { - switch event { - case .next: - if load(self.isStopped) == 0 { - self.onCore(event) - } - case .error, .completed: - if fetchOr(self.isStopped, 1) == 0 { - self.onCore(event) - } - } - } - - func onCore(_ event: Event) { - rxAbstractMethod() - } - - func dispose() { - fetchOr(self.isStopped, 1) - } -} diff --git a/Pods/RxSwift/RxSwift/Observers/TailRecursiveSink.swift b/Pods/RxSwift/RxSwift/Observers/TailRecursiveSink.swift deleted file mode 100644 index fd527001d..000000000 --- a/Pods/RxSwift/RxSwift/Observers/TailRecursiveSink.swift +++ /dev/null @@ -1,151 +0,0 @@ -// -// TailRecursiveSink.swift -// RxSwift -// -// Created by Krunoslav Zaher on 3/21/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -enum TailRecursiveSinkCommand { - case moveNext - case dispose -} - -#if DEBUG || TRACE_RESOURCES - public var maxTailRecursiveSinkStackSize = 0 -#endif - -/// This class is usually used with `Generator` version of the operators. -class TailRecursiveSink - : Sink - , InvocableWithValueType where Sequence.Element: ObservableConvertibleType, Sequence.Element.Element == Observer.Element { - typealias Value = TailRecursiveSinkCommand - typealias Element = Observer.Element - typealias SequenceGenerator = (generator: Sequence.Iterator, remaining: IntMax?) - - var generators: [SequenceGenerator] = [] - var disposed = false - var subscription = SerialDisposable() - - // this is thread safe object - var gate = AsyncLock>>() - - override init(observer: Observer, cancel: Cancelable) { - super.init(observer: observer, cancel: cancel) - } - - func run(_ sources: SequenceGenerator) -> Disposable { - self.generators.append(sources) - - self.schedule(.moveNext) - - return self.subscription - } - - func invoke(_ command: TailRecursiveSinkCommand) { - switch command { - case .dispose: - self.disposeCommand() - case .moveNext: - self.moveNextCommand() - } - } - - // simple implementation for now - func schedule(_ command: TailRecursiveSinkCommand) { - self.gate.invoke(InvocableScheduledItem(invocable: self, state: command)) - } - - func done() { - self.forwardOn(.completed) - self.dispose() - } - - func extract(_ observable: Observable) -> SequenceGenerator? { - rxAbstractMethod() - } - - // should be done on gate locked - - private func moveNextCommand() { - var next: Observable? - - repeat { - guard let (g, left) = self.generators.last else { - break - } - - if self.isDisposed { - return - } - - self.generators.removeLast() - - var e = g - - guard let nextCandidate = e.next()?.asObservable() else { - continue - } - - // `left` is a hint of how many elements are left in generator. - // In case this is the last element, then there is no need to push - // that generator on stack. - // - // This is an optimization used to make sure in tail recursive case - // there is no memory leak in case this operator is used to generate non terminating - // sequence. - - if let knownOriginalLeft = left { - // `- 1` because generator.next() has just been called - if knownOriginalLeft - 1 >= 1 { - self.generators.append((e, knownOriginalLeft - 1)) - } - } - else { - self.generators.append((e, nil)) - } - - let nextGenerator = self.extract(nextCandidate) - - if let nextGenerator = nextGenerator { - self.generators.append(nextGenerator) - #if DEBUG || TRACE_RESOURCES - if maxTailRecursiveSinkStackSize < self.generators.count { - maxTailRecursiveSinkStackSize = self.generators.count - } - #endif - } - else { - next = nextCandidate - } - } while next == nil - - guard let existingNext = next else { - self.done() - return - } - - let disposable = SingleAssignmentDisposable() - self.subscription.disposable = disposable - disposable.setDisposable(self.subscribeToNext(existingNext)) - } - - func subscribeToNext(_ source: Observable) -> Disposable { - rxAbstractMethod() - } - - func disposeCommand() { - self.disposed = true - self.generators.removeAll(keepingCapacity: false) - } - - override func dispose() { - super.dispose() - - self.subscription.dispose() - self.gate.dispose() - - self.schedule(.dispose) - } -} - diff --git a/Pods/RxSwift/RxSwift/Reactive.swift b/Pods/RxSwift/RxSwift/Reactive.swift deleted file mode 100644 index 1bf390dc5..000000000 --- a/Pods/RxSwift/RxSwift/Reactive.swift +++ /dev/null @@ -1,80 +0,0 @@ -// -// Reactive.swift -// RxSwift -// -// Created by Yury Korolev on 5/2/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -/** - Use `Reactive` proxy as customization point for constrained protocol extensions. - - General pattern would be: - - // 1. Extend Reactive protocol with constrain on Base - // Read as: Reactive Extension where Base is a SomeType - extension Reactive where Base: SomeType { - // 2. Put any specific reactive extension for SomeType here - } - - With this approach we can have more specialized methods and properties using - `Base` and not just specialized on common base type. - - `Binder`s are also automatically synthesized using `@dynamicMemberLookup` for writable reference properties of the reactive base. - */ - -@dynamicMemberLookup -public struct Reactive { - /// Base object to extend. - public let base: Base - - /// Creates extensions with base object. - /// - /// - parameter base: Base object. - public init(_ base: Base) { - self.base = base - } - - /// Automatically synthesized binder for a key path between the reactive - /// base and one of its properties - public subscript(dynamicMember keyPath: ReferenceWritableKeyPath) -> Binder where Base: AnyObject { - Binder(self.base) { base, value in - base[keyPath: keyPath] = value - } - } -} - -/// A type that has reactive extensions. -public protocol ReactiveCompatible { - /// Extended type - associatedtype ReactiveBase - - /// Reactive extensions. - static var rx: Reactive.Type { get set } - - /// Reactive extensions. - var rx: Reactive { get set } -} - -extension ReactiveCompatible { - /// Reactive extensions. - public static var rx: Reactive.Type { - get { Reactive.self } - // this enables using Reactive to "mutate" base type - // swiftlint:disable:next unused_setter_value - set { } - } - - /// Reactive extensions. - public var rx: Reactive { - get { Reactive(self) } - // this enables using Reactive to "mutate" base object - // swiftlint:disable:next unused_setter_value - set { } - } -} - -import Foundation - -/// Extend NSObject with `rx` proxy. -extension NSObject: ReactiveCompatible { } diff --git a/Pods/RxSwift/RxSwift/Rx.swift b/Pods/RxSwift/RxSwift/Rx.swift deleted file mode 100644 index bcdd27947..000000000 --- a/Pods/RxSwift/RxSwift/Rx.swift +++ /dev/null @@ -1,142 +0,0 @@ -// -// Rx.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/14/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if TRACE_RESOURCES - private let resourceCount = AtomicInt(0) - - /// Resource utilization information - public struct Resources { - /// Counts internal Rx resource allocations (Observables, Observers, Disposables, etc.). This provides a simple way to detect leaks during development. - public static var total: Int32 { - load(resourceCount) - } - - /// Increments `Resources.total` resource count. - /// - /// - returns: New resource count - public static func incrementTotal() -> Int32 { - increment(resourceCount) - } - - /// Decrements `Resources.total` resource count - /// - /// - returns: New resource count - public static func decrementTotal() -> Int32 { - decrement(resourceCount) - } - } -#endif - -/// Swift does not implement abstract methods. This method is used as a runtime check to ensure that methods which intended to be abstract (i.e., they should be implemented in subclasses) are not called directly on the superclass. -func rxAbstractMethod(file: StaticString = #file, line: UInt = #line) -> Swift.Never { - rxFatalError("Abstract method", file: file, line: line) -} - -func rxFatalError(_ lastMessage: @autoclosure () -> String, file: StaticString = #file, line: UInt = #line) -> Swift.Never { - fatalError(lastMessage(), file: file, line: line) -} - -func rxFatalErrorInDebug(_ lastMessage: @autoclosure () -> String, file: StaticString = #file, line: UInt = #line) { - #if DEBUG - fatalError(lastMessage(), file: file, line: line) - #else - print("\(file):\(line): \(lastMessage())") - #endif -} - -func incrementChecked(_ i: inout Int) throws -> Int { - if i == Int.max { - throw RxError.overflow - } - defer { i += 1 } - return i -} - -func decrementChecked(_ i: inout Int) throws -> Int { - if i == Int.min { - throw RxError.overflow - } - defer { i -= 1 } - return i -} - -#if DEBUG - import Foundation - final class SynchronizationTracker { - private let lock = RecursiveLock() - - public enum SynchronizationErrorMessages: String { - case variable = "Two different threads are trying to assign the same `Variable.value` unsynchronized.\n This is undefined behavior because the end result (variable value) is nondeterministic and depends on the \n operating system thread scheduler. This will cause random behavior of your program.\n" - case `default` = "Two different unsynchronized threads are trying to send some event simultaneously.\n This is undefined behavior because the ordering of the effects caused by these events is nondeterministic and depends on the \n operating system thread scheduler. This will result in a random behavior of your program.\n" - } - - private var threads = [UnsafeMutableRawPointer: Int]() - - private func synchronizationError(_ message: String) { - #if FATAL_SYNCHRONIZATION - rxFatalError(message) - #else - print(message) - #endif - } - - func register(synchronizationErrorMessage: SynchronizationErrorMessages) { - self.lock.lock(); defer { self.lock.unlock() } - let pointer = Unmanaged.passUnretained(Thread.current).toOpaque() - let count = (self.threads[pointer] ?? 0) + 1 - - if count > 1 { - self.synchronizationError( - "⚠️ Reentrancy anomaly was detected.\n" + - " > Debugging: To debug this issue you can set a breakpoint in \(#file):\(#line) and observe the call stack.\n" + - " > Problem: This behavior is breaking the observable sequence grammar. `next (error | completed)?`\n" + - " This behavior breaks the grammar because there is overlapping between sequence events.\n" + - " Observable sequence is trying to send an event before sending of previous event has finished.\n" + - " > Interpretation: This could mean that there is some kind of unexpected cyclic dependency in your code,\n" + - " or that the system is not behaving in the expected way.\n" + - " > Remedy: If this is the expected behavior this message can be suppressed by adding `.observe(on:MainScheduler.asyncInstance)`\n" + - " or by enqueuing sequence events in some other way.\n" - ) - } - - self.threads[pointer] = count - - if self.threads.count > 1 { - self.synchronizationError( - "⚠️ Synchronization anomaly was detected.\n" + - " > Debugging: To debug this issue you can set a breakpoint in \(#file):\(#line) and observe the call stack.\n" + - " > Problem: This behavior is breaking the observable sequence grammar. `next (error | completed)?`\n" + - " This behavior breaks the grammar because there is overlapping between sequence events.\n" + - " Observable sequence is trying to send an event before sending of previous event has finished.\n" + - " > Interpretation: " + synchronizationErrorMessage.rawValue + - " > Remedy: If this is the expected behavior this message can be suppressed by adding `.observe(on:MainScheduler.asyncInstance)`\n" + - " or by synchronizing sequence events in some other way.\n" - ) - } - } - - func unregister() { - self.lock.performLocked { - let pointer = Unmanaged.passUnretained(Thread.current).toOpaque() - self.threads[pointer] = (self.threads[pointer] ?? 1) - 1 - if self.threads[pointer] == 0 { - self.threads[pointer] = nil - } - } - } - } - -#endif - -/// RxSwift global hooks -public enum Hooks { - - // Should capture call stack - public static var recordCallStackOnError: Bool = false - -} diff --git a/Pods/RxSwift/RxSwift/RxMutableBox.swift b/Pods/RxSwift/RxSwift/RxMutableBox.swift deleted file mode 100644 index 73476c367..000000000 --- a/Pods/RxSwift/RxSwift/RxMutableBox.swift +++ /dev/null @@ -1,53 +0,0 @@ -// -// RxMutableBox.swift -// RxSwift -// -// Created by Krunoslav Zaher on 5/22/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -#if os(Linux) -/// As Swift 5 was released, A patch to `Thread` for Linux -/// changed `threadDictionary` to a `NSMutableDictionary` instead of -/// a `Dictionary`: https://github.com/apple/swift-corelibs-foundation/pull/1762/files -/// -/// This means that on Linux specifically, `RxMutableBox` must be a `NSObject` -/// or it won't be possible to store it in `Thread.threadDictionary`. -/// -/// For more information, read the discussion at: -/// https://github.com/ReactiveX/RxSwift/issues/1911#issuecomment-479723298 -import Foundation - -/// Creates mutable reference wrapper for any type. -final class RxMutableBox: NSObject { - /// Wrapped value - var value: T - - /// Creates reference wrapper for `value`. - /// - /// - parameter value: Value to wrap. - init (_ value: T) { - self.value = value - } -} -#else -/// Creates mutable reference wrapper for any type. -final class RxMutableBox: CustomDebugStringConvertible { - /// Wrapped value - var value: T - - /// Creates reference wrapper for `value`. - /// - /// - parameter value: Value to wrap. - init (_ value: T) { - self.value = value - } -} - -extension RxMutableBox { - /// - returns: Box description. - var debugDescription: String { - "MutatingBox(\(self.value))" - } -} -#endif diff --git a/Pods/RxSwift/RxSwift/SchedulerType.swift b/Pods/RxSwift/RxSwift/SchedulerType.swift deleted file mode 100644 index 6c8fe4a38..000000000 --- a/Pods/RxSwift/RxSwift/SchedulerType.swift +++ /dev/null @@ -1,71 +0,0 @@ -// -// SchedulerType.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/8/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import Dispatch -import Foundation - -// Type that represents time interval in the context of RxSwift. -public typealias RxTimeInterval = DispatchTimeInterval - -/// Type that represents absolute time in the context of RxSwift. -public typealias RxTime = Date - -/// Represents an object that schedules units of work. -public protocol SchedulerType: ImmediateSchedulerType { - - /// - returns: Current time. - var now : RxTime { - get - } - - /** - Schedules an action to be executed. - - - parameter state: State passed to the action to be executed. - - parameter dueTime: Relative time after which to execute the action. - - parameter action: Action to be executed. - - returns: The disposable object used to cancel the scheduled action (best effort). - */ - func scheduleRelative(_ state: StateType, dueTime: RxTimeInterval, action: @escaping (StateType) -> Disposable) -> Disposable - - /** - Schedules a periodic piece of work. - - - parameter state: State passed to the action to be executed. - - parameter startAfter: Period after which initial work should be run. - - parameter period: Period for running the work periodically. - - parameter action: Action to be executed. - - returns: The disposable object used to cancel the scheduled action (best effort). - */ - func schedulePeriodic(_ state: StateType, startAfter: RxTimeInterval, period: RxTimeInterval, action: @escaping (StateType) -> StateType) -> Disposable -} - -extension SchedulerType { - - /** - Periodic task will be emulated using recursive scheduling. - - - parameter state: Initial state passed to the action upon the first iteration. - - parameter startAfter: Period after which initial work should be run. - - parameter period: Period for running the work periodically. - - returns: The disposable object used to cancel the scheduled recurring action (best effort). - */ - public func schedulePeriodic(_ state: StateType, startAfter: RxTimeInterval, period: RxTimeInterval, action: @escaping (StateType) -> StateType) -> Disposable { - let schedule = SchedulePeriodicRecursive(scheduler: self, startAfter: startAfter, period: period, action: action, state: state) - - return schedule.start() - } - - func scheduleRecursive(_ state: State, dueTime: RxTimeInterval, action: @escaping (State, AnyRecursiveScheduler) -> Void) -> Disposable { - let scheduler = AnyRecursiveScheduler(scheduler: self, action: action) - - scheduler.schedule(state, dueTime: dueTime) - - return Disposables.create(with: scheduler.dispose) - } -} diff --git a/Pods/RxSwift/RxSwift/Schedulers/ConcurrentDispatchQueueScheduler.swift b/Pods/RxSwift/RxSwift/Schedulers/ConcurrentDispatchQueueScheduler.swift deleted file mode 100644 index 02c47c917..000000000 --- a/Pods/RxSwift/RxSwift/Schedulers/ConcurrentDispatchQueueScheduler.swift +++ /dev/null @@ -1,82 +0,0 @@ -// -// ConcurrentDispatchQueueScheduler.swift -// RxSwift -// -// Created by Krunoslav Zaher on 7/5/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import Dispatch -import Foundation - -/// Abstracts the work that needs to be performed on a specific `dispatch_queue_t`. You can also pass a serial dispatch queue, it shouldn't cause any problems. -/// -/// This scheduler is suitable when some work needs to be performed in background. -public class ConcurrentDispatchQueueScheduler: SchedulerType { - public typealias TimeInterval = Foundation.TimeInterval - public typealias Time = Date - - public var now : Date { - Date() - } - - let configuration: DispatchQueueConfiguration - - /// Constructs new `ConcurrentDispatchQueueScheduler` that wraps `queue`. - /// - /// - parameter queue: Target dispatch queue. - /// - parameter leeway: The amount of time, in nanoseconds, that the system will defer the timer. - public init(queue: DispatchQueue, leeway: DispatchTimeInterval = DispatchTimeInterval.nanoseconds(0)) { - self.configuration = DispatchQueueConfiguration(queue: queue, leeway: leeway) - } - - /// Convenience init for scheduler that wraps one of the global concurrent dispatch queues. - /// - /// - parameter qos: Target global dispatch queue, by quality of service class. - /// - parameter leeway: The amount of time, in nanoseconds, that the system will defer the timer. - public convenience init(qos: DispatchQoS, leeway: DispatchTimeInterval = DispatchTimeInterval.nanoseconds(0)) { - self.init(queue: DispatchQueue( - label: "rxswift.queue.\(qos)", - qos: qos, - attributes: [DispatchQueue.Attributes.concurrent], - target: nil), - leeway: leeway - ) - } - - /** - Schedules an action to be executed immediately. - - - parameter state: State passed to the action to be executed. - - parameter action: Action to be executed. - - returns: The disposable object used to cancel the scheduled action (best effort). - */ - public final func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable { - self.configuration.schedule(state, action: action) - } - - /** - Schedules an action to be executed. - - - parameter state: State passed to the action to be executed. - - parameter dueTime: Relative time after which to execute the action. - - parameter action: Action to be executed. - - returns: The disposable object used to cancel the scheduled action (best effort). - */ - public final func scheduleRelative(_ state: StateType, dueTime: RxTimeInterval, action: @escaping (StateType) -> Disposable) -> Disposable { - self.configuration.scheduleRelative(state, dueTime: dueTime, action: action) - } - - /** - Schedules a periodic piece of work. - - - parameter state: State passed to the action to be executed. - - parameter startAfter: Period after which initial work should be run. - - parameter period: Period for running the work periodically. - - parameter action: Action to be executed. - - returns: The disposable object used to cancel the scheduled action (best effort). - */ - public func schedulePeriodic(_ state: StateType, startAfter: RxTimeInterval, period: RxTimeInterval, action: @escaping (StateType) -> StateType) -> Disposable { - self.configuration.schedulePeriodic(state, startAfter: startAfter, period: period, action: action) - } -} diff --git a/Pods/RxSwift/RxSwift/Schedulers/ConcurrentMainScheduler.swift b/Pods/RxSwift/RxSwift/Schedulers/ConcurrentMainScheduler.swift deleted file mode 100644 index c438d7d4d..000000000 --- a/Pods/RxSwift/RxSwift/Schedulers/ConcurrentMainScheduler.swift +++ /dev/null @@ -1,87 +0,0 @@ -// -// ConcurrentMainScheduler.swift -// RxSwift -// -// Created by Krunoslav Zaher on 10/17/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import Dispatch -import Foundation - -/** -Abstracts work that needs to be performed on `MainThread`. In case `schedule` methods are called from main thread, it will perform action immediately without scheduling. - -This scheduler is optimized for `subscribeOn` operator. If you want to observe observable sequence elements on main thread using `observeOn` operator, -`MainScheduler` is more suitable for that purpose. -*/ -public final class ConcurrentMainScheduler : SchedulerType { - public typealias TimeInterval = Foundation.TimeInterval - public typealias Time = Date - - private let mainScheduler: MainScheduler - private let mainQueue: DispatchQueue - - /// - returns: Current time. - public var now: Date { - self.mainScheduler.now as Date - } - - private init(mainScheduler: MainScheduler) { - self.mainQueue = DispatchQueue.main - self.mainScheduler = mainScheduler - } - - /// Singleton instance of `ConcurrentMainScheduler` - public static let instance = ConcurrentMainScheduler(mainScheduler: MainScheduler.instance) - - /** - Schedules an action to be executed immediately. - - - parameter state: State passed to the action to be executed. - - parameter action: Action to be executed. - - returns: The disposable object used to cancel the scheduled action (best effort). - */ - public func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable { - if DispatchQueue.isMain { - return action(state) - } - - let cancel = SingleAssignmentDisposable() - - self.mainQueue.async { - if cancel.isDisposed { - return - } - - cancel.setDisposable(action(state)) - } - - return cancel - } - - /** - Schedules an action to be executed. - - - parameter state: State passed to the action to be executed. - - parameter dueTime: Relative time after which to execute the action. - - parameter action: Action to be executed. - - returns: The disposable object used to cancel the scheduled action (best effort). - */ - public final func scheduleRelative(_ state: StateType, dueTime: RxTimeInterval, action: @escaping (StateType) -> Disposable) -> Disposable { - self.mainScheduler.scheduleRelative(state, dueTime: dueTime, action: action) - } - - /** - Schedules a periodic piece of work. - - - parameter state: State passed to the action to be executed. - - parameter startAfter: Period after which initial work should be run. - - parameter period: Period for running the work periodically. - - parameter action: Action to be executed. - - returns: The disposable object used to cancel the scheduled action (best effort). - */ - public func schedulePeriodic(_ state: StateType, startAfter: RxTimeInterval, period: RxTimeInterval, action: @escaping (StateType) -> StateType) -> Disposable { - self.mainScheduler.schedulePeriodic(state, startAfter: startAfter, period: period, action: action) - } -} diff --git a/Pods/RxSwift/RxSwift/Schedulers/CurrentThreadScheduler.swift b/Pods/RxSwift/RxSwift/Schedulers/CurrentThreadScheduler.swift deleted file mode 100644 index 16a7dd328..000000000 --- a/Pods/RxSwift/RxSwift/Schedulers/CurrentThreadScheduler.swift +++ /dev/null @@ -1,131 +0,0 @@ -// -// CurrentThreadScheduler.swift -// RxSwift -// -// Created by Krunoslav Zaher on 8/30/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import Dispatch -import Foundation - -#if os(Linux) - fileprivate enum CurrentThreadSchedulerQueueKey { - fileprivate static let instance = "RxSwift.CurrentThreadScheduler.Queue" - } -#else - private class CurrentThreadSchedulerQueueKey: NSObject, NSCopying { - static let instance = CurrentThreadSchedulerQueueKey() - private override init() { - super.init() - } - - override var hash: Int { - return 0 - } - - public func copy(with zone: NSZone? = nil) -> Any { - return self - } - } -#endif - -/// Represents an object that schedules units of work on the current thread. -/// -/// This is the default scheduler for operators that generate elements. -/// -/// This scheduler is also sometimes called `trampoline scheduler`. -public class CurrentThreadScheduler : ImmediateSchedulerType { - typealias ScheduleQueue = RxMutableBox> - - /// The singleton instance of the current thread scheduler. - public static let instance = CurrentThreadScheduler() - - private static var isScheduleRequiredKey: pthread_key_t = { () -> pthread_key_t in - let key = UnsafeMutablePointer.allocate(capacity: 1) - defer { key.deallocate() } - - guard pthread_key_create(key, nil) == 0 else { - rxFatalError("isScheduleRequired key creation failed") - } - - return key.pointee - }() - - private static var scheduleInProgressSentinel: UnsafeRawPointer = { () -> UnsafeRawPointer in - return UnsafeRawPointer(UnsafeMutablePointer.allocate(capacity: 1)) - }() - - static var queue : ScheduleQueue? { - get { - return Thread.getThreadLocalStorageValueForKey(CurrentThreadSchedulerQueueKey.instance) - } - set { - Thread.setThreadLocalStorageValue(newValue, forKey: CurrentThreadSchedulerQueueKey.instance) - } - } - - /// Gets a value that indicates whether the caller must call a `schedule` method. - public static private(set) var isScheduleRequired: Bool { - get { - return pthread_getspecific(CurrentThreadScheduler.isScheduleRequiredKey) == nil - } - set(isScheduleRequired) { - if pthread_setspecific(CurrentThreadScheduler.isScheduleRequiredKey, isScheduleRequired ? nil : scheduleInProgressSentinel) != 0 { - rxFatalError("pthread_setspecific failed") - } - } - } - - /** - Schedules an action to be executed as soon as possible on current thread. - - If this method is called on some thread that doesn't have `CurrentThreadScheduler` installed, scheduler will be - automatically installed and uninstalled after all work is performed. - - - parameter state: State passed to the action to be executed. - - parameter action: Action to be executed. - - returns: The disposable object used to cancel the scheduled action (best effort). - */ - public func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable { - if CurrentThreadScheduler.isScheduleRequired { - CurrentThreadScheduler.isScheduleRequired = false - - let disposable = action(state) - - defer { - CurrentThreadScheduler.isScheduleRequired = true - CurrentThreadScheduler.queue = nil - } - - guard let queue = CurrentThreadScheduler.queue else { - return disposable - } - - while let latest = queue.value.dequeue() { - if latest.isDisposed { - continue - } - latest.invoke() - } - - return disposable - } - - let existingQueue = CurrentThreadScheduler.queue - - let queue: RxMutableBox> - if let existingQueue = existingQueue { - queue = existingQueue - } - else { - queue = RxMutableBox(Queue(capacity: 1)) - CurrentThreadScheduler.queue = queue - } - - let scheduledItem = ScheduledItem(action: action, state: state) - queue.value.enqueue(scheduledItem) - - return scheduledItem - } -} diff --git a/Pods/RxSwift/RxSwift/Schedulers/HistoricalScheduler.swift b/Pods/RxSwift/RxSwift/Schedulers/HistoricalScheduler.swift deleted file mode 100644 index fede60e66..000000000 --- a/Pods/RxSwift/RxSwift/Schedulers/HistoricalScheduler.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// HistoricalScheduler.swift -// RxSwift -// -// Created by Krunoslav Zaher on 12/27/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import Foundation - -/// Provides a virtual time scheduler that uses `Date` for absolute time and `NSTimeInterval` for relative time. -public class HistoricalScheduler : VirtualTimeScheduler { - - /** - Creates a new historical scheduler with initial clock value. - - - parameter initialClock: Initial value for virtual clock. - */ - public init(initialClock: RxTime = Date(timeIntervalSince1970: 0)) { - super.init(initialClock: initialClock, converter: HistoricalSchedulerTimeConverter()) - } -} diff --git a/Pods/RxSwift/RxSwift/Schedulers/HistoricalSchedulerTimeConverter.swift b/Pods/RxSwift/RxSwift/Schedulers/HistoricalSchedulerTimeConverter.swift deleted file mode 100644 index a8fae8a40..000000000 --- a/Pods/RxSwift/RxSwift/Schedulers/HistoricalSchedulerTimeConverter.swift +++ /dev/null @@ -1,67 +0,0 @@ -// -// HistoricalSchedulerTimeConverter.swift -// RxSwift -// -// Created by Krunoslav Zaher on 12/27/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import Foundation - -/// Converts historical virtual time into real time. -/// -/// Since historical virtual time is also measured in `Date`, this converter is identity function. -public struct HistoricalSchedulerTimeConverter : VirtualTimeConverterType { - /// Virtual time unit used that represents ticks of virtual clock. - public typealias VirtualTimeUnit = RxTime - - /// Virtual time unit used to represent differences of virtual times. - public typealias VirtualTimeIntervalUnit = TimeInterval - - /// Returns identical value of argument passed because historical virtual time is equal to real time, just - /// decoupled from local machine clock. - public func convertFromVirtualTime(_ virtualTime: VirtualTimeUnit) -> RxTime { - virtualTime - } - - /// Returns identical value of argument passed because historical virtual time is equal to real time, just - /// decoupled from local machine clock. - public func convertToVirtualTime(_ time: RxTime) -> VirtualTimeUnit { - time - } - - /// Returns identical value of argument passed because historical virtual time is equal to real time, just - /// decoupled from local machine clock. - public func convertFromVirtualTimeInterval(_ virtualTimeInterval: VirtualTimeIntervalUnit) -> TimeInterval { - virtualTimeInterval - } - - /// Returns identical value of argument passed because historical virtual time is equal to real time, just - /// decoupled from local machine clock. - public func convertToVirtualTimeInterval(_ timeInterval: TimeInterval) -> VirtualTimeIntervalUnit { - timeInterval - } - - /** - Offsets `Date` by time interval. - - - parameter time: Time. - - parameter timeInterval: Time interval offset. - - returns: Time offsetted by time interval. - */ - public func offsetVirtualTime(_ time: VirtualTimeUnit, offset: VirtualTimeIntervalUnit) -> VirtualTimeUnit { - time.addingTimeInterval(offset) - } - - /// Compares two `Date`s. - public func compareVirtualTime(_ lhs: VirtualTimeUnit, _ rhs: VirtualTimeUnit) -> VirtualTimeComparison { - switch lhs.compare(rhs as Date) { - case .orderedAscending: - return .lessThan - case .orderedSame: - return .equal - case .orderedDescending: - return .greaterThan - } - } -} diff --git a/Pods/RxSwift/RxSwift/Schedulers/Internal/DispatchQueueConfiguration.swift b/Pods/RxSwift/RxSwift/Schedulers/Internal/DispatchQueueConfiguration.swift deleted file mode 100644 index f313c0b34..000000000 --- a/Pods/RxSwift/RxSwift/Schedulers/Internal/DispatchQueueConfiguration.swift +++ /dev/null @@ -1,97 +0,0 @@ -// -// DispatchQueueConfiguration.swift -// RxSwift -// -// Created by Krunoslav Zaher on 7/23/16. -// Copyright © 2016 Krunoslav Zaher. All rights reserved. -// - -import Dispatch -import Foundation - -struct DispatchQueueConfiguration { - let queue: DispatchQueue - let leeway: DispatchTimeInterval -} - -extension DispatchQueueConfiguration { - func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable { - let cancel = SingleAssignmentDisposable() - - self.queue.async { - if cancel.isDisposed { - return - } - - - cancel.setDisposable(action(state)) - } - - return cancel - } - - func scheduleRelative(_ state: StateType, dueTime: RxTimeInterval, action: @escaping (StateType) -> Disposable) -> Disposable { - let deadline = DispatchTime.now() + dueTime - - let compositeDisposable = CompositeDisposable() - - let timer = DispatchSource.makeTimerSource(queue: self.queue) - timer.schedule(deadline: deadline, leeway: self.leeway) - - // TODO: - // This looks horrible, and yes, it is. - // It looks like Apple has made a conceputal change here, and I'm unsure why. - // Need more info on this. - // It looks like just setting timer to fire and not holding a reference to it - // until deadline causes timer cancellation. - var timerReference: DispatchSourceTimer? = timer - let cancelTimer = Disposables.create { - timerReference?.cancel() - timerReference = nil - } - - timer.setEventHandler(handler: { - if compositeDisposable.isDisposed { - return - } - _ = compositeDisposable.insert(action(state)) - cancelTimer.dispose() - }) - timer.resume() - - _ = compositeDisposable.insert(cancelTimer) - - return compositeDisposable - } - - func schedulePeriodic(_ state: StateType, startAfter: RxTimeInterval, period: RxTimeInterval, action: @escaping (StateType) -> StateType) -> Disposable { - let initial = DispatchTime.now() + startAfter - - var timerState = state - - let timer = DispatchSource.makeTimerSource(queue: self.queue) - timer.schedule(deadline: initial, repeating: period, leeway: self.leeway) - - // TODO: - // This looks horrible, and yes, it is. - // It looks like Apple has made a conceputal change here, and I'm unsure why. - // Need more info on this. - // It looks like just setting timer to fire and not holding a reference to it - // until deadline causes timer cancellation. - var timerReference: DispatchSourceTimer? = timer - let cancelTimer = Disposables.create { - timerReference?.cancel() - timerReference = nil - } - - timer.setEventHandler(handler: { - if cancelTimer.isDisposed { - return - } - timerState = action(timerState) - }) - timer.resume() - - return cancelTimer - } -} diff --git a/Pods/RxSwift/RxSwift/Schedulers/Internal/InvocableScheduledItem.swift b/Pods/RxSwift/RxSwift/Schedulers/Internal/InvocableScheduledItem.swift deleted file mode 100644 index 0e1505610..000000000 --- a/Pods/RxSwift/RxSwift/Schedulers/Internal/InvocableScheduledItem.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// InvocableScheduledItem.swift -// RxSwift -// -// Created by Krunoslav Zaher on 11/7/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -struct InvocableScheduledItem : InvocableType { - - let invocable: I - let state: I.Value - - init(invocable: I, state: I.Value) { - self.invocable = invocable - self.state = state - } - - func invoke() { - self.invocable.invoke(self.state) - } -} diff --git a/Pods/RxSwift/RxSwift/Schedulers/Internal/InvocableType.swift b/Pods/RxSwift/RxSwift/Schedulers/Internal/InvocableType.swift deleted file mode 100644 index 0dba4336a..000000000 --- a/Pods/RxSwift/RxSwift/Schedulers/Internal/InvocableType.swift +++ /dev/null @@ -1,17 +0,0 @@ -// -// InvocableType.swift -// RxSwift -// -// Created by Krunoslav Zaher on 11/7/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -protocol InvocableType { - func invoke() -} - -protocol InvocableWithValueType { - associatedtype Value - - func invoke(_ value: Value) -} diff --git a/Pods/RxSwift/RxSwift/Schedulers/Internal/ScheduledItem.swift b/Pods/RxSwift/RxSwift/Schedulers/Internal/ScheduledItem.swift deleted file mode 100644 index 3d790d7af..000000000 --- a/Pods/RxSwift/RxSwift/Schedulers/Internal/ScheduledItem.swift +++ /dev/null @@ -1,35 +0,0 @@ -// -// ScheduledItem.swift -// RxSwift -// -// Created by Krunoslav Zaher on 9/2/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -struct ScheduledItem - : ScheduledItemType - , InvocableType { - typealias Action = (T) -> Disposable - - private let action: Action - private let state: T - - private let disposable = SingleAssignmentDisposable() - - var isDisposed: Bool { - self.disposable.isDisposed - } - - init(action: @escaping Action, state: T) { - self.action = action - self.state = state - } - - func invoke() { - self.disposable.setDisposable(self.action(self.state)) - } - - func dispose() { - self.disposable.dispose() - } -} diff --git a/Pods/RxSwift/RxSwift/Schedulers/Internal/ScheduledItemType.swift b/Pods/RxSwift/RxSwift/Schedulers/Internal/ScheduledItemType.swift deleted file mode 100644 index d2b16cab7..000000000 --- a/Pods/RxSwift/RxSwift/Schedulers/Internal/ScheduledItemType.swift +++ /dev/null @@ -1,13 +0,0 @@ -// -// ScheduledItemType.swift -// RxSwift -// -// Created by Krunoslav Zaher on 11/7/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -protocol ScheduledItemType - : Cancelable - , InvocableType { - func invoke() -} diff --git a/Pods/RxSwift/RxSwift/Schedulers/MainScheduler.swift b/Pods/RxSwift/RxSwift/Schedulers/MainScheduler.swift deleted file mode 100644 index 703ab440a..000000000 --- a/Pods/RxSwift/RxSwift/Schedulers/MainScheduler.swift +++ /dev/null @@ -1,80 +0,0 @@ -// -// MainScheduler.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/8/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import Dispatch -#if !os(Linux) - import Foundation -#endif - -/** -Abstracts work that needs to be performed on `DispatchQueue.main`. In case `schedule` methods are called from `DispatchQueue.main`, it will perform action immediately without scheduling. - -This scheduler is usually used to perform UI work. - -Main scheduler is a specialization of `SerialDispatchQueueScheduler`. - -This scheduler is optimized for `observeOn` operator. To ensure observable sequence is subscribed on main thread using `subscribeOn` -operator please use `ConcurrentMainScheduler` because it is more optimized for that purpose. -*/ -public final class MainScheduler : SerialDispatchQueueScheduler { - - private let mainQueue: DispatchQueue - - let numberEnqueued = AtomicInt(0) - - /// Initializes new instance of `MainScheduler`. - public init() { - self.mainQueue = DispatchQueue.main - super.init(serialQueue: self.mainQueue) - } - - /// Singleton instance of `MainScheduler` - public static let instance = MainScheduler() - - /// Singleton instance of `MainScheduler` that always schedules work asynchronously - /// and doesn't perform optimizations for calls scheduled from main queue. - public static let asyncInstance = SerialDispatchQueueScheduler(serialQueue: DispatchQueue.main) - - /// In case this method is called on a background thread it will throw an exception. - public class func ensureExecutingOnScheduler(errorMessage: String? = nil) { - if !DispatchQueue.isMain { - rxFatalError(errorMessage ?? "Executing on background thread. Please use `MainScheduler.instance.schedule` to schedule work on main thread.") - } - } - - /// In case this method is running on a background thread it will throw an exception. - public class func ensureRunningOnMainThread(errorMessage: String? = nil) { - #if !os(Linux) // isMainThread is not implemented in Linux Foundation - guard Thread.isMainThread else { - rxFatalError(errorMessage ?? "Running on background thread.") - } - #endif - } - - override func scheduleInternal(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable { - let previousNumberEnqueued = increment(self.numberEnqueued) - - if DispatchQueue.isMain && previousNumberEnqueued == 0 { - let disposable = action(state) - decrement(self.numberEnqueued) - return disposable - } - - let cancel = SingleAssignmentDisposable() - - self.mainQueue.async { - if !cancel.isDisposed { - cancel.setDisposable(action(state)) - } - - decrement(self.numberEnqueued) - } - - return cancel - } -} diff --git a/Pods/RxSwift/RxSwift/Schedulers/OperationQueueScheduler.swift b/Pods/RxSwift/RxSwift/Schedulers/OperationQueueScheduler.swift deleted file mode 100644 index f0ad3d3ce..000000000 --- a/Pods/RxSwift/RxSwift/Schedulers/OperationQueueScheduler.swift +++ /dev/null @@ -1,54 +0,0 @@ -// -// OperationQueueScheduler.swift -// RxSwift -// -// Created by Krunoslav Zaher on 4/4/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import Dispatch -import Foundation - -/// Abstracts the work that needs to be performed on a specific `NSOperationQueue`. -/// -/// This scheduler is suitable for cases when there is some bigger chunk of work that needs to be performed in background and you want to fine tune concurrent processing using `maxConcurrentOperationCount`. -public class OperationQueueScheduler: ImmediateSchedulerType { - public let operationQueue: OperationQueue - public let queuePriority: Operation.QueuePriority - - /// Constructs new instance of `OperationQueueScheduler` that performs work on `operationQueue`. - /// - /// - parameter operationQueue: Operation queue targeted to perform work on. - /// - parameter queuePriority: Queue priority which will be assigned to new operations. - public init(operationQueue: OperationQueue, queuePriority: Operation.QueuePriority = .normal) { - self.operationQueue = operationQueue - self.queuePriority = queuePriority - } - - /** - Schedules an action to be executed recursively. - - - parameter state: State passed to the action to be executed. - - parameter action: Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state. - - returns: The disposable object used to cancel the scheduled action (best effort). - */ - public func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable { - let cancel = SingleAssignmentDisposable() - - let operation = BlockOperation { - if cancel.isDisposed { - return - } - - - cancel.setDisposable(action(state)) - } - - operation.queuePriority = self.queuePriority - - self.operationQueue.addOperation(operation) - - return cancel - } - -} diff --git a/Pods/RxSwift/RxSwift/Schedulers/RecursiveScheduler.swift b/Pods/RxSwift/RxSwift/Schedulers/RecursiveScheduler.swift deleted file mode 100644 index 0ee78cd18..000000000 --- a/Pods/RxSwift/RxSwift/Schedulers/RecursiveScheduler.swift +++ /dev/null @@ -1,220 +0,0 @@ -// -// RecursiveScheduler.swift -// RxSwift -// -// Created by Krunoslav Zaher on 6/7/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -private enum ScheduleState { - case initial - case added(CompositeDisposable.DisposeKey) - case done -} - -/// Type erased recursive scheduler. -final class AnyRecursiveScheduler { - - typealias Action = (State, AnyRecursiveScheduler) -> Void - - private let lock = RecursiveLock() - - // state - private let group = CompositeDisposable() - - private var scheduler: SchedulerType - private var action: Action? - - init(scheduler: SchedulerType, action: @escaping Action) { - self.action = action - self.scheduler = scheduler - } - - /** - Schedules an action to be executed recursively. - - - parameter state: State passed to the action to be executed. - - parameter dueTime: Relative time after which to execute the recursive action. - */ - func schedule(_ state: State, dueTime: RxTimeInterval) { - var scheduleState: ScheduleState = .initial - - let d = self.scheduler.scheduleRelative(state, dueTime: dueTime) { state -> Disposable in - // best effort - if self.group.isDisposed { - return Disposables.create() - } - - let action = self.lock.performLocked { () -> Action? in - switch scheduleState { - case let .added(removeKey): - self.group.remove(for: removeKey) - case .initial: - break - case .done: - break - } - - scheduleState = .done - - return self.action - } - - if let action = action { - action(state, self) - } - - return Disposables.create() - } - - self.lock.performLocked { - switch scheduleState { - case .added: - rxFatalError("Invalid state") - case .initial: - if let removeKey = self.group.insert(d) { - scheduleState = .added(removeKey) - } - else { - scheduleState = .done - } - case .done: - break - } - } - } - - /// Schedules an action to be executed recursively. - /// - /// - parameter state: State passed to the action to be executed. - func schedule(_ state: State) { - var scheduleState: ScheduleState = .initial - - let d = self.scheduler.schedule(state) { state -> Disposable in - // best effort - if self.group.isDisposed { - return Disposables.create() - } - - let action = self.lock.performLocked { () -> Action? in - switch scheduleState { - case let .added(removeKey): - self.group.remove(for: removeKey) - case .initial: - break - case .done: - break - } - - scheduleState = .done - - return self.action - } - - if let action = action { - action(state, self) - } - - return Disposables.create() - } - - self.lock.performLocked { - switch scheduleState { - case .added: - rxFatalError("Invalid state") - case .initial: - if let removeKey = self.group.insert(d) { - scheduleState = .added(removeKey) - } - else { - scheduleState = .done - } - case .done: - break - } - } - } - - func dispose() { - self.lock.performLocked { - self.action = nil - } - self.group.dispose() - } -} - -/// Type erased recursive scheduler. -final class RecursiveImmediateScheduler { - typealias Action = (_ state: State, _ recurse: (State) -> Void) -> Void - - private var lock = SpinLock() - private let group = CompositeDisposable() - - private var action: Action? - private let scheduler: ImmediateSchedulerType - - init(action: @escaping Action, scheduler: ImmediateSchedulerType) { - self.action = action - self.scheduler = scheduler - } - - // immediate scheduling - - /// Schedules an action to be executed recursively. - /// - /// - parameter state: State passed to the action to be executed. - func schedule(_ state: State) { - var scheduleState: ScheduleState = .initial - - let d = self.scheduler.schedule(state) { state -> Disposable in - // best effort - if self.group.isDisposed { - return Disposables.create() - } - - let action = self.lock.performLocked { () -> Action? in - switch scheduleState { - case let .added(removeKey): - self.group.remove(for: removeKey) - case .initial: - break - case .done: - break - } - - scheduleState = .done - - return self.action - } - - if let action = action { - action(state, self.schedule) - } - - return Disposables.create() - } - - self.lock.performLocked { - switch scheduleState { - case .added: - rxFatalError("Invalid state") - case .initial: - if let removeKey = self.group.insert(d) { - scheduleState = .added(removeKey) - } - else { - scheduleState = .done - } - case .done: - break - } - } - } - - func dispose() { - self.lock.performLocked { - self.action = nil - } - self.group.dispose() - } -} diff --git a/Pods/RxSwift/RxSwift/Schedulers/SchedulerServices+Emulation.swift b/Pods/RxSwift/RxSwift/Schedulers/SchedulerServices+Emulation.swift deleted file mode 100644 index cab2bc8b3..000000000 --- a/Pods/RxSwift/RxSwift/Schedulers/SchedulerServices+Emulation.swift +++ /dev/null @@ -1,61 +0,0 @@ -// -// SchedulerServices+Emulation.swift -// RxSwift -// -// Created by Krunoslav Zaher on 6/6/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -enum SchedulePeriodicRecursiveCommand { - case tick - case dispatchStart -} - -final class SchedulePeriodicRecursive { - typealias RecursiveAction = (State) -> State - typealias RecursiveScheduler = AnyRecursiveScheduler - - private let scheduler: SchedulerType - private let startAfter: RxTimeInterval - private let period: RxTimeInterval - private let action: RecursiveAction - - private var state: State - private let pendingTickCount = AtomicInt(0) - - init(scheduler: SchedulerType, startAfter: RxTimeInterval, period: RxTimeInterval, action: @escaping RecursiveAction, state: State) { - self.scheduler = scheduler - self.startAfter = startAfter - self.period = period - self.action = action - self.state = state - } - - func start() -> Disposable { - self.scheduler.scheduleRecursive(SchedulePeriodicRecursiveCommand.tick, dueTime: self.startAfter, action: self.tick) - } - - func tick(_ command: SchedulePeriodicRecursiveCommand, scheduler: RecursiveScheduler) { - // Tries to emulate periodic scheduling as best as possible. - // The problem that could arise is if handling periodic ticks take too long, or - // tick interval is short. - switch command { - case .tick: - scheduler.schedule(.tick, dueTime: self.period) - - // The idea is that if on tick there wasn't any item enqueued, schedule to perform work immediately. - // Else work will be scheduled after previous enqueued work completes. - if increment(self.pendingTickCount) == 0 { - self.tick(.dispatchStart, scheduler: scheduler) - } - - case .dispatchStart: - self.state = self.action(self.state) - // Start work and schedule check is this last batch of work - if decrement(self.pendingTickCount) > 1 { - // This gives priority to scheduler emulation, it's not perfect, but helps - scheduler.schedule(SchedulePeriodicRecursiveCommand.dispatchStart) - } - } - } -} diff --git a/Pods/RxSwift/RxSwift/Schedulers/SerialDispatchQueueScheduler.swift b/Pods/RxSwift/RxSwift/Schedulers/SerialDispatchQueueScheduler.swift deleted file mode 100644 index bb0013c8f..000000000 --- a/Pods/RxSwift/RxSwift/Schedulers/SerialDispatchQueueScheduler.swift +++ /dev/null @@ -1,131 +0,0 @@ -// -// SerialDispatchQueueScheduler.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/8/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import Dispatch -import Foundation - -/** -Abstracts the work that needs to be performed on a specific `dispatch_queue_t`. It will make sure -that even if concurrent dispatch queue is passed, it's transformed into a serial one. - -It is extremely important that this scheduler is serial, because -certain operator perform optimizations that rely on that property. - -Because there is no way of detecting is passed dispatch queue serial or -concurrent, for every queue that is being passed, worst case (concurrent) -will be assumed, and internal serial proxy dispatch queue will be created. - -This scheduler can also be used with internal serial queue alone. - -In case some customization need to be made on it before usage, -internal serial queue can be customized using `serialQueueConfiguration` -callback. -*/ -public class SerialDispatchQueueScheduler : SchedulerType { - public typealias TimeInterval = Foundation.TimeInterval - public typealias Time = Date - - /// - returns: Current time. - public var now : Date { - Date() - } - - let configuration: DispatchQueueConfiguration - - /** - Constructs new `SerialDispatchQueueScheduler` that wraps `serialQueue`. - - - parameter serialQueue: Target dispatch queue. - - parameter leeway: The amount of time, in nanoseconds, that the system will defer the timer. - */ - init(serialQueue: DispatchQueue, leeway: DispatchTimeInterval = DispatchTimeInterval.nanoseconds(0)) { - self.configuration = DispatchQueueConfiguration(queue: serialQueue, leeway: leeway) - } - - /** - Constructs new `SerialDispatchQueueScheduler` with internal serial queue named `internalSerialQueueName`. - - Additional dispatch queue properties can be set after dispatch queue is created using `serialQueueConfiguration`. - - - parameter internalSerialQueueName: Name of internal serial dispatch queue. - - parameter serialQueueConfiguration: Additional configuration of internal serial dispatch queue. - - parameter leeway: The amount of time, in nanoseconds, that the system will defer the timer. - */ - public convenience init(internalSerialQueueName: String, serialQueueConfiguration: ((DispatchQueue) -> Void)? = nil, leeway: DispatchTimeInterval = DispatchTimeInterval.nanoseconds(0)) { - let queue = DispatchQueue(label: internalSerialQueueName, attributes: []) - serialQueueConfiguration?(queue) - self.init(serialQueue: queue, leeway: leeway) - } - - /** - Constructs new `SerialDispatchQueueScheduler` named `internalSerialQueueName` that wraps `queue`. - - - parameter queue: Possibly concurrent dispatch queue used to perform work. - - parameter internalSerialQueueName: Name of internal serial dispatch queue proxy. - - parameter leeway: The amount of time, in nanoseconds, that the system will defer the timer. - */ - public convenience init(queue: DispatchQueue, internalSerialQueueName: String, leeway: DispatchTimeInterval = DispatchTimeInterval.nanoseconds(0)) { - // Swift 3.0 IUO - let serialQueue = DispatchQueue(label: internalSerialQueueName, - attributes: [], - target: queue) - self.init(serialQueue: serialQueue, leeway: leeway) - } - - /** - Constructs new `SerialDispatchQueueScheduler` that wraps one of the global concurrent dispatch queues. - - - parameter qos: Identifier for global dispatch queue with specified quality of service class. - - parameter internalSerialQueueName: Custom name for internal serial dispatch queue proxy. - - parameter leeway: The amount of time, in nanoseconds, that the system will defer the timer. - */ - @available(macOS 10.10, *) - public convenience init(qos: DispatchQoS, internalSerialQueueName: String = "rx.global_dispatch_queue.serial", leeway: DispatchTimeInterval = DispatchTimeInterval.nanoseconds(0)) { - self.init(queue: DispatchQueue.global(qos: qos.qosClass), internalSerialQueueName: internalSerialQueueName, leeway: leeway) - } - - /** - Schedules an action to be executed immediately. - - - parameter state: State passed to the action to be executed. - - parameter action: Action to be executed. - - returns: The disposable object used to cancel the scheduled action (best effort). - */ - public final func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable { - self.scheduleInternal(state, action: action) - } - - func scheduleInternal(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable { - self.configuration.schedule(state, action: action) - } - - /** - Schedules an action to be executed. - - - parameter state: State passed to the action to be executed. - - parameter dueTime: Relative time after which to execute the action. - - parameter action: Action to be executed. - - returns: The disposable object used to cancel the scheduled action (best effort). - */ - public final func scheduleRelative(_ state: StateType, dueTime: RxTimeInterval, action: @escaping (StateType) -> Disposable) -> Disposable { - self.configuration.scheduleRelative(state, dueTime: dueTime, action: action) - } - - /** - Schedules a periodic piece of work. - - - parameter state: State passed to the action to be executed. - - parameter startAfter: Period after which initial work should be run. - - parameter period: Period for running the work periodically. - - parameter action: Action to be executed. - - returns: The disposable object used to cancel the scheduled action (best effort). - */ - public func schedulePeriodic(_ state: StateType, startAfter: RxTimeInterval, period: RxTimeInterval, action: @escaping (StateType) -> StateType) -> Disposable { - self.configuration.schedulePeriodic(state, startAfter: startAfter, period: period, action: action) - } -} diff --git a/Pods/RxSwift/RxSwift/Schedulers/VirtualTimeConverterType.swift b/Pods/RxSwift/RxSwift/Schedulers/VirtualTimeConverterType.swift deleted file mode 100644 index 34151f700..000000000 --- a/Pods/RxSwift/RxSwift/Schedulers/VirtualTimeConverterType.swift +++ /dev/null @@ -1,97 +0,0 @@ -// -// VirtualTimeConverterType.swift -// RxSwift -// -// Created by Krunoslav Zaher on 12/23/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -import Foundation - -/// Parametrization for virtual time used by `VirtualTimeScheduler`s. -public protocol VirtualTimeConverterType { - /// Virtual time unit used that represents ticks of virtual clock. - associatedtype VirtualTimeUnit - - /// Virtual time unit used to represent differences of virtual times. - associatedtype VirtualTimeIntervalUnit - - /** - Converts virtual time to real time. - - - parameter virtualTime: Virtual time to convert to `Date`. - - returns: `Date` corresponding to virtual time. - */ - func convertFromVirtualTime(_ virtualTime: VirtualTimeUnit) -> RxTime - - /** - Converts real time to virtual time. - - - parameter time: `Date` to convert to virtual time. - - returns: Virtual time corresponding to `Date`. - */ - func convertToVirtualTime(_ time: RxTime) -> VirtualTimeUnit - - /** - Converts from virtual time interval to `NSTimeInterval`. - - - parameter virtualTimeInterval: Virtual time interval to convert to `NSTimeInterval`. - - returns: `NSTimeInterval` corresponding to virtual time interval. - */ - func convertFromVirtualTimeInterval(_ virtualTimeInterval: VirtualTimeIntervalUnit) -> TimeInterval - - /** - Converts from `NSTimeInterval` to virtual time interval. - - - parameter timeInterval: `NSTimeInterval` to convert to virtual time interval. - - returns: Virtual time interval corresponding to time interval. - */ - func convertToVirtualTimeInterval(_ timeInterval: TimeInterval) -> VirtualTimeIntervalUnit - - /** - Offsets virtual time by virtual time interval. - - - parameter time: Virtual time. - - parameter offset: Virtual time interval. - - returns: Time corresponding to time offsetted by virtual time interval. - */ - func offsetVirtualTime(_ time: VirtualTimeUnit, offset: VirtualTimeIntervalUnit) -> VirtualTimeUnit - - /** - This is additional abstraction because `Date` is unfortunately not comparable. - Extending `Date` with `Comparable` would be too risky because of possible collisions with other libraries. - */ - func compareVirtualTime(_ lhs: VirtualTimeUnit, _ rhs: VirtualTimeUnit) -> VirtualTimeComparison -} - -/** - Virtual time comparison result. - - This is additional abstraction because `Date` is unfortunately not comparable. - Extending `Date` with `Comparable` would be too risky because of possible collisions with other libraries. -*/ -public enum VirtualTimeComparison { - /// lhs < rhs. - case lessThan - /// lhs == rhs. - case equal - /// lhs > rhs. - case greaterThan -} - -extension VirtualTimeComparison { - /// lhs < rhs. - var lessThen: Bool { - self == .lessThan - } - - /// lhs > rhs - var greaterThan: Bool { - self == .greaterThan - } - - /// lhs == rhs - var equal: Bool { - self == .equal - } -} diff --git a/Pods/RxSwift/RxSwift/Schedulers/VirtualTimeScheduler.swift b/Pods/RxSwift/RxSwift/Schedulers/VirtualTimeScheduler.swift deleted file mode 100644 index e74d5be69..000000000 --- a/Pods/RxSwift/RxSwift/Schedulers/VirtualTimeScheduler.swift +++ /dev/null @@ -1,267 +0,0 @@ -// -// VirtualTimeScheduler.swift -// RxSwift -// -// Created by Krunoslav Zaher on 2/14/15. -// Copyright © 2015 Krunoslav Zaher. All rights reserved. -// - -/// Base class for virtual time schedulers using a priority queue for scheduled items. -open class VirtualTimeScheduler - : SchedulerType { - - public typealias VirtualTime = Converter.VirtualTimeUnit - public typealias VirtualTimeInterval = Converter.VirtualTimeIntervalUnit - - private var running : Bool - - private var currentClock: VirtualTime - - private var schedulerQueue : PriorityQueue> - private var converter: Converter - - private var nextId = 0 - - /// - returns: Current time. - public var now: RxTime { - self.converter.convertFromVirtualTime(self.clock) - } - - /// - returns: Scheduler's absolute time clock value. - public var clock: VirtualTime { - self.currentClock - } - - /// Creates a new virtual time scheduler. - /// - /// - parameter initialClock: Initial value for the clock. - public init(initialClock: VirtualTime, converter: Converter) { - self.currentClock = initialClock - self.running = false - self.converter = converter - self.schedulerQueue = PriorityQueue(hasHigherPriority: { - switch converter.compareVirtualTime($0.time, $1.time) { - case .lessThan: - return true - case .equal: - return $0.id < $1.id - case .greaterThan: - return false - } - }, isEqual: { $0 === $1 }) - #if TRACE_RESOURCES - _ = Resources.incrementTotal() - #endif - } - - /** - Schedules an action to be executed immediately. - - - parameter state: State passed to the action to be executed. - - parameter action: Action to be executed. - - returns: The disposable object used to cancel the scheduled action (best effort). - */ - public func schedule(_ state: StateType, action: @escaping (StateType) -> Disposable) -> Disposable { - return self.scheduleRelative(state, dueTime: .microseconds(0)) { a in - return action(a) - } - } - - /** - Schedules an action to be executed. - - - parameter state: State passed to the action to be executed. - - parameter dueTime: Relative time after which to execute the action. - - parameter action: Action to be executed. - - returns: The disposable object used to cancel the scheduled action (best effort). - */ - public func scheduleRelative(_ state: StateType, dueTime: RxTimeInterval, action: @escaping (StateType) -> Disposable) -> Disposable { - let time = self.now.addingDispatchInterval(dueTime) - let absoluteTime = self.converter.convertToVirtualTime(time) - let adjustedTime = self.adjustScheduledTime(absoluteTime) - return self.scheduleAbsoluteVirtual(state, time: adjustedTime, action: action) - } - - /** - Schedules an action to be executed after relative time has passed. - - - parameter state: State passed to the action to be executed. - - parameter time: Absolute time when to execute the action. If this is less or equal then `now`, `now + 1` will be used. - - parameter action: Action to be executed. - - returns: The disposable object used to cancel the scheduled action (best effort). - */ - public func scheduleRelativeVirtual(_ state: StateType, dueTime: VirtualTimeInterval, action: @escaping (StateType) -> Disposable) -> Disposable { - let time = self.converter.offsetVirtualTime(self.clock, offset: dueTime) - return self.scheduleAbsoluteVirtual(state, time: time, action: action) - } - - /** - Schedules an action to be executed at absolute virtual time. - - - parameter state: State passed to the action to be executed. - - parameter time: Absolute time when to execute the action. - - parameter action: Action to be executed. - - returns: The disposable object used to cancel the scheduled action (best effort). - */ - public func scheduleAbsoluteVirtual(_ state: StateType, time: VirtualTime, action: @escaping (StateType) -> Disposable) -> Disposable { - MainScheduler.ensureExecutingOnScheduler() - - let compositeDisposable = CompositeDisposable() - - let item = VirtualSchedulerItem(action: { - return action(state) - }, time: time, id: self.nextId) - - self.nextId += 1 - - self.schedulerQueue.enqueue(item) - - _ = compositeDisposable.insert(item) - - return compositeDisposable - } - - /// Adjusts time of scheduling before adding item to schedule queue. - open func adjustScheduledTime(_ time: VirtualTime) -> VirtualTime { - time - } - - /// Starts the virtual time scheduler. - public func start() { - MainScheduler.ensureExecutingOnScheduler() - - if self.running { - return - } - - self.running = true - repeat { - guard let next = self.findNext() else { - break - } - - if self.converter.compareVirtualTime(next.time, self.clock).greaterThan { - self.currentClock = next.time - } - - next.invoke() - self.schedulerQueue.remove(next) - } while self.running - - self.running = false - } - - func findNext() -> VirtualSchedulerItem? { - while let front = self.schedulerQueue.peek() { - if front.isDisposed { - self.schedulerQueue.remove(front) - continue - } - - return front - } - - return nil - } - - /// Advances the scheduler's clock to the specified time, running all work till that point. - /// - /// - parameter virtualTime: Absolute time to advance the scheduler's clock to. - public func advanceTo(_ virtualTime: VirtualTime) { - MainScheduler.ensureExecutingOnScheduler() - - if self.running { - fatalError("Scheduler is already running") - } - - self.running = true - repeat { - guard let next = self.findNext() else { - break - } - - if self.converter.compareVirtualTime(next.time, virtualTime).greaterThan { - break - } - - if self.converter.compareVirtualTime(next.time, self.clock).greaterThan { - self.currentClock = next.time - } - next.invoke() - self.schedulerQueue.remove(next) - } while self.running - - self.currentClock = virtualTime - self.running = false - } - - /// Advances the scheduler's clock by the specified relative time. - public func sleep(_ virtualInterval: VirtualTimeInterval) { - MainScheduler.ensureExecutingOnScheduler() - - let sleepTo = self.converter.offsetVirtualTime(self.clock, offset: virtualInterval) - if self.converter.compareVirtualTime(sleepTo, self.clock).lessThen { - fatalError("Can't sleep to past.") - } - - self.currentClock = sleepTo - } - - /// Stops the virtual time scheduler. - public func stop() { - MainScheduler.ensureExecutingOnScheduler() - - self.running = false - } - - #if TRACE_RESOURCES - deinit { - _ = Resources.decrementTotal() - } - #endif -} - -// MARK: description - -extension VirtualTimeScheduler: CustomDebugStringConvertible { - /// A textual representation of `self`, suitable for debugging. - public var debugDescription: String { - self.schedulerQueue.debugDescription - } -} - -final class VirtualSchedulerItem