Преглед на файлове

Remove GoogleUtilities from repo (#7315)

Paul Beusterien преди 5 години
родител
ревизия
02488e99b7
променени са 100 файла, в които са добавени 9 реда и са изтрити 10940 реда
  1. 0 89
      .github/workflows/google-utilities.yml
  2. 0 30
      .travis.yml
  3. 0 1
      CocoapodsIntegrationTest/TestEnvironments/Cocoapods_multiprojects_frameworks/Podfile
  4. 0 1
      CocoapodsIntegrationTest/TestEnvironments/Cocoapods_multiprojects_staticLibs/Podfile
  5. 0 1
      CoreOnly/Tests/FirebasePodTest/Podfile
  6. 0 2
      Dangerfile
  7. 3 1
      Example/watchOSSample/Podfile
  8. 0 1
      FirebaseAuth/Tests/Sample/Podfile
  9. 3 1
      FirebaseDynamicLinks/Tests/Sample/Podfile
  10. 0 1
      FirebaseInAppMessaging/Tests/Integration/DefaultUITestApp/Podfile
  11. 0 1
      FirebaseInAppMessaging/Tests/Integration/FunctionalTestApp/Podfile
  12. 0 1
      FirebaseMessaging/Apps/AdvancedSample/Podfile
  13. 0 1
      FirebaseMessaging/Apps/Sample/Podfile
  14. 3 2
      FirebasePerformance/Tests/FIRPerfE2E/Podfile
  15. 0 1
      FirebaseRemoteConfig/Tests/Sample/Podfile
  16. 0 1
      FirebaseSegmentation/Tests/Sample/Podfile
  17. 0 1
      Firestore/Example/Podfile
  18. 0 1
      GoogleDataTransport/GDTCCTWatchOSTestApp/Podfile
  19. 0 138
      GoogleUtilities.podspec
  20. 0 1070
      GoogleUtilities/AppDelegateSwizzler/GULAppDelegateSwizzler.m
  21. 0 439
      GoogleUtilities/AppDelegateSwizzler/GULSceneDelegateSwizzler.m
  22. 0 55
      GoogleUtilities/AppDelegateSwizzler/Internal/GULAppDelegateSwizzler_Private.h
  23. 0 48
      GoogleUtilities/AppDelegateSwizzler/Internal/GULSceneDelegateSwizzler_Private.h
  24. 0 107
      GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULAppDelegateSwizzler.h
  25. 0 50
      GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULApplication.h
  26. 0 76
      GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULSceneDelegateSwizzler.h
  27. 0 185
      GoogleUtilities/AppDelegateSwizzler/README.md
  28. 0 120
      GoogleUtilities/CHANGELOG.md
  29. 0 56
      GoogleUtilities/Common/GULLoggerCodes.h
  30. 0 159
      GoogleUtilities/Environment/GULHeartbeatDateStorage.m
  31. 0 103
      GoogleUtilities/Environment/GULSecureCoding.m
  32. 0 60
      GoogleUtilities/Environment/Public/GoogleUtilities/GULAppEnvironmentUtil.h
  33. 0 49
      GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorage.h
  34. 0 79
      GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainStorage.h
  35. 0 61
      GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainUtils.h
  36. 0 36
      GoogleUtilities/Environment/Public/GoogleUtilities/GULSecureCoding.h
  37. 0 31
      GoogleUtilities/Environment/Public/GoogleUtilities/GULURLSessionDataResponse.h
  38. 0 37
      GoogleUtilities/Environment/Public/GoogleUtilities/NSURLSession+GULPromises.h
  39. 0 192
      GoogleUtilities/Environment/SecureStorage/GULKeychainStorage.m
  40. 0 113
      GoogleUtilities/Environment/SecureStorage/GULKeychainUtils.m
  41. 0 30
      GoogleUtilities/Environment/URLSessionPromiseWrapper/GULURLSessionDataResponse.m
  42. 0 46
      GoogleUtilities/Environment/URLSessionPromiseWrapper/NSURLSession+GULPromises.m
  43. 0 312
      GoogleUtilities/Environment/third_party/GULAppEnvironmentUtil.m
  44. 0 36
      GoogleUtilities/Environment/third_party/LICENSE
  45. 0 21
      GoogleUtilities/ISASwizzler/GULObjectSwizzler+Internal.h
  46. 0 198
      GoogleUtilities/ISASwizzler/GULObjectSwizzler.m
  47. 0 64
      GoogleUtilities/ISASwizzler/GULSwizzledObject.m
  48. 0 123
      GoogleUtilities/ISASwizzler/Public/GoogleUtilities/GULObjectSwizzler.h
  49. 0 44
      GoogleUtilities/ISASwizzler/Public/GoogleUtilities/GULSwizzledObject.h
  50. 0 247
      GoogleUtilities/LICENSE
  51. 0 215
      GoogleUtilities/Logger/GULLogger.m
  52. 0 159
      GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h
  53. 0 37
      GoogleUtilities/Logger/Public/GoogleUtilities/GULLoggerLevel.h
  54. 0 153
      GoogleUtilities/MethodSwizzler/GULSwizzler.m
  55. 0 207
      GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/GULOriginalIMPConvenienceMacros.h
  56. 0 71
      GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/GULSwizzler.h
  57. 0 207
      GoogleUtilities/NSData+zlib/GULNSData+zlib.m
  58. 0 49
      GoogleUtilities/NSData+zlib/Public/GoogleUtilities/GULNSData+zlib.h
  59. 0 101
      GoogleUtilities/Network/GULMutableDictionary.m
  60. 0 390
      GoogleUtilities/Network/GULNetwork.m
  61. 0 41
      GoogleUtilities/Network/GULNetworkConstants.m
  62. 0 24
      GoogleUtilities/Network/GULNetworkInternal.h
  63. 0 766
      GoogleUtilities/Network/GULNetworkURLSession.m
  64. 0 46
      GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h
  65. 0 87
      GoogleUtilities/Network/Public/GoogleUtilities/GULNetwork.h
  66. 0 71
      GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkConstants.h
  67. 0 49
      GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkLoggerProtocol.h
  68. 0 47
      GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkMessageCode.h
  69. 0 62
      GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkURLSession.h
  70. 0 39
      GoogleUtilities/README.md
  71. 0 48
      GoogleUtilities/Reachability/GULReachabilityChecker+Internal.h
  72. 0 263
      GoogleUtilities/Reachability/GULReachabilityChecker.m
  73. 0 29
      GoogleUtilities/Reachability/GULReachabilityMessageCode.h
  74. 0 79
      GoogleUtilities/Reachability/Public/GoogleUtilities/GULReachabilityChecker.h
  75. 0 24
      GoogleUtilities/SwizzlerTestHelpers/GULProxy.h
  76. 0 95
      GoogleUtilities/SwizzlerTestHelpers/GULProxy.m
  77. 0 44
      GoogleUtilities/SwizzlerTestHelpers/GULRuntimeClassDiff.h
  78. 0 82
      GoogleUtilities/SwizzlerTestHelpers/GULRuntimeClassDiff.m
  79. 0 48
      GoogleUtilities/SwizzlerTestHelpers/GULRuntimeClassSnapshot.h
  80. 0 211
      GoogleUtilities/SwizzlerTestHelpers/GULRuntimeClassSnapshot.m
  81. 0 37
      GoogleUtilities/SwizzlerTestHelpers/GULRuntimeDiff.h
  82. 0 69
      GoogleUtilities/SwizzlerTestHelpers/GULRuntimeDiff.m
  83. 0 46
      GoogleUtilities/SwizzlerTestHelpers/GULRuntimeSnapshot.h
  84. 0 129
      GoogleUtilities/SwizzlerTestHelpers/GULRuntimeSnapshot.m
  85. 0 50
      GoogleUtilities/SwizzlerTestHelpers/GULRuntimeStateHelper.h
  86. 0 56
      GoogleUtilities/SwizzlerTestHelpers/GULRuntimeStateHelper.m
  87. 0 63
      GoogleUtilities/SwizzlerTestHelpers/GULSwizzler+Unswizzle.m
  88. 0 76
      GoogleUtilities/SwizzlerTestHelpers/GULSwizzlingCache.h
  89. 0 134
      GoogleUtilities/SwizzlerTestHelpers/GULSwizzlingCache.m
  90. 0 46
      GoogleUtilities/SwizzlerTestHelpers/GULSwizzlingCache_Private.h
  91. 0 47
      GoogleUtilities/SwizzlerTestHelpers/Public/GoogleUtilities/GULSwizzler+Unswizzle.h
  92. 0 24
      GoogleUtilities/Tests/SwiftUnit/GULAppEnvironmentUtilTest.swift
  93. 0 108
      GoogleUtilities/Tests/Unit/Environment/GULAppEnvironmentUtilTest.m
  94. 0 90
      GoogleUtilities/Tests/Unit/Environment/GULHeartbeatDateStorageTest.m
  95. 0 207
      GoogleUtilities/Tests/Unit/Environment/GULKeychainStorageTests.m
  96. 0 100
      GoogleUtilities/Tests/Unit/Environment/NSURLSession+GULPromisesTests.m
  97. 0 117
      GoogleUtilities/Tests/Unit/Logger/GULLoggerTest.m
  98. 0 87
      GoogleUtilities/Tests/Unit/Network/GULMutableDictionaryTest.m
  99. 0 1015
      GoogleUtilities/Tests/Unit/Network/GULNetworkTest.m
  100. 0 173
      GoogleUtilities/Tests/Unit/Network/third_party/GTMHTTPServer.h

+ 0 - 89
.github/workflows/google-utilities.yml

@@ -1,89 +0,0 @@
-name: google-utilities
-
-on:
-  pull_request:
-    paths:
-    - 'GoogleUtilities**'
-    - '.github/workflows/google-utilities.yml'
-    - 'Gemfile'
-  schedule:
-    # Run every day at 11pm (PST) - cron uses UTC times
-    - cron:  '0 7 * * *'
-
-jobs:
-  pod-lib-lint:
-    # Don't run on private repo unless it is a PR.
-    if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request'
-
-    runs-on: macOS-latest
-    strategy:
-      matrix:
-        target: [ios, tvos, macos]
-    steps:
-    - uses: actions/checkout@v2
-    - name: Setup Bundler
-      run: scripts/setup_bundler.sh
-    - name: Build and test
-      run: |
-        scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb GoogleUtilities.podspec \
-          --platforms=${{ matrix.target }}
-
-  spm:
-    # Don't run on private repo unless it is a PR.
-    if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request'
-    runs-on: macOS-latest
-    steps:
-    - uses: actions/checkout@v2
-    - name: Initialize xcodebuild
-      run: xcodebuild -list
-    - name: iOS Unit Tests
-      # Only UserDefaults currently has a scheme.
-      run: scripts/third_party/travis/retry.sh ./scripts/build.sh GoogleUtilities_UserDefaults iOS spmbuildonly
-
-  spm-cron:
-    # Don't run on private repo.
-    if: github.event_name == 'schedule' && github.repository == 'Firebase/firebase-ios-sdk'
-    runs-on: macOS-latest
-    strategy:
-      matrix:
-        target: [tvOS, macOS, catalyst]
-    steps:
-    - uses: actions/checkout@v2
-    - name: Initialize xcodebuild
-      run: xcodebuild -list
-    - name: Unit Tests
-      run: scripts/third_party/travis/retry.sh ./scripts/build.sh GoogleUtilities_UserDefaults ${{ matrix.target }} spmbuildonly
-
-  catalyst:
-    # Don't run on private repo unless it is a PR.
-    if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request'
-
-    runs-on: macOS-latest
-    steps:
-    - uses: actions/checkout@v2
-    - name: Setup Bundler
-      run: scripts/setup_bundler.sh
-    - name: Setup project and Build for Catalyst
-      run: scripts/test_catalyst.sh GoogleUtilities test GoogleUtilities-Unit-unit
-
-  utilities-cron-only:
-    # Don't run on private repo.
-    if: github.event_name == 'schedule' && github.repository == 'Firebase/firebase-ios-sdk'
-
-    runs-on: macos-latest
-    strategy:
-      matrix:
-        target: [ios, tvos, macos]
-        flags: [
-          '--use-static-frameworks',
-          '--use-libraries --skip-tests'
-        ]
-    needs: pod-lib-lint
-    steps:
-    - uses: actions/checkout@v2
-    - name: Setup Bundler
-      run: scripts/setup_bundler.sh
-    - name: PodLibLint GoogleUtilities Cron
-      run: |
-        scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb \
-          GoogleUtilities.podspec --platforms=${{ matrix.target }} ${{ matrix.flags }}

+ 0 - 30
.travis.yml

@@ -130,36 +130,6 @@ jobs:
       script:
         - travis_retry ./scripts/if_changed.sh ./scripts/build.sh $PROJECT $PLATFORM $METHOD
 
-    - stage: test
-      env:
-        - PROJECT=GoogleUtilities METHOD=pod-lib-lint
-      script:
-        - travis_retry ./scripts/if_changed.sh ./scripts/pod_lib_lint.rb GoogleUtilities.podspec
-
-    - stage: test
-      env:
-        - PROJECT=GoogleUtilities METHOD=pod-lib-lint
-      script:
-        - travis_retry ./scripts/if_changed.sh ./scripts/pod_lib_lint.rb GoogleUtilities.podspec --platforms=ios
-        - travis_retry ./scripts/if_changed.sh ./scripts/pod_lib_lint.rb GoogleUtilities.podspec --platforms=tvos
-        - travis_retry ./scripts/if_changed.sh ./scripts/pod_lib_lint.rb GoogleUtilities.podspec --platforms=macos
-        - travis_retry ./scripts/if_changed.sh ./scripts/pod_lib_lint.rb GoogleUtilities.podspec --use-static-frameworks --platforms=ios
-        - travis_retry ./scripts/if_changed.sh ./scripts/pod_lib_lint.rb GoogleUtilities.podspec --use-static-frameworks  --platforms=tvos
-        - travis_retry ./scripts/if_changed.sh ./scripts/pod_lib_lint.rb GoogleUtilities.podspec --use-static-frameworks  --platforms=macos
-
-    - stage: test
-      if: type = cron
-      env:
-        - PROJECT=GoogleUtilitiesCron METHOD=pod-lib-lint
-      script:
-
-        - travis_retry ./scripts/pod_lib_lint.rb GoogleUtilities.podspec --use-libraries --platforms=ios --skip-tests
-        - travis_retry ./scripts/pod_lib_lint.rb GoogleUtilities.podspec --use-libraries --platforms=tvos --skip-tests
-        - travis_retry ./scripts/pod_lib_lint.rb GoogleUtilities.podspec --use-libraries --platforms=macos --skip-tests
-        - travis_retry ./scripts/pod_lib_lint.rb GoogleUtilities.podspec --use-modular-headers --platforms=ios
-        - travis_retry ./scripts/pod_lib_lint.rb GoogleUtilities.podspec --use-modular-headers --platforms=tvos
-        - travis_retry ./scripts/pod_lib_lint.rb GoogleUtilities.podspec --use-modular-headers --platforms=macos
-
     - stage: test
       env:
         - PROJECT=GoogleUtilitiesComponents METHOD=pod-lib-lint

+ 0 - 1
CocoapodsIntegrationTest/TestEnvironments/Cocoapods_multiprojects_frameworks/Podfile

@@ -21,7 +21,6 @@ target 'CocoapodsIntegrationTest' do
   pod 'FirebasePerformance', :path => '../'
   pod 'FirebaseStorage', :path => '../'
   pod 'GoogleDataTransport', :path => '../'
-  pod 'GoogleUtilities', :path => '../'
 end
 
 # Using the new speed-enhancing features available with CocoaPods 1.7+

+ 0 - 1
CocoapodsIntegrationTest/TestEnvironments/Cocoapods_multiprojects_staticLibs/Podfile

@@ -19,7 +19,6 @@ target 'CocoapodsIntegrationTest' do
   pod 'FirebasePerformance', :path => '../'
   pod 'FirebaseStorage', :path => '../'
   pod 'GoogleDataTransport', :path => '../'
-  pod 'GoogleUtilities', :path => '../'
 end
 
 # Using the new speed-enhancing features available with CocoaPods 1.7+

+ 0 - 1
CoreOnly/Tests/FirebasePodTest/Podfile

@@ -30,7 +30,6 @@ target 'FirebasePodTest' do
   # Get dependent pods from the repo also
   pod 'FirebaseCoreDiagnostics', :path => '../../../'
   pod 'GoogleDataTransport', :path => '../../../'
-  pod 'GoogleUtilities', :path => '../../../'
 
   pod 'FirebaseAnalytics' # Analytics is not open source
 end

+ 0 - 2
Dangerfile

@@ -53,7 +53,6 @@ def labelsForModifiedFiles()
   labels.push("api: segmentation") if @has_segmentation_changes
   labels.push("api: storage") if @has_storage_changes
   labels.push("GoogleDataTransport") if @has_gdt_changes
-  labels.push("GoogleUtilities") if @has_googleutilities_changes
   labels.push("release-tooling") if @has_releasetooling_changes
   labels.push("public-api-change") if @has_api_changes
   return labels
@@ -113,7 +112,6 @@ has_license_changes = didModify(["LICENSE"])
 
 @has_gdt_changes = hasChangesIn(["GoogleDataTransport/"])
 @has_gdt_api_changes = hasChangesIn("GoogleDataTransport/GDTCORLibrary/Public")
-@has_googleutilities_changes = hasChangesIn("GoogleUtilities/")
 @has_releasetooling_changes = hasChangesIn("ReleaseTooling/")
 
 # Convenient flag for all API changes.

+ 3 - 1
Example/watchOSSample/Podfile

@@ -1,10 +1,12 @@
+source 'https://github.com/firebase/SpecsStaging.git'
+source 'https://cdn.cocoapods.org/'
+
 use_frameworks!
 
 target 'SampleWatchAppWatchKitExtension' do
   platform :watchos, '6.0'
 
   pod 'FirebaseCore', :path => '../../'
-  pod 'GoogleUtilities', :path => '../../'
   pod 'FirebaseMessaging', :path => '../../'
   pod 'FirebaseInstanceID', :path => '../../'
   pod 'FirebaseCoreDiagnostics', :path => '../../'

+ 0 - 1
FirebaseAuth/Tests/Sample/Podfile

@@ -12,7 +12,6 @@ target 'AuthSample' do
   pod 'FirebaseCore', :path => '../../../'
   pod 'FirebaseCoreDiagnostics', :path => '../../../'
   pod 'GoogleDataTransport', :path => '../../../'
-  pod 'GoogleUtilities', :path => '../../../'
   pod 'FirebaseAuth', :path => '../../../', :testspecs => ['unit']
   pod 'FirebaseInstallations', :path => '../../..'
   pod 'FirebaseInstanceID', :path => '../../..'

+ 3 - 1
FirebaseDynamicLinks/Tests/Sample/Podfile

@@ -1,3 +1,6 @@
+source 'https://github.com/firebase/SpecsStaging.git'
+source 'https://cdn.cocoapods.org/'
+
 target 'FDLBuilderTestAppObjC' do
   platform :ios, '10.0'
   use_frameworks!
@@ -5,6 +8,5 @@ target 'FDLBuilderTestAppObjC' do
   pod 'FirebaseCore', :path => '../../../'
   pod 'FirebaseCoreDiagnostics', :path => '../../../'
   pod 'GoogleDataTransport', :path => '../../../'
-  pod 'GoogleUtilities', :path => '../../../'
   pod 'FirebaseDynamicLinks', :path => '../../../'
 end

+ 0 - 1
FirebaseInAppMessaging/Tests/Integration/DefaultUITestApp/Podfile

@@ -7,7 +7,6 @@ pod 'FirebaseCore', :path => '../../../..'
 pod 'FirebaseInstallations', :path => '../../../..'
 pod 'FirebaseCoreDiagnostics', :path => '../../../..'
 pod 'GoogleDataTransport', :path => '../../../..'
-pod 'GoogleUtilities', :path => '../../../..'
 pod 'FirebaseABTesting', :path => '../../../..'
 
 target 'FiamDisplaySwiftExample' do

+ 0 - 1
FirebaseInAppMessaging/Tests/Integration/FunctionalTestApp/Podfile

@@ -8,7 +8,6 @@ pod 'FirebaseCore', :path => '../../../..'
 pod 'FirebaseInstallations', :path => '../../../..'
 pod 'FirebaseCoreDiagnostics', :path => '../../../..'
 pod 'GoogleDataTransport', :path => '../../../..'
-pod 'GoogleUtilities', :path => '../../../..'
 pod 'FirebaseABTesting', :path => '../../../..'
 
 target 'InAppMessaging_Example_iOS' do

+ 0 - 1
FirebaseMessaging/Apps/AdvancedSample/Podfile

@@ -5,7 +5,6 @@ source 'https://cdn.cocoapods.org/'
 
 def shared_pods
   pod 'FirebaseCore', :path => '../../../'
-  pod 'GoogleUtilities', :path => '../../../'
   pod 'FirebaseMessaging', :path => '../../../'
   pod 'FirebaseInstanceID', :path => '../../../'
   pod 'FirebaseCoreDiagnostics', :path => '../../../'

+ 0 - 1
FirebaseMessaging/Apps/Sample/Podfile

@@ -7,7 +7,6 @@ target 'Sample' do
   platform :ios, '13.0'
 
   pod 'FirebaseCore', :path => '../../../'
-  pod 'GoogleUtilities', :path => '../../../'
   pod 'FirebaseMessaging', :path => '../../../'
   pod 'FirebaseInstanceID', :path => '../../../'
   pod 'FirebaseCoreDiagnostics', :path => '../../../'

+ 3 - 2
FirebasePerformance/Tests/FIRPerfE2E/Podfile

@@ -1,3 +1,6 @@
+source 'https://github.com/firebase/SpecsStaging.git'
+source 'https://cdn.cocoapods.org/'
+
 # Uncomment the next line to define a global platform for your project
 platform :ios, '10.0'
 
@@ -12,7 +15,6 @@ target 'FIRPerfE2EAutopush' do
   pod 'FirebaseRemoteConfig', :path => '../../../'
   pod 'FirebaseABTesting', :path => '../../../'
   pod 'FirebaseInstallations', :path => '../../../'
-  pod 'GoogleUtilities', :path => '../../../'
   pod 'FirebaseCoreDiagnostics', :path => '../../../'
 
   # Data transport dependencies
@@ -37,7 +39,6 @@ target 'FIRPerfE2EProd' do
   pod 'FirebaseRemoteConfig', :path => '../../../'
   pod 'FirebaseABTesting', :path => '../../../'
   pod 'FirebaseInstallations', :path => '../../../'
-  pod 'GoogleUtilities', :path => '../../../'
   pod 'FirebaseCoreDiagnostics', :path => '../../../'
 
   # Data transport dependencies

+ 0 - 1
FirebaseRemoteConfig/Tests/Sample/Podfile

@@ -14,7 +14,6 @@ target 'RemoteConfigSampleApp' do
   pod 'FirebaseRemoteConfig', :path => '../../../'
   pod 'FirebaseABTesting', :path => '../../..'
   pod 'GoogleDataTransport', :path => '../../..'
-  pod 'GoogleUtilities', :path => '../../..'
 
   # Pods for RemoteConfigSampleApp
 

+ 0 - 1
FirebaseSegmentation/Tests/Sample/Podfile

@@ -14,6 +14,5 @@ target 'SegmentationSampleApp' do
   pod 'FirebaseInstallations', :path => '../../../'
   pod 'FirebaseSegmentation', :path => '../../../'
   pod 'GoogleDataTransport', :path => '../../../'
-  pod 'GoogleUtilities', :path => '../../../'
 
 end

+ 0 - 1
Firestore/Example/Podfile

@@ -49,7 +49,6 @@ end
 def configure_local_pods()
   # Firestore is always local; that's what's under development here.
   pod 'FirebaseFirestore', :path => '../..'
-  pod 'GoogleUtilities', :path => '../..'
 
   # FirebaseCore must always be a local pod so that CI builds that make changes
   # to its podspec can still function. See Firestore-*-xcodebuild in

+ 0 - 1
GoogleDataTransport/GDTCCTWatchOSTestApp/Podfile

@@ -10,7 +10,6 @@ target 'GDTCCTWatchOSIndependentTestAppWatchKitExtension' do
   pod 'SwiftProtobuf', '~> 1.0'
   pod 'GoogleDataTransport', :path => '../../'
   pod 'FirebaseCore', :path => '../../'
-  pod 'GoogleUtilities', :path => '../../'
   pod 'FirebaseMessaging', :path => '../../'
   pod 'FirebaseInstanceID', :path => '../../'
   pod 'FirebaseCoreDiagnostics', :path => '../../'

+ 0 - 138
GoogleUtilities.podspec

@@ -1,138 +0,0 @@
-Pod::Spec.new do |s|
-  s.name             = 'GoogleUtilities'
-  s.version          = '7.2.0'
-  s.summary          = 'Google Utilities for iOS (plus community support for macOS and tvOS)'
-
-  s.description      = <<-DESC
-Internal Google Utilities including Network, Reachability Environment, Logger and Swizzling for
-other Google CocoaPods. They're not intended for direct public usage.
-                       DESC
-
-  s.homepage         = 'https://github.com/firebase/firebase-ios-sdk/tree/master/GoogleUtilities'
-  s.license          = { :type => 'Apache', :file => 'GoogleUtilities/LICENSE' }
-  s.authors          = 'Google, Inc.'
-
-  s.source           = {
-    :git => 'https://github.com/firebase/firebase-ios-sdk.git',
-    :tag => 'Utilities-' + s.version.to_s
-  }
-
-  s.ios.deployment_target = '9.0'
-  s.osx.deployment_target = '10.12'
-  s.tvos.deployment_target = '10.0'
-  s.watchos.deployment_target = '6.0'
-
-  s.cocoapods_version = '>= 1.4.0'
-  s.prefix_header_file = false
-
-  s.pod_target_xcconfig = {
-    'GCC_C_LANGUAGE_STANDARD' => 'c99',
-    'HEADER_SEARCH_PATHS' => '"${PODS_TARGET_SRCROOT}"',
-  }
-
-  s.subspec 'Environment' do |es|
-    es.source_files = 'GoogleUtilities/Environment/**/*.[mh]'
-    es.public_header_files = 'GoogleUtilities/Environment/Public/GoogleUtilities/*.h'
-    es.dependency 'PromisesObjC', '~> 1.2'
-  end
-
-  s.subspec 'Logger' do |ls|
-    ls.source_files = 'GoogleUtilities/Logger/**/*.[mh]'
-    ls.public_header_files = 'GoogleUtilities/Logger/Public/GoogleUtilities/*.h'
-    ls.dependency 'GoogleUtilities/Environment'
-  end
-
-
-  s.subspec 'Network' do |ns|
-    ns.source_files = 'GoogleUtilities/Network/**/*.[mh]'
-    ns.public_header_files = 'GoogleUtilities/Network/Public/GoogleUtilities/*.h'
-    ns.dependency 'GoogleUtilities/NSData+zlib'
-    ns.dependency 'GoogleUtilities/Logger'
-    ns.dependency 'GoogleUtilities/Reachability'
-    ns.frameworks = [
-      'Security'
-    ]
-  end
-
-  s.subspec 'NSData+zlib' do |ns|
-    ns.source_files = 'GoogleUtilities/NSData+zlib/**/*.[mh]'
-    ns.public_header_files = 'GoogleUtilities/NSData+zlib/Public/GoogleUtilities/*.h'
-    ns.libraries = [
-      'z'
-    ]
-  end
-
-  s.subspec 'Reachability' do |rs|
-    rs.source_files = 'GoogleUtilities/Reachability/**/*.[mh]'
-    rs.public_header_files = 'GoogleUtilities/Reachability/Public/GoogleUtilities/*.h'
-    rs.ios.frameworks = [
-      'SystemConfiguration'
-    ]
-    rs.osx.frameworks = [
-      'SystemConfiguration'
-    ]
-    rs.tvos.frameworks = [
-      'SystemConfiguration'
-    ]
-    rs.dependency 'GoogleUtilities/Logger'
-  end
-
-  s.subspec 'AppDelegateSwizzler' do |adss|
-    adss.source_files = [
-      'GoogleUtilities/AppDelegateSwizzler/Internal/*.h',
-      'GoogleUtilities/AppDelegateSwizzler/Public/**/*.h',
-      'GoogleUtilities/AppDelegateSwizzler/*.m',
-      'GoogleUtilities/Common/*.h',
-    ]
-    adss.public_header_files = [
-      'GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/*.h',
-    ]
-    adss.dependency 'GoogleUtilities/Logger'
-    adss.dependency 'GoogleUtilities/Network'
-    adss.dependency 'GoogleUtilities/Environment'
-  end
-
-  s.subspec 'ISASwizzler' do |iss|
-    iss.source_files = 'GoogleUtilities/ISASwizzler/**/*.[mh]', 'GoogleUtilities/Common/*.h'
-    iss.public_header_files = 'GoogleUtilities/ISASwizzler/Public/GoogleUtilities/*.h'
-  end
-
-  s.subspec 'MethodSwizzler' do |mss|
-    mss.source_files = 'GoogleUtilities/MethodSwizzler/**/*.[mh]', 'GoogleUtilities/Common/*.h'
-    mss.public_header_files = 'GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/*.h'
-    mss.dependency 'GoogleUtilities/Logger'
-  end
-
-  s.subspec 'SwizzlerTestHelpers' do |sths|
-    sths.source_files = 'GoogleUtilities/SwizzlerTestHelpers/**/*.[hm]'
-    sths.public_header_files = 'GoogleUtilities/SwizzlerTestHelpers/Public/GoogleUtilities/*.h'
-    sths.dependency 'GoogleUtilities/MethodSwizzler'
-  end
-
-  s.subspec 'UserDefaults' do |ud|
-    ud.source_files = 'GoogleUtilities/UserDefaults/**/*.[hm]'
-    ud.public_header_files = 'GoogleUtilities/UserDefaults/Public/GoogleUtilities/*.h'
-    ud.dependency 'GoogleUtilities/Logger'
-  end
-
-  s.test_spec 'unit' do |unit_tests|
-    unit_tests.scheme = { :code_coverage => true }
-    # All tests require arc except Tests/Network/third_party/GTMHTTPServer.m
-    unit_tests.platforms = {:ios => '8.0', :osx => '10.11', :tvos => '10.0'}
-    unit_tests.source_files = [
-      'GoogleUtilities/Tests/Unit/**/*.[mh]',
-      'SharedTestUtilities/URLSession/*.[mh]',
-  ]
-    unit_tests.requires_arc = 'GoogleUtilities/Tests/Unit/*/*.[mh]'
-    unit_tests.requires_app_host = true
-    unit_tests.dependency 'OCMock'
-  end
-
-  s.test_spec 'unit-swift' do |unit_tests_swift|
-    unit_tests_swift.scheme = { :code_coverage => true }
-    unit_tests_swift.platforms = {:ios => '8.0', :osx => '10.11', :tvos => '10.0'}
-    unit_tests_swift.source_files = 'GoogleUtilities/Tests/SwiftUnit/**/*.swift',
-                                    'GoogleUtilities/Tests/SwiftUnit/**/*.h'
-    unit_tests_swift.requires_app_host = true
-  end
-end

+ 0 - 1070
GoogleUtilities/AppDelegateSwizzler/GULAppDelegateSwizzler.m

@@ -1,1070 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import <TargetConditionals.h>
-
-#import "GoogleUtilities/AppDelegateSwizzler/Internal/GULAppDelegateSwizzler_Private.h"
-#import "GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULAppDelegateSwizzler.h"
-#import "GoogleUtilities/Common/GULLoggerCodes.h"
-#import "GoogleUtilities/Environment/Public/GoogleUtilities/GULAppEnvironmentUtil.h"
-#import "GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h"
-#import "GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h"
-
-#import <dispatch/group.h>
-#import <objc/runtime.h>
-
-// Implementations need to be typed before calling the implementation directly to cast the
-// arguments and the return types correctly. Otherwise, it will crash the app.
-typedef BOOL (*GULRealOpenURLSourceApplicationAnnotationIMP)(
-    id, SEL, GULApplication *, NSURL *, NSString *, id);
-
-typedef BOOL (*GULRealOpenURLOptionsIMP)(
-    id, SEL, GULApplication *, NSURL *, NSDictionary<NSString *, id> *);
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wstrict-prototypes"
-typedef void (*GULRealHandleEventsForBackgroundURLSessionIMP)(
-    id, SEL, GULApplication *, NSString *, void (^)());
-#pragma clang diagnostic pop
-
-typedef BOOL (*GULRealContinueUserActivityIMP)(
-    id, SEL, GULApplication *, NSUserActivity *, void (^)(NSArray *restorableObjects));
-
-typedef void (*GULRealDidRegisterForRemoteNotificationsIMP)(id, SEL, GULApplication *, NSData *);
-
-typedef void (*GULRealDidFailToRegisterForRemoteNotificationsIMP)(id,
-                                                                  SEL,
-                                                                  GULApplication *,
-                                                                  NSError *);
-
-typedef void (*GULRealDidReceiveRemoteNotificationIMP)(id, SEL, GULApplication *, NSDictionary *);
-
-#if !TARGET_OS_WATCH && !TARGET_OS_OSX
-typedef void (*GULRealDidReceiveRemoteNotificationWithCompletionIMP)(
-    id, SEL, GULApplication *, NSDictionary *, void (^)(UIBackgroundFetchResult));
-#endif  // !TARGET_OS_WATCH && !TARGET_OS_OSX
-
-typedef void (^GULAppDelegateInterceptorCallback)(id<GULApplicationDelegate>);
-
-// The strings below are the keys for associated objects.
-static char const *const kGULRealIMPBySelectorKey = "GUL_realIMPBySelector";
-static char const *const kGULRealClassKey = "GUL_realClass";
-
-static NSString *const kGULAppDelegateKeyPath = @"delegate";
-
-static GULLoggerService kGULLoggerSwizzler = @"[GoogleUtilities/AppDelegateSwizzler]";
-
-// Since Firebase SDKs also use this for app delegate proxying, in order to not be a breaking change
-// we disable App Delegate proxying when either of these two flags are set to NO.
-
-/** Plist key that allows Firebase developers to disable App and Scene Delegate Proxying. */
-static NSString *const kGULFirebaseAppDelegateProxyEnabledPlistKey =
-    @"FirebaseAppDelegateProxyEnabled";
-
-/** Plist key that allows developers not using Firebase to disable App and Scene Delegate Proxying.
- */
-static NSString *const kGULGoogleUtilitiesAppDelegateProxyEnabledPlistKey =
-    @"GoogleUtilitiesAppDelegateProxyEnabled";
-
-/** The prefix of the App Delegate. */
-static NSString *const kGULAppDelegatePrefix = @"GUL_";
-
-/** The original instance of App Delegate. */
-static id<GULApplicationDelegate> gOriginalAppDelegate;
-
-/** The original App Delegate class */
-static Class gOriginalAppDelegateClass;
-
-/** The subclass of the original App Delegate. */
-static Class gAppDelegateSubclass;
-
-/** Remote notification methods selectors
- *
- *  We have to opt out of referencing APNS related App Delegate methods directly to prevent
- *  an Apple review warning email about missing Push Notification Entitlement
- *  (like here: https://github.com/firebase/firebase-ios-sdk/issues/2807). From our experience, the
- *  warning is triggered when any of the symbols is present in the application sent to review, even
- *  if the code is never executed. Because GULAppDelegateSwizzler may be used by applications that
- *  are not using APNS we have to refer to the methods indirectly using selector constructed from
- *  string.
- *
- *  NOTE: None of the methods is proxied unless it is explicitly requested by calling the method
- *  +[GULAppDelegateSwizzler proxyOriginalDelegateIncludingAPNSMethods]
- */
-static NSString *const kGULDidRegisterForRemoteNotificationsSEL =
-    @"application:didRegisterForRemoteNotificationsWithDeviceToken:";
-static NSString *const kGULDidFailToRegisterForRemoteNotificationsSEL =
-    @"application:didFailToRegisterForRemoteNotificationsWithError:";
-static NSString *const kGULDidReceiveRemoteNotificationSEL =
-    @"application:didReceiveRemoteNotification:";
-static NSString *const kGULDidReceiveRemoteNotificationWithCompletionSEL =
-    @"application:didReceiveRemoteNotification:fetchCompletionHandler:";
-
-/**
- * This class is necessary to store the delegates in an NSArray without retaining them.
- * [NSValue valueWithNonRetainedObject] also provides this functionality, but does not provide a
- * zeroing pointer. This will cause EXC_BAD_ACCESS when trying to access the object after it is
- * dealloced. Instead, this container stores a weak, zeroing reference to the object, which
- * automatically is set to nil by the runtime when the object is dealloced.
- */
-@interface GULZeroingWeakContainer : NSObject
-
-/** Stores a weak object. */
-@property(nonatomic, weak) id object;
-
-@end
-
-@implementation GULZeroingWeakContainer
-@end
-
-@interface GULAppDelegateObserver : NSObject
-@end
-
-@implementation GULAppDelegateObserver {
-  BOOL _isObserving;
-}
-
-+ (GULAppDelegateObserver *)sharedInstance {
-  static GULAppDelegateObserver *instance;
-  static dispatch_once_t once;
-  dispatch_once(&once, ^{
-    instance = [[GULAppDelegateObserver alloc] init];
-  });
-  return instance;
-}
-
-- (void)observeUIApplication {
-  if (_isObserving) {
-    return;
-  }
-  [[GULAppDelegateSwizzler sharedApplication]
-      addObserver:self
-       forKeyPath:kGULAppDelegateKeyPath
-          options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
-          context:nil];
-  _isObserving = YES;
-}
-
-- (void)observeValueForKeyPath:(NSString *)keyPath
-                      ofObject:(id)object
-                        change:(NSDictionary *)change
-                       context:(void *)context {
-  if ([keyPath isEqual:kGULAppDelegateKeyPath]) {
-    id newValue = change[NSKeyValueChangeNewKey];
-    id oldValue = change[NSKeyValueChangeOldKey];
-    if ([newValue isEqual:oldValue]) {
-      return;
-    }
-    // Free the stored app delegate instance because it has been changed to a different instance to
-    // avoid keeping it alive forever.
-    if ([oldValue isEqual:gOriginalAppDelegate]) {
-      gOriginalAppDelegate = nil;
-      // Remove the observer. Parse it to NSObject to avoid warning.
-      [[GULAppDelegateSwizzler sharedApplication] removeObserver:self
-                                                      forKeyPath:kGULAppDelegateKeyPath];
-      _isObserving = NO;
-    }
-  }
-}
-
-@end
-
-@implementation GULAppDelegateSwizzler
-
-static dispatch_once_t sProxyAppDelegateOnceToken;
-static dispatch_once_t sProxyAppDelegateRemoteNotificationOnceToken;
-
-#pragma mark - Public methods
-
-+ (BOOL)isAppDelegateProxyEnabled {
-  NSDictionary *infoDictionary = [NSBundle mainBundle].infoDictionary;
-
-  id isFirebaseProxyEnabledPlistValue = infoDictionary[kGULFirebaseAppDelegateProxyEnabledPlistKey];
-  id isGoogleProxyEnabledPlistValue =
-      infoDictionary[kGULGoogleUtilitiesAppDelegateProxyEnabledPlistKey];
-
-  // Enabled by default.
-  BOOL isFirebaseAppDelegateProxyEnabled = YES;
-  BOOL isGoogleUtilitiesAppDelegateProxyEnabled = YES;
-
-  if ([isFirebaseProxyEnabledPlistValue isKindOfClass:[NSNumber class]]) {
-    isFirebaseAppDelegateProxyEnabled = [isFirebaseProxyEnabledPlistValue boolValue];
-  }
-
-  if ([isGoogleProxyEnabledPlistValue isKindOfClass:[NSNumber class]]) {
-    isGoogleUtilitiesAppDelegateProxyEnabled = [isGoogleProxyEnabledPlistValue boolValue];
-  }
-
-  // Only deactivate the proxy if it is explicitly disabled by app developers using either one of
-  // the plist flags.
-  return isFirebaseAppDelegateProxyEnabled && isGoogleUtilitiesAppDelegateProxyEnabled;
-}
-
-+ (GULAppDelegateInterceptorID)registerAppDelegateInterceptor:
-    (id<GULApplicationDelegate>)interceptor {
-  NSAssert(interceptor, @"AppDelegateProxy cannot add nil interceptor");
-  NSAssert([interceptor conformsToProtocol:@protocol(GULApplicationDelegate)],
-           @"AppDelegateProxy interceptor does not conform to UIApplicationDelegate");
-
-  if (!interceptor) {
-    GULLogError(kGULLoggerSwizzler, NO,
-                [NSString stringWithFormat:@"I-SWZ%06ld",
-                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling000],
-                @"AppDelegateProxy cannot add nil interceptor.");
-    return nil;
-  }
-  if (![interceptor conformsToProtocol:@protocol(GULApplicationDelegate)]) {
-    GULLogError(kGULLoggerSwizzler, NO,
-                [NSString stringWithFormat:@"I-SWZ%06ld",
-                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling001],
-                @"AppDelegateProxy interceptor does not conform to UIApplicationDelegate");
-    return nil;
-  }
-
-  // The ID should be the same given the same interceptor object.
-  NSString *interceptorID = [NSString stringWithFormat:@"%@%p", kGULAppDelegatePrefix, interceptor];
-  if (!interceptorID.length) {
-    GULLogError(kGULLoggerSwizzler, NO,
-                [NSString stringWithFormat:@"I-SWZ%06ld",
-                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling002],
-                @"AppDelegateProxy cannot create Interceptor ID.");
-    return nil;
-  }
-  GULZeroingWeakContainer *weakObject = [[GULZeroingWeakContainer alloc] init];
-  weakObject.object = interceptor;
-  [GULAppDelegateSwizzler interceptors][interceptorID] = weakObject;
-  return interceptorID;
-}
-
-+ (void)unregisterAppDelegateInterceptorWithID:(GULAppDelegateInterceptorID)interceptorID {
-  NSAssert(interceptorID, @"AppDelegateProxy cannot unregister nil interceptor ID.");
-  NSAssert(((NSString *)interceptorID).length != 0,
-           @"AppDelegateProxy cannot unregister empty interceptor ID.");
-
-  if (!interceptorID) {
-    GULLogError(kGULLoggerSwizzler, NO,
-                [NSString stringWithFormat:@"I-SWZ%06ld",
-                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling003],
-                @"AppDelegateProxy cannot unregister empty interceptor ID.");
-    return;
-  }
-
-  GULZeroingWeakContainer *weakContainer = [GULAppDelegateSwizzler interceptors][interceptorID];
-  if (!weakContainer.object) {
-    GULLogError(kGULLoggerSwizzler, NO,
-                [NSString stringWithFormat:@"I-SWZ%06ld",
-                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling004],
-                @"AppDelegateProxy cannot unregister interceptor that was not registered. "
-                 "Interceptor ID %@",
-                interceptorID);
-    return;
-  }
-
-  [[GULAppDelegateSwizzler interceptors] removeObjectForKey:interceptorID];
-}
-
-+ (void)proxyOriginalDelegate {
-  if ([GULAppEnvironmentUtil isAppExtension]) {
-    return;
-  }
-
-  dispatch_once(&sProxyAppDelegateOnceToken, ^{
-    id<GULApplicationDelegate> originalDelegate =
-        [GULAppDelegateSwizzler sharedApplication].delegate;
-    [GULAppDelegateSwizzler proxyAppDelegate:originalDelegate];
-  });
-}
-
-+ (void)proxyOriginalDelegateIncludingAPNSMethods {
-  if ([GULAppEnvironmentUtil isAppExtension]) {
-    return;
-  }
-
-  [self proxyOriginalDelegate];
-
-  dispatch_once(&sProxyAppDelegateRemoteNotificationOnceToken, ^{
-    id<GULApplicationDelegate> appDelegate = [GULAppDelegateSwizzler sharedApplication].delegate;
-
-    NSMutableDictionary *realImplementationsBySelector =
-        [objc_getAssociatedObject(appDelegate, &kGULRealIMPBySelectorKey) mutableCopy];
-
-    [self proxyRemoteNotificationsMethodsWithAppDelegateSubClass:gAppDelegateSubclass
-                                                       realClass:gOriginalAppDelegateClass
-                                                     appDelegate:appDelegate
-                                   realImplementationsBySelector:realImplementationsBySelector];
-
-    objc_setAssociatedObject(appDelegate, &kGULRealIMPBySelectorKey,
-                             [realImplementationsBySelector copy], OBJC_ASSOCIATION_RETAIN);
-    [self reassignAppDelegate];
-  });
-}
-
-#pragma mark - Create proxy
-
-+ (GULApplication *)sharedApplication {
-  if ([GULAppEnvironmentUtil isAppExtension]) {
-    return nil;
-  }
-  id sharedApplication = nil;
-  Class uiApplicationClass = NSClassFromString(kGULApplicationClassName);
-  if (uiApplicationClass &&
-      [uiApplicationClass respondsToSelector:(NSSelectorFromString(@"sharedApplication"))]) {
-    sharedApplication = [uiApplicationClass sharedApplication];
-  }
-  return sharedApplication;
-}
-
-#pragma mark - Override default methods
-
-/** Creates a new subclass of the class of the given object and sets the isa value of the given
- *  object to the new subclass. Additionally this copies methods to that new subclass that allow us
- *  to intercept UIApplicationDelegate methods. This is better known as isa swizzling.
- *
- *  @param appDelegate The object to which you want to isa swizzle. This has to conform to the
- *      UIApplicationDelegate subclass.
- *  @return Returns the new subclass.
- */
-+ (nullable Class)createSubclassWithObject:(id<GULApplicationDelegate>)appDelegate {
-  Class realClass = [appDelegate class];
-
-  // Create GUL_<RealAppDelegate>_<UUID>
-  NSString *classNameWithPrefix =
-      [kGULAppDelegatePrefix stringByAppendingString:NSStringFromClass(realClass)];
-  NSString *newClassName =
-      [NSString stringWithFormat:@"%@-%@", classNameWithPrefix, [NSUUID UUID].UUIDString];
-
-  if (NSClassFromString(newClassName)) {
-    GULLogError(kGULLoggerSwizzler, NO,
-                [NSString stringWithFormat:@"I-SWZ%06ld",
-                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling005],
-                @"Cannot create a proxy for App Delegate. Subclass already exists. Original Class: "
-                @"%@, subclass: %@",
-                NSStringFromClass(realClass), newClassName);
-    return nil;
-  }
-
-  // Register the new class as subclass of the real one. Do not allocate more than the real class
-  // size.
-  Class appDelegateSubClass = objc_allocateClassPair(realClass, newClassName.UTF8String, 0);
-  if (appDelegateSubClass == Nil) {
-    GULLogError(kGULLoggerSwizzler, NO,
-                [NSString stringWithFormat:@"I-SWZ%06ld",
-                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling006],
-                @"Cannot create a proxy for App Delegate. Subclass already exists. Original Class: "
-                @"%@, subclass: Nil",
-                NSStringFromClass(realClass));
-    return nil;
-  }
-
-  NSMutableDictionary<NSString *, NSValue *> *realImplementationsBySelector =
-      [[NSMutableDictionary alloc] init];
-
-  // For application:continueUserActivity:restorationHandler:
-  SEL continueUserActivitySEL = @selector(application:continueUserActivity:restorationHandler:);
-  [self proxyDestinationSelector:continueUserActivitySEL
-      implementationsFromSourceSelector:continueUserActivitySEL
-                              fromClass:[GULAppDelegateSwizzler class]
-                                toClass:appDelegateSubClass
-                              realClass:realClass
-       storeDestinationImplementationTo:realImplementationsBySelector];
-
-#if TARGET_OS_IOS || TARGET_OS_TV
-  // Add the following methods from GULAppDelegate class, and store the real implementation so it
-  // can forward to the real one.
-  // For application:openURL:options:
-  SEL applicationOpenURLOptionsSEL = @selector(application:openURL:options:);
-  if ([appDelegate respondsToSelector:applicationOpenURLOptionsSEL]) {
-    // Only add the application:openURL:options: method if the original AppDelegate implements it.
-    // This fixes a bug if an app only implements application:openURL:sourceApplication:annotation:
-    // (if we add the `options` method, iOS sees that one exists and does not call the
-    // `sourceApplication` method, which in this case is the only one the app implements).
-
-    [self proxyDestinationSelector:applicationOpenURLOptionsSEL
-        implementationsFromSourceSelector:applicationOpenURLOptionsSEL
-                                fromClass:[GULAppDelegateSwizzler class]
-                                  toClass:appDelegateSubClass
-                                realClass:realClass
-         storeDestinationImplementationTo:realImplementationsBySelector];
-  }
-
-  // For application:handleEventsForBackgroundURLSession:completionHandler:
-  SEL handleEventsForBackgroundURLSessionSEL = @selector(application:
-                                 handleEventsForBackgroundURLSession:completionHandler:);
-  [self proxyDestinationSelector:handleEventsForBackgroundURLSessionSEL
-      implementationsFromSourceSelector:handleEventsForBackgroundURLSessionSEL
-                              fromClass:[GULAppDelegateSwizzler class]
-                                toClass:appDelegateSubClass
-                              realClass:realClass
-       storeDestinationImplementationTo:realImplementationsBySelector];
-#endif  // TARGET_OS_IOS || TARGET_OS_TV
-
-#if TARGET_OS_IOS
-  // For application:openURL:sourceApplication:annotation:
-  SEL openURLSourceApplicationAnnotationSEL = @selector(application:
-                                                            openURL:sourceApplication:annotation:);
-
-  [self proxyDestinationSelector:openURLSourceApplicationAnnotationSEL
-      implementationsFromSourceSelector:openURLSourceApplicationAnnotationSEL
-                              fromClass:[GULAppDelegateSwizzler class]
-                                toClass:appDelegateSubClass
-                              realClass:realClass
-       storeDestinationImplementationTo:realImplementationsBySelector];
-#endif  // TARGET_OS_IOS
-
-  // Override the description too so the custom class name will not show up.
-  [GULAppDelegateSwizzler addInstanceMethodWithDestinationSelector:@selector(description)
-                              withImplementationFromSourceSelector:@selector(fakeDescription)
-                                                         fromClass:[self class]
-                                                           toClass:appDelegateSubClass];
-
-  // Store original implementations to a fake property of the original delegate.
-  objc_setAssociatedObject(appDelegate, &kGULRealIMPBySelectorKey,
-                           [realImplementationsBySelector copy], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
-  objc_setAssociatedObject(appDelegate, &kGULRealClassKey, realClass,
-                           OBJC_ASSOCIATION_RETAIN_NONATOMIC);
-
-  // The subclass size has to be exactly the same size with the original class size. The subclass
-  // cannot have more ivars/properties than its superclass since it will cause an offset in memory
-  // that can lead to overwriting the isa of an object in the next frame.
-  if (class_getInstanceSize(realClass) != class_getInstanceSize(appDelegateSubClass)) {
-    GULLogError(kGULLoggerSwizzler, NO,
-                [NSString stringWithFormat:@"I-SWZ%06ld",
-                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling007],
-                @"Cannot create subclass of App Delegate, because the created subclass is not the "
-                @"same size. %@",
-                NSStringFromClass(realClass));
-    NSAssert(NO, @"Classes must be the same size to swizzle isa");
-    return nil;
-  }
-
-  // Make the newly created class to be the subclass of the real App Delegate class.
-  objc_registerClassPair(appDelegateSubClass);
-  if (object_setClass(appDelegate, appDelegateSubClass)) {
-    GULLogDebug(kGULLoggerSwizzler, NO,
-                [NSString stringWithFormat:@"I-SWZ%06ld",
-                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling008],
-                @"Successfully created App Delegate Proxy automatically. To disable the "
-                @"proxy, set the flag %@ to NO (Boolean) in the Info.plist",
-                [GULAppDelegateSwizzler correctAppDelegateProxyKey]);
-  }
-
-  return appDelegateSubClass;
-}
-
-+ (void)proxyRemoteNotificationsMethodsWithAppDelegateSubClass:(Class)appDelegateSubClass
-                                                     realClass:(Class)realClass
-                                                   appDelegate:(id)appDelegate
-                                 realImplementationsBySelector:
-                                     (NSMutableDictionary *)realImplementationsBySelector {
-  if (realClass == nil || appDelegateSubClass == nil || appDelegate == nil ||
-      realImplementationsBySelector == nil) {
-    // The App Delegate has not been swizzled.
-    return;
-  }
-
-  // For application:didRegisterForRemoteNotificationsWithDeviceToken:
-  SEL didRegisterForRemoteNotificationsSEL =
-      NSSelectorFromString(kGULDidRegisterForRemoteNotificationsSEL);
-  SEL didRegisterForRemoteNotificationsDonorSEL = @selector(application:
-                 donor_didRegisterForRemoteNotificationsWithDeviceToken:);
-
-  [self proxyDestinationSelector:didRegisterForRemoteNotificationsSEL
-      implementationsFromSourceSelector:didRegisterForRemoteNotificationsDonorSEL
-                              fromClass:[GULAppDelegateSwizzler class]
-                                toClass:appDelegateSubClass
-                              realClass:realClass
-       storeDestinationImplementationTo:realImplementationsBySelector];
-
-  // For application:didFailToRegisterForRemoteNotificationsWithError:
-  SEL didFailToRegisterForRemoteNotificationsSEL =
-      NSSelectorFromString(kGULDidFailToRegisterForRemoteNotificationsSEL);
-  SEL didFailToRegisterForRemoteNotificationsDonorSEL = @selector(application:
-                       donor_didFailToRegisterForRemoteNotificationsWithError:);
-
-  [self proxyDestinationSelector:didFailToRegisterForRemoteNotificationsSEL
-      implementationsFromSourceSelector:didFailToRegisterForRemoteNotificationsDonorSEL
-                              fromClass:[GULAppDelegateSwizzler class]
-                                toClass:appDelegateSubClass
-                              realClass:realClass
-       storeDestinationImplementationTo:realImplementationsBySelector];
-
-  // For application:didReceiveRemoteNotification:
-  SEL didReceiveRemoteNotificationSEL = NSSelectorFromString(kGULDidReceiveRemoteNotificationSEL);
-  SEL didReceiveRemoteNotificationDonotSEL = @selector(application:
-                                donor_didReceiveRemoteNotification:);
-
-  [self proxyDestinationSelector:didReceiveRemoteNotificationSEL
-      implementationsFromSourceSelector:didReceiveRemoteNotificationDonotSEL
-                              fromClass:[GULAppDelegateSwizzler class]
-                                toClass:appDelegateSubClass
-                              realClass:realClass
-       storeDestinationImplementationTo:realImplementationsBySelector];
-
-  // For application:didReceiveRemoteNotification:fetchCompletionHandler:
-#if !TARGET_OS_WATCH && !TARGET_OS_OSX
-  SEL didReceiveRemoteNotificationWithCompletionSEL =
-      NSSelectorFromString(kGULDidReceiveRemoteNotificationWithCompletionSEL);
-  SEL didReceiveRemoteNotificationWithCompletionDonorSEL =
-      @selector(application:donor_didReceiveRemoteNotification:fetchCompletionHandler:);
-  if ([appDelegate respondsToSelector:didReceiveRemoteNotificationWithCompletionSEL]) {
-    // Only add the application:didReceiveRemoteNotification:fetchCompletionHandler: method if
-    // the original AppDelegate implements it.
-    // This fixes a bug if an app only implements application:didReceiveRemoteNotification:
-    // (if we add the method with completion, iOS sees that one exists and does not call
-    // the method without the completion, which in this case is the only one the app implements).
-
-    [self proxyDestinationSelector:didReceiveRemoteNotificationWithCompletionSEL
-        implementationsFromSourceSelector:didReceiveRemoteNotificationWithCompletionDonorSEL
-                                fromClass:[GULAppDelegateSwizzler class]
-                                  toClass:appDelegateSubClass
-                                realClass:realClass
-         storeDestinationImplementationTo:realImplementationsBySelector];
-  }
-#endif  // !TARGET_OS_WATCH && !TARGET_OS_OSX
-}
-
-/// We have to do this to invalidate the cache that caches the original respondsToSelector of
-/// openURL handlers. Without this, it won't call the default implementations because the system
-/// checks and caches them.
-/// Register KVO only once. Otherwise, the observing method will be called as many times as
-/// being registered.
-+ (void)reassignAppDelegate {
-#if !TARGET_OS_WATCH
-  id<GULApplicationDelegate> delegate = [self sharedApplication].delegate;
-  [self sharedApplication].delegate = nil;
-  [self sharedApplication].delegate = delegate;
-  gOriginalAppDelegate = delegate;
-  [[GULAppDelegateObserver sharedInstance] observeUIApplication];
-#endif
-}
-
-#pragma mark - Helper methods
-
-+ (GULMutableDictionary *)interceptors {
-  static dispatch_once_t onceToken;
-  static GULMutableDictionary *sInterceptors;
-  dispatch_once(&onceToken, ^{
-    sInterceptors = [[GULMutableDictionary alloc] init];
-  });
-  return sInterceptors;
-}
-
-+ (nullable NSValue *)originalImplementationForSelector:(SEL)selector object:(id)object {
-  NSDictionary *realImplementationBySelector =
-      objc_getAssociatedObject(object, &kGULRealIMPBySelectorKey);
-  return realImplementationBySelector[NSStringFromSelector(selector)];
-}
-
-+ (void)proxyDestinationSelector:(SEL)destinationSelector
-    implementationsFromSourceSelector:(SEL)sourceSelector
-                            fromClass:(Class)sourceClass
-                              toClass:(Class)destinationClass
-                            realClass:(Class)realClass
-     storeDestinationImplementationTo:
-         (NSMutableDictionary<NSString *, NSValue *> *)destinationImplementationsBySelector {
-  [self addInstanceMethodWithDestinationSelector:destinationSelector
-            withImplementationFromSourceSelector:sourceSelector
-                                       fromClass:sourceClass
-                                         toClass:destinationClass];
-  IMP sourceImplementation =
-      [GULAppDelegateSwizzler implementationOfMethodSelector:destinationSelector
-                                                   fromClass:realClass];
-  NSValue *sourceImplementationPointer = [NSValue valueWithPointer:sourceImplementation];
-
-  NSString *destinationSelectorString = NSStringFromSelector(destinationSelector);
-  destinationImplementationsBySelector[destinationSelectorString] = sourceImplementationPointer;
-}
-
-/** Copies a method identified by the methodSelector from one class to the other. After this method
- *  is called, performing [toClassInstance methodSelector] will be similar to calling
- *  [fromClassInstance methodSelector]. This method does nothing if toClass already has a method
- *  identified by methodSelector.
- *
- *  @param methodSelector The SEL that identifies both the method on the fromClass as well as the
- *      one on the toClass.
- *  @param fromClass The class from which a method is sourced.
- *  @param toClass The class to which the method is added. If the class already has a method with
- *      the same selector, this has no effect.
- */
-+ (void)addInstanceMethodWithSelector:(SEL)methodSelector
-                            fromClass:(Class)fromClass
-                              toClass:(Class)toClass {
-  [self addInstanceMethodWithDestinationSelector:methodSelector
-            withImplementationFromSourceSelector:methodSelector
-                                       fromClass:fromClass
-                                         toClass:toClass];
-}
-
-/** Copies a method identified by the sourceSelector from the fromClass as a method for the
- *  destinationSelector on the toClass. After this method is called, performing
- *  [toClassInstance destinationSelector] will be similar to calling
- *  [fromClassInstance sourceSelector]. This method does nothing if toClass already has a method
- *  identified by destinationSelector.
- *
- *  @param destinationSelector The SEL that identifies the method on the toClass.
- *  @param sourceSelector The SEL that identifies the method on the fromClass.
- *  @param fromClass The class from which a method is sourced.
- *  @param toClass The class to which the method is added. If the class already has a method with
- *      the same selector, this has no effect.
- */
-+ (void)addInstanceMethodWithDestinationSelector:(SEL)destinationSelector
-            withImplementationFromSourceSelector:(SEL)sourceSelector
-                                       fromClass:(Class)fromClass
-                                         toClass:(Class)toClass {
-  Method method = class_getInstanceMethod(fromClass, sourceSelector);
-  IMP methodIMP = method_getImplementation(method);
-  const char *types = method_getTypeEncoding(method);
-  if (!class_addMethod(toClass, destinationSelector, methodIMP, types)) {
-    GULLogWarning(kGULLoggerSwizzler, NO,
-                  [NSString stringWithFormat:@"I-SWZ%06ld",
-                                             (long)kGULSwizzlerMessageCodeAppDelegateSwizzling009],
-                  @"Cannot copy method to destination selector %@ as it already exists",
-                  NSStringFromSelector(destinationSelector));
-  }
-}
-
-/** Gets the IMP of the instance method on the class identified by the selector.
- *
- *  @param selector The selector of which the IMP is to be fetched.
- *  @param aClass The class from which the IMP is to be fetched.
- *  @return The IMP of the instance method identified by selector and aClass.
- */
-+ (IMP)implementationOfMethodSelector:(SEL)selector fromClass:(Class)aClass {
-  Method aMethod = class_getInstanceMethod(aClass, selector);
-  return method_getImplementation(aMethod);
-}
-
-/** Enumerates through all the interceptors and if they respond to a given selector, executes a
- *  GULAppDelegateInterceptorCallback with the interceptor.
- *
- *  @param methodSelector The SEL to check if an interceptor responds to.
- *  @param callback the GULAppDelegateInterceptorCallback.
- */
-+ (void)notifyInterceptorsWithMethodSelector:(SEL)methodSelector
-                                    callback:(GULAppDelegateInterceptorCallback)callback {
-  if (!callback) {
-    return;
-  }
-
-  NSDictionary *interceptors = [GULAppDelegateSwizzler interceptors].dictionary;
-  [interceptors enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
-    GULZeroingWeakContainer *interceptorContainer = obj;
-    id interceptor = interceptorContainer.object;
-    if (!interceptor) {
-      GULLogWarning(
-          kGULLoggerSwizzler, NO,
-          [NSString
-              stringWithFormat:@"I-SWZ%06ld", (long)kGULSwizzlerMessageCodeAppDelegateSwizzling010],
-          @"AppDelegateProxy cannot find interceptor with ID %@. Removing the interceptor.", key);
-      [[GULAppDelegateSwizzler interceptors] removeObjectForKey:key];
-      return;
-    }
-    if ([interceptor respondsToSelector:methodSelector]) {
-      callback(interceptor);
-    }
-  }];
-}
-
-// The methods below are donor methods which are added to the dynamic subclass of the App Delegate.
-// They are called within the scope of the real App Delegate so |self| does not refer to the
-// GULAppDelegateSwizzler instance but the real App Delegate instance.
-
-#pragma mark - [Donor Methods] Overridden instance description method
-
-- (NSString *)fakeDescription {
-  Class realClass = objc_getAssociatedObject(self, &kGULRealClassKey);
-  return [NSString stringWithFormat:@"<%@: %p>", realClass, self];
-}
-
-#pragma mark - [Donor Methods] URL overridden handler methods
-#if TARGET_OS_IOS || TARGET_OS_TV
-
-- (BOOL)application:(GULApplication *)application
-            openURL:(NSURL *)url
-            options:(NSDictionary<NSString *, id> *)options {
-  SEL methodSelector = @selector(application:openURL:options:);
-  // Call the real implementation if the real App Delegate has any.
-  NSValue *openURLIMPPointer =
-      [GULAppDelegateSwizzler originalImplementationForSelector:methodSelector object:self];
-  GULRealOpenURLOptionsIMP openURLOptionsIMP = [openURLIMPPointer pointerValue];
-
-  __block BOOL returnedValue = NO;
-
-// This is needed to for the library to be warning free on iOS versions < 9.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunguarded-availability"
-  [GULAppDelegateSwizzler
-      notifyInterceptorsWithMethodSelector:methodSelector
-                                  callback:^(id<GULApplicationDelegate> interceptor) {
-                                    returnedValue |= [interceptor application:application
-                                                                      openURL:url
-                                                                      options:options];
-                                  }];
-#pragma clang diagnostic pop
-  if (openURLOptionsIMP) {
-    returnedValue |= openURLOptionsIMP(self, methodSelector, application, url, options);
-  }
-  return returnedValue;
-}
-
-#endif  // TARGET_OS_IOS || TARGET_OS_TV
-
-#if TARGET_OS_IOS
-
-- (BOOL)application:(GULApplication *)application
-              openURL:(NSURL *)url
-    sourceApplication:(NSString *)sourceApplication
-           annotation:(id)annotation {
-  SEL methodSelector = @selector(application:openURL:sourceApplication:annotation:);
-
-  // Call the real implementation if the real App Delegate has any.
-  NSValue *openURLSourceAppAnnotationIMPPointer =
-      [GULAppDelegateSwizzler originalImplementationForSelector:methodSelector object:self];
-  GULRealOpenURLSourceApplicationAnnotationIMP openURLSourceApplicationAnnotationIMP =
-      [openURLSourceAppAnnotationIMPPointer pointerValue];
-
-  __block BOOL returnedValue = NO;
-  [GULAppDelegateSwizzler
-      notifyInterceptorsWithMethodSelector:methodSelector
-                                  callback:^(id<GULApplicationDelegate> interceptor) {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-                                    returnedValue |= [interceptor application:application
-                                                                      openURL:url
-                                                            sourceApplication:sourceApplication
-                                                                   annotation:annotation];
-#pragma clang diagnostic pop
-                                  }];
-  if (openURLSourceApplicationAnnotationIMP) {
-    returnedValue |= openURLSourceApplicationAnnotationIMP(self, methodSelector, application, url,
-                                                           sourceApplication, annotation);
-  }
-  return returnedValue;
-}
-
-#endif  // TARGET_OS_IOS
-
-#pragma mark - [Donor Methods] Network overridden handler methods
-
-#if TARGET_OS_IOS || TARGET_OS_TV
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wstrict-prototypes"
-- (void)application:(GULApplication *)application
-    handleEventsForBackgroundURLSession:(NSString *)identifier
-                      completionHandler:(void (^)())completionHandler API_AVAILABLE(ios(7.0)) {
-#pragma clang diagnostic pop
-  SEL methodSelector = @selector(application:
-         handleEventsForBackgroundURLSession:completionHandler:);
-  NSValue *handleBackgroundSessionPointer =
-      [GULAppDelegateSwizzler originalImplementationForSelector:methodSelector object:self];
-  GULRealHandleEventsForBackgroundURLSessionIMP handleBackgroundSessionIMP =
-      [handleBackgroundSessionPointer pointerValue];
-
-  // Notify interceptors.
-  [GULAppDelegateSwizzler
-      notifyInterceptorsWithMethodSelector:methodSelector
-                                  callback:^(id<GULApplicationDelegate> interceptor) {
-                                    [interceptor application:application
-                                        handleEventsForBackgroundURLSession:identifier
-                                                          completionHandler:completionHandler];
-                                  }];
-  // Call the real implementation if the real App Delegate has any.
-  if (handleBackgroundSessionIMP) {
-    handleBackgroundSessionIMP(self, methodSelector, application, identifier, completionHandler);
-  }
-}
-
-#endif  // TARGET_OS_IOS || TARGET_OS_TV
-
-#pragma mark - [Donor Methods] User Activities overridden handler methods
-
-- (BOOL)application:(GULApplication *)application
-    continueUserActivity:(NSUserActivity *)userActivity
-      restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {
-  SEL methodSelector = @selector(application:continueUserActivity:restorationHandler:);
-  NSValue *continueUserActivityIMPPointer =
-      [GULAppDelegateSwizzler originalImplementationForSelector:methodSelector object:self];
-  GULRealContinueUserActivityIMP continueUserActivityIMP =
-      continueUserActivityIMPPointer.pointerValue;
-
-  __block BOOL returnedValue = NO;
-#if !TARGET_OS_WATCH
-  [GULAppDelegateSwizzler
-      notifyInterceptorsWithMethodSelector:methodSelector
-                                  callback:^(id<GULApplicationDelegate> interceptor) {
-                                    returnedValue |= [interceptor application:application
-                                                         continueUserActivity:userActivity
-                                                           restorationHandler:restorationHandler];
-                                  }];
-#endif
-  // Call the real implementation if the real App Delegate has any.
-  if (continueUserActivityIMP) {
-    returnedValue |= continueUserActivityIMP(self, methodSelector, application, userActivity,
-                                             restorationHandler);
-  }
-  return returnedValue;
-}
-
-#pragma mark - [Donor Methods] Remote Notifications
-
-- (void)application:(GULApplication *)application
-    donor_didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
-  SEL methodSelector = NSSelectorFromString(kGULDidRegisterForRemoteNotificationsSEL);
-
-  NSValue *didRegisterForRemoteNotificationsIMPPointer =
-      [GULAppDelegateSwizzler originalImplementationForSelector:methodSelector object:self];
-  GULRealDidRegisterForRemoteNotificationsIMP didRegisterForRemoteNotificationsIMP =
-      [didRegisterForRemoteNotificationsIMPPointer pointerValue];
-
-  // Notify interceptors.
-  [GULAppDelegateSwizzler
-      notifyInterceptorsWithMethodSelector:methodSelector
-                                  callback:^(id<GULApplicationDelegate> interceptor) {
-                                    NSInvocation *invocation = [GULAppDelegateSwizzler
-                                        appDelegateInvocationForSelector:methodSelector];
-                                    [invocation setTarget:interceptor];
-                                    [invocation setSelector:methodSelector];
-                                    [invocation setArgument:(void *)(&application) atIndex:2];
-                                    [invocation setArgument:(void *)(&deviceToken) atIndex:3];
-                                    [invocation invoke];
-                                  }];
-  // Call the real implementation if the real App Delegate has any.
-  if (didRegisterForRemoteNotificationsIMP) {
-    didRegisterForRemoteNotificationsIMP(self, methodSelector, application, deviceToken);
-  }
-}
-
-- (void)application:(GULApplication *)application
-    donor_didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
-  SEL methodSelector = NSSelectorFromString(kGULDidFailToRegisterForRemoteNotificationsSEL);
-  NSValue *didFailToRegisterForRemoteNotificationsIMPPointer =
-      [GULAppDelegateSwizzler originalImplementationForSelector:methodSelector object:self];
-  GULRealDidFailToRegisterForRemoteNotificationsIMP didFailToRegisterForRemoteNotificationsIMP =
-      [didFailToRegisterForRemoteNotificationsIMPPointer pointerValue];
-
-  // Notify interceptors.
-  [GULAppDelegateSwizzler
-      notifyInterceptorsWithMethodSelector:methodSelector
-                                  callback:^(id<GULApplicationDelegate> interceptor) {
-                                    NSInvocation *invocation = [GULAppDelegateSwizzler
-                                        appDelegateInvocationForSelector:methodSelector];
-                                    [invocation setTarget:interceptor];
-                                    [invocation setSelector:methodSelector];
-                                    [invocation setArgument:(void *)(&application) atIndex:2];
-                                    [invocation setArgument:(void *)(&error) atIndex:3];
-                                    [invocation invoke];
-                                  }];
-  // Call the real implementation if the real App Delegate has any.
-  if (didFailToRegisterForRemoteNotificationsIMP) {
-    didFailToRegisterForRemoteNotificationsIMP(self, methodSelector, application, error);
-  }
-}
-
-#if !TARGET_OS_WATCH && !TARGET_OS_OSX
-- (void)application:(GULApplication *)application
-    donor_didReceiveRemoteNotification:(NSDictionary *)userInfo
-                fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
-  SEL methodSelector = NSSelectorFromString(kGULDidReceiveRemoteNotificationWithCompletionSEL);
-  NSValue *didReceiveRemoteNotificationWithCompletionIMPPointer =
-      [GULAppDelegateSwizzler originalImplementationForSelector:methodSelector object:self];
-  GULRealDidReceiveRemoteNotificationWithCompletionIMP
-      didReceiveRemoteNotificationWithCompletionIMP =
-          [didReceiveRemoteNotificationWithCompletionIMPPointer pointerValue];
-
-  dispatch_group_t __block callbackGroup = dispatch_group_create();
-  NSMutableArray<NSNumber *> *__block fetchResults = [NSMutableArray array];
-
-  void (^localCompletionHandler)(UIBackgroundFetchResult) =
-      ^void(UIBackgroundFetchResult fetchResult) {
-        [fetchResults addObject:[NSNumber numberWithInt:(int)fetchResult]];
-        dispatch_group_leave(callbackGroup);
-      };
-
-  // Notify interceptors.
-  [GULAppDelegateSwizzler
-      notifyInterceptorsWithMethodSelector:methodSelector
-                                  callback:^(id<GULApplicationDelegate> interceptor) {
-                                    dispatch_group_enter(callbackGroup);
-
-                                    NSInvocation *invocation = [GULAppDelegateSwizzler
-                                        appDelegateInvocationForSelector:methodSelector];
-                                    [invocation setTarget:interceptor];
-                                    [invocation setSelector:methodSelector];
-                                    [invocation setArgument:(void *)(&application) atIndex:2];
-                                    [invocation setArgument:(void *)(&userInfo) atIndex:3];
-                                    [invocation setArgument:(void *)(&localCompletionHandler)
-                                                    atIndex:4];
-                                    [invocation invoke];
-                                  }];
-  // Call the real implementation if the real App Delegate has any.
-  if (didReceiveRemoteNotificationWithCompletionIMP) {
-    dispatch_group_enter(callbackGroup);
-
-    didReceiveRemoteNotificationWithCompletionIMP(self, methodSelector, application, userInfo,
-                                                  localCompletionHandler);
-  }
-
-  dispatch_group_notify(callbackGroup, dispatch_get_main_queue(), ^() {
-    BOOL allFetchesFailed = YES;
-    BOOL anyFetchHasNewData = NO;
-
-    for (NSNumber *oneResult in fetchResults) {
-      UIBackgroundFetchResult result = oneResult.intValue;
-
-      switch (result) {
-        case UIBackgroundFetchResultNoData:
-          allFetchesFailed = NO;
-          break;
-        case UIBackgroundFetchResultNewData:
-          allFetchesFailed = NO;
-          anyFetchHasNewData = YES;
-          break;
-        case UIBackgroundFetchResultFailed:
-
-          break;
-      }
-    }
-
-    UIBackgroundFetchResult finalFetchResult = UIBackgroundFetchResultNoData;
-
-    if (allFetchesFailed) {
-      finalFetchResult = UIBackgroundFetchResultFailed;
-    } else if (anyFetchHasNewData) {
-      finalFetchResult = UIBackgroundFetchResultNewData;
-    } else {
-      finalFetchResult = UIBackgroundFetchResultNoData;
-    }
-
-    completionHandler(finalFetchResult);
-  });
-}
-#endif  // !TARGET_OS_WATCH && !TARGET_OS_OSX
-
-- (void)application:(GULApplication *)application
-    donor_didReceiveRemoteNotification:(NSDictionary *)userInfo {
-  SEL methodSelector = NSSelectorFromString(kGULDidReceiveRemoteNotificationSEL);
-  NSValue *didReceiveRemoteNotificationIMPPointer =
-      [GULAppDelegateSwizzler originalImplementationForSelector:methodSelector object:self];
-  GULRealDidReceiveRemoteNotificationIMP didReceiveRemoteNotificationIMP =
-      [didReceiveRemoteNotificationIMPPointer pointerValue];
-
-  // Notify interceptors.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-  [GULAppDelegateSwizzler
-      notifyInterceptorsWithMethodSelector:methodSelector
-                                  callback:^(id<GULApplicationDelegate> interceptor) {
-                                    NSInvocation *invocation = [GULAppDelegateSwizzler
-                                        appDelegateInvocationForSelector:methodSelector];
-                                    [invocation setTarget:interceptor];
-                                    [invocation setSelector:methodSelector];
-                                    [invocation setArgument:(void *)(&application) atIndex:2];
-                                    [invocation setArgument:(void *)(&userInfo) atIndex:3];
-                                    [invocation invoke];
-                                  }];
-#pragma clang diagnostic pop
-  // Call the real implementation if the real App Delegate has any.
-  if (didReceiveRemoteNotificationIMP) {
-    didReceiveRemoteNotificationIMP(self, methodSelector, application, userInfo);
-  }
-}
-
-+ (nullable NSInvocation *)appDelegateInvocationForSelector:(SEL)selector {
-  struct objc_method_description methodDescription =
-      protocol_getMethodDescription(@protocol(GULApplicationDelegate), selector, NO, YES);
-  if (methodDescription.types == NULL) {
-    return nil;
-  }
-
-  NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:methodDescription.types];
-  return [NSInvocation invocationWithMethodSignature:signature];
-}
-
-+ (void)proxyAppDelegate:(id<GULApplicationDelegate>)appDelegate {
-  if (![appDelegate conformsToProtocol:@protocol(GULApplicationDelegate)]) {
-    GULLogNotice(
-        kGULLoggerSwizzler, NO,
-        [NSString
-            stringWithFormat:@"I-SWZ%06ld",
-                             (long)kGULSwizzlerMessageCodeAppDelegateSwizzlingInvalidAppDelegate],
-        @"App Delegate does not conform to UIApplicationDelegate protocol. %@",
-        [GULAppDelegateSwizzler correctAlternativeWhenAppDelegateProxyNotCreated]);
-    return;
-  }
-
-  id<GULApplicationDelegate> originalDelegate = appDelegate;
-  // Do not create a subclass if it is not enabled.
-  if (![GULAppDelegateSwizzler isAppDelegateProxyEnabled]) {
-    GULLogNotice(kGULLoggerSwizzler, NO,
-                 [NSString stringWithFormat:@"I-SWZ%06ld",
-                                            (long)kGULSwizzlerMessageCodeAppDelegateSwizzling011],
-                 @"App Delegate Proxy is disabled. %@",
-                 [GULAppDelegateSwizzler correctAlternativeWhenAppDelegateProxyNotCreated]);
-    return;
-  }
-  // Do not accept nil delegate.
-  if (!originalDelegate) {
-    GULLogError(kGULLoggerSwizzler, NO,
-                [NSString stringWithFormat:@"I-SWZ%06ld",
-                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling012],
-                @"Cannot create App Delegate Proxy because App Delegate instance is nil. %@",
-                [GULAppDelegateSwizzler correctAlternativeWhenAppDelegateProxyNotCreated]);
-    return;
-  }
-
-  @try {
-    gOriginalAppDelegateClass = [originalDelegate class];
-    gAppDelegateSubclass = [self createSubclassWithObject:originalDelegate];
-    [self reassignAppDelegate];
-  } @catch (NSException *exception) {
-    GULLogError(kGULLoggerSwizzler, NO,
-                [NSString stringWithFormat:@"I-SWZ%06ld",
-                                           (long)kGULSwizzlerMessageCodeAppDelegateSwizzling013],
-                @"Cannot create App Delegate Proxy. %@",
-                [GULAppDelegateSwizzler correctAlternativeWhenAppDelegateProxyNotCreated]);
-    return;
-  }
-}
-
-#pragma mark - Methods to print correct debug logs
-
-+ (NSString *)correctAppDelegateProxyKey {
-  return NSClassFromString(@"FIRCore") ? kGULFirebaseAppDelegateProxyEnabledPlistKey
-                                       : kGULGoogleUtilitiesAppDelegateProxyEnabledPlistKey;
-}
-
-+ (NSString *)correctAlternativeWhenAppDelegateProxyNotCreated {
-  return NSClassFromString(@"FIRCore")
-             ? @"To log deep link campaigns manually, call the methods in "
-               @"FIRAnalytics+AppDelegate.h."
-             : @"";
-}
-
-#pragma mark - Private Methods for Testing
-
-+ (void)clearInterceptors {
-  [[self interceptors] removeAllObjects];
-}
-
-+ (void)resetProxyOriginalDelegateOnceToken {
-  sProxyAppDelegateOnceToken = 0;
-  sProxyAppDelegateRemoteNotificationOnceToken = 0;
-}
-
-+ (id<GULApplicationDelegate>)originalDelegate {
-  return gOriginalAppDelegate;
-}
-
-@end

+ 0 - 439
GoogleUtilities/AppDelegateSwizzler/GULSceneDelegateSwizzler.m

@@ -1,439 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import <TargetConditionals.h>
-
-#import "GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULSceneDelegateSwizzler.h"
-
-#import "GoogleUtilities/AppDelegateSwizzler/Internal/GULSceneDelegateSwizzler_Private.h"
-#import "GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULAppDelegateSwizzler.h"
-#import "GoogleUtilities/Common/GULLoggerCodes.h"
-#import "GoogleUtilities/Environment/Public/GoogleUtilities/GULAppEnvironmentUtil.h"
-#import "GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h"
-#import "GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h"
-
-#import <objc/runtime.h>
-
-#if UISCENE_SUPPORTED
-API_AVAILABLE(ios(13.0), tvos(13.0))
-typedef void (*GULOpenURLContextsIMP)(id, SEL, UIScene *, NSSet<UIOpenURLContext *> *);
-
-API_AVAILABLE(ios(13.0), tvos(13.0))
-typedef void (^GULSceneDelegateInterceptorCallback)(id<UISceneDelegate>);
-
-// The strings below are the keys for associated objects.
-static char const *const kGULRealIMPBySelectorKey = "GUL_realIMPBySelector";
-static char const *const kGULRealClassKey = "GUL_realClass";
-#endif  // UISCENE_SUPPORTED
-
-static GULLoggerService kGULLoggerSwizzler = @"[GoogleUtilities/SceneDelegateSwizzler]";
-
-// Since Firebase SDKs also use this for app delegate proxying, in order to not be a breaking change
-// we disable App Delegate proxying when either of these two flags are set to NO.
-
-/** Plist key that allows Firebase developers to disable App and Scene Delegate Proxying. */
-static NSString *const kGULFirebaseSceneDelegateProxyEnabledPlistKey =
-    @"FirebaseAppDelegateProxyEnabled";
-
-/** Plist key that allows developers not using Firebase to disable App and Scene Delegate Proxying.
- */
-static NSString *const kGULGoogleUtilitiesSceneDelegateProxyEnabledPlistKey =
-    @"GoogleUtilitiesAppDelegateProxyEnabled";
-
-/** The prefix of the Scene Delegate. */
-static NSString *const kGULSceneDelegatePrefix = @"GUL_";
-
-/**
- * This class is necessary to store the delegates in an NSArray without retaining them.
- * [NSValue valueWithNonRetainedObject] also provides this functionality, but does not provide a
- * zeroing pointer. This will cause EXC_BAD_ACCESS when trying to access the object after it is
- * dealloced. Instead, this container stores a weak, zeroing reference to the object, which
- * automatically is set to nil by the runtime when the object is dealloced.
- */
-@interface GULSceneZeroingWeakContainer : NSObject
-
-/** Stores a weak object. */
-@property(nonatomic, weak) id object;
-
-@end
-
-@implementation GULSceneZeroingWeakContainer
-@end
-
-@implementation GULSceneDelegateSwizzler
-
-#pragma mark - Public methods
-
-+ (BOOL)isSceneDelegateProxyEnabled {
-  return [GULAppDelegateSwizzler isAppDelegateProxyEnabled];
-}
-
-+ (void)proxyOriginalSceneDelegate {
-#if UISCENE_SUPPORTED
-  if ([GULAppEnvironmentUtil isAppExtension]) {
-    return;
-  }
-
-  static dispatch_once_t onceToken;
-  dispatch_once(&onceToken, ^{
-    if (@available(iOS 13.0, tvOS 13.0, *)) {
-      if (![GULSceneDelegateSwizzler isSceneDelegateProxyEnabled]) {
-        return;
-      }
-      [[NSNotificationCenter defaultCenter]
-          addObserver:self
-             selector:@selector(handleSceneWillConnectToNotification:)
-                 name:UISceneWillConnectNotification
-               object:nil];
-    }
-  });
-#endif  // UISCENE_SUPPORTED
-}
-
-#if UISCENE_SUPPORTED
-+ (GULSceneDelegateInterceptorID)registerSceneDelegateInterceptor:(id<UISceneDelegate>)interceptor {
-  NSAssert(interceptor, @"SceneDelegateProxy cannot add nil interceptor");
-  NSAssert([interceptor conformsToProtocol:@protocol(UISceneDelegate)],
-           @"SceneDelegateProxy interceptor does not conform to UIApplicationDelegate");
-
-  if (!interceptor) {
-    GULLogError(kGULLoggerSwizzler, NO,
-                [NSString stringWithFormat:@"I-SWZ%06ld",
-                                           (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling000],
-                @"SceneDelegateProxy cannot add nil interceptor.");
-    return nil;
-  }
-  if (![interceptor conformsToProtocol:@protocol(UISceneDelegate)]) {
-    GULLogError(kGULLoggerSwizzler, NO,
-                [NSString stringWithFormat:@"I-SWZ%06ld",
-                                           (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling001],
-                @"SceneDelegateProxy interceptor does not conform to UIApplicationDelegate");
-    return nil;
-  }
-
-  // The ID should be the same given the same interceptor object.
-  NSString *interceptorID =
-      [NSString stringWithFormat:@"%@%p", kGULSceneDelegatePrefix, interceptor];
-  if (!interceptorID.length) {
-    GULLogError(kGULLoggerSwizzler, NO,
-                [NSString stringWithFormat:@"I-SWZ%06ld",
-                                           (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling002],
-                @"SceneDelegateProxy cannot create Interceptor ID.");
-    return nil;
-  }
-  GULSceneZeroingWeakContainer *weakObject = [[GULSceneZeroingWeakContainer alloc] init];
-  weakObject.object = interceptor;
-  [GULSceneDelegateSwizzler interceptors][interceptorID] = weakObject;
-  return interceptorID;
-}
-
-+ (void)unregisterSceneDelegateInterceptorWithID:(GULSceneDelegateInterceptorID)interceptorID {
-  NSAssert(interceptorID, @"SceneDelegateProxy cannot unregister nil interceptor ID.");
-  NSAssert(((NSString *)interceptorID).length != 0,
-           @"SceneDelegateProxy cannot unregister empty interceptor ID.");
-
-  if (!interceptorID) {
-    GULLogError(kGULLoggerSwizzler, NO,
-                [NSString stringWithFormat:@"I-SWZ%06ld",
-                                           (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling003],
-                @"SceneDelegateProxy cannot unregister empty interceptor ID.");
-    return;
-  }
-
-  GULSceneZeroingWeakContainer *weakContainer =
-      [GULSceneDelegateSwizzler interceptors][interceptorID];
-  if (!weakContainer.object) {
-    GULLogError(kGULLoggerSwizzler, NO,
-                [NSString stringWithFormat:@"I-SWZ%06ld",
-                                           (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling004],
-                @"SceneDelegateProxy cannot unregister interceptor that was not registered. "
-                 "Interceptor ID %@",
-                interceptorID);
-    return;
-  }
-
-  [[GULSceneDelegateSwizzler interceptors] removeObjectForKey:interceptorID];
-}
-
-#pragma mark - Helper methods
-
-+ (GULMutableDictionary *)interceptors {
-  static dispatch_once_t onceToken;
-  static GULMutableDictionary *sInterceptors;
-  dispatch_once(&onceToken, ^{
-    sInterceptors = [[GULMutableDictionary alloc] init];
-  });
-  return sInterceptors;
-}
-
-+ (void)clearInterceptors {
-  [[self interceptors] removeAllObjects];
-}
-
-+ (nullable NSValue *)originalImplementationForSelector:(SEL)selector object:(id)object {
-  NSDictionary *realImplementationBySelector =
-      objc_getAssociatedObject(object, &kGULRealIMPBySelectorKey);
-  return realImplementationBySelector[NSStringFromSelector(selector)];
-}
-
-+ (void)proxyDestinationSelector:(SEL)destinationSelector
-    implementationsFromSourceSelector:(SEL)sourceSelector
-                            fromClass:(Class)sourceClass
-                              toClass:(Class)destinationClass
-                            realClass:(Class)realClass
-     storeDestinationImplementationTo:
-         (NSMutableDictionary<NSString *, NSValue *> *)destinationImplementationsBySelector {
-  [self addInstanceMethodWithDestinationSelector:destinationSelector
-            withImplementationFromSourceSelector:sourceSelector
-                                       fromClass:sourceClass
-                                         toClass:destinationClass];
-  IMP sourceImplementation =
-      [GULSceneDelegateSwizzler implementationOfMethodSelector:destinationSelector
-                                                     fromClass:realClass];
-  NSValue *sourceImplementationPointer = [NSValue valueWithPointer:sourceImplementation];
-
-  NSString *destinationSelectorString = NSStringFromSelector(destinationSelector);
-  destinationImplementationsBySelector[destinationSelectorString] = sourceImplementationPointer;
-}
-
-/** Copies a method identified by the methodSelector from one class to the other. After this method
- *  is called, performing [toClassInstance methodSelector] will be similar to calling
- *  [fromClassInstance methodSelector]. This method does nothing if toClass already has a method
- *  identified by methodSelector.
- *
- *  @param methodSelector The SEL that identifies both the method on the fromClass as well as the
- *      one on the toClass.
- *  @param fromClass The class from which a method is sourced.
- *  @param toClass The class to which the method is added. If the class already has a method with
- *      the same selector, this has no effect.
- */
-+ (void)addInstanceMethodWithSelector:(SEL)methodSelector
-                            fromClass:(Class)fromClass
-                              toClass:(Class)toClass {
-  [self addInstanceMethodWithDestinationSelector:methodSelector
-            withImplementationFromSourceSelector:methodSelector
-                                       fromClass:fromClass
-                                         toClass:toClass];
-}
-
-/** Copies a method identified by the sourceSelector from the fromClass as a method for the
- *  destinationSelector on the toClass. After this method is called, performing
- *  [toClassInstance destinationSelector] will be similar to calling
- *  [fromClassInstance sourceSelector]. This method does nothing if toClass already has a method
- *  identified by destinationSelector.
- *
- *  @param destinationSelector The SEL that identifies the method on the toClass.
- *  @param sourceSelector The SEL that identifies the method on the fromClass.
- *  @param fromClass The class from which a method is sourced.
- *  @param toClass The class to which the method is added. If the class already has a method with
- *      the same selector, this has no effect.
- */
-+ (void)addInstanceMethodWithDestinationSelector:(SEL)destinationSelector
-            withImplementationFromSourceSelector:(SEL)sourceSelector
-                                       fromClass:(Class)fromClass
-                                         toClass:(Class)toClass {
-  Method method = class_getInstanceMethod(fromClass, sourceSelector);
-  IMP methodIMP = method_getImplementation(method);
-  const char *types = method_getTypeEncoding(method);
-  if (!class_addMethod(toClass, destinationSelector, methodIMP, types)) {
-    GULLogWarning(
-        kGULLoggerSwizzler, NO,
-        [NSString
-            stringWithFormat:@"I-SWZ%06ld", (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling009],
-        @"Cannot copy method to destination selector %@ as it already exists",
-        NSStringFromSelector(destinationSelector));
-  }
-}
-
-/** Gets the IMP of the instance method on the class identified by the selector.
- *
- *  @param selector The selector of which the IMP is to be fetched.
- *  @param aClass The class from which the IMP is to be fetched.
- *  @return The IMP of the instance method identified by selector and aClass.
- */
-+ (IMP)implementationOfMethodSelector:(SEL)selector fromClass:(Class)aClass {
-  Method aMethod = class_getInstanceMethod(aClass, selector);
-  return method_getImplementation(aMethod);
-}
-
-/** Enumerates through all the interceptors and if they respond to a given selector, executes a
- *  GULSceneDelegateInterceptorCallback with the interceptor.
- *
- *  @param methodSelector The SEL to check if an interceptor responds to.
- *  @param callback the GULSceneDelegateInterceptorCallback.
- */
-+ (void)notifyInterceptorsWithMethodSelector:(SEL)methodSelector
-                                    callback:(GULSceneDelegateInterceptorCallback)callback
-    API_AVAILABLE(ios(13.0)) {
-  if (!callback) {
-    return;
-  }
-
-  NSDictionary *interceptors = [GULSceneDelegateSwizzler interceptors].dictionary;
-  [interceptors enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
-    GULSceneZeroingWeakContainer *interceptorContainer = obj;
-    id interceptor = interceptorContainer.object;
-    if (!interceptor) {
-      GULLogWarning(
-          kGULLoggerSwizzler, NO,
-          [NSString stringWithFormat:@"I-SWZ%06ld",
-                                     (long)kGULSwizzlerMessageCodeSceneDelegateSwizzling010],
-          @"SceneDelegateProxy cannot find interceptor with ID %@. Removing the interceptor.", key);
-      [[GULSceneDelegateSwizzler interceptors] removeObjectForKey:key];
-      return;
-    }
-    if ([interceptor respondsToSelector:methodSelector]) {
-      callback(interceptor);
-    }
-  }];
-}
-
-+ (void)handleSceneWillConnectToNotification:(NSNotification *)notification {
-  if (@available(iOS 13.0, tvOS 13.0, *)) {
-    if ([notification.object isKindOfClass:[UIScene class]]) {
-      UIScene *scene = (UIScene *)notification.object;
-      [GULSceneDelegateSwizzler proxySceneDelegateIfNeeded:scene];
-    }
-  }
-}
-
-#pragma mark - [Donor Methods] UISceneDelegate URL handler
-
-- (void)scene:(UIScene *)scene
-    openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts API_AVAILABLE(ios(13.0), tvos(13.0)) {
-  if (@available(iOS 13.0, tvOS 13.0, *)) {
-    SEL methodSelector = @selector(scene:openURLContexts:);
-    // Call the real implementation if the real Scene Delegate has any.
-    NSValue *openURLContextsIMPPointer =
-        [GULSceneDelegateSwizzler originalImplementationForSelector:methodSelector object:self];
-    GULOpenURLContextsIMP openURLContextsIMP = [openURLContextsIMPPointer pointerValue];
-
-    [GULSceneDelegateSwizzler
-        notifyInterceptorsWithMethodSelector:methodSelector
-                                    callback:^(id<UISceneDelegate> interceptor) {
-                                      if ([interceptor
-                                              conformsToProtocol:@protocol(UISceneDelegate)]) {
-                                        id<UISceneDelegate> sceneInterceptor =
-                                            (id<UISceneDelegate>)interceptor;
-                                        [sceneInterceptor scene:scene openURLContexts:URLContexts];
-                                      }
-                                    }];
-
-    if (openURLContextsIMP) {
-      openURLContextsIMP(self, methodSelector, scene, URLContexts);
-    }
-  }
-}
-
-+ (void)proxySceneDelegateIfNeeded:(UIScene *)scene {
-  Class realClass = [scene.delegate class];
-  NSString *className = NSStringFromClass(realClass);
-
-  // Skip proxying if failed to get the delegate class name for some reason (e.g. `delegate == nil`)
-  // or the class has a prefix of kGULAppDelegatePrefix, which means it has been proxied before.
-  if (className == nil || [className hasPrefix:kGULSceneDelegatePrefix]) {
-    return;
-  }
-
-  NSString *classNameWithPrefix = [kGULSceneDelegatePrefix stringByAppendingString:className];
-  NSString *newClassName =
-      [NSString stringWithFormat:@"%@-%@", classNameWithPrefix, [NSUUID UUID].UUIDString];
-
-  if (NSClassFromString(newClassName)) {
-    GULLogError(
-        kGULLoggerSwizzler, NO,
-        [NSString
-            stringWithFormat:@"I-SWZ%06ld",
-                             (long)
-                                 kGULSwizzlerMessageCodeSceneDelegateSwizzlingInvalidSceneDelegate],
-        @"Cannot create a proxy for Scene Delegate. Subclass already exists. Original Class"
-        @": %@, subclass: %@",
-        className, newClassName);
-    return;
-  }
-
-  // Register the new class as subclass of the real one. Do not allocate more than the real class
-  // size.
-  Class sceneDelegateSubClass = objc_allocateClassPair(realClass, newClassName.UTF8String, 0);
-  if (sceneDelegateSubClass == Nil) {
-    GULLogError(
-        kGULLoggerSwizzler, NO,
-        [NSString
-            stringWithFormat:@"I-SWZ%06ld",
-                             (long)
-                                 kGULSwizzlerMessageCodeSceneDelegateSwizzlingInvalidSceneDelegate],
-        @"Cannot create a proxy for Scene Delegate. Subclass already exists. Original Class"
-        @": %@, subclass: Nil",
-        className);
-    return;
-  }
-
-  NSMutableDictionary<NSString *, NSValue *> *realImplementationsBySelector =
-      [[NSMutableDictionary alloc] init];
-
-  // For scene:openURLContexts:
-  SEL openURLContextsSEL = @selector(scene:openURLContexts:);
-  [self proxyDestinationSelector:openURLContextsSEL
-      implementationsFromSourceSelector:openURLContextsSEL
-                              fromClass:[GULSceneDelegateSwizzler class]
-                                toClass:sceneDelegateSubClass
-                              realClass:realClass
-       storeDestinationImplementationTo:realImplementationsBySelector];
-
-  // Store original implementations to a fake property of the original delegate.
-  objc_setAssociatedObject(scene.delegate, &kGULRealIMPBySelectorKey,
-                           [realImplementationsBySelector copy], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
-  objc_setAssociatedObject(scene.delegate, &kGULRealClassKey, realClass,
-                           OBJC_ASSOCIATION_RETAIN_NONATOMIC);
-
-  // The subclass size has to be exactly the same size with the original class size. The subclass
-  // cannot have more ivars/properties than its superclass since it will cause an offset in memory
-  // that can lead to overwriting the isa of an object in the next frame.
-  if (class_getInstanceSize(realClass) != class_getInstanceSize(sceneDelegateSubClass)) {
-    GULLogError(
-        kGULLoggerSwizzler, NO,
-        [NSString
-            stringWithFormat:@"I-SWZ%06ld",
-                             (long)
-                                 kGULSwizzlerMessageCodeSceneDelegateSwizzlingInvalidSceneDelegate],
-        @"Cannot create subclass of Scene Delegate, because the created subclass is not the "
-        @"same size. %@",
-        className);
-    NSAssert(NO, @"Classes must be the same size to swizzle isa");
-    return;
-  }
-
-  // Make the newly created class to be the subclass of the real Scene Delegate class.
-  objc_registerClassPair(sceneDelegateSubClass);
-  if (object_setClass(scene.delegate, sceneDelegateSubClass)) {
-    GULLogDebug(
-        kGULLoggerSwizzler, NO,
-        [NSString
-            stringWithFormat:@"I-SWZ%06ld",
-                             (long)
-                                 kGULSwizzlerMessageCodeSceneDelegateSwizzlingInvalidSceneDelegate],
-        @"Successfully created Scene Delegate Proxy automatically. To disable the "
-        @"proxy, set the flag %@ to NO (Boolean) in the Info.plist",
-        [GULSceneDelegateSwizzler correctSceneDelegateProxyKey]);
-  }
-}
-
-+ (NSString *)correctSceneDelegateProxyKey {
-  return NSClassFromString(@"FIRCore") ? kGULFirebaseSceneDelegateProxyEnabledPlistKey
-                                       : kGULGoogleUtilitiesSceneDelegateProxyEnabledPlistKey;
-}
-
-#endif  // UISCENE_SUPPORTED
-
-@end

+ 0 - 55
GoogleUtilities/AppDelegateSwizzler/Internal/GULAppDelegateSwizzler_Private.h

@@ -1,55 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-#import "GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULAppDelegateSwizzler.h"
-#import "GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h"
-
-@class GULApplication;
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface GULAppDelegateSwizzler ()
-
-/** ISA Swizzles the given appDelegate as the original app delegate would be.
- *
- *  @param appDelegate The object that needs to be isa swizzled. This should conform to the
- *      application delegate protocol.
- */
-+ (void)proxyAppDelegate:(id<GULApplicationDelegate>)appDelegate;
-
-/** Returns a dictionary containing interceptor IDs mapped to a GULZeroingWeakContainer.
- *
- *  @return A dictionary of the form {NSString : GULZeroingWeakContainer}, where the NSString is
- *      the interceptorID.
- */
-+ (GULMutableDictionary *)interceptors;
-
-/** Deletes all the registered interceptors. */
-+ (void)clearInterceptors;
-
-/** Resets the token that prevents the app delegate proxy from being isa swizzled multiple times. */
-+ (void)resetProxyOriginalDelegateOnceToken;
-
-/** Returns the original app delegate that was proxied.
- *
- *  @return The original app delegate instance that was proxied.
- */
-+ (id<GULApplicationDelegate>)originalDelegate;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 48
GoogleUtilities/AppDelegateSwizzler/Internal/GULSceneDelegateSwizzler_Private.h

@@ -1,48 +0,0 @@
-/*
- * Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-#import "GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULSceneDelegateSwizzler.h"
-#import "GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface GULSceneDelegateSwizzler ()
-
-#if UISCENE_SUPPORTED
-
-/** Returns a dictionary containing interceptor IDs mapped to a GULZeroingWeakContainer.
- *
- *  @return A dictionary of the form {NSString : GULZeroingWeakContainer}, where the NSString is
- *      the interceptorID.
- */
-+ (GULMutableDictionary *)interceptors;
-
-/** Deletes all the registered interceptors. */
-+ (void)clearInterceptors;
-
-/** ISA Swizzles the given appDelegate as the original app delegate would be.
- *
- *  @param scene The scene whose delegate needs to be isa swizzled. This should conform to the
- *      scene delegate protocol.
- */
-+ (void)proxySceneDelegateIfNeeded:(UIScene *)scene API_AVAILABLE(ios(13.0), tvos(13.0));
-
-#endif  // UISCENE_SUPPORTED
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 107
GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULAppDelegateSwizzler.h

@@ -1,107 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-#import "GULApplication.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-typedef NSString *const GULAppDelegateInterceptorID;
-
-/** This class contains methods that isa swizzle the app delegate. */
-@interface GULAppDelegateSwizzler : NSProxy
-
-/** Registers an app delegate interceptor whose methods will be invoked as they're invoked on the
- *  original app delegate.
- *
- *  @param interceptor An instance of a class that conforms to the application delegate protocol.
- *      The interceptor is NOT retained.
- *  @return A unique GULAppDelegateInterceptorID if interceptor was successfully registered; nil
- *      if it fails.
- */
-+ (nullable GULAppDelegateInterceptorID)registerAppDelegateInterceptor:
-    (id<GULApplicationDelegate>)interceptor;
-
-/** Unregisters an interceptor with the given ID if it exists.
- *
- *  @param interceptorID The object that was generated when the interceptor was registered.
- */
-+ (void)unregisterAppDelegateInterceptorWithID:(GULAppDelegateInterceptorID)interceptorID;
-
-/** This method ensures that the original app delegate has been proxied. Call this before
- *  registering your interceptor. This method is safe to call multiple times (but it only proxies
- *  the app delegate once).
- *
- *  This method doesn't proxy APNS related methods:
- *  @code
- *    - application:didRegisterForRemoteNotificationsWithDeviceToken:
- *    - application:didFailToRegisterForRemoteNotificationsWithError:
- *    - application:didReceiveRemoteNotification:fetchCompletionHandler:
- *    - application:didReceiveRemoteNotification:
- *  @endcode
- *
- *  To proxy these methods use +[GULAppDelegateSwizzler
- *  proxyOriginalDelegateIncludingAPNSMethods]. The methods have to be proxied separately to
- *  avoid potential warnings from Apple review about missing Push Notification Entitlement (e.g.
- *  https://github.com/firebase/firebase-ios-sdk/issues/2807)
- *
- *  The method has no effect for extensions.
- *
- *  @see proxyOriginalDelegateIncludingAPNSMethods
- */
-+ (void)proxyOriginalDelegate;
-
-/** This method ensures that the original app delegate has been proxied including APNS related
- *  methods. Call this before registering your interceptor. This method is safe to call multiple
- *  times (but it only proxies the app delegate once) or
- *  after +[GULAppDelegateSwizzler proxyOriginalDelegate]
- *
- *  This method calls +[GULAppDelegateSwizzler proxyOriginalDelegate] under the hood.
- *  After calling this method the following App Delegate methods will be proxied in addition to
- *  the methods proxied by proxyOriginalDelegate:
- *  @code
- *    - application:didRegisterForRemoteNotificationsWithDeviceToken:
- *    - application:didFailToRegisterForRemoteNotificationsWithError:
- *    - application:didReceiveRemoteNotification:fetchCompletionHandler:
- *    - application:didReceiveRemoteNotification:
- *  @endcode
- *
- *  The method has no effect for extensions.
- *
- *  @see proxyOriginalDelegate
- */
-+ (void)proxyOriginalDelegateIncludingAPNSMethods;
-
-/** Indicates whether app delegate proxy is explicitly disabled or enabled. Enabled by default.
- *
- *  @return YES if AppDelegateProxy is Enabled, NO otherwise.
- */
-+ (BOOL)isAppDelegateProxyEnabled;
-
-/** Returns the current sharedApplication.
- *
- *  @return the current application instance if in an app, or nil if in extension or if it doesn't
- * exist.
- */
-+ (nullable GULApplication *)sharedApplication;
-
-/** Do not initialize this class. */
-- (instancetype)init NS_UNAVAILABLE;
-
-NS_ASSUME_NONNULL_END
-
-@end

+ 0 - 50
GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULApplication.h

@@ -1,50 +0,0 @@
-/*
- * Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-#if TARGET_OS_IOS || TARGET_OS_TV
-
-#import <UIKit/UIKit.h>
-
-#define GULApplication UIApplication
-#define GULApplicationDelegate UIApplicationDelegate
-#define GULUserActivityRestoring UIUserActivityRestoring
-
-static NSString *const kGULApplicationClassName = @"UIApplication";
-
-#elif TARGET_OS_OSX
-
-#import <AppKit/AppKit.h>
-
-#define GULApplication NSApplication
-#define GULApplicationDelegate NSApplicationDelegate
-#define GULUserActivityRestoring NSUserActivityRestoring
-
-static NSString *const kGULApplicationClassName = @"NSApplication";
-
-#elif TARGET_OS_WATCH
-
-#import <WatchKit/WatchKit.h>
-
-// We match the according watchOS API but swizzling should not work in watch
-#define GULApplication WKExtension
-#define GULApplicationDelegate WKExtensionDelegate
-#define GULUserActivityRestoring NSUserActivityRestoring
-
-static NSString *const kGULApplicationClassName = @"WKExtension";
-
-#endif

+ 0 - 76
GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULSceneDelegateSwizzler.h

@@ -1,76 +0,0 @@
-/*
- * Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-#import <TargetConditionals.h>
-
-#if !TARGET_OS_OSX
-#import <UIKit/UIKit.h>
-#endif  // !TARGET_OS_OSX
-
-#if ((TARGET_OS_IOS || TARGET_OS_TV) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 130000))
-#define UISCENE_SUPPORTED 1
-#endif
-
-NS_ASSUME_NONNULL_BEGIN
-
-typedef NSString *const GULSceneDelegateInterceptorID;
-
-/** This class contains methods that isa swizzle the scene delegate. */
-@interface GULSceneDelegateSwizzler : NSProxy
-
-#if UISCENE_SUPPORTED
-
-/** Registers a scene delegate interceptor whose methods will be invoked as they're invoked on the
- *  original scene delegate.
- *
- *  @param interceptor An instance of a class that conforms to the application delegate protocol.
- *      The interceptor is NOT retained.
- *  @return A unique GULSceneDelegateInterceptorID if interceptor was successfully registered; nil
- *      if it fails.
- */
-+ (nullable GULSceneDelegateInterceptorID)registerSceneDelegateInterceptor:
-    (id<UISceneDelegate>)interceptor API_AVAILABLE(ios(13.0), tvos(13.0));
-
-/** Unregisters an interceptor with the given ID if it exists.
- *
- *  @param interceptorID The object that was generated when the interceptor was registered.
- */
-+ (void)unregisterSceneDelegateInterceptorWithID:(GULSceneDelegateInterceptorID)interceptorID
-    API_AVAILABLE(ios(13.0), tvos(13.0));
-
-/** Do not initialize this class. */
-- (instancetype)init NS_UNAVAILABLE;
-
-#endif  // UISCENE_SUPPORTED
-
-/** This method ensures that the original scene delegate has been proxied. Call this before
- *  registering your interceptor. This method is safe to call multiple times (but it only proxies
- *  the scene delegate once).
- *
- *  The method has no effect for extensions.
- */
-+ (void)proxyOriginalSceneDelegate;
-
-/** Indicates whether scene delegate proxy is explicitly disabled or enabled. Enabled by default.
- *
- *  @return YES if SceneDelegateProxy is Enabled, NO otherwise.
- */
-+ (BOOL)isSceneDelegateProxyEnabled;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 185
GoogleUtilities/AppDelegateSwizzler/README.md

@@ -1,185 +0,0 @@
-# App Delegate Swizzler
-
-## Overview
-
-The App Delegate Swizzler swizzles certain methods on the AppDelegate and allows interested parties
-(for eg. other SDKs like Firebase Analytics) to register listeners when certain App Delegate methods
-are called.
-
-The App Delegate Swizzler uses [isa swizzling](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueObserving/Articles/KVOImplementation.html)
-to create a dynamic subclass of the app delegate class and add methods to it that have the logic to
-add multiple "interceptors".
-
-Adding interceptors to the following methods is currently supported by the App Delegate Swizzler.
-
-* `- (BOOL)application:openURL:options:` [Reference](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application?language=objc)
-
-Note: This method is added only if the original app delegate implements it. This prevents a bug
-where if an app only implements application:openURL:sourceApplication:annotation: and if we add the
-`options` method, iOS sees that the `options` method exists and so does not call the
-`sourceApplication` method, which causes the app developer's logic in `sourceApplication` to not be
-called.
-
-* `- (BOOL)application:openURL:sourceApplication:annotation:`
-    [Reference](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623073-application?language=objc)
-
-* `- (void)application:handleEventsForBackgroundURLSession:completionHandler:`
-    [Reference](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622941-application?language=objc)
-
-* `- (BOOL)application:continueUserActivity:restorationHandler:`
-    [Reference](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623072-application?language=objc)
-
-We are looking into adding support for more methods as we need them.
-
-## Adopting the swizzler
-
-To start using the app delegate swizzler to intercept app delegate methods do the following:
-
-The following assumes that you are an SDK that ships using Cocoapods and need to react to one of the
-app delegate methods listed above.
-
-1. Add a dependency to the app delegate swizzler - `GoogleUtilities/AppDelegateSwizzler:~> 5.2`. We
-follow Semantic Versioning.
-
-2. Create an interceptor class that implements the `UIApplicationDelegate` and implements the
-methods you want to intercept. For eg.
-
-MYAppDelegateInterceptor.h
-
-```objc
-
-#import <Foundation/Foundation.h>
-#import <UIKit/UIKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-/// An instance of this class is meant to be registered as an AppDelegate interceptor, and
-/// implements the logic that my SDK needs to perform when certain app delegate methods are invoked.
-@interface MYAppDelegateInterceptor : NSObject <UIApplicationDelegate>
-
-/// Returns the MYAppDelegateInterceptor singleton.
-/// Always register just this singleton as the app delegate interceptor. This instance is
-/// retained. The App Delegate Swizzler only retains weak references and so this is needed.
-+ (instancetype)sharedInstance;
-
-@end
-
-NS_ASSUME_NONNULL_END
-
-```
-
-MYAppDelegateInterceptor.m
-
-```objc
-#import "MYAppDelegateInterceptor.h"
-
-@implementation MYAppDelegateInterceptor
-
-+ (instancetype)sharedInstance {
-  static dispatch_once_t once;
-  static MYAppDelegateInterceptor *sharedInstance;
-  dispatch_once(&once, ^{
-    sharedInstance = [[MYAppDelegateInterceptor alloc] init];
-  });
-  return sharedInstance;
-}
-
-- (BOOL)application:(UIApplication *)application
-            openURL:(NSURL *)URL
-            options:(NSDictionary<NSString *, id> *)options {
-
-  [MYInterestingClass doSomething];
-
-  // Results of this are ORed and NO doesn't affect other delegate interceptors' result.
-  return NO;
-}
-
-- (BOOL)application:(UIApplication *)application
-            openURL:(NSURL *)URL
-  sourceApplication:(NSString *)sourceApplication
-         annotation:(id)annotation {
-
-    [MYInterestingClass doSomething];
-
-  // Results of this are ORed and NO doesn't affect other delegate interceptors' result.
-  return NO;
-}
-
-#pragma mark - Network overridden handler methods
-
-- (void)application:(UIApplication *)application
-    handleEventsForBackgroundURLSession:(NSString *)identifier
-                      completionHandler:(void (^)(void))completionHandler {
-
-  // Note: Interceptors are not responsible for (and should not) call the completion handler.
-  [MYInterestingClass doSomething];
-}
-
-#pragma mark - User Activities overridden handler methods
-
-- (BOOL)application:(UIApplication *)application
-    continueUserActivity:(NSUserActivity *)userActivity
-      restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {
-
-  [MYInterestingClass doSomething];
-
-  // Results of this are ORed and NO doesn't affect other delegate interceptors' result.
-  return NO;
-}
-
-@end
-```
-
-3. Register your interceptor when it makes sense to do so.
-
-For eg.
-
-```objc
-
-// MYInterestingClass.m
-
-#import "GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULAppDelegateSwizzler.h"
-
-...
-
-- (void)someInterestingMethod {
-    ...
-
-    // Calling this ensures that the app delegate is proxied (has no effect if some other SDK has
-    // already done it).
-    [GULAppDelegateSwizzler proxyOriginalDelegate];
-
-    MYAppDelegateInterceptor *interceptor = [MYAppDelegateInterceptor sharedInstance];
-    [GULAppDelegateSwizzler registerAppDelegateInterceptor:interceptor];
-}
-```
-## Swizzling of App Delegate APNS methods
-
-Swizzling of the APNS related App Delegate methods may lead to an Apple review warning email about
-missing Push Notification Entitlement during the app review process
-(like here: https://github.com/firebase/firebase-ios-sdk/issues/2807) if Push Notifications are
-actually not used by the app. To avoid the warning the methods below are not swizzled
-by `[GULAppDelegateSwizzler proxyOriginalDelegate]`:
-
-```objc
-
-- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
-
-- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error;
-
-- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo;
-
-- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;
-```
-
-If you need to swizzle these methods you can call
-`[GULAppDelegateSwizzler proxyOriginalDelegateIncludingAPNSMethods]`. The method can be safely
-called instead or after `[GULAppDelegateSwizzler proxyOriginalDelegate]`.
-
-## Disabling App Delegate Swizzling by App Developers
-
-Sometimes app developers that consume our SDKs prefer that we do not swizzle the app delegate. We've
-added support for developers to disable any sort of app delegate swizzling that we may do, and this
-is achieved by adding the Plist flag `GoogleUtilitiesAppDelegateProxyEnabled` to `NO` (Boolean). If
-this is set, even if you call `[GULAppDelegateSwizzler proxyOriginalDelegate]`, it won't have any
-effect.

+ 0 - 120
GoogleUtilities/CHANGELOG.md

@@ -1,120 +0,0 @@
-# 7.4.0
-- `NSURLSession` promise extension public API. (#7097)
-
-# 7.1.1
-- Fix `unrecognized selector` for isiOSAppOnMac on early iOS 14 betas. (#6969)
-
-# 7.1.0
-- Added `NSURLSession` promise extension. (#6753)
-- `ios_on_mac` option added to `GULAppEnvironmentUtil.applePlatform()`. (#6799)
-- Fixed completion handler issue in `GULAppDelegateSwizzler` for
-  `application(_:didReceiveRemoteNotification:fetchCompletionHandler:)` method.  (#6863)
-
-# 7.0.0
-- All APIs are now public. All CocoaPods private headers are transitioned to public. Note that
-  GoogleUtilities may have more frequent breaking changes than Firebase. (#6588)
-- Fixed writing heartbeat to disk on tvOS devices. (#6658)
-- Refactor `GULSwizzledObject` to ARC to unblock SwiftPM support. (#5862)
-
-# 6.7.1
-- Fix import regression when mixing 6.7.0 with earlier Firebase versions. (#6047)
-
-# 6.7.0 -- M75
-- Lazily access filesystem outside of `GULHeartbeatDateStorage` initializer. (#5969)
-- Update source imports to use repo-relative headers. (#5824)
-- Source cleanups to remove pre-iOS 8 code. (#5841)
-
-# 6.6.0 -- M69
-- Keychain utilities and Keychain based key-value storage added to
-  `GoogleUtilities/Environment`. (#5329)
-
-# 6.5.2
-- Fixed an issue where GoogleUtilities misidentified Catalyst as a
-  simulator runtime environment. (#5048)
-
-# 6.5.1
-- Standardized import paths. (#4655)
-
-# 6.5.0
-- Swizzler changes.
-
-# 6.4.0
-- Add function to gul secure encoding to encode multiple classes. (#4282)
-- Add heartbeat feature. (#4098)
-- Support UISceneDelegate changes in Auth. (#4380)
-
-# 6.3.1
-- Fix GULMutableDictionary keyed subscript methods. (#3882)
-- Update Networking to receive data for POST requests. (#3940)
-- Fix crash in GULLogBasic. (#3928)
-
-# 6.3.0
-- GULSecureCoding introduced. (#3707)
-- Mark unused variables. (#3854)
-
-# 6.2.5
-- Remove test-only method and update tests to include Catalyst. (#3544)
-
-# 6.2.4
-- Fix `GULObjectSwizzler` dealloc thread-safety. (#3300, #3183)
-
-# 6.2.3
-- Revert "Fix `GULMutableDictionary` thread-safety." (#3322)
-
-# 6.2.2
-- Add explicit Foundation import for headers.
-- Fix headers import. (#3277)
-- Fix README. (#3305)
-- Fix `GULMutableDictionary` thread-safety. (#3322)
-
-# 6.2.1
-- Fix Xcode 11 build warning. (#3133)
-
-# 6.2.0
-- Stop conditional compilation for GoogleUtilities testing. (#3058)
-
-# 6.1.0
-- Added `GULAppDelegateSwizzler` macOS support. (#2911)
-
-# 6.0.0
-- GULAppDelegateSwizzler - proxy APNS methods separately. (#2835)
-- Cocoapods 1.7.0 multiproject support. (#2751)
-- Bump minimium iOS version to iOS 8. (#2876)
-
-# 5.7.0
-- Restore to 5.5.0 tag after increased App Store warnings. (#2807)
-
-# 5.6.0
-- `GULAppDelegateSwizzler`: support of remote notification methods. (#2698)
-- `GULAppDelegateSwizzler`: tvOS support. (#2698)
-
-# 5.5.0
-- Revert 5.4.x changes restoring 5.3.7 version.
-
-# 5.4.1
-- Fix GULResetLogger API breakage. (#2551)
-
-# 5.4.0
-- Update GULLogger to use os_log instead of asl_log on iOS 9 and later. (#2374, #2504)
-
-# 5.3.7
-- Fixed `pod lib lint GoogleUtilities.podspec --use-libraries` regression. (#2130)
-- Fixed macOS conditional check in UserDefaults. (#2245)
-- Migrate to clang-format 8.0.0. (#2222)
-
-# 5.3.6
-- Fix nullability issues. (#2079)
-
-# 5.3.5
-- Fixed an issue where GoogleUtilities would leak non-background URL sessions.
-  (#2061)
-- Fixed a crash caused due to `NSURLConnection` delegates being wrapped in an
-  `NSProxy`. (#1936)
-
-# 5.3.4
-- Fixed a crash caused by unprotected access to sessions in
-  `GULNetworkURLSession`. (#1964)
-
-# 5.3.3
-- Fixed an issue where GoogleUtilities would leak instances of `NSURLSession`.
-  (#1917)

+ 0 - 56
GoogleUtilities/Common/GULLoggerCodes.h

@@ -1,56 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-typedef NS_ENUM(NSInteger, GULSwizzlerMessageCode) {
-  // App Delegate Swizzling.
-  kGULSwizzlerMessageCodeAppDelegateSwizzling000 = 1000,                 // I-SWZ001000
-  kGULSwizzlerMessageCodeAppDelegateSwizzling001 = 1001,                 // I-SWZ001001
-  kGULSwizzlerMessageCodeAppDelegateSwizzling002 = 1002,                 // I-SWZ001002
-  kGULSwizzlerMessageCodeAppDelegateSwizzling003 = 1003,                 // I-SWZ001003
-  kGULSwizzlerMessageCodeAppDelegateSwizzling004 = 1004,                 // I-SWZ001004
-  kGULSwizzlerMessageCodeAppDelegateSwizzling005 = 1005,                 // I-SWZ001005
-  kGULSwizzlerMessageCodeAppDelegateSwizzling006 = 1006,                 // I-SWZ001006
-  kGULSwizzlerMessageCodeAppDelegateSwizzling007 = 1007,                 // I-SWZ001007
-  kGULSwizzlerMessageCodeAppDelegateSwizzling008 = 1008,                 // I-SWZ001008
-  kGULSwizzlerMessageCodeAppDelegateSwizzling009 = 1009,                 // I-SWZ001009
-  kGULSwizzlerMessageCodeAppDelegateSwizzling010 = 1010,                 // I-SWZ001010
-  kGULSwizzlerMessageCodeAppDelegateSwizzling011 = 1011,                 // I-SWZ001011
-  kGULSwizzlerMessageCodeAppDelegateSwizzling012 = 1012,                 // I-SWZ001012
-  kGULSwizzlerMessageCodeAppDelegateSwizzling013 = 1013,                 // I-SWZ001013
-  kGULSwizzlerMessageCodeAppDelegateSwizzlingInvalidAppDelegate = 1014,  // I-SWZ001014
-
-  // Scene Delegate Swizzling.
-  kGULSwizzlerMessageCodeSceneDelegateSwizzling000 = 1100,                   // I-SWZ001100
-  kGULSwizzlerMessageCodeSceneDelegateSwizzling001 = 1101,                   // I-SWZ001101
-  kGULSwizzlerMessageCodeSceneDelegateSwizzling002 = 1102,                   // I-SWZ001102
-  kGULSwizzlerMessageCodeSceneDelegateSwizzling003 = 1103,                   // I-SWZ001103
-  kGULSwizzlerMessageCodeSceneDelegateSwizzling004 = 1104,                   // I-SWZ001104
-  kGULSwizzlerMessageCodeSceneDelegateSwizzling005 = 1105,                   // I-SWZ001105
-  kGULSwizzlerMessageCodeSceneDelegateSwizzling006 = 1106,                   // I-SWZ001106
-  kGULSwizzlerMessageCodeSceneDelegateSwizzling007 = 1107,                   // I-SWZ001107
-  kGULSwizzlerMessageCodeSceneDelegateSwizzling008 = 1108,                   // I-SWZ001108
-  kGULSwizzlerMessageCodeSceneDelegateSwizzling009 = 1109,                   // I-SWZ001109
-  kGULSwizzlerMessageCodeSceneDelegateSwizzling010 = 1110,                   // I-SWZ001110
-  kGULSwizzlerMessageCodeSceneDelegateSwizzling011 = 1111,                   // I-SWZ001111
-  kGULSwizzlerMessageCodeSceneDelegateSwizzling012 = 1112,                   // I-SWZ001112
-  kGULSwizzlerMessageCodeSceneDelegateSwizzling013 = 1113,                   // I-SWZ001113
-  kGULSwizzlerMessageCodeSceneDelegateSwizzlingInvalidSceneDelegate = 1114,  // I-SWZ001114
-
-  // Method Swizzling.
-  kGULSwizzlerMessageCodeMethodSwizzling000 = 2000,  // I-SWZ002000
-};

+ 0 - 159
GoogleUtilities/Environment/GULHeartbeatDateStorage.m

@@ -1,159 +0,0 @@
-/*
- * Copyright 2019 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import "GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorage.h"
-#import "GoogleUtilities/Environment/Public/GoogleUtilities/GULSecureCoding.h"
-
-@interface GULHeartbeatDateStorage ()
-/** The storage to store the date of the last sent heartbeat. */
-@property(nonatomic, readonly) NSFileCoordinator *fileCoordinator;
-/** The name of the file that stores heartbeat information. */
-@property(nonatomic, readonly) NSString *fileName;
-@end
-
-@implementation GULHeartbeatDateStorage
-
-@synthesize fileURL = _fileURL;
-
-- (instancetype)initWithFileName:(NSString *)fileName {
-  if (fileName == nil) {
-    return nil;
-  }
-
-  self = [super init];
-  if (self) {
-    _fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
-    _fileName = fileName;
-  }
-  return self;
-}
-
-/** Lazy getter for fileURL
- * @return fileURL where heartbeat information is stored.
- */
-- (NSURL *)fileURL {
-  if (!_fileURL) {
-    NSURL *directoryURL = [[self class] directoryPathURL];
-    [[self class] checkAndCreateDirectory:directoryURL fileCoordinator:_fileCoordinator];
-    _fileURL = [directoryURL URLByAppendingPathComponent:_fileName];
-  }
-  return _fileURL;
-}
-
-/** Returns the URL path of the directory for heartbeat storage data.
- * @return the URL path of the directory for heartbeat storage data.
- */
-+ (NSURL *)directoryPathURL {
-#if TARGET_OS_TV
-  NSArray<NSString *> *paths =
-      NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
-#else
-  NSArray<NSString *> *paths =
-      NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
-#endif
-  NSArray<NSString *> *components = @[ paths.lastObject, @"Google/FIRApp" ];
-  NSString *directoryString = [NSString pathWithComponents:components];
-  NSURL *directoryURL = [NSURL fileURLWithPath:directoryString];
-  return directoryURL;
-}
-
-/** Checks and creates a directory for the directory specified by the
- * directory url
- * @param directoryPathURL The path to the directory which needs to be created.
- * @param fileCoordinator The fileCoordinator object to coordinate writes to the directory.
- */
-+ (void)checkAndCreateDirectory:(NSURL *)directoryPathURL
-                fileCoordinator:(NSFileCoordinator *)fileCoordinator {
-  NSError *fileCoordinatorError = nil;
-  [fileCoordinator
-      coordinateWritingItemAtURL:directoryPathURL
-                         options:0
-                           error:&fileCoordinatorError
-                      byAccessor:^(NSURL *writingDirectoryURL) {
-                        NSError *error;
-                        if (![writingDirectoryURL checkResourceIsReachableAndReturnError:&error]) {
-                          // If fail creating the Application Support directory, log warning.
-                          NSError *error;
-                          [[NSFileManager defaultManager] createDirectoryAtURL:writingDirectoryURL
-                                                   withIntermediateDirectories:YES
-                                                                    attributes:nil
-                                                                         error:&error];
-                        }
-                      }];
-}
-
-- (nullable NSMutableDictionary *)heartbeatDictionaryWithFileURL:(NSURL *)readingFileURL {
-  NSError *error;
-  NSMutableDictionary *dict;
-  NSData *objectData = [NSData dataWithContentsOfURL:readingFileURL options:0 error:&error];
-  if (objectData == nil || error != nil) {
-    dict = [NSMutableDictionary dictionary];
-  } else {
-    dict = [GULSecureCoding
-        unarchivedObjectOfClasses:[NSSet setWithArray:@[ NSDictionary.class, NSDate.class ]]
-                         fromData:objectData
-                            error:&error];
-    if (dict == nil || error != nil) {
-      dict = [NSMutableDictionary dictionary];
-    }
-  }
-  return dict;
-}
-
-- (nullable NSDate *)heartbeatDateForTag:(NSString *)tag {
-  __block NSMutableDictionary *dict;
-  NSError *error;
-  [self.fileCoordinator coordinateReadingItemAtURL:self.fileURL
-                                           options:0
-                                             error:&error
-                                        byAccessor:^(NSURL *readingURL) {
-                                          dict = [self heartbeatDictionaryWithFileURL:readingURL];
-                                        }];
-  return dict[tag];
-}
-
-- (BOOL)setHearbeatDate:(NSDate *)date forTag:(NSString *)tag {
-  NSError *error;
-  __block BOOL isSuccess = false;
-  [self.fileCoordinator coordinateReadingItemAtURL:self.fileURL
-                                           options:0
-                                  writingItemAtURL:self.fileURL
-                                           options:0
-                                             error:&error
-                                        byAccessor:^(NSURL *readingURL, NSURL *writingURL) {
-                                          NSMutableDictionary *dictionary =
-                                              [self heartbeatDictionaryWithFileURL:readingURL];
-                                          dictionary[tag] = date;
-                                          NSError *error;
-                                          isSuccess = [self writeDictionary:dictionary
-                                                              forWritingURL:writingURL
-                                                                      error:&error];
-                                        }];
-  return isSuccess;
-}
-
-- (BOOL)writeDictionary:(NSMutableDictionary *)dictionary
-          forWritingURL:(NSURL *)writingFileURL
-                  error:(NSError **)outError {
-  NSData *data = [GULSecureCoding archivedDataWithRootObject:dictionary error:outError];
-  if (*outError != nil) {
-    return false;
-  } else {
-    return [data writeToURL:writingFileURL atomically:YES];
-  }
-}
-
-@end

+ 0 - 103
GoogleUtilities/Environment/GULSecureCoding.m

@@ -1,103 +0,0 @@
-// Copyright 2019 Google
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import "GoogleUtilities/Environment/Public/GoogleUtilities/GULSecureCoding.h"
-
-NSString *const kGULSecureCodingError = @"GULSecureCodingError";
-
-@implementation GULSecureCoding
-
-+ (nullable id)unarchivedObjectOfClasses:(NSSet<Class> *)classes
-                                fromData:(NSData *)data
-                                   error:(NSError **)outError {
-  id object;
-#if __has_builtin(__builtin_available)
-  if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)) {
-    object = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes fromData:data error:outError];
-  } else
-#endif  // __has_builtin(__builtin_available)
-  {
-    @try {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-      NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
-#pragma clang diagnostic pop
-      unarchiver.requiresSecureCoding = YES;
-
-      object = [unarchiver decodeObjectOfClasses:classes forKey:NSKeyedArchiveRootObjectKey];
-    } @catch (NSException *exception) {
-      if (outError) {
-        *outError = [self archivingErrorWithException:exception];
-      }
-    }
-
-    if (object == nil && outError && *outError == nil) {
-      NSString *failureReason = @"NSKeyedUnarchiver failed to unarchive data.";
-      *outError = [NSError errorWithDomain:kGULSecureCodingError
-                                      code:-1
-                                  userInfo:@{NSLocalizedFailureReasonErrorKey : failureReason}];
-    }
-  }
-
-  return object;
-}
-
-+ (nullable id)unarchivedObjectOfClass:(Class)class
-                              fromData:(NSData *)data
-                                 error:(NSError **)outError {
-  return [self unarchivedObjectOfClasses:[NSSet setWithObject:class] fromData:data error:outError];
-}
-
-+ (nullable NSData *)archivedDataWithRootObject:(id<NSCoding>)object error:(NSError **)outError {
-  NSData *archiveData;
-#if __has_builtin(__builtin_available)
-  if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *)) {
-    archiveData = [NSKeyedArchiver archivedDataWithRootObject:object
-                                        requiringSecureCoding:YES
-                                                        error:outError];
-  } else
-#endif  // __has_builtin(__builtin_available)
-  {
-    @try {
-      NSMutableData *data = [NSMutableData data];
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-      NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
-#pragma clang diagnostic pop
-      archiver.requiresSecureCoding = YES;
-
-      [archiver encodeObject:object forKey:NSKeyedArchiveRootObjectKey];
-      [archiver finishEncoding];
-
-      archiveData = [data copy];
-    } @catch (NSException *exception) {
-      if (outError) {
-        *outError = [self archivingErrorWithException:exception];
-      }
-    }
-  }
-
-  return archiveData;
-}
-
-+ (NSError *)archivingErrorWithException:(NSException *)exception {
-  NSString *failureReason = [NSString
-      stringWithFormat:@"NSKeyedArchiver exception with name: %@, reason: %@, userInfo: %@",
-                       exception.name, exception.reason, exception.userInfo];
-  NSDictionary *errorUserInfo = @{NSLocalizedFailureReasonErrorKey : failureReason};
-
-  return [NSError errorWithDomain:kGULSecureCodingError code:-1 userInfo:errorUserInfo];
-}
-
-@end

+ 0 - 60
GoogleUtilities/Environment/Public/GoogleUtilities/GULAppEnvironmentUtil.h

@@ -1,60 +0,0 @@
-/*
- * Copyright 2017 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface GULAppEnvironmentUtil : NSObject
-
-/// Indicates whether the app is from Apple Store or not. Returns NO if the app is on simulator,
-/// development environment or sideloaded.
-+ (BOOL)isFromAppStore;
-
-/// Indicates whether the app is a Testflight app. Returns YES if the app has sandbox receipt.
-/// Returns NO otherwise.
-+ (BOOL)isAppStoreReceiptSandbox;
-
-/// Indicates whether the app is on simulator or not at runtime depending on the device
-/// architecture.
-+ (BOOL)isSimulator;
-
-/// The current device model. Returns an empty string if device model cannot be retrieved.
-+ (nullable NSString *)deviceModel;
-
-/// The current operating system version. Returns an empty string if the system version cannot be
-/// retrieved.
-+ (NSString *)systemVersion;
-
-/// Indicates whether it is running inside an extension or an app.
-+ (BOOL)isAppExtension;
-
-/// @return Returns @YES when is run on iOS version greater or equal to 7.0
-+ (BOOL)isIOS7OrHigher DEPRECATED_MSG_ATTRIBUTE(
-    "Always `YES` because only iOS 8 and higher supported. The method will be removed.");
-
-/// @return YES if Swift runtime detected in the app.
-+ (BOOL)hasSwiftRuntime;
-
-/// @return An Apple platform. Possible values "ios", "tvos", "macos", "watchos", "maccatalyst".
-+ (NSString *)applePlatform;
-
-/// @return The way the library was added to the app, e.g. "swiftpm", "cocoapods", etc.
-+ (NSString *)deploymentType;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 49
GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorage.h

@@ -1,49 +0,0 @@
-/*
- * Copyright 2019 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-/// Stores either a date or a dictionary to a specified file.
-@interface GULHeartbeatDateStorage : NSObject
-
-- (instancetype)init NS_UNAVAILABLE;
-
-@property(nonatomic, readonly) NSURL *fileURL;
-
-/**
- * Default initializer.
- * @param fileName The name of the file to store the date information.
- * exist, it will be created if needed.
- */
-- (instancetype)initWithFileName:(NSString *)fileName;
-
-/**
- * Reads the date from the specified file for the given tag.
- * @return Returns date if exists, otherwise `nil`.
- */
-- (nullable NSDate *)heartbeatDateForTag:(NSString *)tag;
-
-/**
- * Saves the date for the specified tag in the specified file.
- * @return YES on success, NO otherwise.
- */
-- (BOOL)setHearbeatDate:(NSDate *)date forTag:(NSString *)tag;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 79
GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainStorage.h

@@ -1,79 +0,0 @@
-/*
- * Copyright 2019 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-@class FBLPromise<ValueType>;
-
-NS_ASSUME_NONNULL_BEGIN
-
-/// The class provides a convenient abstraction on top of the iOS Keychain API to save data.
-@interface GULKeychainStorage : NSObject
-
-- (instancetype)init NS_UNAVAILABLE;
-
-/** Initializes the keychain storage with Keychain Service name.
- *  @param service A Keychain Service name that will be used to store and retrieve objects. See also
- * `kSecAttrService`.
- */
-- (instancetype)initWithService:(NSString *)service;
-
-/**
- * Get an object by key.
- * @param key The key.
- * @param objectClass The expected object class required by `NSSecureCoding`.
- * @param accessGroup The Keychain Access Group.
- *
- * @return Returns a promise. It is resolved with an object stored by key if exists. It is resolved
- * with `nil` when the object not found. It fails on a Keychain error.
- */
-- (FBLPromise<id<NSSecureCoding>> *)getObjectForKey:(NSString *)key
-                                        objectClass:(Class)objectClass
-                                        accessGroup:(nullable NSString *)accessGroup;
-
-/**
- * Saves the given object by the given key.
- * @param object The object to store.
- * @param key The key to store the object. If there is an existing object by the key, it will be
- * overridden.
- * @param accessGroup The Keychain Access Group.
- *
- * @return Returns which is resolved with `[NSNull null]` on success.
- */
-- (FBLPromise<NSNull *> *)setObject:(id<NSSecureCoding>)object
-                             forKey:(NSString *)key
-                        accessGroup:(nullable NSString *)accessGroup;
-
-/**
- * Removes the object by the given key.
- * @param key The key to store the object. If there is an existing object by the key, it will be
- * overridden.
- * @param accessGroup The Keychain Access Group.
- *
- * @return Returns which is resolved with `[NSNull null]` on success.
- */
-- (FBLPromise<NSNull *> *)removeObjectForKey:(NSString *)key
-                                 accessGroup:(nullable NSString *)accessGroup;
-
-#if TARGET_OS_OSX
-/// If not `nil`, then only this keychain will be used to save and read data (see
-/// `kSecMatchSearchList` and `kSecUseKeychain`. It is mostly intended to be used by unit tests.
-@property(nonatomic, nullable) SecKeychainRef keychainRef;
-#endif  // TARGET_OSX
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 61
GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainUtils.h

@@ -1,61 +0,0 @@
-/*
- * Copyright 2019 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-FOUNDATION_EXPORT NSString *const kGULKeychainUtilsErrorDomain;
-
-/// Helper functions to access Keychain.
-@interface GULKeychainUtils : NSObject
-
-/** Fetches a keychain item data matching to the provided query.
- *  @param query A dictionary with Keychain query parameters. See docs for `SecItemCopyMatching` for
- * details.
- *  @param outError A pointer to `NSError` instance or `NULL`. The instance at `outError` will be
- * assigned with an error if there is.
- *  @returns Data for the first Keychain Item matching the provided query or `nil` if there is not
- * such an item (`outError` will be `nil` in this case) or an error occurred.
- */
-+ (nullable NSData *)getItemWithQuery:(NSDictionary *)query
-                                error:(NSError *_Nullable *_Nullable)outError;
-
-/** Stores data to a Keychain Item matching to the provided query. An existing Keychain Item
- * matching the query parameters will be updated or a new will be created.
- *  @param item A Keychain Item data to store.
- *  @param query A dictionary with Keychain query parameters. See docs for `SecItemAdd` and
- * `SecItemUpdate` for details.
- *  @param outError A pointer to `NSError` instance or `NULL`. The instance at `outError` will be
- * assigned with an error if there is.
- *  @returns `YES` when data was successfully stored, `NO` otherwise.
- */
-+ (BOOL)setItem:(NSData *)item
-      withQuery:(NSDictionary *)query
-          error:(NSError *_Nullable *_Nullable)outError;
-
-/** Removes a Keychain Item matching to the provided query.
- *  @param query A dictionary with Keychain query parameters. See docs for `SecItemDelete` for
- * details.
- *  @param outError A pointer to `NSError` instance or `NULL`. The instance at `outError` will be
- * assigned with an error if there is.
- *  @returns `YES` if the item was removed successfully or doesn't exist, `NO` otherwise.
- */
-+ (BOOL)removeItemWithQuery:(NSDictionary *)query error:(NSError *_Nullable *_Nullable)outError;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 36
GoogleUtilities/Environment/Public/GoogleUtilities/GULSecureCoding.h

@@ -1,36 +0,0 @@
-// Copyright 2019 Google
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-/** The class wraps `NSKeyedArchiver` and `NSKeyedUnarchiver` API to provide a unified secure coding
- *  methods for iOS versions before and after 11.
- */
-@interface GULSecureCoding : NSObject
-
-+ (nullable id)unarchivedObjectOfClasses:(NSSet<Class> *)classes
-                                fromData:(NSData *)data
-                                   error:(NSError **)outError;
-
-+ (nullable id)unarchivedObjectOfClass:(Class)class
-                              fromData:(NSData *)data
-                                 error:(NSError **)outError;
-
-+ (nullable NSData *)archivedDataWithRootObject:(id<NSCoding>)object error:(NSError **)outError;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 31
GoogleUtilities/Environment/Public/GoogleUtilities/GULURLSessionDataResponse.h

@@ -1,31 +0,0 @@
-/*
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-/** The class represents HTTP response received from `NSURLSession`. */
-@interface GULURLSessionDataResponse : NSObject
-
-@property(nonatomic, readonly) NSHTTPURLResponse *HTTPResponse;
-@property(nonatomic, nullable, readonly) NSData *HTTPBody;
-
-- (instancetype)initWithResponse:(NSHTTPURLResponse *)response HTTPBody:(nullable NSData *)body;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 37
GoogleUtilities/Environment/Public/GoogleUtilities/NSURLSession+GULPromises.h

@@ -1,37 +0,0 @@
-/*
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-@class FBLPromise<Value>;
-@class GULURLSessionDataResponse;
-
-NS_ASSUME_NONNULL_BEGIN
-
-/** Promise based API for `NSURLSession`. */
-@interface NSURLSession (GULPromises)
-
-/** Creates a promise wrapping `-[NSURLSession dataTaskWithRequest:completionHandler:]` method.
- * @param URLRequest The request to create a data task with.
- * @return A promise that is fulfilled when an HTTP response is received (with any response code),
- * or is rejected with the error passed to the task completion.
- */
-- (FBLPromise<GULURLSessionDataResponse *> *)gul_dataTaskPromiseWithRequest:
-    (NSURLRequest *)URLRequest;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 192
GoogleUtilities/Environment/SecureStorage/GULKeychainStorage.m

@@ -1,192 +0,0 @@
-/*
- * Copyright 2019 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import "GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainStorage.h"
-#import <Security/Security.h>
-
-#if __has_include(<FBLPromises/FBLPromises.h>)
-#import <FBLPromises/FBLPromises.h>
-#else
-#import "FBLPromises.h"
-#endif
-
-#import "GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainUtils.h"
-#import "GoogleUtilities/Environment/Public/GoogleUtilities/GULSecureCoding.h"
-
-@interface GULKeychainStorage ()
-@property(nonatomic, readonly) dispatch_queue_t keychainQueue;
-@property(nonatomic, readonly) dispatch_queue_t inMemoryCacheQueue;
-@property(nonatomic, readonly) NSString *service;
-@property(nonatomic, readonly) NSCache<NSString *, id<NSSecureCoding>> *inMemoryCache;
-@end
-
-@implementation GULKeychainStorage
-
-- (instancetype)initWithService:(NSString *)service {
-  NSCache *cache = [[NSCache alloc] init];
-  // Cache up to 5 installations.
-  cache.countLimit = 5;
-  return [self initWithService:service cache:cache];
-}
-
-- (instancetype)initWithService:(NSString *)service cache:(NSCache *)cache {
-  self = [super init];
-  if (self) {
-    _keychainQueue =
-        dispatch_queue_create("com.gul.KeychainStorage.Keychain", DISPATCH_QUEUE_SERIAL);
-    _inMemoryCacheQueue =
-        dispatch_queue_create("com.gul.KeychainStorage.InMemoryCache", DISPATCH_QUEUE_SERIAL);
-    _service = [service copy];
-    _inMemoryCache = cache;
-  }
-  return self;
-}
-
-#pragma mark - Public
-
-- (FBLPromise<id<NSSecureCoding>> *)getObjectForKey:(NSString *)key
-                                        objectClass:(Class)objectClass
-                                        accessGroup:(nullable NSString *)accessGroup {
-  return [FBLPromise onQueue:self.inMemoryCacheQueue
-                          do:^id _Nullable {
-                            // Return cached object or fail otherwise.
-                            id object = [self.inMemoryCache objectForKey:key];
-                            return object
-                                       ?: [[NSError alloc]
-                                              initWithDomain:FBLPromiseErrorDomain
-                                                        code:FBLPromiseErrorCodeValidationFailure
-                                                    userInfo:nil];
-                          }]
-      .recover(^id _Nullable(NSError *error) {
-        // Look for the object in the keychain.
-        return [self getObjectFromKeychainForKey:key
-                                     objectClass:objectClass
-                                     accessGroup:accessGroup];
-      });
-}
-
-- (FBLPromise<NSNull *> *)setObject:(id<NSSecureCoding>)object
-                             forKey:(NSString *)key
-                        accessGroup:(nullable NSString *)accessGroup {
-  return [FBLPromise onQueue:self.inMemoryCacheQueue
-                          do:^id _Nullable {
-                            // Save to the in-memory cache first.
-                            [self.inMemoryCache setObject:object forKey:[key copy]];
-                            return [NSNull null];
-                          }]
-      .thenOn(self.keychainQueue, ^id(id result) {
-        // Then store the object to the keychain.
-        NSDictionary *query = [self keychainQueryWithKey:key accessGroup:accessGroup];
-        NSError *error;
-        NSData *encodedObject = [GULSecureCoding archivedDataWithRootObject:object error:&error];
-        if (!encodedObject) {
-          return error;
-        }
-
-        if (![GULKeychainUtils setItem:encodedObject withQuery:query error:&error]) {
-          return error;
-        }
-
-        return [NSNull null];
-      });
-}
-
-- (FBLPromise<NSNull *> *)removeObjectForKey:(NSString *)key
-                                 accessGroup:(nullable NSString *)accessGroup {
-  return [FBLPromise onQueue:self.inMemoryCacheQueue
-                          do:^id _Nullable {
-                            [self.inMemoryCache removeObjectForKey:key];
-                            return nil;
-                          }]
-      .thenOn(self.keychainQueue, ^id(id result) {
-        NSDictionary *query = [self keychainQueryWithKey:key accessGroup:accessGroup];
-
-        NSError *error;
-        if (![GULKeychainUtils removeItemWithQuery:query error:&error]) {
-          return error;
-        }
-
-        return [NSNull null];
-      });
-}
-
-#pragma mark - Private
-
-- (FBLPromise<id<NSSecureCoding>> *)getObjectFromKeychainForKey:(NSString *)key
-                                                    objectClass:(Class)objectClass
-                                                    accessGroup:(nullable NSString *)accessGroup {
-  // Look for the object in the keychain.
-  return [FBLPromise
-             onQueue:self.keychainQueue
-                  do:^id {
-                    NSDictionary *query = [self keychainQueryWithKey:key accessGroup:accessGroup];
-                    NSError *error;
-                    NSData *encodedObject = [GULKeychainUtils getItemWithQuery:query error:&error];
-
-                    if (error) {
-                      return error;
-                    }
-                    if (!encodedObject) {
-                      return nil;
-                    }
-                    id object = [GULSecureCoding unarchivedObjectOfClass:objectClass
-                                                                fromData:encodedObject
-                                                                   error:&error];
-                    if (error) {
-                      return error;
-                    }
-
-                    return object;
-                  }]
-      .thenOn(self.inMemoryCacheQueue,
-              ^id<NSSecureCoding> _Nullable(id<NSSecureCoding> _Nullable object) {
-                // Save object to the in-memory cache if exists and return the object.
-                if (object) {
-                  [self.inMemoryCache setObject:object forKey:[key copy]];
-                }
-                return object;
-              });
-}
-
-- (void)resetInMemoryCache {
-  [self.inMemoryCache removeAllObjects];
-}
-
-#pragma mark - Keychain
-
-- (NSMutableDictionary<NSString *, id> *)keychainQueryWithKey:(NSString *)key
-                                                  accessGroup:(nullable NSString *)accessGroup {
-  NSMutableDictionary<NSString *, id> *query = [NSMutableDictionary dictionary];
-
-  query[(__bridge NSString *)kSecClass] = (__bridge NSString *)kSecClassGenericPassword;
-  query[(__bridge NSString *)kSecAttrService] = self.service;
-  query[(__bridge NSString *)kSecAttrAccount] = key;
-
-  if (accessGroup) {
-    query[(__bridge NSString *)kSecAttrAccessGroup] = accessGroup;
-  }
-
-#if TARGET_OS_OSX
-  if (self.keychainRef) {
-    query[(__bridge NSString *)kSecUseKeychain] = (__bridge id)(self.keychainRef);
-    query[(__bridge NSString *)kSecMatchSearchList] = @[ (__bridge id)(self.keychainRef) ];
-  }
-#endif  // TARGET_OSX
-
-  return query;
-}
-
-@end

+ 0 - 113
GoogleUtilities/Environment/SecureStorage/GULKeychainUtils.m

@@ -1,113 +0,0 @@
-/*
- * Copyright 2019 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import "GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainUtils.h"
-
-NSString *const kGULKeychainUtilsErrorDomain = @"com.gul.keychain.ErrorDomain";
-
-@implementation GULKeychainUtils
-
-+ (nullable NSData *)getItemWithQuery:(NSDictionary *)query
-                                error:(NSError *_Nullable *_Nullable)outError {
-  NSMutableDictionary *mutableQuery = [query mutableCopy];
-
-  mutableQuery[(__bridge id)kSecReturnData] = @YES;
-  mutableQuery[(__bridge id)kSecMatchLimit] = (__bridge id)kSecMatchLimitOne;
-
-  CFDataRef result = NULL;
-  OSStatus status =
-      SecItemCopyMatching((__bridge CFDictionaryRef)mutableQuery, (CFTypeRef *)&result);
-
-  if (status == errSecSuccess && result != NULL) {
-    if (outError) {
-      *outError = nil;
-    }
-
-    return (__bridge_transfer NSData *)result;
-  }
-
-  if (status == errSecItemNotFound) {
-    if (outError) {
-      *outError = nil;
-    }
-  } else {
-    if (outError) {
-      *outError = [self keychainErrorWithFunction:@"SecItemCopyMatching" status:status];
-    }
-  }
-  return nil;
-}
-
-+ (BOOL)setItem:(NSData *)item
-      withQuery:(NSDictionary *)query
-          error:(NSError *_Nullable *_Nullable)outError {
-  NSData *existingItem = [self getItemWithQuery:query error:outError];
-  if (outError && *outError) {
-    return NO;
-  }
-
-  NSMutableDictionary *mutableQuery = [query mutableCopy];
-  mutableQuery[(__bridge id)kSecAttrAccessible] =
-      (__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;
-
-  OSStatus status;
-  if (!existingItem) {
-    mutableQuery[(__bridge id)kSecValueData] = item;
-    status = SecItemAdd((__bridge CFDictionaryRef)mutableQuery, NULL);
-  } else {
-    NSDictionary *attributes = @{(__bridge id)kSecValueData : item};
-    status = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)attributes);
-  }
-
-  if (status == noErr) {
-    if (outError) {
-      *outError = nil;
-    }
-    return YES;
-  }
-
-  NSString *function = existingItem ? @"SecItemUpdate" : @"SecItemAdd";
-  if (outError) {
-    *outError = [self keychainErrorWithFunction:function status:status];
-  }
-  return NO;
-}
-
-+ (BOOL)removeItemWithQuery:(NSDictionary *)query error:(NSError *_Nullable *_Nullable)outError {
-  OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query);
-
-  if (status == noErr || status == errSecItemNotFound) {
-    if (outError) {
-      *outError = nil;
-    }
-    return YES;
-  }
-
-  if (outError) {
-    *outError = [self keychainErrorWithFunction:@"SecItemDelete" status:status];
-  }
-  return NO;
-}
-
-#pragma mark - Errors
-
-+ (NSError *)keychainErrorWithFunction:(NSString *)keychainFunction status:(OSStatus)status {
-  NSString *failureReason = [NSString stringWithFormat:@"%@ (%li)", keychainFunction, (long)status];
-  NSDictionary *userInfo = @{NSLocalizedFailureReasonErrorKey : failureReason};
-  return [NSError errorWithDomain:kGULKeychainUtilsErrorDomain code:0 userInfo:userInfo];
-}
-
-@end

+ 0 - 30
GoogleUtilities/Environment/URLSessionPromiseWrapper/GULURLSessionDataResponse.m

@@ -1,30 +0,0 @@
-/*
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import "GoogleUtilities/Environment/Public/GoogleUtilities/GULURLSessionDataResponse.h"
-
-@implementation GULURLSessionDataResponse
-
-- (instancetype)initWithResponse:(NSHTTPURLResponse *)response HTTPBody:(NSData *)body {
-  self = [super init];
-  if (self) {
-    _HTTPResponse = response;
-    _HTTPBody = body;
-  }
-  return self;
-}
-
-@end

+ 0 - 46
GoogleUtilities/Environment/URLSessionPromiseWrapper/NSURLSession+GULPromises.m

@@ -1,46 +0,0 @@
-/*
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import "GoogleUtilities/Environment/Public/GoogleUtilities/NSURLSession+GULPromises.h"
-
-#if __has_include(<FBLPromises/FBLPromises.h>)
-#import <FBLPromises/FBLPromises.h>
-#else
-#import "FBLPromises.h"
-#endif
-
-#import "GoogleUtilities/Environment/Public/GoogleUtilities/GULURLSessionDataResponse.h"
-
-@implementation NSURLSession (GULPromises)
-
-- (FBLPromise<GULURLSessionDataResponse *> *)gul_dataTaskPromiseWithRequest:
-    (NSURLRequest *)URLRequest {
-  return [FBLPromise async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) {
-    [[self dataTaskWithRequest:URLRequest
-             completionHandler:^(NSData *_Nullable data, NSURLResponse *_Nullable response,
-                                 NSError *_Nullable error) {
-               if (error) {
-                 reject(error);
-               } else {
-                 fulfill([[GULURLSessionDataResponse alloc]
-                     initWithResponse:(NSHTTPURLResponse *)response
-                             HTTPBody:data]);
-               }
-             }] resume];
-  }];
-}
-
-@end

+ 0 - 312
GoogleUtilities/Environment/third_party/GULAppEnvironmentUtil.m

@@ -1,312 +0,0 @@
-// Copyright 2017 Google
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import "GoogleUtilities/Environment/Public/GoogleUtilities/GULAppEnvironmentUtil.h"
-
-#import <Foundation/Foundation.h>
-#import <dlfcn.h>
-#import <mach-o/dyld.h>
-#import <sys/utsname.h>
-#import <objc/runtime.h>
-
-#if TARGET_OS_IOS
-#import <UIKit/UIKit.h>
-#endif
-
-/// The encryption info struct and constants are missing from the iPhoneSimulator SDK, but not from
-/// the iPhoneOS or Mac OS X SDKs. Since one doesn't ever ship a Simulator binary, we'll just
-/// provide the definitions here.
-#if TARGET_OS_SIMULATOR && !defined(LC_ENCRYPTION_INFO)
-#define LC_ENCRYPTION_INFO 0x21
-struct encryption_info_command {
-  uint32_t cmd;
-  uint32_t cmdsize;
-  uint32_t cryptoff;
-  uint32_t cryptsize;
-  uint32_t cryptid;
-};
-#endif
-
-@implementation GULAppEnvironmentUtil
-
-/// A key for the Info.plist to enable or disable checking if the App Store is running in a sandbox.
-/// This will affect your data integrity when using Firebase Analytics, as it will disable some
-/// necessary checks.
-static NSString *const kFIRAppStoreReceiptURLCheckEnabledKey =
-    @"FirebaseAppStoreReceiptURLCheckEnabled";
-
-/// The file name of the sandbox receipt. This is available on iOS >= 8.0
-static NSString *const kFIRAIdentitySandboxReceiptFileName = @"sandboxReceipt";
-
-/// The following copyright from Landon J. Fuller applies to the isAppEncrypted function.
-///
-/// Copyright (c) 2017 Landon J. Fuller <landon@landonf.org>
-/// 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.
-///
-/// Comment from <a href="http://iphonedevwiki.net/index.php/Crack_prevention">iPhone Dev Wiki
-/// Crack Prevention</a>:
-/// App Store binaries are signed by both their developer and Apple. This encrypts the binary so
-/// that decryption keys are needed in order to make the binary readable. When iOS executes the
-/// binary, the decryption keys are used to decrypt the binary into a readable state where it is
-/// then loaded into memory and executed. iOS can tell the encryption status of a binary via the
-/// cryptid structure member of LC_ENCRYPTION_INFO MachO load command. If cryptid is a non-zero
-/// value then the binary is encrypted.
-///
-/// 'Cracking' works by letting the kernel decrypt the binary then siphoning the decrypted data into
-/// a new binary file, resigning, and repackaging. This will only work on jailbroken devices as
-/// codesignature validation has been removed. Resigning takes place because while the codesignature
-/// doesn't have to be valid thanks to the jailbreak, it does have to be in place unless you have
-/// AppSync or similar to disable codesignature checks.
-///
-/// More information at <a href="http://landonf.org/2009/02/index.html">Landon Fuller's blog</a>
-static BOOL IsAppEncrypted() {
-  const struct mach_header *executableHeader = NULL;
-  for (uint32_t i = 0; i < _dyld_image_count(); i++) {
-    const struct mach_header *header = _dyld_get_image_header(i);
-    if (header && header->filetype == MH_EXECUTE) {
-      executableHeader = header;
-      break;
-    }
-  }
-
-  if (!executableHeader) {
-    return NO;
-  }
-
-  BOOL is64bit = (executableHeader->magic == MH_MAGIC_64);
-  uintptr_t cursor = (uintptr_t)executableHeader +
-                     (is64bit ? sizeof(struct mach_header_64) : sizeof(struct mach_header));
-  const struct segment_command *segmentCommand = NULL;
-  uint32_t i = 0;
-
-  while (i++ < executableHeader->ncmds) {
-    segmentCommand = (struct segment_command *)cursor;
-
-    if (!segmentCommand) {
-      continue;
-    }
-
-    if ((!is64bit && segmentCommand->cmd == LC_ENCRYPTION_INFO) ||
-        (is64bit && segmentCommand->cmd == LC_ENCRYPTION_INFO_64)) {
-      if (is64bit) {
-        struct encryption_info_command_64 *cryptCmd =
-            (struct encryption_info_command_64 *)segmentCommand;
-        return cryptCmd && cryptCmd->cryptid != 0;
-      } else {
-        struct encryption_info_command *cryptCmd = (struct encryption_info_command *)segmentCommand;
-        return cryptCmd && cryptCmd->cryptid != 0;
-      }
-    }
-    cursor += segmentCommand->cmdsize;
-  }
-
-  return NO;
-}
-
-static BOOL HasSCInfoFolder() {
-#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH
-  NSString *bundlePath = [NSBundle mainBundle].bundlePath;
-  NSString *scInfoPath = [bundlePath stringByAppendingPathComponent:@"SC_Info"];
-  return [[NSFileManager defaultManager] fileExistsAtPath:scInfoPath];
-#elif TARGET_OS_OSX
-  return NO;
-#endif
-}
-
-static BOOL HasEmbeddedMobileProvision() {
-#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH
-  return [[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"].length > 0;
-#elif TARGET_OS_OSX
-  return NO;
-#endif
-}
-
-+ (BOOL)isFromAppStore {
-  static dispatch_once_t isEncryptedOnce;
-  static BOOL isEncrypted = NO;
-
-  dispatch_once(&isEncryptedOnce, ^{
-    isEncrypted = IsAppEncrypted();
-  });
-
-  if ([GULAppEnvironmentUtil isSimulator]) {
-    return NO;
-  }
-
-  // If an app contain the sandboxReceipt file, it means its coming from TestFlight
-  // This must be checked before the SCInfo Folder check below since TestFlight apps may
-  // also have an SCInfo folder.
-  if ([GULAppEnvironmentUtil isAppStoreReceiptSandbox]) {
-    return NO;
-  }
-
-  if (HasSCInfoFolder()) {
-    // When iTunes downloads a .ipa, it also gets a customized .sinf file which is added to the
-    // main SC_Info directory.
-    return YES;
-  }
-
-  // For iOS >= 8.0, iTunesMetadata.plist is moved outside of the sandbox. Any attempt to read
-  // the iTunesMetadata.plist outside of the sandbox will be rejected by Apple.
-  // If the app does not contain the embedded.mobileprovision which is stripped out by Apple when
-  // the app is submitted to store, then it is highly likely that it is from Apple Store.
-  return isEncrypted && !HasEmbeddedMobileProvision();
-}
-
-+ (BOOL)isAppStoreReceiptSandbox {
-  // Since checking the App Store's receipt URL can be memory intensive, check the option in the
-  // Info.plist if developers opted out of this check.
-  id enableSandboxCheck =
-      [[NSBundle mainBundle] objectForInfoDictionaryKey:kFIRAppStoreReceiptURLCheckEnabledKey];
-  if (enableSandboxCheck && [enableSandboxCheck isKindOfClass:[NSNumber class]] &&
-      ![enableSandboxCheck boolValue]) {
-    return NO;
-  }
-
-  NSURL *appStoreReceiptURL = [NSBundle mainBundle].appStoreReceiptURL;
-  NSString *appStoreReceiptFileName = appStoreReceiptURL.lastPathComponent;
-  return [appStoreReceiptFileName isEqualToString:kFIRAIdentitySandboxReceiptFileName];
-}
-
-+ (BOOL)isSimulator {
-#if TARGET_OS_SIMULATOR
-  return YES;
-#elif TARGET_OS_MACCATALYST
-  return NO;
-#elif TARGET_OS_IOS || TARGET_OS_TV
-  NSString *platform = [GULAppEnvironmentUtil deviceModel];
-  return [platform isEqual:@"x86_64"] || [platform isEqual:@"i386"];
-#elif TARGET_OS_OSX
-  return NO;
-#endif
-  return NO;
-}
-
-+ (NSString *)deviceModel {
-  static dispatch_once_t once;
-  static NSString *deviceModel;
-
-  dispatch_once(&once, ^{
-    struct utsname systemInfo;
-    if (uname(&systemInfo) == 0) {
-      deviceModel = [NSString stringWithUTF8String:systemInfo.machine];
-    }
-  });
-  return deviceModel;
-}
-
-+ (NSString *)systemVersion {
-#if TARGET_OS_IOS
-  return [UIDevice currentDevice].systemVersion;
-#elif TARGET_OS_OSX || TARGET_OS_TV || TARGET_OS_WATCH
-  // Assemble the systemVersion, excluding the patch version if it's 0.
-  NSOperatingSystemVersion osVersion = [NSProcessInfo processInfo].operatingSystemVersion;
-  NSMutableString *versionString = [[NSMutableString alloc]
-      initWithFormat:@"%ld.%ld", (long)osVersion.majorVersion, (long)osVersion.minorVersion];
-  if (osVersion.patchVersion != 0) {
-    [versionString appendFormat:@".%ld", (long)osVersion.patchVersion];
-  }
-  return versionString;
-#endif
-}
-
-+ (BOOL)isAppExtension {
-#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH
-  // Documented by <a href="https://goo.gl/RRB2Up">Apple</a>
-  BOOL appExtension = [[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"];
-  return appExtension;
-#elif TARGET_OS_OSX
-  return NO;
-#endif
-}
-
-+ (BOOL)isIOS7OrHigher {
-  return YES;
-}
-
-+ (BOOL)hasSwiftRuntime {
-  // The class
-  // [Swift._SwiftObject](https://github.com/apple/swift/blob/5eac3e2818eb340b11232aff83edfbd1c307fa03/stdlib/public/runtime/SwiftObject.h#L35)
-  // is a part of Swift runtime, so it should be present if Swift runtime is available.
-
-  BOOL hasSwiftRuntime =
-      objc_lookUpClass("Swift._SwiftObject") != nil ||
-      // Swift object class name before
-      // https://github.com/apple/swift/commit/9637b4a6e11ddca72f5f6dbe528efc7c92f14d01
-      objc_getClass("_TtCs12_SwiftObject") != nil;
-
-  return hasSwiftRuntime;
-}
-
-+ (NSString *)applePlatform {
-  NSString *applePlatform = @"unknown";
-
-  // When a Catalyst app is run on macOS then both `TARGET_OS_MACCATALYST` and `TARGET_OS_IOS` are
-  // `true`, which means the condition list is order-sensitive.
-#if TARGET_OS_MACCATALYST
-  applePlatform = @"maccatalyst";
-#elif TARGET_OS_IOS
-#if defined(__IPHONE_14_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
-  if (@available(iOS 14.0, *)) {
-    // Early iOS 14 betas do not include isiOSAppOnMac (#6969)
-    applePlatform = ([[NSProcessInfo processInfo] respondsToSelector:@selector(isiOSAppOnMac)] &&
-                      [NSProcessInfo processInfo].isiOSAppOnMac) ? @"ios_on_mac" : @"ios";
-  } else {
-    applePlatform = @"ios";
-  }
-#else // defined(__IPHONE_14_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
-  applePlatform = @"ios";
-#endif // defined(__IPHONE_14_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
-
-#elif TARGET_OS_TV
-  applePlatform = @"tvos";
-#elif TARGET_OS_OSX
-  applePlatform = @"macos";
-#elif TARGET_OS_WATCH
-  applePlatform = @"watchos";
-#endif // TARGET_OS_MACCATALYST
-
-  return applePlatform;
-}
-
-+ (NSString *)deploymentType {
-#if SWIFT_PACKAGE
-  NSString *deploymentType = @"swiftpm";
-#elif FIREBASE_BUILD_CARTHAGE
-  NSString *deploymentType = @"carthage";
-#elif FIREBASE_BUILD_ZIP_FILE
-  NSString *deploymentType = @"zip";
-#else
-  NSString *deploymentType = @"cocoapods";
-#endif
-
-  return deploymentType;
-}
-
-@end

+ 0 - 36
GoogleUtilities/Environment/third_party/LICENSE

@@ -1,36 +0,0 @@
-The following copyright from Landon J. Fuller applies to the isAppEncrypted function.
-
-Copyright (c) 2017 Landon J. Fuller <landon@landonf.org>
-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.
-
-Comment from <a href="http://iphonedevwiki.net/index.php/Crack_prevention">iPhone Dev Wiki
-Crack Prevention</a>:
-App Store binaries are signed by both their developer and Apple. This encrypts the binary so
-that decryption keys are needed in order to make the binary readable. When iOS executes the
-binary, the decryption keys are used to decrypt the binary into a readable state where it is
-then loaded into memory and executed. iOS can tell the encryption status of a binary via the
-cryptid structure member of LC_ENCRYPTION_INFO MachO load command. If cryptid is a non-zero
-value then the binary is encrypted.
-
-'Cracking' works by letting the kernel decrypt the binary then siphoning the decrypted data into
-a new binary file, resigning, and repackaging. This will only work on jailbroken devices as
-codesignature validation has been removed. Resigning takes place because while the codesignature
-doesn't have to be valid thanks to the jailbreak, it does have to be in place unless you have
-AppSync or similar to disable codesignature checks.
-
-More information at <a href="http://landonf.org/2009/02/index.html">Landon Fuller's blog</a>

+ 0 - 21
GoogleUtilities/ISASwizzler/GULObjectSwizzler+Internal.h

@@ -1,21 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import "GoogleUtilities/ISASwizzler/Public/GoogleUtilities/GULObjectSwizzler.h"
-
-@interface GULObjectSwizzler (Internal)
-
-- (void)swizzledObjectHasBeenDeallocatedWithGeneratedSubclass:(BOOL)isInstanceOfGeneratedSubclass;
-
-@end

+ 0 - 198
GoogleUtilities/ISASwizzler/GULObjectSwizzler.m

@@ -1,198 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import "GoogleUtilities/ISASwizzler/Public/GoogleUtilities/GULObjectSwizzler.h"
-
-#import <objc/runtime.h>
-
-#import "GoogleUtilities/ISASwizzler/Public/GoogleUtilities/GULSwizzledObject.h"
-
-@implementation GULObjectSwizzler {
-  // The swizzled object.
-  __weak id _swizzledObject;
-
-  // The original class of the object.
-  Class _originalClass;
-
-  // The dynamically generated subclass of _originalClass.
-  Class _generatedClass;
-}
-
-#pragma mark - Class methods
-
-+ (void)setAssociatedObject:(id)object
-                        key:(NSString *)key
-                      value:(nullable id)value
-                association:(GUL_ASSOCIATION)association {
-  objc_AssociationPolicy resolvedAssociation;
-  switch (association) {
-    case GUL_ASSOCIATION_ASSIGN:
-      resolvedAssociation = OBJC_ASSOCIATION_ASSIGN;
-      break;
-
-    case GUL_ASSOCIATION_RETAIN_NONATOMIC:
-      resolvedAssociation = OBJC_ASSOCIATION_RETAIN_NONATOMIC;
-      break;
-
-    case GUL_ASSOCIATION_COPY_NONATOMIC:
-      resolvedAssociation = OBJC_ASSOCIATION_COPY_NONATOMIC;
-      break;
-
-    case GUL_ASSOCIATION_RETAIN:
-      resolvedAssociation = OBJC_ASSOCIATION_RETAIN;
-      break;
-
-    case GUL_ASSOCIATION_COPY:
-      resolvedAssociation = OBJC_ASSOCIATION_COPY;
-      break;
-
-    default:
-      break;
-  }
-  objc_setAssociatedObject(object, key.UTF8String, value, resolvedAssociation);
-}
-
-+ (nullable id)getAssociatedObject:(id)object key:(NSString *)key {
-  return objc_getAssociatedObject(object, key.UTF8String);
-}
-
-#pragma mark - Instance methods
-
-/** Instantiates an instance of this class.
- *
- *  @param object The object to swizzle.
- *  @return An instance of this class.
- */
-- (instancetype)initWithObject:(id)object {
-  if (object == nil) {
-    return nil;
-  }
-
-  GULObjectSwizzler *existingSwizzler =
-      [[self class] getAssociatedObject:object key:kSwizzlerAssociatedObjectKey];
-  if ([existingSwizzler isKindOfClass:[GULObjectSwizzler class]]) {
-    // The object has been swizzled already, no need to swizzle again.
-    return existingSwizzler;
-  }
-
-  self = [super init];
-  if (self) {
-    _swizzledObject = object;
-    _originalClass = object_getClass(object);
-    NSString *newClassName = [NSString stringWithFormat:@"fir_%@_%@", [[NSUUID UUID] UUIDString],
-                                                        NSStringFromClass(_originalClass)];
-    _generatedClass = objc_allocateClassPair(_originalClass, newClassName.UTF8String, 0);
-    NSAssert(_generatedClass, @"Wasn't able to allocate the class pair.");
-  }
-  return self;
-}
-
-- (void)copySelector:(SEL)selector fromClass:(Class)aClass isClassSelector:(BOOL)isClassSelector {
-  NSAssert(_generatedClass, @"This object has already been unswizzled.");
-  Method method = isClassSelector ? class_getClassMethod(aClass, selector)
-                                  : class_getInstanceMethod(aClass, selector);
-  Class targetClass = isClassSelector ? object_getClass(_generatedClass) : _generatedClass;
-  IMP implementation = method_getImplementation(method);
-
-  const char *typeEncoding = method_getTypeEncoding(method);
-  class_replaceMethod(targetClass, selector, implementation, typeEncoding);
-}
-
-- (void)setAssociatedObjectWithKey:(NSString *)key
-                             value:(id)value
-                       association:(GUL_ASSOCIATION)association {
-  __strong id swizzledObject = _swizzledObject;
-  if (swizzledObject) {
-    [[self class] setAssociatedObject:swizzledObject key:key value:value association:association];
-  }
-}
-
-- (nullable id)getAssociatedObjectForKey:(NSString *)key {
-  __strong id swizzledObject = _swizzledObject;
-  if (swizzledObject) {
-    return [[self class] getAssociatedObject:swizzledObject key:key];
-  }
-  return nil;
-}
-
-- (void)swizzle {
-  __strong id swizzledObject = _swizzledObject;
-
-  GULObjectSwizzler *existingSwizzler =
-      [[self class] getAssociatedObject:swizzledObject key:kSwizzlerAssociatedObjectKey];
-  if (existingSwizzler != nil) {
-    NSAssert(existingSwizzler == self, @"The swizzled object has a different swizzler.");
-    // The object has been swizzled already.
-    return;
-  }
-
-  if (swizzledObject) {
-    [GULObjectSwizzler setAssociatedObject:swizzledObject
-                                       key:kSwizzlerAssociatedObjectKey
-                                     value:self
-                               association:GUL_ASSOCIATION_RETAIN];
-
-    [GULSwizzledObject copyDonorSelectorsUsingObjectSwizzler:self];
-
-    NSAssert(_originalClass == object_getClass(swizzledObject),
-             @"The original class is not the reported class now.");
-    NSAssert(class_getInstanceSize(_originalClass) == class_getInstanceSize(_generatedClass),
-             @"The instance size of the generated class must be equal to the original class.");
-    objc_registerClassPair(_generatedClass);
-    Class doubleCheckOriginalClass __unused = object_setClass(_swizzledObject, _generatedClass);
-    NSAssert(_originalClass == doubleCheckOriginalClass,
-             @"The original class must be the same as the class returned by object_setClass");
-  } else {
-    NSAssert(NO, @"You can't swizzle a nil object");
-  }
-}
-
-- (void)dealloc {
-  if (_generatedClass) {
-    if (_swizzledObject == nil) {
-      // The swizzled object has been deallocated already, so the generated class can be disposed
-      // now.
-      objc_disposeClassPair(_generatedClass);
-      return;
-    }
-
-    // GULSwizzledObject is retained by the swizzled object which means that the swizzled object is
-    // being deallocated now. Let's see if we should schedule the generated class disposal.
-
-    // If the swizzled object has a different class, it most likely indicates that the object was
-    // ISA swizzled one more time. In this case it is not safe to dispose the generated class. We
-    // will have to keep it to prevent a crash.
-
-    // TODO: Consider adding a flag that can be set by the host application to dispose the class
-    // pair unconditionally. It may be used by apps that use ISA Swizzling themself and are
-    // confident in disposing their subclasses.
-    BOOL isSwizzledObjectInstanceOfGeneratedClass =
-        object_getClass(_swizzledObject) == _generatedClass;
-
-    if (isSwizzledObjectInstanceOfGeneratedClass) {
-      Class generatedClass = _generatedClass;
-
-      // Schedule the generated class disposal after the swizzled object has been deallocated.
-      dispatch_async(dispatch_get_main_queue(), ^{
-        objc_disposeClassPair(generatedClass);
-      });
-    }
-  }
-}
-
-- (BOOL)isSwizzlingProxyObject {
-  return [_swizzledObject isProxy];
-}
-
-@end

+ 0 - 64
GoogleUtilities/ISASwizzler/GULSwizzledObject.m

@@ -1,64 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import <objc/runtime.h>
-
-#import "GoogleUtilities/ISASwizzler/GULObjectSwizzler+Internal.h"
-#import "GoogleUtilities/ISASwizzler/Public/GoogleUtilities/GULSwizzledObject.h"
-
-NSString *kSwizzlerAssociatedObjectKey = @"gul_objectSwizzler";
-
-@interface GULSwizzledObject ()
-
-@end
-
-@implementation GULSwizzledObject
-
-+ (void)copyDonorSelectorsUsingObjectSwizzler:(GULObjectSwizzler *)objectSwizzler {
-  [objectSwizzler copySelector:@selector(gul_objectSwizzler) fromClass:self isClassSelector:NO];
-  [objectSwizzler copySelector:@selector(gul_class) fromClass:self isClassSelector:NO];
-
-  // This is needed because NSProxy objects usually override -[NSObjectProtocol respondsToSelector:]
-  // and ask this question to the underlying object. Since we don't swizzle the underlying object
-  // but swizzle the proxy, when someone calls -[NSObjectProtocol respondsToSelector:] on the proxy,
-  // the answer ends up being NO even if we added new methods to the subclass through ISA Swizzling.
-  // To solve that, we override -[NSObjectProtocol respondsToSelector:] in such a way that takes
-  // into account the fact that we've added new methods.
-  if ([objectSwizzler isSwizzlingProxyObject]) {
-    [objectSwizzler copySelector:@selector(respondsToSelector:) fromClass:self isClassSelector:NO];
-  }
-}
-
-- (instancetype)init {
-  NSAssert(NO, @"Do not instantiate this class, it's only a donor class");
-  return nil;
-}
-
-- (GULObjectSwizzler *)gul_objectSwizzler {
-  return [GULObjectSwizzler getAssociatedObject:self key:kSwizzlerAssociatedObjectKey];
-}
-
-#pragma mark - Donor methods
-
-- (Class)gul_class {
-  return [[self gul_objectSwizzler] generatedClass];
-}
-
-// Only added to a class when we detect it is a proxy.
-- (BOOL)respondsToSelector:(SEL)aSelector {
-  Class gulClass = [[self gul_objectSwizzler] generatedClass];
-  return [gulClass instancesRespondToSelector:aSelector] || [super respondsToSelector:aSelector];
-}
-
-@end

+ 0 - 123
GoogleUtilities/ISASwizzler/Public/GoogleUtilities/GULObjectSwizzler.h

@@ -1,123 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-/** Enums that map to their OBJC-prefixed counterparts. */
-typedef OBJC_ENUM(uintptr_t, GUL_ASSOCIATION){
-
-    // Is a weak association.
-    GUL_ASSOCIATION_ASSIGN,
-
-    // Is a nonatomic strong association.
-    GUL_ASSOCIATION_RETAIN_NONATOMIC,
-
-    // Is a nonatomic copy association.
-    GUL_ASSOCIATION_COPY_NONATOMIC,
-
-    // Is an atomic strong association.
-    GUL_ASSOCIATION_RETAIN,
-
-    // Is an atomic copy association.
-    GUL_ASSOCIATION_COPY};
-
-/** This class handles swizzling a specific instance of a class by generating a
- *  dynamic subclass and installing selectors and properties onto the dynamic
- *  subclass. Then, the instance's class is set to the dynamic subclass. There
- *  should be a 1:1 ratio of object swizzlers to swizzled instances.
- */
-@interface GULObjectSwizzler : NSObject
-
-/** The subclass that is generated. */
-@property(nullable, nonatomic, readonly) Class generatedClass;
-
-/** Sets an associated object in the runtime. This mechanism can be used to
- *  simulate adding properties.
- *
- *  @param object The object that will be queried for the associated object.
- *  @param key The key of the associated object.
- *  @param value The value to associate to the swizzled object.
- *  @param association The mechanism to use when associating the objects.
- */
-+ (void)setAssociatedObject:(id)object
-                        key:(NSString *)key
-                      value:(nullable id)value
-                association:(GUL_ASSOCIATION)association;
-
-/** Gets an associated object in the runtime. This mechanism can be used to
- *  simulate adding properties.
- *
- *  @param object The object that will be queried for the associated object.
- *  @param key The key of the associated object.
- */
-+ (nullable id)getAssociatedObject:(id)object key:(NSString *)key;
-
-/** Please use the designated initializer. */
-- (instancetype)init NS_UNAVAILABLE;
-
-/** Instantiates an object swizzler using an object it will operate on.
- *  Generates a new class pair.
- *
- *  @note There is no need to store this object. After calling -swizzle, this
- *  object can be found by calling -gul_objectSwizzler
- *
- *  @param object The object to be swizzled.
- *  @return An instance of this class.
- */
-- (instancetype)initWithObject:(id)object NS_DESIGNATED_INITIALIZER;
-
-/** Sets an associated object in the runtime. This mechanism can be used to
- *  simulate adding properties.
- *
- *  @param key The key of the associated object.
- *  @param value The value to associate to the swizzled object.
- *  @param association The mechanism to use when associating the objects.
- */
-- (void)setAssociatedObjectWithKey:(NSString *)key
-                             value:(id)value
-                       association:(GUL_ASSOCIATION)association;
-
-/** Gets an associated object in the runtime. This mechanism can be used to
- *  simulate adding properties.
- *
- *  @param key The key of the associated object.
- */
-- (nullable id)getAssociatedObjectForKey:(NSString *)key;
-
-/** Copies a selector from an existing class onto the generated dynamic subclass
- *  that this object will adopt. This mechanism can be used to add methods to
- *  specific instances of a class.
- *
- *  @note Should not be called after calling -swizzle.
- *  @param selector The selector to add to the instance.
- *  @param aClass The class supplying an implementation of the method.
- *  @param isClassSelector A BOOL specifying whether the selector is a class or
- * instance selector.
- */
-- (void)copySelector:(SEL)selector fromClass:(Class)aClass isClassSelector:(BOOL)isClassSelector;
-
-/** Swizzles the object, changing its class to the generated class. Registers
- *  the class pair. */
-- (void)swizzle;
-
-/** @return The value of -[objectBeingSwizzled isProxy] */
-- (BOOL)isSwizzlingProxyObject;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 44
GoogleUtilities/ISASwizzler/Public/GoogleUtilities/GULSwizzledObject.h

@@ -1,44 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-@class GULObjectSwizzler;
-
-FOUNDATION_EXPORT NSString *kSwizzlerAssociatedObjectKey;
-
-/** This class exists as a method donor. These methods will be added to all objects that are
- *  swizzled by the object swizzler. This class should not be instantiated.
- */
-@interface GULSwizzledObject : NSObject
-
-- (instancetype)init NS_UNAVAILABLE;
-
-/** Copies the methods below to the swizzled object.
- *
- *  @param objectSwizzler The swizzler to use when adding the methods below.
- */
-+ (void)copyDonorSelectorsUsingObjectSwizzler:(GULObjectSwizzler *)objectSwizzler;
-
-#pragma mark - Donor methods.
-
-/** @return The generated subclass. Used in respondsToSelector: calls. */
-- (Class)gul_class;
-
-/** @return The object swizzler that manages this object. */
-- (GULObjectSwizzler *)gul_objectSwizzler;
-
-@end

+ 0 - 247
GoogleUtilities/LICENSE

@@ -1,247 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-================================================================================
-
-The following copyright from Landon J. Fuller applies to the isAppEncrypted
-function in Environment/third_party/GULAppEnvironmentUtil.m.
-
-Copyright (c) 2017 Landon J. Fuller <landon@landonf.org>
-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.
-
-Comment from
-<a href="http://iphonedevwiki.net/index.php/Crack_prevention">iPhone Dev Wiki
-Crack Prevention</a>: App Store binaries are signed by both their developer
-and Apple. This encrypts the binary so that decryption keys are needed in order
-to make the binary readable. When iOS executes the binary, the decryption keys
-are used to decrypt the binary into a readable state where it is then loaded
-into memory and executed. iOS can tell the encryption status of a binary via the
-cryptid structure member of LC_ENCRYPTION_INFO MachO load command. If cryptid is
-a non-zero value then the binary is encrypted.
-
-'Cracking' works by letting the kernel decrypt the binary then siphoning the
-decrypted data into a new binary file, resigning, and repackaging. This will
-only work on jailbroken devices as codesignature validation has been removed.
-Resigning takes place because while the codesignature doesn't have to be valid
-thanks to the jailbreak, it does have to be in place unless you have AppSync or
-similar to disable codesignature checks.
-
-More information at <a href="http://landonf.org/2009/02/index.html">Landon
-Fuller's blog</a>

+ 0 - 215
GoogleUtilities/Logger/GULLogger.m

@@ -1,215 +0,0 @@
-// Copyright 2018 Google
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import "GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h"
-
-#include <asl.h>
-
-#import "GoogleUtilities/Environment/Public/GoogleUtilities/GULAppEnvironmentUtil.h"
-#import "GoogleUtilities/Logger/Public/GoogleUtilities/GULLoggerLevel.h"
-
-/// ASL client facility name used by GULLogger.
-const char *kGULLoggerASLClientFacilityName = "com.google.utilities.logger";
-
-static dispatch_once_t sGULLoggerOnceToken;
-
-static aslclient sGULLoggerClient;
-
-static dispatch_queue_t sGULClientQueue;
-
-static BOOL sGULLoggerDebugMode;
-
-static GULLoggerLevel sGULLoggerMaximumLevel;
-
-// Allow clients to register a version to include in the log.
-static NSString *sVersion = @"";
-
-static GULLoggerService kGULLoggerLogger = @"[GULLogger]";
-
-#ifdef DEBUG
-/// The regex pattern for the message code.
-static NSString *const kMessageCodePattern = @"^I-[A-Z]{3}[0-9]{6}$";
-static NSRegularExpression *sMessageCodeRegex;
-#endif
-
-void GULLoggerInitializeASL(void) {
-  dispatch_once(&sGULLoggerOnceToken, ^{
-    NSInteger majorOSVersion = [[GULAppEnvironmentUtil systemVersion] integerValue];
-    uint32_t aslOptions = ASL_OPT_STDERR;
-#if TARGET_OS_SIMULATOR
-    // The iOS 11 simulator doesn't need the ASL_OPT_STDERR flag.
-    if (majorOSVersion >= 11) {
-      aslOptions = 0;
-    }
-#else
-    // Devices running iOS 10 or higher don't need the ASL_OPT_STDERR flag.
-    if (majorOSVersion >= 10) {
-      aslOptions = 0;
-    }
-#endif  // TARGET_OS_SIMULATOR
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"  // asl is deprecated
-    // Initialize the ASL client handle.
-    sGULLoggerClient = asl_open(NULL, kGULLoggerASLClientFacilityName, aslOptions);
-    sGULLoggerMaximumLevel = GULLoggerLevelNotice;
-
-    // Set the filter used by system/device log. Initialize in default mode.
-    asl_set_filter(sGULLoggerClient, ASL_FILTER_MASK_UPTO(ASL_LEVEL_NOTICE));
-
-    sGULClientQueue = dispatch_queue_create("GULLoggingClientQueue", DISPATCH_QUEUE_SERIAL);
-    dispatch_set_target_queue(sGULClientQueue,
-                              dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0));
-#ifdef DEBUG
-    sMessageCodeRegex = [NSRegularExpression regularExpressionWithPattern:kMessageCodePattern
-                                                                  options:0
-                                                                    error:NULL];
-#endif
-  });
-}
-
-void GULLoggerEnableSTDERR(void) {
-  asl_add_log_file(sGULLoggerClient, STDERR_FILENO);
-}
-
-void GULLoggerForceDebug(void) {
-  // We should enable debug mode if we're not running from App Store.
-  if (![GULAppEnvironmentUtil isFromAppStore]) {
-    sGULLoggerDebugMode = YES;
-    GULSetLoggerLevel(GULLoggerLevelDebug);
-  }
-}
-
-__attribute__((no_sanitize("thread"))) void GULSetLoggerLevel(GULLoggerLevel loggerLevel) {
-  if (loggerLevel < GULLoggerLevelMin || loggerLevel > GULLoggerLevelMax) {
-    GULLogError(kGULLoggerLogger, NO, @"I-COR000023", @"Invalid logger level, %ld",
-                (long)loggerLevel);
-    return;
-  }
-  GULLoggerInitializeASL();
-  // We should not raise the logger level if we are running from App Store.
-  if (loggerLevel >= GULLoggerLevelNotice && [GULAppEnvironmentUtil isFromAppStore]) {
-    return;
-  }
-
-  sGULLoggerMaximumLevel = loggerLevel;
-  dispatch_async(sGULClientQueue, ^{
-    asl_set_filter(sGULLoggerClient, ASL_FILTER_MASK_UPTO(loggerLevel));
-  });
-}
-
-/**
- * Check if the level is high enough to be loggable.
- */
-__attribute__((no_sanitize("thread"))) BOOL GULIsLoggableLevel(GULLoggerLevel loggerLevel) {
-  GULLoggerInitializeASL();
-  if (sGULLoggerDebugMode) {
-    return YES;
-  }
-  return (BOOL)(loggerLevel <= sGULLoggerMaximumLevel);
-}
-
-#ifdef DEBUG
-void GULResetLogger() {
-  sGULLoggerOnceToken = 0;
-  sGULLoggerDebugMode = NO;
-}
-
-aslclient getGULLoggerClient() {
-  return sGULLoggerClient;
-}
-
-dispatch_queue_t getGULClientQueue() {
-  return sGULClientQueue;
-}
-
-BOOL getGULLoggerDebugMode() {
-  return sGULLoggerDebugMode;
-}
-#endif
-
-void GULLoggerRegisterVersion(NSString *version) {
-  sVersion = version;
-}
-
-void GULLogBasic(GULLoggerLevel level,
-                 GULLoggerService service,
-                 BOOL forceLog,
-                 NSString *messageCode,
-                 NSString *message,
-                 va_list args_ptr) {
-  GULLoggerInitializeASL();
-  if (!(level <= sGULLoggerMaximumLevel || sGULLoggerDebugMode || forceLog)) {
-    return;
-  }
-
-#ifdef DEBUG
-  NSCAssert(messageCode.length == 11, @"Incorrect message code length.");
-  NSRange messageCodeRange = NSMakeRange(0, messageCode.length);
-  NSUInteger numberOfMatches = [sMessageCodeRegex numberOfMatchesInString:messageCode
-                                                                  options:0
-                                                                    range:messageCodeRange];
-  NSCAssert(numberOfMatches == 1, @"Incorrect message code format.");
-#endif
-  NSString *logMsg;
-  if (args_ptr == NULL) {
-    logMsg = message;
-  } else {
-    logMsg = [[NSString alloc] initWithFormat:message arguments:args_ptr];
-  }
-  logMsg = [NSString stringWithFormat:@"%@ - %@[%@] %@", sVersion, service, messageCode, logMsg];
-  dispatch_async(sGULClientQueue, ^{
-    asl_log(sGULLoggerClient, NULL, (int)level, "%s", logMsg.UTF8String);
-  });
-}
-#pragma clang diagnostic pop
-
-/**
- * Generates the logging functions using macros.
- *
- * Calling GULLogError({service}, @"I-XYZ000001", @"Configure %@ failed.", @"blah") shows:
- * yyyy-mm-dd hh:mm:ss.SSS sender[PID] <Error> [{service}][I-XYZ000001] Configure blah failed.
- * Calling GULLogDebug({service}, @"I-XYZ000001", @"Configure succeed.") shows:
- * yyyy-mm-dd hh:mm:ss.SSS sender[PID] <Debug> [{service}][I-XYZ000001] Configure succeed.
- */
-#define GUL_LOGGING_FUNCTION(level)                                                     \
-  void GULLog##level(GULLoggerService service, BOOL force, NSString *messageCode,       \
-                     NSString *message, ...) {                                          \
-    va_list args_ptr;                                                                   \
-    va_start(args_ptr, message);                                                        \
-    GULLogBasic(GULLoggerLevel##level, service, force, messageCode, message, args_ptr); \
-    va_end(args_ptr);                                                                   \
-  }
-
-GUL_LOGGING_FUNCTION(Error)
-GUL_LOGGING_FUNCTION(Warning)
-GUL_LOGGING_FUNCTION(Notice)
-GUL_LOGGING_FUNCTION(Info)
-GUL_LOGGING_FUNCTION(Debug)
-
-#undef GUL_MAKE_LOGGER
-
-#pragma mark - GULLoggerWrapper
-
-@implementation GULLoggerWrapper
-
-+ (void)logWithLevel:(GULLoggerLevel)level
-         withService:(GULLoggerService)service
-            withCode:(NSString *)messageCode
-         withMessage:(NSString *)message
-            withArgs:(va_list)args {
-  GULLogBasic(level, service, NO, messageCode, message, args);
-}
-
-@end

+ 0 - 159
GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h

@@ -1,159 +0,0 @@
-/*
- * Copyright 2018 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-#import "GULLoggerLevel.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-/**
- * The services used in the logger.
- */
-typedef NSString *const GULLoggerService;
-
-#ifdef __cplusplus
-extern "C" {
-#endif  // __cplusplus
-
-/**
- * Initialize GULLogger.
- */
-extern void GULLoggerInitializeASL(void);
-
-/**
- * Override log level to Debug.
- */
-void GULLoggerForceDebug(void);
-
-/**
- * Turn on logging to STDERR.
- */
-extern void GULLoggerEnableSTDERR(void);
-
-/**
- * Changes the default logging level of GULLoggerLevelNotice to a user-specified level.
- * The default level cannot be set above GULLoggerLevelNotice if the app is running from App Store.
- * (required) log level (one of the GULLoggerLevel enum values).
- */
-extern void GULSetLoggerLevel(GULLoggerLevel loggerLevel);
-
-/**
- * Checks if the specified logger level is loggable given the current settings.
- * (required) log level (one of the GULLoggerLevel enum values).
- */
-extern BOOL GULIsLoggableLevel(GULLoggerLevel loggerLevel);
-
-/**
- * Register version to include in logs.
- * (required) version
- */
-extern void GULLoggerRegisterVersion(NSString *version);
-
-/**
- * Logs a message to the Xcode console and the device log. If running from AppStore, will
- * not log any messages with a level higher than GULLoggerLevelNotice to avoid log spamming.
- * (required) log level (one of the GULLoggerLevel enum values).
- * (required) service name of type GULLoggerService.
- * (required) message code starting with "I-" which means iOS, followed by a capitalized
- *            three-character service identifier and a six digit integer message ID that is unique
- *            within the service.
- *            An example of the message code is @"I-COR000001".
- * (required) message string which can be a format string.
- * (optional) variable arguments list obtained from calling va_start, used when message is a format
- *            string.
- */
-extern void GULLogBasic(GULLoggerLevel level,
-                        GULLoggerService service,
-                        BOOL forceLog,
-                        NSString *messageCode,
-                        NSString *message,
-// On 64-bit simulators, va_list is not a pointer, so cannot be marked nullable
-// See: http://stackoverflow.com/q/29095469
-#if __LP64__ && TARGET_OS_SIMULATOR || TARGET_OS_OSX
-                        va_list args_ptr
-#else
-                        va_list _Nullable args_ptr
-#endif
-);
-
-/**
- * The following functions accept the following parameters in order:
- * (required) service name of type GULLoggerService.
- * (required) message code starting from "I-" which means iOS, followed by a capitalized
- *            three-character service identifier and a six digit integer message ID that is unique
- *            within the service.
- *            An example of the message code is @"I-COR000001".
- *            See go/firebase-log-proposal for details.
- * (required) message string which can be a format string.
- * (optional) the list of arguments to substitute into the format string.
- * Example usage:
- * GULLogError(kGULLoggerCore, @"I-COR000001", @"Configuration of %@ failed.", app.name);
- */
-extern void GULLogError(GULLoggerService service,
-                        BOOL force,
-                        NSString *messageCode,
-                        NSString *message,
-                        ...) NS_FORMAT_FUNCTION(4, 5);
-extern void GULLogWarning(GULLoggerService service,
-                          BOOL force,
-                          NSString *messageCode,
-                          NSString *message,
-                          ...) NS_FORMAT_FUNCTION(4, 5);
-extern void GULLogNotice(GULLoggerService service,
-                         BOOL force,
-                         NSString *messageCode,
-                         NSString *message,
-                         ...) NS_FORMAT_FUNCTION(4, 5);
-extern void GULLogInfo(GULLoggerService service,
-                       BOOL force,
-                       NSString *messageCode,
-                       NSString *message,
-                       ...) NS_FORMAT_FUNCTION(4, 5);
-extern void GULLogDebug(GULLoggerService service,
-                        BOOL force,
-                        NSString *messageCode,
-                        NSString *message,
-                        ...) NS_FORMAT_FUNCTION(4, 5);
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif  // __cplusplus
-
-@interface GULLoggerWrapper : NSObject
-
-/**
- * Objective-C wrapper for GULLogBasic to allow weak linking to GULLogger
- * (required) log level (one of the GULLoggerLevel enum values).
- * (required) service name of type GULLoggerService.
- * (required) message code starting with "I-" which means iOS, followed by a capitalized
- *            three-character service identifier and a six digit integer message ID that is unique
- *            within the service.
- *            An example of the message code is @"I-COR000001".
- * (required) message string which can be a format string.
- * (optional) variable arguments list obtained from calling va_start, used when message is a format
- *            string.
- */
-
-+ (void)logWithLevel:(GULLoggerLevel)level
-         withService:(GULLoggerService)service
-            withCode:(NSString *)messageCode
-         withMessage:(NSString *)message
-            withArgs:(va_list)args;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 37
GoogleUtilities/Logger/Public/GoogleUtilities/GULLoggerLevel.h

@@ -1,37 +0,0 @@
-/*
- * Copyright 2018 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-/**
- * The log levels used by internal logging.
- */
-typedef NS_ENUM(NSInteger, GULLoggerLevel) {
-  /** Error level, matches ASL_LEVEL_ERR. */
-  GULLoggerLevelError = 3,
-  /** Warning level, matches ASL_LEVEL_WARNING. */
-  GULLoggerLevelWarning = 4,
-  /** Notice level, matches ASL_LEVEL_NOTICE. */
-  GULLoggerLevelNotice = 5,
-  /** Info level, matches ASL_LEVEL_INFO. */
-  GULLoggerLevelInfo = 6,
-  /** Debug level, matches ASL_LEVEL_DEBUG. */
-  GULLoggerLevelDebug = 7,
-  /** Minimum log level. */
-  GULLoggerLevelMin = GULLoggerLevelError,
-  /** Maximum log level. */
-  GULLoggerLevelMax = GULLoggerLevelDebug
-} NS_SWIFT_NAME(GoogleLoggerLevel);

+ 0 - 153
GoogleUtilities/MethodSwizzler/GULSwizzler.m

@@ -1,153 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import "GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/GULSwizzler.h"
-
-#import <objc/runtime.h>
-
-#ifdef DEBUG
-#import "GoogleUtilities/Common/GULLoggerCodes.h"
-#import "GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h"
-
-static GULLoggerService kGULLoggerSwizzler = @"[GoogleUtilities/MethodSwizzler]";
-#endif
-
-dispatch_queue_t GetGULSwizzlingQueue(void) {
-  static dispatch_queue_t queue;
-  static dispatch_once_t onceToken;
-  dispatch_once(&onceToken, ^{
-    queue = dispatch_queue_create("com.google.GULSwizzler", DISPATCH_QUEUE_SERIAL);
-  });
-  return queue;
-}
-
-@implementation GULSwizzler
-
-+ (void)swizzleClass:(Class)aClass
-            selector:(SEL)selector
-     isClassSelector:(BOOL)isClassSelector
-           withBlock:(nullable id)block {
-  dispatch_sync(GetGULSwizzlingQueue(), ^{
-    NSAssert(selector, @"The selector cannot be NULL");
-    NSAssert(aClass, @"The class cannot be Nil");
-    Class resolvedClass = aClass;
-    Method method = nil;
-    if (isClassSelector) {
-      method = class_getClassMethod(aClass, selector);
-      resolvedClass = object_getClass(aClass);
-    } else {
-      method = class_getInstanceMethod(aClass, selector);
-    }
-    NSAssert(method, @"You're attempting to swizzle a method that doesn't exist. (%@, %@)",
-             NSStringFromClass(resolvedClass), NSStringFromSelector(selector));
-    IMP newImp = imp_implementationWithBlock(block);
-#ifdef DEBUG
-    IMP currentImp = class_getMethodImplementation(resolvedClass, selector);
-    Class class = NSClassFromString(@"GULSwizzlingCache");
-    if (class) {
-      SEL cacheSelector = NSSelectorFromString(@"cacheCurrentIMP:forNewIMP:forClass:withSelector:");
-      NSMethodSignature *methodSignature = [class methodSignatureForSelector:cacheSelector];
-      if (methodSignature != nil) {
-        NSInvocation *inv = [NSInvocation invocationWithMethodSignature:methodSignature];
-        [inv setSelector:cacheSelector];
-        [inv setTarget:class];
-        [inv setArgument:&(currentImp) atIndex:2];
-        [inv setArgument:&(newImp) atIndex:3];
-        [inv setArgument:&(resolvedClass) atIndex:4];
-        [inv setArgument:(void *_Nonnull) & (selector) atIndex:5];
-        [inv invoke];
-      }
-    }
-#endif
-
-    const char *typeEncoding = method_getTypeEncoding(method);
-    __unused IMP originalImpOfClass =
-        class_replaceMethod(resolvedClass, selector, newImp, typeEncoding);
-
-#ifdef DEBUG
-    // If !originalImpOfClass, then the IMP came from a superclass.
-    if (originalImpOfClass) {
-      SEL selector = NSSelectorFromString(@"originalIMPOfCurrentIMP:");
-      NSMethodSignature *methodSignature = [class methodSignatureForSelector:selector];
-      if (methodSignature != nil) {
-        NSInvocation *inv = [NSInvocation invocationWithMethodSignature:methodSignature];
-        [inv setSelector:selector];
-        [inv setTarget:class];
-        [inv setArgument:&(currentImp) atIndex:2];
-        [inv invoke];
-        IMP testOriginal;
-        [inv getReturnValue:&testOriginal];
-        if (originalImpOfClass != testOriginal) {
-          GULLogWarning(kGULLoggerSwizzler, NO,
-                        [NSString stringWithFormat:@"I-SWZ%06ld",
-                                                   (long)kGULSwizzlerMessageCodeMethodSwizzling000],
-                        @"Swizzling class: %@ SEL:%@ after it has been previously been swizzled.",
-                        NSStringFromClass(resolvedClass), NSStringFromSelector(selector));
-        }
-      }
-    }
-#endif
-  });
-}
-
-+ (nullable IMP)currentImplementationForClass:(Class)aClass
-                                     selector:(SEL)selector
-                              isClassSelector:(BOOL)isClassSelector {
-  NSAssert(selector, @"The selector cannot be NULL");
-  NSAssert(aClass, @"The class cannot be Nil");
-  if (selector == NULL || aClass == nil) {
-    return nil;
-  }
-  __block IMP currentIMP = nil;
-  dispatch_sync(GetGULSwizzlingQueue(), ^{
-    Method method = nil;
-    if (isClassSelector) {
-      method = class_getClassMethod(aClass, selector);
-    } else {
-      method = class_getInstanceMethod(aClass, selector);
-    }
-    NSAssert(method, @"The Method for this class/selector combo doesn't exist (%@, %@).",
-             NSStringFromClass(aClass), NSStringFromSelector(selector));
-    if (method == nil) {
-      return;
-    }
-    currentIMP = method_getImplementation(method);
-    NSAssert(currentIMP, @"The IMP for this class/selector combo doesn't exist (%@, %@).",
-             NSStringFromClass(aClass), NSStringFromSelector(selector));
-  });
-  return currentIMP;
-}
-
-+ (BOOL)selector:(SEL)selector existsInClass:(Class)aClass isClassSelector:(BOOL)isClassSelector {
-  Method method = isClassSelector ? class_getClassMethod(aClass, selector)
-                                  : class_getInstanceMethod(aClass, selector);
-  return method != nil;
-}
-
-+ (NSArray<id> *)ivarObjectsForObject:(id)object {
-  NSMutableArray *array = [NSMutableArray array];
-  unsigned int count;
-  Ivar *vars = class_copyIvarList([object class], &count);
-  for (NSUInteger i = 0; i < count; i++) {
-    const char *typeEncoding = ivar_getTypeEncoding(vars[i]);
-    // Check to see if the ivar is an object.
-    if (strncmp(typeEncoding, "@", 1) == 0) {
-      id ivarObject = object_getIvar(object, vars[i]);
-      [array addObject:ivarObject];
-    }
-  }
-  free(vars);
-  return array;
-}
-@end

+ 0 - 207
GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/GULOriginalIMPConvenienceMacros.h

@@ -1,207 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * GULOriginalIMPConvenienceMacros.h
- *
- * This header contains convenience macros for invoking the original IMP of a swizzled method.
- */
-
-/**
- *  Invokes original IMP when the original selector takes no arguments.
- *
- *  @param __receivingObject The object on which the IMP is invoked.
- *  @param __swizzledSEL The selector used for swizzling.
- *  @param __returnType  The return type of the original implementation.
- *  @param __originalIMP The original IMP.
- */
-#define GUL_INVOKE_ORIGINAL_IMP0(__receivingObject, __swizzledSEL, __returnType, __originalIMP) \
-  ((__returnType(*)(id, SEL))__originalIMP)(__receivingObject, __swizzledSEL)
-
-/**
- *  Invokes original IMP when the original selector takes 1 argument.
- *
- *  @param __receivingObject The object on which the IMP is invoked.
- *  @param __swizzledSEL The selector used for swizzling.
- *  @param __returnType  The return type of the original implementation.
- *  @param __originalIMP The original IMP.
- *  @param __arg1 The first argument.
- */
-#define GUL_INVOKE_ORIGINAL_IMP1(__receivingObject, __swizzledSEL, __returnType, __originalIMP,   \
-                                 __arg1)                                                          \
-  ((__returnType(*)(id, SEL, __typeof__(__arg1)))__originalIMP)(__receivingObject, __swizzledSEL, \
-                                                                __arg1)
-
-/**
- *  Invokes original IMP when the original selector takes 2 arguments.
- *
- *  @param __receivingObject The object on which the IMP is invoked.
- *  @param __swizzledSEL The selector used for swizzling.
- *  @param __returnType  The return type of the original implementation.
- *  @param __originalIMP The original IMP.
- *  @param __arg1 The first argument.
- *  @param __arg2 The second argument.
- */
-#define GUL_INVOKE_ORIGINAL_IMP2(__receivingObject, __swizzledSEL, __returnType, __originalIMP, \
-                                 __arg1, __arg2)                                                \
-  ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2)))__originalIMP)(            \
-      __receivingObject, __swizzledSEL, __arg1, __arg2)
-
-/**
- *  Invokes original IMP when the original selector takes 3 arguments.
- *
- *  @param __receivingObject The object on which the IMP is invoked.
- *  @param __swizzledSEL The selector used for swizzling.
- *  @param __returnType  The return type of the original implementation.
- *  @param __originalIMP The original IMP.
- *  @param __arg1 The first argument.
- *  @param __arg2 The second argument.
- *  @param __arg3 The third argument.
- */
-#define GUL_INVOKE_ORIGINAL_IMP3(__receivingObject, __swizzledSEL, __returnType, __originalIMP,  \
-                                 __arg1, __arg2, __arg3)                                         \
-  ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2),                             \
-                    __typeof__(__arg3)))__originalIMP)(__receivingObject, __swizzledSEL, __arg1, \
-                                                       __arg2, __arg3)
-
-/**
- *  Invokes original IMP when the original selector takes 4 arguments.
- *
- *  @param __receivingObject The object on which the IMP is invoked.
- *  @param __swizzledSEL The selector used for swizzling.
- *  @param __returnType  The return type of the original implementation.
- *  @param __originalIMP The original IMP.
- *  @param __arg1 The first argument.
- *  @param __arg2 The second argument.
- *  @param __arg3 The third argument.
- *  @param __arg4 The fourth argument.
- */
-#define GUL_INVOKE_ORIGINAL_IMP4(__receivingObject, __swizzledSEL, __returnType, __originalIMP,  \
-                                 __arg1, __arg2, __arg3, __arg4)                                 \
-  ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2), __typeof__(__arg3),         \
-                    __typeof__(__arg4)))__originalIMP)(__receivingObject, __swizzledSEL, __arg1, \
-                                                       __arg2, __arg3, __arg4)
-
-/**
- *  Invokes original IMP when the original selector takes 5 arguments.
- *
- *  @param __receivingObject The object on which the IMP is invoked.
- *  @param __swizzledSEL The selector used for swizzling.
- *  @param __returnType  The return type of the original implementation.
- *  @param __originalIMP The original IMP.
- *  @param __arg1 The first argument.
- *  @param __arg2 The second argument.
- *  @param __arg3 The third argument.
- *  @param __arg4 The fourth argument.
- *  @param __arg5 The fifth argument.
- */
-#define GUL_INVOKE_ORIGINAL_IMP5(__receivingObject, __swizzledSEL, __returnType, __originalIMP, \
-                                 __arg1, __arg2, __arg3, __arg4, __arg5)                        \
-  ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2), __typeof__(__arg3),        \
-                    __typeof__(__arg4), __typeof__(__arg5)))__originalIMP)(                     \
-      __receivingObject, __swizzledSEL, __arg1, __arg2, __arg3, __arg4, __arg5)
-
-/**
- *  Invokes original IMP when the original selector takes 6 arguments.
- *
- *  @param __receivingObject The object on which the IMP is invoked.
- *  @param __swizzledSEL The selector used for swizzling.
- *  @param __returnType  The return type of the original implementation.
- *  @param __originalIMP The original IMP.
- *  @param __arg1 The first argument.
- *  @param __arg2 The second argument.
- *  @param __arg3 The third argument.
- *  @param __arg4 The fourth argument.
- *  @param __arg5 The fifth argument.
- *  @param __arg6 The sixth argument.
- */
-#define GUL_INVOKE_ORIGINAL_IMP6(__receivingObject, __swizzledSEL, __returnType, __originalIMP, \
-                                 __arg1, __arg2, __arg3, __arg4, __arg5, __arg6)                \
-  ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2), __typeof__(__arg3),        \
-                    __typeof__(__arg4), __typeof__(__arg5), __typeof__(__arg6)))__originalIMP)( \
-      __receivingObject, __swizzledSEL, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6)
-
-/**
- *  Invokes original IMP when the original selector takes 7 arguments.
- *
- *  @param __receivingObject The object on which the IMP is invoked.
- *  @param __swizzledSEL The selector used for swizzling.
- *  @param __returnType  The return type of the original implementation.
- *  @param __originalIMP The original IMP.
- *  @param __arg1 The first argument.
- *  @param __arg2 The second argument.
- *  @param __arg3 The third argument.
- *  @param __arg4 The fourth argument.
- *  @param __arg5 The fifth argument.
- *  @param __arg6 The sixth argument.
- *  @param __arg7 The seventh argument.
- */
-#define GUL_INVOKE_ORIGINAL_IMP7(__receivingObject, __swizzledSEL, __returnType, __originalIMP, \
-                                 __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7)        \
-  ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2), __typeof__(__arg3),        \
-                    __typeof__(__arg4), __typeof__(__arg5), __typeof__(__arg6),                 \
-                    __typeof__(__arg7)))__originalIMP)(                                         \
-      __receivingObject, __swizzledSEL, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7)
-
-/**
- *  Invokes original IMP when the original selector takes 8 arguments.
- *
- *  @param __receivingObject The object on which the IMP is invoked.
- *  @param __swizzledSEL The selector used for swizzling.
- *  @param __returnType  The return type of the original implementation.
- *  @param __originalIMP The original IMP.
- *  @param __arg1 The first argument.
- *  @param __arg2 The second argument.
- *  @param __arg3 The third argument.
- *  @param __arg4 The fourth argument.
- *  @param __arg5 The fifth argument.
- *  @param __arg6 The sixth argument.
- *  @param __arg7 The seventh argument.
- *  @param __arg8 The eighth argument.
- */
-#define GUL_INVOKE_ORIGINAL_IMP8(__receivingObject, __swizzledSEL, __returnType, __originalIMP,  \
-                                 __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7, __arg8) \
-  ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2), __typeof__(__arg3),         \
-                    __typeof__(__arg4), __typeof__(__arg5), __typeof__(__arg6),                  \
-                    __typeof__(__arg7), __typeof__(__arg8)))__originalIMP)(                      \
-      __receivingObject, __swizzledSEL, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7,  \
-      __arg8)
-
-/**
- *  Invokes original IMP when the original selector takes 9 arguments.
- *
- *  @param __receivingObject The object on which the IMP is invoked.
- *  @param __swizzledSEL The selector used for swizzling.
- *  @param __returnType  The return type of the original implementation.
- *  @param __originalIMP The original IMP.
- *  @param __arg1 The first argument.
- *  @param __arg2 The second argument.
- *  @param __arg3 The third argument.
- *  @param __arg4 The fourth argument.
- *  @param __arg5 The fifth argument.
- *  @param __arg6 The sixth argument.
- *  @param __arg7 The seventh argument.
- *  @param __arg8 The eighth argument.
- *  @param __arg9 The ninth argument.
- */
-#define GUL_INVOKE_ORIGINAL_IMP9(__receivingObject, __swizzledSEL, __returnType, __originalIMP,  \
-                                 __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7, __arg8, \
-                                 __arg9)                                                         \
-  ((__returnType(*)(id, SEL, __typeof__(__arg1), __typeof__(__arg2), __typeof__(__arg3),         \
-                    __typeof__(__arg4), __typeof__(__arg5), __typeof__(__arg6),                  \
-                    __typeof__(__arg7), __typeof__(__arg8), __typeof__(__arg9)))__originalIMP)(  \
-      __receivingObject, __swizzledSEL, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7,  \
-      __arg8, __arg9)

+ 0 - 71
GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/GULSwizzler.h

@@ -1,71 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-/** This class handles the runtime manipulation necessary to instrument selectors. It stores the
- *  classes and selectors that have been swizzled, and runs all operations on its own queue.
- */
-@interface GULSwizzler : NSObject
-
-/** Manipulates the Objective-C runtime to replace the original IMP with the supplied block.
- *
- *  @param aClass The class to swizzle.
- *  @param selector The selector of the class to swizzle.
- *  @param isClassSelector A BOOL specifying whether the selector is a class or instance selector.
- *  @param block The block that replaces the original IMP.
- */
-+ (void)swizzleClass:(Class)aClass
-            selector:(SEL)selector
-     isClassSelector:(BOOL)isClassSelector
-           withBlock:(nullable id)block;
-
-/** Returns the current IMP for the given class and selector.
- *
- *  @param aClass The class to use.
- *  @param selector The selector to find the implementation of.
- *  @param isClassSelector A BOOL specifying whether the selector is a class or instance selector.
- *  @return The implementation of the selector in the runtime.
- */
-+ (nullable IMP)currentImplementationForClass:(Class)aClass
-                                     selector:(SEL)selector
-                              isClassSelector:(BOOL)isClassSelector;
-
-/** Checks the runtime to see if a selector exists on a class. If a property is declared as
- *  @dynamic, we have a reverse swizzling situation, where the implementation of a method exists
- *  only in concrete subclasses, and NOT in the superclass. We can detect that situation using
- *  this helper method. Similarly, we can detect situations where a class doesn't implement a
- *  protocol method.
- *
- *  @param selector The selector to check for.
- *  @param aClass The class to check.
- *  @param isClassSelector A BOOL specifying whether the selector is a class or instance selector.
- *  @return YES if the method was found in this selector/class combination, NO otherwise.
- */
-+ (BOOL)selector:(SEL)selector existsInClass:(Class)aClass isClassSelector:(BOOL)isClassSelector;
-
-/** Returns a list of all Objective-C (and not primitive) ivars contained by the given object.
- *
- *  @param object The object whose ivars will be iterated.
- *  @return The list of ivar objects.
- */
-+ (NSArray<id> *)ivarObjectsForObject:(id)object;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 207
GoogleUtilities/NSData+zlib/GULNSData+zlib.m

@@ -1,207 +0,0 @@
-// Copyright 2018 Google
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import "GoogleUtilities/NSData+zlib/Public/GoogleUtilities/GULNSData+zlib.h"
-
-#import <zlib.h>
-
-#define kChunkSize 1024
-#define Z_DEFAULT_COMPRESSION (-1)
-
-NSString *const GULNSDataZlibErrorDomain = @"com.google.GULNSDataZlibErrorDomain";
-NSString *const GULNSDataZlibErrorKey = @"GULNSDataZlibErrorKey";
-NSString *const GULNSDataZlibRemainingBytesKey = @"GULNSDataZlibRemainingBytesKey";
-
-@implementation NSData (GULGzip)
-
-+ (NSData *)gul_dataByInflatingGzippedData:(NSData *)data error:(NSError **)error {
-  const void *bytes = [data bytes];
-  NSUInteger length = [data length];
-  if (!bytes || !length) {
-    return nil;
-  }
-
-#if defined(__LP64__) && __LP64__
-  // Don't support > 32bit length for 64 bit, see note in header.
-  if (length > UINT_MAX) {
-    return nil;
-  }
-#endif
-
-  z_stream strm;
-  bzero(&strm, sizeof(z_stream));
-
-  // Setup the input.
-  strm.avail_in = (unsigned int)length;
-  strm.next_in = (unsigned char *)bytes;
-
-  int windowBits = 15;  // 15 to enable any window size
-  windowBits += 32;     // and +32 to enable zlib or gzip header detection.
-
-  int retCode;
-  if ((retCode = inflateInit2(&strm, windowBits)) != Z_OK) {
-    if (error) {
-      NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode]
-                                                           forKey:GULNSDataZlibErrorKey];
-      *error = [NSError errorWithDomain:GULNSDataZlibErrorDomain
-                                   code:GULNSDataZlibErrorInternal
-                               userInfo:userInfo];
-    }
-    return nil;
-  }
-
-  // Hint the size at 4x the input size.
-  NSMutableData *result = [NSMutableData dataWithCapacity:(length * 4)];
-  unsigned char output[kChunkSize];
-
-  // Loop to collect the data.
-  do {
-    // Update what we're passing in.
-    strm.avail_out = kChunkSize;
-    strm.next_out = output;
-    retCode = inflate(&strm, Z_NO_FLUSH);
-    if ((retCode != Z_OK) && (retCode != Z_STREAM_END)) {
-      if (error) {
-        NSMutableDictionary *userInfo =
-            [NSMutableDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode]
-                                               forKey:GULNSDataZlibErrorKey];
-        if (strm.msg) {
-          NSString *message = [NSString stringWithUTF8String:strm.msg];
-          if (message) {
-            [userInfo setObject:message forKey:NSLocalizedDescriptionKey];
-          }
-        }
-        *error = [NSError errorWithDomain:GULNSDataZlibErrorDomain
-                                     code:GULNSDataZlibErrorInternal
-                                 userInfo:userInfo];
-      }
-      inflateEnd(&strm);
-      return nil;
-    }
-    // Collect what we got.
-    unsigned gotBack = kChunkSize - strm.avail_out;
-    if (gotBack > 0) {
-      [result appendBytes:output length:gotBack];
-    }
-
-  } while (retCode == Z_OK);
-
-  // Make sure there wasn't more data tacked onto the end of a valid compressed stream.
-  if (strm.avail_in != 0) {
-    if (error) {
-      NSDictionary *userInfo =
-          [NSDictionary dictionaryWithObject:[NSNumber numberWithUnsignedInt:strm.avail_in]
-                                      forKey:GULNSDataZlibRemainingBytesKey];
-      *error = [NSError errorWithDomain:GULNSDataZlibErrorDomain
-                                   code:GULNSDataZlibErrorDataRemaining
-                               userInfo:userInfo];
-    }
-    result = nil;
-  }
-  // The only way out of the loop was by hitting the end of the stream.
-  NSAssert(retCode == Z_STREAM_END,
-           @"Thought we finished inflate w/o getting a result of stream end, code %d", retCode);
-
-  // Clean up.
-  inflateEnd(&strm);
-
-  return result;
-}
-
-+ (NSData *)gul_dataByGzippingData:(NSData *)data error:(NSError **)error {
-  const void *bytes = [data bytes];
-  NSUInteger length = [data length];
-
-  int level = Z_DEFAULT_COMPRESSION;
-  if (!bytes || !length) {
-    return nil;
-  }
-
-#if defined(__LP64__) && __LP64__
-  // Don't support > 32bit length for 64 bit, see note in header.
-  if (length > UINT_MAX) {
-    if (error) {
-      *error = [NSError errorWithDomain:GULNSDataZlibErrorDomain
-                                   code:GULNSDataZlibErrorGreaterThan32BitsToCompress
-                               userInfo:nil];
-    }
-    return nil;
-  }
-#endif
-
-  z_stream strm;
-  bzero(&strm, sizeof(z_stream));
-
-  int memLevel = 8;          // Default.
-  int windowBits = 15 + 16;  // Enable gzip header instead of zlib header.
-
-  int retCode;
-  if ((retCode = deflateInit2(&strm, level, Z_DEFLATED, windowBits, memLevel,
-                              Z_DEFAULT_STRATEGY)) != Z_OK) {
-    if (error) {
-      NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode]
-                                                           forKey:GULNSDataZlibErrorKey];
-      *error = [NSError errorWithDomain:GULNSDataZlibErrorDomain
-                                   code:GULNSDataZlibErrorInternal
-                               userInfo:userInfo];
-    }
-    return nil;
-  }
-
-  // Hint the size at 1/4 the input size.
-  NSMutableData *result = [NSMutableData dataWithCapacity:(length / 4)];
-  unsigned char output[kChunkSize];
-
-  // Setup the input.
-  strm.avail_in = (unsigned int)length;
-  strm.next_in = (unsigned char *)bytes;
-
-  // Collect the data.
-  do {
-    // update what we're passing in
-    strm.avail_out = kChunkSize;
-    strm.next_out = output;
-    retCode = deflate(&strm, Z_FINISH);
-    if ((retCode != Z_OK) && (retCode != Z_STREAM_END)) {
-      if (error) {
-        NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode]
-                                                             forKey:GULNSDataZlibErrorKey];
-        *error = [NSError errorWithDomain:GULNSDataZlibErrorDomain
-                                     code:GULNSDataZlibErrorInternal
-                                 userInfo:userInfo];
-      }
-      deflateEnd(&strm);
-      return nil;
-    }
-    // Collect what we got.
-    unsigned gotBack = kChunkSize - strm.avail_out;
-    if (gotBack > 0) {
-      [result appendBytes:output length:gotBack];
-    }
-
-  } while (retCode == Z_OK);
-
-  // If the loop exits, it used all input and the stream ended.
-  NSAssert(strm.avail_in == 0,
-           @"Should have finished deflating without using all input, %u bytes left", strm.avail_in);
-  NSAssert(retCode == Z_STREAM_END,
-           @"thought we finished deflate w/o getting a result of stream end, code %d", retCode);
-
-  // Clean up.
-  deflateEnd(&strm);
-
-  return result;
-}
-
-@end

+ 0 - 49
GoogleUtilities/NSData+zlib/Public/GoogleUtilities/GULNSData+zlib.h

@@ -1,49 +0,0 @@
-// Copyright 2018 Google
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import <Foundation/Foundation.h>
-
-/// This is a copy of Google Toolbox for Mac library to avoid creating an extra framework.
-
-// NOTE: For 64bit, none of these apis handle input sizes >32bits, they will return nil when given
-// such data. To handle data of that size you really should be streaming it rather then doing it all
-// in memory.
-
-@interface NSData (GULGzip)
-
-/// Returns an data as the result of decompressing the payload of |data|.The data to decompress must
-/// be a gzipped payloads.
-+ (NSData *)gul_dataByInflatingGzippedData:(NSData *)data error:(NSError **)error;
-
-/// Returns an compressed data with the result of gzipping the payload of |data|. Uses the default
-/// compression level.
-+ (NSData *)gul_dataByGzippingData:(NSData *)data error:(NSError **)error;
-
-FOUNDATION_EXPORT NSString *const GULNSDataZlibErrorDomain;
-FOUNDATION_EXPORT NSString *const GULNSDataZlibErrorKey;           // NSNumber
-FOUNDATION_EXPORT NSString *const GULNSDataZlibRemainingBytesKey;  // NSNumber
-
-typedef NS_ENUM(NSInteger, GULNSDataZlibError) {
-  GULNSDataZlibErrorGreaterThan32BitsToCompress = 1024,
-  // An internal zlib error.
-  // GULNSDataZlibErrorKey will contain the error value.
-  // NSLocalizedDescriptionKey may contain an error string from zlib.
-  // Look in zlib.h for list of errors.
-  GULNSDataZlibErrorInternal,
-  // There was left over data in the buffer that was not used.
-  // GULNSDataZlibRemainingBytesKey will contain number of remaining bytes.
-  GULNSDataZlibErrorDataRemaining
-};
-
-@end

+ 0 - 101
GoogleUtilities/Network/GULMutableDictionary.m

@@ -1,101 +0,0 @@
-// Copyright 2017 Google
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import "GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h"
-
-@implementation GULMutableDictionary {
-  /// The mutable dictionary.
-  NSMutableDictionary *_objects;
-
-  /// Serial synchronization queue. All reads should use dispatch_sync, while writes use
-  /// dispatch_async.
-  dispatch_queue_t _queue;
-}
-
-- (instancetype)init {
-  self = [super init];
-
-  if (self) {
-    _objects = [[NSMutableDictionary alloc] init];
-    _queue = dispatch_queue_create("GULMutableDictionary", DISPATCH_QUEUE_SERIAL);
-  }
-
-  return self;
-}
-
-- (NSString *)description {
-  __block NSString *description;
-  dispatch_sync(_queue, ^{
-    description = self->_objects.description;
-  });
-  return description;
-}
-
-- (id)objectForKey:(id)key {
-  __block id object;
-  dispatch_sync(_queue, ^{
-    object = [self->_objects objectForKey:key];
-  });
-  return object;
-}
-
-- (void)setObject:(id)object forKey:(id<NSCopying>)key {
-  dispatch_async(_queue, ^{
-    [self->_objects setObject:object forKey:key];
-  });
-}
-
-- (void)removeObjectForKey:(id)key {
-  dispatch_async(_queue, ^{
-    [self->_objects removeObjectForKey:key];
-  });
-}
-
-- (void)removeAllObjects {
-  dispatch_async(_queue, ^{
-    [self->_objects removeAllObjects];
-  });
-}
-
-- (NSUInteger)count {
-  __block NSUInteger count;
-  dispatch_sync(_queue, ^{
-    count = self->_objects.count;
-  });
-  return count;
-}
-
-- (id)objectForKeyedSubscript:(id<NSCopying>)key {
-  __block id object;
-  dispatch_sync(_queue, ^{
-    object = self->_objects[key];
-  });
-  return object;
-}
-
-- (void)setObject:(id)obj forKeyedSubscript:(id<NSCopying>)key {
-  dispatch_async(_queue, ^{
-    self->_objects[key] = obj;
-  });
-}
-
-- (NSDictionary *)dictionary {
-  __block NSDictionary *dictionary;
-  dispatch_sync(_queue, ^{
-    dictionary = [self->_objects copy];
-  });
-  return dictionary;
-}
-
-@end

+ 0 - 390
GoogleUtilities/Network/GULNetwork.m

@@ -1,390 +0,0 @@
-// Copyright 2017 Google
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import "GoogleUtilities/Network/Public/GoogleUtilities/GULNetwork.h"
-#import "GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkMessageCode.h"
-
-#import "GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h"
-#import "GoogleUtilities/NSData+zlib/Public/GoogleUtilities/GULNSData+zlib.h"
-#import "GoogleUtilities/Network/GULNetworkInternal.h"
-#import "GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h"
-#import "GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkConstants.h"
-#import "GoogleUtilities/Reachability/Public/GoogleUtilities/GULReachabilityChecker.h"
-
-/// Constant string for request header Content-Encoding.
-static NSString *const kGULNetworkContentCompressionKey = @"Content-Encoding";
-
-/// Constant string for request header Content-Encoding value.
-static NSString *const kGULNetworkContentCompressionValue = @"gzip";
-
-/// Constant string for request header Content-Length.
-static NSString *const kGULNetworkContentLengthKey = @"Content-Length";
-
-/// Constant string for request header Content-Type.
-static NSString *const kGULNetworkContentTypeKey = @"Content-Type";
-
-/// Constant string for request header Content-Type value.
-static NSString *const kGULNetworkContentTypeValue = @"application/x-www-form-urlencoded";
-
-/// Constant string for GET request method.
-static NSString *const kGULNetworkGETRequestMethod = @"GET";
-
-/// Constant string for POST request method.
-static NSString *const kGULNetworkPOSTRequestMethod = @"POST";
-
-/// Default constant string as a prefix for network logger.
-static NSString *const kGULNetworkLogTag = @"Google/Utilities/Network";
-
-@interface GULNetwork () <GULReachabilityDelegate, GULNetworkLoggerDelegate>
-@end
-
-@implementation GULNetwork {
-  /// Network reachability.
-  GULReachabilityChecker *_reachability;
-
-  /// The dictionary of requests by session IDs { NSString : id }.
-  GULMutableDictionary *_requests;
-}
-
-- (instancetype)init {
-  return [self initWithReachabilityHost:kGULNetworkReachabilityHost];
-}
-
-- (instancetype)initWithReachabilityHost:(NSString *)reachabilityHost {
-  self = [super init];
-  if (self) {
-    // Setup reachability.
-    _reachability = [[GULReachabilityChecker alloc] initWithReachabilityDelegate:self
-                                                                        withHost:reachabilityHost];
-    if (![_reachability start]) {
-      return nil;
-    }
-
-    _requests = [[GULMutableDictionary alloc] init];
-    _timeoutInterval = kGULNetworkTimeOutInterval;
-  }
-  return self;
-}
-
-- (void)dealloc {
-  _reachability.reachabilityDelegate = nil;
-  [_reachability stop];
-}
-
-#pragma mark - External Methods
-
-+ (void)handleEventsForBackgroundURLSessionID:(NSString *)sessionID
-                            completionHandler:(GULNetworkSystemCompletionHandler)completionHandler {
-  [GULNetworkURLSession handleEventsForBackgroundURLSessionID:sessionID
-                                            completionHandler:completionHandler];
-}
-
-- (NSString *)postURL:(NSURL *)url
-                   payload:(NSData *)payload
-                     queue:(dispatch_queue_t)queue
-    usingBackgroundSession:(BOOL)usingBackgroundSession
-         completionHandler:(GULNetworkCompletionHandler)handler {
-  if (!url.absoluteString.length) {
-    [self handleErrorWithCode:GULErrorCodeNetworkInvalidURL queue:queue withHandler:handler];
-    return nil;
-  }
-
-  NSTimeInterval timeOutInterval = _timeoutInterval ?: kGULNetworkTimeOutInterval;
-
-  NSMutableURLRequest *request =
-      [[NSMutableURLRequest alloc] initWithURL:url
-                                   cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
-                               timeoutInterval:timeOutInterval];
-
-  if (!request) {
-    [self handleErrorWithCode:GULErrorCodeNetworkSessionTaskCreation
-                        queue:queue
-                  withHandler:handler];
-    return nil;
-  }
-
-  NSError *compressError = nil;
-  NSData *compressedData = [NSData gul_dataByGzippingData:payload error:&compressError];
-  if (!compressedData || compressError) {
-    if (compressError || payload.length > 0) {
-      // If the payload is not empty but it fails to compress the payload, something has been wrong.
-      [self handleErrorWithCode:GULErrorCodeNetworkPayloadCompression
-                          queue:queue
-                    withHandler:handler];
-      return nil;
-    }
-    compressedData = [[NSData alloc] init];
-  }
-
-  NSString *postLength = @(compressedData.length).stringValue;
-
-  // Set up the request with the compressed data.
-  [request setValue:postLength forHTTPHeaderField:kGULNetworkContentLengthKey];
-  request.HTTPBody = compressedData;
-  request.HTTPMethod = kGULNetworkPOSTRequestMethod;
-  [request setValue:kGULNetworkContentTypeValue forHTTPHeaderField:kGULNetworkContentTypeKey];
-  [request setValue:kGULNetworkContentCompressionValue
-      forHTTPHeaderField:kGULNetworkContentCompressionKey];
-
-  GULNetworkURLSession *fetcher = [[GULNetworkURLSession alloc] initWithNetworkLoggerDelegate:self];
-  fetcher.backgroundNetworkEnabled = usingBackgroundSession;
-
-  __weak GULNetwork *weakSelf = self;
-  NSString *requestID = [fetcher
-      sessionIDFromAsyncPOSTRequest:request
-                  completionHandler:^(NSHTTPURLResponse *response, NSData *data,
-                                      NSString *sessionID, NSError *error) {
-                    GULNetwork *strongSelf = weakSelf;
-                    if (!strongSelf) {
-                      return;
-                    }
-                    dispatch_queue_t queueToDispatch = queue ? queue : dispatch_get_main_queue();
-                    dispatch_async(queueToDispatch, ^{
-                      if (sessionID.length) {
-                        [strongSelf->_requests removeObjectForKey:sessionID];
-                      }
-                      if (handler) {
-                        handler(response, data, error);
-                      }
-                    });
-                  }];
-  if (!requestID) {
-    [self handleErrorWithCode:GULErrorCodeNetworkSessionTaskCreation
-                        queue:queue
-                  withHandler:handler];
-    return nil;
-  }
-
-  [self GULNetwork_logWithLevel:kGULNetworkLogLevelDebug
-                    messageCode:kGULNetworkMessageCodeNetwork000
-                        message:@"Uploading data. Host"
-                        context:url];
-  _requests[requestID] = fetcher;
-  return requestID;
-}
-
-- (NSString *)getURL:(NSURL *)url
-                   headers:(NSDictionary *)headers
-                     queue:(dispatch_queue_t)queue
-    usingBackgroundSession:(BOOL)usingBackgroundSession
-         completionHandler:(GULNetworkCompletionHandler)handler {
-  if (!url.absoluteString.length) {
-    [self handleErrorWithCode:GULErrorCodeNetworkInvalidURL queue:queue withHandler:handler];
-    return nil;
-  }
-
-  NSTimeInterval timeOutInterval = _timeoutInterval ?: kGULNetworkTimeOutInterval;
-  NSMutableURLRequest *request =
-      [[NSMutableURLRequest alloc] initWithURL:url
-                                   cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
-                               timeoutInterval:timeOutInterval];
-
-  if (!request) {
-    [self handleErrorWithCode:GULErrorCodeNetworkSessionTaskCreation
-                        queue:queue
-                  withHandler:handler];
-    return nil;
-  }
-
-  request.HTTPMethod = kGULNetworkGETRequestMethod;
-  request.allHTTPHeaderFields = headers;
-
-  GULNetworkURLSession *fetcher = [[GULNetworkURLSession alloc] initWithNetworkLoggerDelegate:self];
-  fetcher.backgroundNetworkEnabled = usingBackgroundSession;
-
-  __weak GULNetwork *weakSelf = self;
-  NSString *requestID = [fetcher
-      sessionIDFromAsyncGETRequest:request
-                 completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSString *sessionID,
-                                     NSError *error) {
-                   GULNetwork *strongSelf = weakSelf;
-                   if (!strongSelf) {
-                     return;
-                   }
-                   dispatch_queue_t queueToDispatch = queue ? queue : dispatch_get_main_queue();
-                   dispatch_async(queueToDispatch, ^{
-                     if (sessionID.length) {
-                       [strongSelf->_requests removeObjectForKey:sessionID];
-                     }
-                     if (handler) {
-                       handler(response, data, error);
-                     }
-                   });
-                 }];
-
-  if (!requestID) {
-    [self handleErrorWithCode:GULErrorCodeNetworkSessionTaskCreation
-                        queue:queue
-                  withHandler:handler];
-    return nil;
-  }
-
-  [self GULNetwork_logWithLevel:kGULNetworkLogLevelDebug
-                    messageCode:kGULNetworkMessageCodeNetwork001
-                        message:@"Downloading data. Host"
-                        context:url];
-  _requests[requestID] = fetcher;
-  return requestID;
-}
-
-- (BOOL)hasUploadInProgress {
-  return _requests.count > 0;
-}
-
-#pragma mark - Network Reachability
-
-/// Tells reachability delegate to call reachabilityDidChangeToStatus: to notify the network
-/// reachability has changed.
-- (void)reachability:(GULReachabilityChecker *)reachability
-       statusChanged:(GULReachabilityStatus)status {
-  _networkConnected = (status == kGULReachabilityViaCellular || status == kGULReachabilityViaWifi);
-  [_reachabilityDelegate reachabilityDidChange];
-}
-
-#pragma mark - Network logger delegate
-
-- (void)setLoggerDelegate:(id<GULNetworkLoggerDelegate>)loggerDelegate {
-  // Explicitly check whether the delegate responds to the methods because conformsToProtocol does
-  // not work correctly even though the delegate does respond to the methods.
-  if (!loggerDelegate ||
-      ![loggerDelegate respondsToSelector:@selector(GULNetwork_logWithLevel:
-                                                                messageCode:message:contexts:)] ||
-      ![loggerDelegate respondsToSelector:@selector(GULNetwork_logWithLevel:
-                                                                messageCode:message:context:)] ||
-      ![loggerDelegate respondsToSelector:@selector(GULNetwork_logWithLevel:
-                                                                messageCode:message:)]) {
-    GULLogError(kGULLoggerNetwork, NO,
-                [NSString stringWithFormat:@"I-NET%06ld", (long)kGULNetworkMessageCodeNetwork002],
-                @"Cannot set the network logger delegate: delegate does not conform to the network "
-                 "logger protocol.");
-    return;
-  }
-  _loggerDelegate = loggerDelegate;
-}
-
-#pragma mark - Private methods
-
-/// Handles network error and calls completion handler with the error.
-- (void)handleErrorWithCode:(NSInteger)code
-                      queue:(dispatch_queue_t)queue
-                withHandler:(GULNetworkCompletionHandler)handler {
-  NSDictionary *userInfo = @{kGULNetworkErrorContext : @"Failed to create network request"};
-  NSError *error = [[NSError alloc] initWithDomain:kGULNetworkErrorDomain
-                                              code:code
-                                          userInfo:userInfo];
-  [self GULNetwork_logWithLevel:kGULNetworkLogLevelWarning
-                    messageCode:kGULNetworkMessageCodeNetwork002
-                        message:@"Failed to create network request. Code, error"
-                       contexts:@[ @(code), error ]];
-  if (handler) {
-    dispatch_queue_t queueToDispatch = queue ? queue : dispatch_get_main_queue();
-    dispatch_async(queueToDispatch, ^{
-      handler(nil, nil, error);
-    });
-  }
-}
-
-#pragma mark - Network logger
-
-- (void)GULNetwork_logWithLevel:(GULNetworkLogLevel)logLevel
-                    messageCode:(GULNetworkMessageCode)messageCode
-                        message:(NSString *)message
-                       contexts:(NSArray *)contexts {
-  // Let the delegate log the message if there is a valid logger delegate. Otherwise, just log
-  // errors/warnings/info messages to the console log.
-  if (_loggerDelegate) {
-    [_loggerDelegate GULNetwork_logWithLevel:logLevel
-                                 messageCode:messageCode
-                                     message:message
-                                    contexts:contexts];
-    return;
-  }
-  if (_isDebugModeEnabled || logLevel == kGULNetworkLogLevelError ||
-      logLevel == kGULNetworkLogLevelWarning || logLevel == kGULNetworkLogLevelInfo) {
-    NSString *formattedMessage = GULStringWithLogMessage(message, logLevel, contexts);
-    NSLog(@"%@", formattedMessage);
-    GULLogBasic((GULLoggerLevel)logLevel, kGULLoggerNetwork, NO,
-                [NSString stringWithFormat:@"I-NET%06ld", (long)messageCode], formattedMessage,
-                NULL);
-  }
-}
-
-- (void)GULNetwork_logWithLevel:(GULNetworkLogLevel)logLevel
-                    messageCode:(GULNetworkMessageCode)messageCode
-                        message:(NSString *)message
-                        context:(id)context {
-  if (_loggerDelegate) {
-    [_loggerDelegate GULNetwork_logWithLevel:logLevel
-                                 messageCode:messageCode
-                                     message:message
-                                     context:context];
-    return;
-  }
-  NSArray *contexts = context ? @[ context ] : @[];
-  [self GULNetwork_logWithLevel:logLevel messageCode:messageCode message:message contexts:contexts];
-}
-
-- (void)GULNetwork_logWithLevel:(GULNetworkLogLevel)logLevel
-                    messageCode:(GULNetworkMessageCode)messageCode
-                        message:(NSString *)message {
-  if (_loggerDelegate) {
-    [_loggerDelegate GULNetwork_logWithLevel:logLevel messageCode:messageCode message:message];
-    return;
-  }
-  [self GULNetwork_logWithLevel:logLevel messageCode:messageCode message:message contexts:@[]];
-}
-
-/// Returns a string for the given log level (e.g. kGULNetworkLogLevelError -> @"ERROR").
-static NSString *GULLogLevelDescriptionFromLogLevel(GULNetworkLogLevel logLevel) {
-  static NSDictionary *levelNames = nil;
-  static dispatch_once_t onceToken;
-  dispatch_once(&onceToken, ^{
-    levelNames = @{
-      @(kGULNetworkLogLevelError) : @"ERROR",
-      @(kGULNetworkLogLevelWarning) : @"WARNING",
-      @(kGULNetworkLogLevelInfo) : @"INFO",
-      @(kGULNetworkLogLevelDebug) : @"DEBUG"
-    };
-  });
-  return levelNames[@(logLevel)];
-}
-
-/// Returns a formatted string to be used for console logging.
-static NSString *GULStringWithLogMessage(NSString *message,
-                                         GULNetworkLogLevel logLevel,
-                                         NSArray *contexts) {
-  if (!message) {
-    message = @"(Message was nil)";
-  } else if (!message.length) {
-    message = @"(Message was empty)";
-  }
-  NSMutableString *result = [[NSMutableString alloc]
-      initWithFormat:@"<%@/%@> %@", kGULNetworkLogTag, GULLogLevelDescriptionFromLogLevel(logLevel),
-                     message];
-
-  if (!contexts.count) {
-    return result;
-  }
-
-  NSMutableArray *formattedContexts = [[NSMutableArray alloc] init];
-  for (id item in contexts) {
-    [formattedContexts addObject:(item != [NSNull null] ? item : @"(nil)")];
-  }
-
-  [result appendString:@": "];
-  [result appendString:[formattedContexts componentsJoinedByString:@", "]];
-  return result;
-}
-
-@end

+ 0 - 41
GoogleUtilities/Network/GULNetworkConstants.m

@@ -1,41 +0,0 @@
-// Copyright 2017 Google
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import "GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkConstants.h"
-#import "GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h"
-
-#import <Foundation/Foundation.h>
-
-NSString *const kGULNetworkBackgroundSessionConfigIDPrefix = @"com.gul.network.background-upload";
-NSString *const kGULNetworkApplicationSupportSubdirectory = @"GUL/Network";
-NSString *const kGULNetworkTempDirectoryName = @"GULNetworkTemporaryDirectory";
-const NSTimeInterval kGULNetworkTempFolderExpireTime = 60 * 60;  // 1 hour
-const NSTimeInterval kGULNetworkTimeOutInterval = 60;            // 1 minute.
-NSString *const kGULNetworkReachabilityHost = @"app-measurement.com";
-NSString *const kGULNetworkErrorContext = @"Context";
-
-const int kGULNetworkHTTPStatusOK = 200;
-const int kGULNetworkHTTPStatusNoContent = 204;
-const int kGULNetworkHTTPStatusCodeMultipleChoices = 300;
-const int kGULNetworkHTTPStatusCodeMovedPermanently = 301;
-const int kGULNetworkHTTPStatusCodeFound = 302;
-const int kGULNetworkHTTPStatusCodeNotModified = 304;
-const int kGULNetworkHTTPStatusCodeMovedTemporarily = 307;
-const int kGULNetworkHTTPStatusCodeNotFound = 404;
-const int kGULNetworkHTTPStatusCodeCannotAcceptTraffic = 429;
-const int kGULNetworkHTTPStatusCodeUnavailable = 503;
-
-NSString *const kGULNetworkErrorDomain = @"com.gul.network.ErrorDomain";
-
-GULLoggerService kGULLoggerNetwork = @"[GULNetwork]";

+ 0 - 24
GoogleUtilities/Network/GULNetworkInternal.h

@@ -1,24 +0,0 @@
-/*
- * Copyright 2017 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-#import "GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h"
-
-extern NSString *const kGULNetworkErrorDomain;
-
-/// The logger service for GULNetwork.
-extern GULLoggerService kGULLoggerNetwork;

+ 0 - 766
GoogleUtilities/Network/GULNetworkURLSession.m

@@ -1,766 +0,0 @@
-// Copyright 2017 Google
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import <Foundation/Foundation.h>
-
-#import "GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkURLSession.h"
-
-#import "GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h"
-#import "GoogleUtilities/Network/GULNetworkInternal.h"
-#import "GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h"
-#import "GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkConstants.h"
-#import "GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkMessageCode.h"
-
-@interface GULNetworkURLSession () <NSURLSessionDelegate,
-                                    NSURLSessionDataDelegate,
-                                    NSURLSessionDownloadDelegate,
-                                    NSURLSessionTaskDelegate>
-@end
-
-@implementation GULNetworkURLSession {
-  /// The handler to be called when the request completes or error has occurs.
-  GULNetworkURLSessionCompletionHandler _completionHandler;
-
-  /// Session ID generated randomly with a fixed prefix.
-  NSString *_sessionID;
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunguarded-availability"
-  /// The session configuration. NSURLSessionConfiguration' is only available on iOS 7.0 or newer.
-  NSURLSessionConfiguration *_sessionConfig;
-
-  /// The current NSURLSession.
-  NSURLSession *__weak _Nullable _URLSession;
-#pragma clang diagnostic pop
-
-  /// The path to the directory where all temporary files are stored before uploading.
-  NSURL *_networkDirectoryURL;
-
-  /// The downloaded data from fetching.
-  NSData *_downloadedData;
-
-  /// The path to the temporary file which stores the uploading data.
-  NSURL *_uploadingFileURL;
-
-  /// The current request.
-  NSURLRequest *_request;
-}
-
-#pragma mark - Init
-
-- (instancetype)initWithNetworkLoggerDelegate:(id<GULNetworkLoggerDelegate>)networkLoggerDelegate {
-  self = [super init];
-  if (self) {
-    // Create URL to the directory where all temporary files to upload have to be stored.
-#if TARGET_OS_TV
-    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
-#else
-    NSArray *paths =
-        NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
-#endif
-    NSString *storageDirectory = paths.firstObject;
-    NSArray *tempPathComponents = @[
-      storageDirectory, kGULNetworkApplicationSupportSubdirectory, kGULNetworkTempDirectoryName
-    ];
-    _networkDirectoryURL = [NSURL fileURLWithPathComponents:tempPathComponents];
-    _sessionID = [NSString stringWithFormat:@"%@-%@", kGULNetworkBackgroundSessionConfigIDPrefix,
-                                            [[NSUUID UUID] UUIDString]];
-    _loggerDelegate = networkLoggerDelegate;
-  }
-  return self;
-}
-
-#pragma mark - External Methods
-
-#pragma mark - To be called from AppDelegate
-
-+ (void)handleEventsForBackgroundURLSessionID:(NSString *)sessionID
-                            completionHandler:
-                                (GULNetworkSystemCompletionHandler)systemCompletionHandler {
-  // The session may not be Analytics background. Ignore those that do not have the prefix.
-  if (![sessionID hasPrefix:kGULNetworkBackgroundSessionConfigIDPrefix]) {
-    return;
-  }
-  GULNetworkURLSession *fetcher = [self fetcherWithSessionIdentifier:sessionID];
-  if (fetcher != nil) {
-    [fetcher addSystemCompletionHandler:systemCompletionHandler forSession:sessionID];
-  } else {
-    GULLogError(kGULLoggerNetwork, NO,
-                [NSString stringWithFormat:@"I-NET%06ld", (long)kGULNetworkMessageCodeNetwork003],
-                @"Failed to retrieve background session with ID %@ after app is relaunched.",
-                sessionID);
-  }
-}
-
-#pragma mark - External Methods
-
-/// Sends an async POST request using NSURLSession for iOS >= 7.0, and returns an ID of the
-/// connection.
-- (nullable NSString *)sessionIDFromAsyncPOSTRequest:(NSURLRequest *)request
-                                   completionHandler:(GULNetworkURLSessionCompletionHandler)handler
-    API_AVAILABLE(ios(7.0)) {
-  // NSURLSessionUploadTask does not work with NSData in the background.
-  // To avoid this issue, write the data to a temporary file to upload it.
-  // Make a temporary file with the data subset.
-  _uploadingFileURL = [self temporaryFilePathWithSessionID:_sessionID];
-  NSError *writeError;
-  NSURLSessionUploadTask *postRequestTask;
-  NSURLSession *session;
-  BOOL didWriteFile = NO;
-
-  // Clean up the entire temp folder to avoid temp files that remain in case the previous session
-  // crashed and did not clean up.
-  [self maybeRemoveTempFilesAtURL:_networkDirectoryURL
-                     expiringTime:kGULNetworkTempFolderExpireTime];
-
-  // If there is no background network enabled, no need to write to file. This will allow default
-  // network session which runs on the foreground.
-  if (_backgroundNetworkEnabled && [self ensureTemporaryDirectoryExists]) {
-    didWriteFile = [request.HTTPBody writeToFile:_uploadingFileURL.path
-                                         options:NSDataWritingAtomic
-                                           error:&writeError];
-
-    if (writeError) {
-      [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelError
-                                   messageCode:kGULNetworkMessageCodeURLSession000
-                                       message:@"Failed to write request data to file"
-                                       context:writeError];
-    }
-  }
-
-  if (didWriteFile) {
-    // Exclude this file from backing up to iTunes. There are conflicting reports that excluding
-    // directory from backing up does not exclude files of that directory from backing up.
-    [self excludeFromBackupForURL:_uploadingFileURL];
-
-    _sessionConfig = [self backgroundSessionConfigWithSessionID:_sessionID];
-    [self populateSessionConfig:_sessionConfig withRequest:request];
-    session = [NSURLSession sessionWithConfiguration:_sessionConfig
-                                            delegate:self
-                                       delegateQueue:[NSOperationQueue mainQueue]];
-    postRequestTask = [session uploadTaskWithRequest:request fromFile:_uploadingFileURL];
-  } else {
-    // If we cannot write to file, just send it in the foreground.
-    _sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
-    [self populateSessionConfig:_sessionConfig withRequest:request];
-    session = [NSURLSession sessionWithConfiguration:_sessionConfig
-                                            delegate:self
-                                       delegateQueue:[NSOperationQueue mainQueue]];
-    postRequestTask = [session uploadTaskWithRequest:request fromData:request.HTTPBody];
-  }
-
-  if (!session || !postRequestTask) {
-    NSError *error = [[NSError alloc]
-        initWithDomain:kGULNetworkErrorDomain
-                  code:GULErrorCodeNetworkRequestCreation
-              userInfo:@{kGULNetworkErrorContext : @"Cannot create network session"}];
-    [self callCompletionHandler:handler withResponse:nil data:nil error:error];
-    return nil;
-  }
-
-  _URLSession = session;
-
-  // Save the session into memory.
-  [[self class] setSessionInFetcherMap:self forSessionID:_sessionID];
-
-  _request = [request copy];
-
-  // Store completion handler because background session does not accept handler block but custom
-  // delegate.
-  _completionHandler = [handler copy];
-  [postRequestTask resume];
-
-  return _sessionID;
-}
-
-/// Sends an async GET request using NSURLSession for iOS >= 7.0, and returns an ID of the session.
-- (nullable NSString *)sessionIDFromAsyncGETRequest:(NSURLRequest *)request
-                                  completionHandler:(GULNetworkURLSessionCompletionHandler)handler
-    API_AVAILABLE(ios(7.0)) {
-  if (_backgroundNetworkEnabled) {
-    _sessionConfig = [self backgroundSessionConfigWithSessionID:_sessionID];
-  } else {
-    _sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
-  }
-
-  [self populateSessionConfig:_sessionConfig withRequest:request];
-
-  // Do not cache the GET request.
-  _sessionConfig.URLCache = nil;
-
-  NSURLSession *session = [NSURLSession sessionWithConfiguration:_sessionConfig
-                                                        delegate:self
-                                                   delegateQueue:[NSOperationQueue mainQueue]];
-  NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request];
-
-  if (!session || !downloadTask) {
-    NSError *error = [[NSError alloc]
-        initWithDomain:kGULNetworkErrorDomain
-                  code:GULErrorCodeNetworkRequestCreation
-              userInfo:@{kGULNetworkErrorContext : @"Cannot create network session"}];
-    [self callCompletionHandler:handler withResponse:nil data:nil error:error];
-    return nil;
-  }
-
-  _URLSession = session;
-
-  // Save the session into memory.
-  [[self class] setSessionInFetcherMap:self forSessionID:_sessionID];
-
-  _request = [request copy];
-
-  _completionHandler = [handler copy];
-  [downloadTask resume];
-
-  return _sessionID;
-}
-
-#pragma mark - NSURLSessionDataDelegate
-
-/// Called by the NSURLSession when the data task has received some of the expected data.
-/// Once the session is completed, URLSession:task:didCompleteWithError will be called and the
-/// completion handler will be called with the downloaded data.
-- (void)URLSession:(NSURLSession *)session
-          dataTask:(NSURLSessionDataTask *)dataTask
-    didReceiveData:(NSData *)data {
-  @synchronized(self) {
-    NSMutableData *mutableData = [[NSMutableData alloc] init];
-    if (_downloadedData) {
-      mutableData = _downloadedData.mutableCopy;
-    }
-    [mutableData appendData:data];
-    _downloadedData = mutableData;
-  }
-}
-
-#pragma mark - NSURLSessionTaskDelegate
-
-/// Called by the NSURLSession once the download task is completed. The file is saved in the
-/// provided URL so we need to read the data and store into _downloadedData. Once the session is
-/// completed, URLSession:task:didCompleteWithError will be called and the completion handler will
-/// be called with the downloaded data.
-- (void)URLSession:(NSURLSession *)session
-                 downloadTask:(NSURLSessionDownloadTask *)task
-    didFinishDownloadingToURL:(NSURL *)url API_AVAILABLE(ios(7.0)) {
-  if (!url.path) {
-    [_loggerDelegate
-        GULNetwork_logWithLevel:kGULNetworkLogLevelError
-                    messageCode:kGULNetworkMessageCodeURLSession001
-                        message:@"Unable to read downloaded data from empty temp path"];
-    _downloadedData = nil;
-    return;
-  }
-
-  NSError *error;
-  _downloadedData = [NSData dataWithContentsOfFile:url.path options:0 error:&error];
-
-  if (error) {
-    [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelError
-                                 messageCode:kGULNetworkMessageCodeURLSession002
-                                     message:@"Cannot read the content of downloaded data"
-                                     context:error];
-    _downloadedData = nil;
-  }
-}
-
-#if TARGET_OS_IOS || TARGET_OS_TV
-- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session
-    API_AVAILABLE(ios(7.0)) {
-  [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelDebug
-                               messageCode:kGULNetworkMessageCodeURLSession003
-                                   message:@"Background session finished"
-                                   context:session.configuration.identifier];
-  [self callSystemCompletionHandler:session.configuration.identifier];
-}
-#endif
-
-- (void)URLSession:(NSURLSession *)session
-                    task:(NSURLSessionTask *)task
-    didCompleteWithError:(NSError *)error API_AVAILABLE(ios(7.0)) {
-  // Avoid any chance of recursive behavior leading to it being used repeatedly.
-  GULNetworkURLSessionCompletionHandler handler = _completionHandler;
-  _completionHandler = nil;
-
-  if (task.response) {
-    // The following assertion should always be true for HTTP requests, see https://goo.gl/gVLxT7.
-    NSAssert([task.response isKindOfClass:[NSHTTPURLResponse class]], @"URL response must be HTTP");
-
-    // The server responded so ignore the error created by the system.
-    error = nil;
-  } else if (!error) {
-    error = [[NSError alloc]
-        initWithDomain:kGULNetworkErrorDomain
-                  code:GULErrorCodeNetworkInvalidResponse
-              userInfo:@{kGULNetworkErrorContext : @"Network Error: Empty network response"}];
-  }
-
-  [self callCompletionHandler:handler
-                 withResponse:(NSHTTPURLResponse *)task.response
-                         data:_downloadedData
-                        error:error];
-
-  // Remove the temp file to avoid trashing devices with lots of temp files.
-  [self removeTempItemAtURL:_uploadingFileURL];
-
-  // Try to clean up stale files again.
-  [self maybeRemoveTempFilesAtURL:_networkDirectoryURL
-                     expiringTime:kGULNetworkTempFolderExpireTime];
-
-  // This is called without checking the sessionID here since non-background sessions
-  // won't have an ID.
-  [session finishTasksAndInvalidate];
-
-  // Explicitly remove the session so it won't be reused. The weak map table should
-  // remove the session on deallocation, but dealloc may not happen immediately after
-  // calling `finishTasksAndInvalidate`.
-  NSString *sessionID = session.configuration.identifier;
-  [[self class] setSessionInFetcherMap:nil forSessionID:sessionID];
-}
-
-- (void)URLSession:(NSURLSession *)session
-                   task:(NSURLSessionTask *)task
-    didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
-      completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition,
-                                  NSURLCredential *credential))completionHandler
-    API_AVAILABLE(ios(7.0)) {
-  // The handling is modeled after GTMSessionFetcher.
-  if ([challenge.protectionSpace.authenticationMethod
-          isEqualToString:NSURLAuthenticationMethodServerTrust]) {
-    SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
-    if (serverTrust == NULL) {
-      [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelDebug
-                                   messageCode:kGULNetworkMessageCodeURLSession004
-                                       message:@"Received empty server trust for host. Host"
-                                       context:_request.URL];
-      completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
-      return;
-    }
-    NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
-    if (!credential) {
-      [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelWarning
-                                   messageCode:kGULNetworkMessageCodeURLSession005
-                                       message:@"Unable to verify server identity. Host"
-                                       context:_request.URL];
-      completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
-      return;
-    }
-
-    [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelDebug
-                                 messageCode:kGULNetworkMessageCodeURLSession006
-                                     message:@"Received SSL challenge for host. Host"
-                                     context:_request.URL];
-
-    void (^callback)(BOOL) = ^(BOOL allow) {
-      if (allow) {
-        completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
-      } else {
-        [self->_loggerDelegate
-            GULNetwork_logWithLevel:kGULNetworkLogLevelDebug
-                        messageCode:kGULNetworkMessageCodeURLSession007
-                            message:@"Cancelling authentication challenge for host. Host"
-                            context:self->_request.URL];
-        completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
-      }
-    };
-
-    // Retain the trust object to avoid a SecTrustEvaluate() crash on iOS 7.
-    CFRetain(serverTrust);
-
-    // Evaluate the certificate chain.
-    //
-    // The delegate queue may be the main thread. Trust evaluation could cause some
-    // blocking network activity, so we must evaluate async, as documented at
-    // https://developer.apple.com/library/ios/technotes/tn2232/
-    dispatch_queue_t evaluateBackgroundQueue =
-        dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
-
-    dispatch_async(evaluateBackgroundQueue, ^{
-      SecTrustResultType trustEval = kSecTrustResultInvalid;
-      BOOL shouldAllow;
-      OSStatus trustError;
-
-      @synchronized([GULNetworkURLSession class]) {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-        trustError = SecTrustEvaluate(serverTrust, &trustEval);
-#pragma clang dianostic pop
-      }
-
-      if (trustError != errSecSuccess) {
-        [self->_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelError
-                                           messageCode:kGULNetworkMessageCodeURLSession008
-                                               message:@"Cannot evaluate server trust. Error, host"
-                                              contexts:@[ @(trustError), self->_request.URL ]];
-        shouldAllow = NO;
-      } else {
-        // Having a trust level "unspecified" by the user is the usual result, described at
-        // https://developer.apple.com/library/mac/qa/qa1360
-        shouldAllow =
-            (trustEval == kSecTrustResultUnspecified || trustEval == kSecTrustResultProceed);
-      }
-
-      // Call the call back with the permission.
-      callback(shouldAllow);
-
-      CFRelease(serverTrust);
-    });
-    return;
-  }
-
-  // Default handling for other Auth Challenges.
-  completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
-}
-
-#pragma mark - Internal Methods
-
-/// Stores system completion handler with session ID as key.
-- (void)addSystemCompletionHandler:(GULNetworkSystemCompletionHandler)handler
-                        forSession:(NSString *)identifier {
-  if (!handler) {
-    [_loggerDelegate
-        GULNetwork_logWithLevel:kGULNetworkLogLevelError
-                    messageCode:kGULNetworkMessageCodeURLSession009
-                        message:@"Cannot store nil system completion handler in network"];
-    return;
-  }
-
-  if (!identifier.length) {
-    [_loggerDelegate
-        GULNetwork_logWithLevel:kGULNetworkLogLevelError
-                    messageCode:kGULNetworkMessageCodeURLSession010
-                        message:@"Cannot store system completion handler with empty network "
-                                 "session identifier"];
-    return;
-  }
-
-  GULMutableDictionary *systemCompletionHandlers =
-      [[self class] sessionIDToSystemCompletionHandlerDictionary];
-  if (systemCompletionHandlers[identifier]) {
-    [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelWarning
-                                 messageCode:kGULNetworkMessageCodeURLSession011
-                                     message:@"Got multiple system handlers for a single session ID"
-                                     context:identifier];
-  }
-
-  systemCompletionHandlers[identifier] = handler;
-}
-
-/// Calls the system provided completion handler with the session ID stored in the dictionary.
-/// The handler will be removed from the dictionary after being called.
-- (void)callSystemCompletionHandler:(NSString *)identifier {
-  GULMutableDictionary *systemCompletionHandlers =
-      [[self class] sessionIDToSystemCompletionHandlerDictionary];
-  GULNetworkSystemCompletionHandler handler = [systemCompletionHandlers objectForKey:identifier];
-
-  if (handler) {
-    [systemCompletionHandlers removeObjectForKey:identifier];
-
-    dispatch_async(dispatch_get_main_queue(), ^{
-      handler();
-    });
-  }
-}
-
-/// Sets or updates the session ID of this session.
-- (void)setSessionID:(NSString *)sessionID {
-  _sessionID = [sessionID copy];
-}
-
-/// Creates a background session configuration with the session ID using the supported method.
-- (NSURLSessionConfiguration *)backgroundSessionConfigWithSessionID:(NSString *)sessionID
-    API_AVAILABLE(ios(7.0)) {
-#if (TARGET_OS_OSX && defined(MAC_OS_X_VERSION_10_10) &&         \
-     MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10) || \
-    TARGET_OS_TV ||                                              \
-    (TARGET_OS_IOS && defined(__IPHONE_8_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0)
-
-  // iOS 8/10.10 builds require the new backgroundSessionConfiguration method name.
-  return [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:sessionID];
-
-#elif (TARGET_OS_OSX && defined(MAC_OS_X_VERSION_10_10) &&        \
-       MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10) || \
-    (TARGET_OS_IOS && defined(__IPHONE_8_0) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0)
-
-  // Do a runtime check to avoid a deprecation warning about using
-  // +backgroundSessionConfiguration: on iOS 8.
-  if ([NSURLSessionConfiguration
-          respondsToSelector:@selector(backgroundSessionConfigurationWithIdentifier:)]) {
-    // Running on iOS 8+/OS X 10.10+.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunguarded-availability"
-    return [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:sessionID];
-#pragma clang diagnostic pop
-  } else {
-    // Running on iOS 7/OS X 10.9.
-    return [NSURLSessionConfiguration backgroundSessionConfiguration:sessionID];
-  }
-
-#else
-  // Building with an SDK earlier than iOS 8/OS X 10.10.
-  return [NSURLSessionConfiguration backgroundSessionConfiguration:sessionID];
-#endif
-}
-
-- (void)maybeRemoveTempFilesAtURL:(NSURL *)folderURL expiringTime:(NSTimeInterval)staleTime {
-  if (!folderURL.absoluteString.length) {
-    return;
-  }
-
-  NSFileManager *fileManager = [NSFileManager defaultManager];
-  NSError *error = nil;
-
-  NSArray *properties = @[ NSURLCreationDateKey ];
-  NSArray *directoryContent =
-      [fileManager contentsOfDirectoryAtURL:folderURL
-                 includingPropertiesForKeys:properties
-                                    options:NSDirectoryEnumerationSkipsSubdirectoryDescendants
-                                      error:&error];
-  if (error && error.code != NSFileReadNoSuchFileError) {
-    [_loggerDelegate
-        GULNetwork_logWithLevel:kGULNetworkLogLevelDebug
-                    messageCode:kGULNetworkMessageCodeURLSession012
-                        message:@"Cannot get files from the temporary network folder. Error"
-                        context:error];
-    return;
-  }
-
-  if (!directoryContent.count) {
-    return;
-  }
-
-  NSTimeInterval now = [NSDate date].timeIntervalSince1970;
-  for (NSURL *tempFile in directoryContent) {
-    NSDate *creationDate;
-    BOOL getCreationDate = [tempFile getResourceValue:&creationDate
-                                               forKey:NSURLCreationDateKey
-                                                error:NULL];
-    if (!getCreationDate) {
-      continue;
-    }
-    NSTimeInterval creationTimeInterval = creationDate.timeIntervalSince1970;
-    if (fabs(now - creationTimeInterval) > staleTime) {
-      [self removeTempItemAtURL:tempFile];
-    }
-  }
-}
-
-/// Removes the temporary file written to disk for sending the request. It has to be cleaned up
-/// after the session is done.
-- (void)removeTempItemAtURL:(NSURL *)fileURL {
-  if (!fileURL.absoluteString.length) {
-    return;
-  }
-
-  NSFileManager *fileManager = [NSFileManager defaultManager];
-  NSError *error = nil;
-
-  if (![fileManager removeItemAtURL:fileURL error:&error] && error.code != NSFileNoSuchFileError) {
-    [_loggerDelegate
-        GULNetwork_logWithLevel:kGULNetworkLogLevelError
-                    messageCode:kGULNetworkMessageCodeURLSession013
-                        message:@"Failed to remove temporary uploading data file. Error"
-                        context:error.localizedDescription];
-  }
-}
-
-/// Gets the fetcher with the session ID.
-+ (instancetype)fetcherWithSessionIdentifier:(NSString *)sessionIdentifier {
-  GULNetworkURLSession *session = [self sessionFromFetcherMapForSessionID:sessionIdentifier];
-  if (!session && [sessionIdentifier hasPrefix:kGULNetworkBackgroundSessionConfigIDPrefix]) {
-    session = [[GULNetworkURLSession alloc] initWithNetworkLoggerDelegate:nil];
-    [session setSessionID:sessionIdentifier];
-    [self setSessionInFetcherMap:session forSessionID:sessionIdentifier];
-  }
-  return session;
-}
-
-/// Returns a map of the fetcher by session ID. Creates a map if it is not created.
-/// When reading and writing from/to the session map, don't use this method directly.
-/// To avoid thread safety issues, use one of the helper methods at the bottom of the
-/// file: setSessionInFetcherMap:forSessionID:, sessionFromFetcherMapForSessionID:
-+ (NSMapTable<NSString *, GULNetworkURLSession *> *)sessionIDToFetcherMap {
-  static NSMapTable *sessionIDToFetcherMap;
-
-  static dispatch_once_t sessionMapOnceToken;
-  dispatch_once(&sessionMapOnceToken, ^{
-    sessionIDToFetcherMap = [NSMapTable strongToWeakObjectsMapTable];
-  });
-  return sessionIDToFetcherMap;
-}
-
-+ (NSLock *)sessionIDToFetcherMapReadWriteLock {
-  static NSLock *lock;
-
-  static dispatch_once_t onceToken;
-  dispatch_once(&onceToken, ^{
-    lock = [[NSLock alloc] init];
-  });
-  return lock;
-}
-
-/// Returns a map of system provided completion handler by session ID. Creates a map if it is not
-/// created.
-+ (GULMutableDictionary *)sessionIDToSystemCompletionHandlerDictionary {
-  static GULMutableDictionary *systemCompletionHandlers;
-
-  static dispatch_once_t systemCompletionHandlerOnceToken;
-  dispatch_once(&systemCompletionHandlerOnceToken, ^{
-    systemCompletionHandlers = [[GULMutableDictionary alloc] init];
-  });
-  return systemCompletionHandlers;
-}
-
-- (NSURL *)temporaryFilePathWithSessionID:(NSString *)sessionID {
-  NSString *tempName = [NSString stringWithFormat:@"GULUpload_temp_%@", sessionID];
-  return [_networkDirectoryURL URLByAppendingPathComponent:tempName];
-}
-
-/// Makes sure that the directory to store temp files exists. If not, tries to create it and returns
-/// YES. If there is anything wrong, returns NO.
-- (BOOL)ensureTemporaryDirectoryExists {
-  NSFileManager *fileManager = [NSFileManager defaultManager];
-  NSError *error = nil;
-
-  // Create a temporary directory if it does not exist or was deleted.
-  if ([_networkDirectoryURL checkResourceIsReachableAndReturnError:&error]) {
-    return YES;
-  }
-
-  if (error && error.code != NSFileReadNoSuchFileError) {
-    [_loggerDelegate
-        GULNetwork_logWithLevel:kGULNetworkLogLevelWarning
-                    messageCode:kGULNetworkMessageCodeURLSession014
-                        message:@"Error while trying to access Network temp folder. Error"
-                        context:error];
-  }
-
-  NSError *writeError = nil;
-
-  [fileManager createDirectoryAtURL:_networkDirectoryURL
-        withIntermediateDirectories:YES
-                         attributes:nil
-                              error:&writeError];
-  if (writeError) {
-    [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelError
-                                 messageCode:kGULNetworkMessageCodeURLSession015
-                                     message:@"Cannot create temporary directory. Error"
-                                     context:writeError];
-    return NO;
-  }
-
-  // Set the iCloud exclusion attribute on the Documents URL.
-  [self excludeFromBackupForURL:_networkDirectoryURL];
-
-  return YES;
-}
-
-- (void)excludeFromBackupForURL:(NSURL *)url {
-  if (!url.path) {
-    return;
-  }
-
-  // Set the iCloud exclusion attribute on the Documents URL.
-  NSError *preventBackupError = nil;
-  [url setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:&preventBackupError];
-  if (preventBackupError) {
-    [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelError
-                                 messageCode:kGULNetworkMessageCodeURLSession016
-                                     message:@"Cannot exclude temporary folder from iTunes backup"];
-  }
-}
-
-- (void)URLSession:(NSURLSession *)session
-                          task:(NSURLSessionTask *)task
-    willPerformHTTPRedirection:(NSHTTPURLResponse *)response
-                    newRequest:(NSURLRequest *)request
-             completionHandler:(void (^)(NSURLRequest *))completionHandler API_AVAILABLE(ios(7.0)) {
-  NSArray *nonAllowedRedirectionCodes = @[
-    @(kGULNetworkHTTPStatusCodeFound), @(kGULNetworkHTTPStatusCodeMovedPermanently),
-    @(kGULNetworkHTTPStatusCodeMovedTemporarily), @(kGULNetworkHTTPStatusCodeMultipleChoices)
-  ];
-
-  // Allow those not in the non allowed list to be followed.
-  if (![nonAllowedRedirectionCodes containsObject:@(response.statusCode)]) {
-    completionHandler(request);
-    return;
-  }
-
-  // Do not allow redirection if the response code is in the non-allowed list.
-  NSURLRequest *newRequest = request;
-
-  if (response) {
-    newRequest = nil;
-  }
-
-  completionHandler(newRequest);
-}
-
-#pragma mark - Helper Methods
-
-+ (void)setSessionInFetcherMap:(GULNetworkURLSession *)session forSessionID:(NSString *)sessionID {
-  [[self sessionIDToFetcherMapReadWriteLock] lock];
-  GULNetworkURLSession *existingSession =
-      [[[self class] sessionIDToFetcherMap] objectForKey:sessionID];
-  if (existingSession) {
-    if (session) {
-      NSString *message = [NSString stringWithFormat:@"Discarding session: %@", existingSession];
-      [existingSession->_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelInfo
-                                                    messageCode:kGULNetworkMessageCodeURLSession019
-                                                        message:message];
-    }
-    [existingSession->_URLSession finishTasksAndInvalidate];
-  }
-  if (session) {
-    [[[self class] sessionIDToFetcherMap] setObject:session forKey:sessionID];
-  } else {
-    [[[self class] sessionIDToFetcherMap] removeObjectForKey:sessionID];
-  }
-  [[self sessionIDToFetcherMapReadWriteLock] unlock];
-}
-
-+ (nullable GULNetworkURLSession *)sessionFromFetcherMapForSessionID:(NSString *)sessionID {
-  [[self sessionIDToFetcherMapReadWriteLock] lock];
-  GULNetworkURLSession *session = [[[self class] sessionIDToFetcherMap] objectForKey:sessionID];
-  [[self sessionIDToFetcherMapReadWriteLock] unlock];
-  return session;
-}
-
-- (void)callCompletionHandler:(GULNetworkURLSessionCompletionHandler)handler
-                 withResponse:(NSHTTPURLResponse *)response
-                         data:(NSData *)data
-                        error:(NSError *)error {
-  if (error) {
-    [_loggerDelegate GULNetwork_logWithLevel:kGULNetworkLogLevelError
-                                 messageCode:kGULNetworkMessageCodeURLSession017
-                                     message:@"Encounter network error. Code, error"
-                                    contexts:@[ @(error.code), error ]];
-  }
-
-  if (handler) {
-    dispatch_async(dispatch_get_main_queue(), ^{
-      handler(response, data, self->_sessionID, error);
-    });
-  }
-}
-
-// Always use the request parameters even if the default session configuration is more restrictive.
-- (void)populateSessionConfig:(NSURLSessionConfiguration *)sessionConfig
-                  withRequest:(NSURLRequest *)request API_AVAILABLE(ios(7.0)) {
-  sessionConfig.HTTPAdditionalHeaders = request.allHTTPHeaderFields;
-  sessionConfig.timeoutIntervalForRequest = request.timeoutInterval;
-  sessionConfig.timeoutIntervalForResource = request.timeoutInterval;
-  sessionConfig.requestCachePolicy = request.cachePolicy;
-}
-
-@end

+ 0 - 46
GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h

@@ -1,46 +0,0 @@
-/*
- * Copyright 2017 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-/// A mutable dictionary that provides atomic accessor and mutators.
-@interface GULMutableDictionary : NSObject
-
-/// Returns an object given a key in the dictionary or nil if not found.
-- (id)objectForKey:(id)key;
-
-/// Updates the object given its key or adds it to the dictionary if it is not in the dictionary.
-- (void)setObject:(id)object forKey:(id<NSCopying>)key;
-
-/// Removes the object given its session ID from the dictionary.
-- (void)removeObjectForKey:(id)key;
-
-/// Removes all objects.
-- (void)removeAllObjects;
-
-/// Returns the number of current objects in the dictionary.
-- (NSUInteger)count;
-
-/// Returns an object given a key in the dictionary or nil if not found.
-- (id)objectForKeyedSubscript:(id<NSCopying>)key;
-
-/// Updates the object given its key or adds it to the dictionary if it is not in the dictionary.
-- (void)setObject:(id)obj forKeyedSubscript:(id<NSCopying>)key;
-
-/// Returns the immutable dictionary.
-- (NSDictionary *)dictionary;
-
-@end

+ 0 - 87
GoogleUtilities/Network/Public/GoogleUtilities/GULNetwork.h

@@ -1,87 +0,0 @@
-/*
- * Copyright 2017 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-#import "GULNetworkConstants.h"
-#import "GULNetworkLoggerProtocol.h"
-#import "GULNetworkURLSession.h"
-
-/// Delegate protocol for GULNetwork events.
-@protocol GULNetworkReachabilityDelegate
-
-/// Tells the delegate to handle events when the network reachability changes to connected or not
-/// connected.
-- (void)reachabilityDidChange;
-
-@end
-
-/// The Network component that provides network status and handles network requests and responses.
-/// This is not thread safe.
-///
-/// NOTE:
-/// User must add FIRAnalytics handleEventsForBackgroundURLSessionID:completionHandler to the
-/// AppDelegate application:handleEventsForBackgroundURLSession:completionHandler:
-@interface GULNetwork : NSObject
-
-/// Indicates if network connectivity is available.
-@property(nonatomic, readonly, getter=isNetworkConnected) BOOL networkConnected;
-
-/// Indicates if there are any uploads in progress.
-@property(nonatomic, readonly, getter=hasUploadInProgress) BOOL uploadInProgress;
-
-/// An optional delegate that can be used in the event when network reachability changes.
-@property(nonatomic, weak) id<GULNetworkReachabilityDelegate> reachabilityDelegate;
-
-/// An optional delegate that can be used to log messages, warnings or errors that occur in the
-/// network operations.
-@property(nonatomic, weak) id<GULNetworkLoggerDelegate> loggerDelegate;
-
-/// Indicates whether the logger should display debug messages.
-@property(nonatomic, assign) BOOL isDebugModeEnabled;
-
-/// The time interval in seconds for the network request to timeout.
-@property(nonatomic, assign) NSTimeInterval timeoutInterval;
-
-/// Initializes with the default reachability host.
-- (instancetype)init;
-
-/// Initializes with a custom reachability host.
-- (instancetype)initWithReachabilityHost:(NSString *)reachabilityHost;
-
-/// Handles events when background session with the given ID has finished.
-+ (void)handleEventsForBackgroundURLSessionID:(NSString *)sessionID
-                            completionHandler:(GULNetworkSystemCompletionHandler)completionHandler;
-
-/// Compresses and sends a POST request with the provided data to the URL. The session will be
-/// background session if usingBackgroundSession is YES. Otherwise, the POST session is default
-/// session. Returns a session ID or nil if an error occurs.
-- (NSString *)postURL:(NSURL *)url
-                   payload:(NSData *)payload
-                     queue:(dispatch_queue_t)queue
-    usingBackgroundSession:(BOOL)usingBackgroundSession
-         completionHandler:(GULNetworkCompletionHandler)handler;
-
-/// Sends a GET request with the provided data to the URL. The session will be background session
-/// if usingBackgroundSession is YES. Otherwise, the GET session is default session. Returns a
-/// session ID or nil if an error occurs.
-- (NSString *)getURL:(NSURL *)url
-                   headers:(NSDictionary *)headers
-                     queue:(dispatch_queue_t)queue
-    usingBackgroundSession:(BOOL)usingBackgroundSession
-         completionHandler:(GULNetworkCompletionHandler)handler;
-
-@end

+ 0 - 71
GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkConstants.h

@@ -1,71 +0,0 @@
-/*
- * Copyright 2017 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-/// Error codes in Firebase Network error domain.
-/// Note: these error codes should never change. It would make it harder to decode the errors if
-/// we inadvertently altered any of these codes in a future SDK version.
-typedef NS_ENUM(NSInteger, GULNetworkErrorCode) {
-  /// Unknown error.
-  GULNetworkErrorCodeUnknown = 0,
-  /// Error occurs when the request URL is invalid.
-  GULErrorCodeNetworkInvalidURL = 1,
-  /// Error occurs when request cannot be constructed.
-  GULErrorCodeNetworkRequestCreation = 2,
-  /// Error occurs when payload cannot be compressed.
-  GULErrorCodeNetworkPayloadCompression = 3,
-  /// Error occurs when session task cannot be created.
-  GULErrorCodeNetworkSessionTaskCreation = 4,
-  /// Error occurs when there is no response.
-  GULErrorCodeNetworkInvalidResponse = 5
-};
-
-#pragma mark - Network constants
-
-/// The prefix of the ID of the background session.
-extern NSString *const kGULNetworkBackgroundSessionConfigIDPrefix;
-
-/// The sub directory to store the files of data that is being uploaded in the background.
-extern NSString *const kGULNetworkApplicationSupportSubdirectory;
-
-/// Name of the temporary directory that stores files for background uploading.
-extern NSString *const kGULNetworkTempDirectoryName;
-
-/// The period when the temporary uploading file can stay.
-extern const NSTimeInterval kGULNetworkTempFolderExpireTime;
-
-/// The default network request timeout interval.
-extern const NSTimeInterval kGULNetworkTimeOutInterval;
-
-/// The host to check the reachability of the network.
-extern NSString *const kGULNetworkReachabilityHost;
-
-/// The key to get the error context of the UserInfo.
-extern NSString *const kGULNetworkErrorContext;
-
-#pragma mark - Network Status Code
-
-extern const int kGULNetworkHTTPStatusOK;
-extern const int kGULNetworkHTTPStatusNoContent;
-extern const int kGULNetworkHTTPStatusCodeMultipleChoices;
-extern const int kGULNetworkHTTPStatusCodeMovedPermanently;
-extern const int kGULNetworkHTTPStatusCodeFound;
-extern const int kGULNetworkHTTPStatusCodeNotModified;
-extern const int kGULNetworkHTTPStatusCodeMovedTemporarily;
-extern const int kGULNetworkHTTPStatusCodeNotFound;
-extern const int kGULNetworkHTTPStatusCodeCannotAcceptTraffic;
-extern const int kGULNetworkHTTPStatusCodeUnavailable;

+ 0 - 49
GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkLoggerProtocol.h

@@ -1,49 +0,0 @@
-/*
- * Copyright 2017 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-#import "GULNetworkMessageCode.h"
-
-/// The log levels used by GULNetworkLogger.
-typedef NS_ENUM(NSInteger, GULNetworkLogLevel) {
-  kGULNetworkLogLevelError = 3,
-  kGULNetworkLogLevelWarning = 4,
-  kGULNetworkLogLevelInfo = 6,
-  kGULNetworkLogLevelDebug = 7,
-};
-
-@protocol GULNetworkLoggerDelegate <NSObject>
-
-@required
-/// Tells the delegate to log a message with an array of contexts and the log level.
-- (void)GULNetwork_logWithLevel:(GULNetworkLogLevel)logLevel
-                    messageCode:(GULNetworkMessageCode)messageCode
-                        message:(NSString *)message
-                       contexts:(NSArray *)contexts;
-
-/// Tells the delegate to log a message with a context and the log level.
-- (void)GULNetwork_logWithLevel:(GULNetworkLogLevel)logLevel
-                    messageCode:(GULNetworkMessageCode)messageCode
-                        message:(NSString *)message
-                        context:(id)context;
-
-/// Tells the delegate to log a message with the log level.
-- (void)GULNetwork_logWithLevel:(GULNetworkLogLevel)logLevel
-                    messageCode:(GULNetworkMessageCode)messageCode
-                        message:(NSString *)message;
-
-@end

+ 0 - 47
GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkMessageCode.h

@@ -1,47 +0,0 @@
-/*
- * Copyright 2017 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-// Make sure these codes do not overlap with any contained in the FIRAMessageCode enum.
-typedef NS_ENUM(NSInteger, GULNetworkMessageCode) {
-  // GULNetwork.m
-  kGULNetworkMessageCodeNetwork000 = 900000,  // I-NET900000
-  kGULNetworkMessageCodeNetwork001 = 900001,  // I-NET900001
-  kGULNetworkMessageCodeNetwork002 = 900002,  // I-NET900002
-  kGULNetworkMessageCodeNetwork003 = 900003,  // I-NET900003
-  // GULNetworkURLSession.m
-  kGULNetworkMessageCodeURLSession000 = 901000,  // I-NET901000
-  kGULNetworkMessageCodeURLSession001 = 901001,  // I-NET901001
-  kGULNetworkMessageCodeURLSession002 = 901002,  // I-NET901002
-  kGULNetworkMessageCodeURLSession003 = 901003,  // I-NET901003
-  kGULNetworkMessageCodeURLSession004 = 901004,  // I-NET901004
-  kGULNetworkMessageCodeURLSession005 = 901005,  // I-NET901005
-  kGULNetworkMessageCodeURLSession006 = 901006,  // I-NET901006
-  kGULNetworkMessageCodeURLSession007 = 901007,  // I-NET901007
-  kGULNetworkMessageCodeURLSession008 = 901008,  // I-NET901008
-  kGULNetworkMessageCodeURLSession009 = 901009,  // I-NET901009
-  kGULNetworkMessageCodeURLSession010 = 901010,  // I-NET901010
-  kGULNetworkMessageCodeURLSession011 = 901011,  // I-NET901011
-  kGULNetworkMessageCodeURLSession012 = 901012,  // I-NET901012
-  kGULNetworkMessageCodeURLSession013 = 901013,  // I-NET901013
-  kGULNetworkMessageCodeURLSession014 = 901014,  // I-NET901014
-  kGULNetworkMessageCodeURLSession015 = 901015,  // I-NET901015
-  kGULNetworkMessageCodeURLSession016 = 901016,  // I-NET901016
-  kGULNetworkMessageCodeURLSession017 = 901017,  // I-NET901017
-  kGULNetworkMessageCodeURLSession018 = 901018,  // I-NET901018
-  kGULNetworkMessageCodeURLSession019 = 901019,  // I-NET901019
-};

+ 0 - 62
GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkURLSession.h

@@ -1,62 +0,0 @@
-/*
- * Copyright 2017 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-#import "GULNetworkLoggerProtocol.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-typedef void (^GULNetworkCompletionHandler)(NSHTTPURLResponse *_Nullable response,
-                                            NSData *_Nullable data,
-                                            NSError *_Nullable error);
-typedef void (^GULNetworkURLSessionCompletionHandler)(NSHTTPURLResponse *_Nullable response,
-                                                      NSData *_Nullable data,
-                                                      NSString *sessionID,
-                                                      NSError *_Nullable error);
-typedef void (^GULNetworkSystemCompletionHandler)(void);
-
-/// The protocol that uses NSURLSession for iOS >= 7.0 to handle requests and responses.
-@interface GULNetworkURLSession : NSObject
-
-/// Indicates whether the background network is enabled. Default value is NO.
-@property(nonatomic, getter=isBackgroundNetworkEnabled) BOOL backgroundNetworkEnabled;
-
-/// The logger delegate to log message, errors or warnings that occur during the network operations.
-@property(nonatomic, weak, nullable) id<GULNetworkLoggerDelegate> loggerDelegate;
-
-/// Calls the system provided completion handler after the background session is finished.
-+ (void)handleEventsForBackgroundURLSessionID:(NSString *)sessionID
-                            completionHandler:(GULNetworkSystemCompletionHandler)completionHandler;
-
-/// Initializes with logger delegate.
-- (instancetype)initWithNetworkLoggerDelegate:
-    (nullable id<GULNetworkLoggerDelegate>)networkLoggerDelegate NS_DESIGNATED_INITIALIZER;
-
-- (instancetype)init NS_UNAVAILABLE;
-
-/// Sends an asynchronous POST request and calls the provided completion handler when the request
-/// completes or when errors occur, and returns an ID of the session/connection.
-- (nullable NSString *)sessionIDFromAsyncPOSTRequest:(NSURLRequest *)request
-                                   completionHandler:(GULNetworkURLSessionCompletionHandler)handler;
-
-/// Sends an asynchronous GET request and calls the provided completion handler when the request
-/// completes or when errors occur, and returns an ID of the session.
-- (nullable NSString *)sessionIDFromAsyncGETRequest:(NSURLRequest *)request
-                                  completionHandler:(GULNetworkURLSessionCompletionHandler)handler;
-
-NS_ASSUME_NONNULL_END
-@end

+ 0 - 39
GoogleUtilities/README.md

@@ -1,39 +0,0 @@
-# Google Utilities
-
-## Overview
-
-The GoogleUtilities pod is a set of utilities organized into CocoaPods subspecs.
-See the [podspec](../GoogleUtilities.podspec) for a summary of what utilities
-are currently included. They're used by Firebase and other Google products.
-
-Direct usage by non-Google products and CocoaPods is **NOT** currently
-recommended or supported in general.
-
-**However**, we do specifically recommend that non-Google SDKs can use the App Delegate Swizzler to hook into app delegate methods as this reduces conflicts with multiple SDKs trying to do the same.
-
-Instructions on how to adopt the app delegate swizzler for use by your SDK are available [here](./AppDelegateSwizzler/README.md).
-
-## Development
-
-Follow the subsequent instructions to develop, debug, unit test, and
-integration test FirebaseFunctions:
-
-### Prereqs
-
-- At least CocoaPods 1.7.0
-
-### To Develop
-
-- Run `pod gen GoogleUtilities.podspec`
-- `open gen/GoogleUtilities/GoogleUtilities.xcworkspace`
-
-OR these two commands can be combined with
-
-- `pod gen GoogleUtilities.podspec --auto-open --gen-directory="gen" --clean`
-
-You're now in an Xcode workspace generate for building, debugging and
-testing the GoogleUtilities CocoaPod.
-
-### Running Unit Tests
-
-Choose the one of the Tests* schemes and press Command-u.

+ 0 - 48
GoogleUtilities/Reachability/GULReachabilityChecker+Internal.h

@@ -1,48 +0,0 @@
-/*
- * Copyright 2017 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import "GoogleUtilities/Reachability/Public/GoogleUtilities/GULReachabilityChecker.h"
-
-#if !TARGET_OS_WATCH
-typedef SCNetworkReachabilityRef (*GULReachabilityCreateWithNameFn)(CFAllocatorRef allocator,
-                                                                    const char *host);
-
-typedef Boolean (*GULReachabilitySetCallbackFn)(SCNetworkReachabilityRef target,
-                                                SCNetworkReachabilityCallBack callback,
-                                                SCNetworkReachabilityContext *context);
-typedef Boolean (*GULReachabilityScheduleWithRunLoopFn)(SCNetworkReachabilityRef target,
-                                                        CFRunLoopRef runLoop,
-                                                        CFStringRef runLoopMode);
-typedef Boolean (*GULReachabilityUnscheduleFromRunLoopFn)(SCNetworkReachabilityRef target,
-                                                          CFRunLoopRef runLoop,
-                                                          CFStringRef runLoopMode);
-
-typedef void (*GULReachabilityReleaseFn)(CFTypeRef cf);
-
-struct GULReachabilityApi {
-  GULReachabilityCreateWithNameFn createWithNameFn;
-  GULReachabilitySetCallbackFn setCallbackFn;
-  GULReachabilityScheduleWithRunLoopFn scheduleWithRunLoopFn;
-  GULReachabilityUnscheduleFromRunLoopFn unscheduleFromRunLoopFn;
-  GULReachabilityReleaseFn releaseFn;
-};
-#endif
-@interface GULReachabilityChecker (Internal)
-
-- (const struct GULReachabilityApi *)reachabilityApi;
-- (void)setReachabilityApi:(const struct GULReachabilityApi *)reachabilityApi;
-
-@end

+ 0 - 263
GoogleUtilities/Reachability/GULReachabilityChecker.m

@@ -1,263 +0,0 @@
-// Copyright 2017 Google
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import <Foundation/Foundation.h>
-
-#import "GoogleUtilities/Reachability/Public/GoogleUtilities/GULReachabilityChecker.h"
-
-#import "GoogleUtilities/Reachability/GULReachabilityChecker+Internal.h"
-#import "GoogleUtilities/Reachability/GULReachabilityMessageCode.h"
-
-#import "GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h"
-
-static GULLoggerService kGULLoggerReachability = @"[GULReachability]";
-#if !TARGET_OS_WATCH
-static void ReachabilityCallback(SCNetworkReachabilityRef reachability,
-                                 SCNetworkReachabilityFlags flags,
-                                 void *info);
-
-static const struct GULReachabilityApi kGULDefaultReachabilityApi = {
-    SCNetworkReachabilityCreateWithName,
-    SCNetworkReachabilitySetCallback,
-    SCNetworkReachabilityScheduleWithRunLoop,
-    SCNetworkReachabilityUnscheduleFromRunLoop,
-    CFRelease,
-};
-
-static NSString *const kGULReachabilityUnknownStatus = @"Unknown";
-static NSString *const kGULReachabilityConnectedStatus = @"Connected";
-static NSString *const kGULReachabilityDisconnectedStatus = @"Disconnected";
-#endif
-@interface GULReachabilityChecker ()
-
-@property(nonatomic, assign) const struct GULReachabilityApi *reachabilityApi;
-@property(nonatomic, assign) GULReachabilityStatus reachabilityStatus;
-@property(nonatomic, copy) NSString *host;
-#if !TARGET_OS_WATCH
-@property(nonatomic, assign) SCNetworkReachabilityRef reachability;
-#endif
-
-@end
-
-@implementation GULReachabilityChecker
-
-@synthesize reachabilityApi = reachabilityApi_;
-#if !TARGET_OS_WATCH
-@synthesize reachability = reachability_;
-#endif
-
-- (const struct GULReachabilityApi *)reachabilityApi {
-  return reachabilityApi_;
-}
-
-- (void)setReachabilityApi:(const struct GULReachabilityApi *)reachabilityApi {
-#if !TARGET_OS_WATCH
-  if (reachability_) {
-    GULLogError(kGULLoggerReachability, NO,
-                [NSString stringWithFormat:@"I-REA%06ld", (long)kGULReachabilityMessageCode000],
-                @"Cannot change reachability API while reachability is running. "
-                @"Call stop first.");
-    return;
-  }
-  reachabilityApi_ = reachabilityApi;
-#endif
-}
-
-@synthesize reachabilityStatus = reachabilityStatus_;
-@synthesize host = host_;
-@synthesize reachabilityDelegate = reachabilityDelegate_;
-
-- (BOOL)isActive {
-#if !TARGET_OS_WATCH
-  return reachability_ != nil;
-#else
-  return NO;
-#endif
-}
-
-- (void)setReachabilityDelegate:(id<GULReachabilityDelegate>)reachabilityDelegate {
-  if (reachabilityDelegate &&
-      (![(NSObject *)reachabilityDelegate conformsToProtocol:@protocol(GULReachabilityDelegate)])) {
-    GULLogError(kGULLoggerReachability, NO,
-                [NSString stringWithFormat:@"I-NET%06ld", (long)kGULReachabilityMessageCode005],
-                @"Reachability delegate doesn't conform to Reachability protocol.");
-    return;
-  }
-  reachabilityDelegate_ = reachabilityDelegate;
-}
-
-- (instancetype)initWithReachabilityDelegate:(id<GULReachabilityDelegate>)reachabilityDelegate
-                                    withHost:(NSString *)host {
-  self = [super init];
-
-  if (!host || !host.length) {
-    GULLogError(kGULLoggerReachability, NO,
-                [NSString stringWithFormat:@"I-REA%06ld", (long)kGULReachabilityMessageCode001],
-                @"Invalid host specified");
-    return nil;
-  }
-  if (self) {
-#if !TARGET_OS_WATCH
-    [self setReachabilityDelegate:reachabilityDelegate];
-    reachabilityApi_ = &kGULDefaultReachabilityApi;
-    reachabilityStatus_ = kGULReachabilityUnknown;
-    host_ = [host copy];
-    reachability_ = nil;
-#endif
-  }
-  return self;
-}
-
-- (void)dealloc {
-  reachabilityDelegate_ = nil;
-  [self stop];
-}
-
-- (BOOL)start {
-#if TARGET_OS_WATCH
-  return NO;
-#else
-
-  if (!reachability_) {
-    reachability_ = reachabilityApi_->createWithNameFn(kCFAllocatorDefault, [host_ UTF8String]);
-    if (!reachability_) {
-      return NO;
-    }
-    SCNetworkReachabilityContext context = {
-        0,                       /* version */
-        (__bridge void *)(self), /* info (passed as last parameter to reachability callback) */
-        NULL,                    /* retain */
-        NULL,                    /* release */
-        NULL                     /* copyDescription */
-    };
-    if (!reachabilityApi_->setCallbackFn(reachability_, ReachabilityCallback, &context) ||
-        !reachabilityApi_->scheduleWithRunLoopFn(reachability_, CFRunLoopGetMain(),
-                                                 kCFRunLoopCommonModes)) {
-      reachabilityApi_->releaseFn(reachability_);
-      reachability_ = nil;
-
-      GULLogError(kGULLoggerReachability, NO,
-                  [NSString stringWithFormat:@"I-REA%06ld", (long)kGULReachabilityMessageCode002],
-                  @"Failed to start reachability handle");
-      return NO;
-    }
-  }
-  GULLogDebug(kGULLoggerReachability, NO,
-              [NSString stringWithFormat:@"I-REA%06ld", (long)kGULReachabilityMessageCode003],
-              @"Monitoring the network status");
-  return YES;
-#endif
-}
-
-- (void)stop {
-#if !TARGET_OS_WATCH
-  if (reachability_) {
-    reachabilityStatus_ = kGULReachabilityUnknown;
-    reachabilityApi_->unscheduleFromRunLoopFn(reachability_, CFRunLoopGetMain(),
-                                              kCFRunLoopCommonModes);
-    reachabilityApi_->releaseFn(reachability_);
-    reachability_ = nil;
-  }
-#endif
-}
-
-#if !TARGET_OS_WATCH
-- (GULReachabilityStatus)statusForFlags:(SCNetworkReachabilityFlags)flags {
-  GULReachabilityStatus status = kGULReachabilityNotReachable;
-  // If the Reachable flag is not set, we definitely don't have connectivity.
-  if (flags & kSCNetworkReachabilityFlagsReachable) {
-    // Reachable flag is set. Check further flags.
-    if (!(flags & kSCNetworkReachabilityFlagsConnectionRequired)) {
-// Connection required flag is not set, so we have connectivity.
-#if TARGET_OS_IOS || TARGET_OS_TV
-      status = (flags & kSCNetworkReachabilityFlagsIsWWAN) ? kGULReachabilityViaCellular
-                                                           : kGULReachabilityViaWifi;
-#elif TARGET_OS_OSX
-      status = kGULReachabilityViaWifi;
-#endif
-    } else if ((flags & (kSCNetworkReachabilityFlagsConnectionOnDemand |
-                         kSCNetworkReachabilityFlagsConnectionOnTraffic)) &&
-               !(flags & kSCNetworkReachabilityFlagsInterventionRequired)) {
-// If the connection on demand or connection on traffic flag is set, and user intervention
-// is not required, we have connectivity.
-#if TARGET_OS_IOS || TARGET_OS_TV
-      status = (flags & kSCNetworkReachabilityFlagsIsWWAN) ? kGULReachabilityViaCellular
-                                                           : kGULReachabilityViaWifi;
-#elif TARGET_OS_OSX
-      status = kGULReachabilityViaWifi;
-#endif
-    }
-  }
-  return status;
-}
-
-- (void)reachabilityFlagsChanged:(SCNetworkReachabilityFlags)flags {
-  GULReachabilityStatus status = [self statusForFlags:flags];
-  if (reachabilityStatus_ != status) {
-    NSString *reachabilityStatusString;
-    if (status == kGULReachabilityUnknown) {
-      reachabilityStatusString = kGULReachabilityUnknownStatus;
-    } else {
-      reachabilityStatusString = (status == kGULReachabilityNotReachable)
-                                     ? kGULReachabilityDisconnectedStatus
-                                     : kGULReachabilityConnectedStatus;
-    }
-
-    GULLogDebug(kGULLoggerReachability, NO,
-                [NSString stringWithFormat:@"I-REA%06ld", (long)kGULReachabilityMessageCode004],
-                @"Network status has changed. Code:%@, status:%@", @(status),
-                reachabilityStatusString);
-    reachabilityStatus_ = status;
-    [reachabilityDelegate_ reachability:self statusChanged:reachabilityStatus_];
-  }
-}
-
-#endif
-@end
-
-#if !TARGET_OS_WATCH
-static void ReachabilityCallback(SCNetworkReachabilityRef reachability,
-                                 SCNetworkReachabilityFlags flags,
-                                 void *info) {
-  GULReachabilityChecker *checker = (__bridge GULReachabilityChecker *)info;
-  [checker reachabilityFlagsChanged:flags];
-}
-#endif
-
-// This function used to be at the top of the file, but it was moved here
-// as a workaround for a suspected compiler bug. When compiled in Release mode
-// and run on an iOS device with WiFi disabled, the reachability code crashed
-// when calling SCNetworkReachabilityScheduleWithRunLoop, or shortly thereafter.
-// After unsuccessfully trying to diagnose the cause of the crash, it was
-// discovered that moving this function to the end of the file magically fixed
-// the crash. If you are going to edit this file, exercise caution and make sure
-// to test thoroughly with an iOS device under various network conditions.
-const NSString *GULReachabilityStatusString(GULReachabilityStatus status) {
-  switch (status) {
-    case kGULReachabilityUnknown:
-      return @"Reachability Unknown";
-
-    case kGULReachabilityNotReachable:
-      return @"Not reachable";
-
-    case kGULReachabilityViaWifi:
-      return @"Reachable via Wifi";
-
-    case kGULReachabilityViaCellular:
-      return @"Reachable via Cellular Data";
-
-    default:
-      return [NSString stringWithFormat:@"Invalid reachability status %d", (int)status];
-  }
-}

+ 0 - 29
GoogleUtilities/Reachability/GULReachabilityMessageCode.h

@@ -1,29 +0,0 @@
-/*
- * Copyright 2017 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-// Make sure these codes do not overlap with any contained in the FIRAMessageCode enum.
-typedef NS_ENUM(NSInteger, GULReachabilityMessageCode) {
-  // GULReachabilityChecker.m
-  kGULReachabilityMessageCode000 = 902000,  // I-NET902000
-  kGULReachabilityMessageCode001 = 902001,  // I-NET902001
-  kGULReachabilityMessageCode002 = 902002,  // I-NET902002
-  kGULReachabilityMessageCode003 = 902003,  // I-NET902003
-  kGULReachabilityMessageCode004 = 902004,  // I-NET902004
-  kGULReachabilityMessageCode005 = 902005,  // I-NET902005
-  kGULReachabilityMessageCode006 = 902006,  // I-NET902006
-};

+ 0 - 79
GoogleUtilities/Reachability/Public/GoogleUtilities/GULReachabilityChecker.h

@@ -1,79 +0,0 @@
-/*
- * Copyright 2017 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-#if !TARGET_OS_WATCH
-#import <SystemConfiguration/SystemConfiguration.h>
-#endif
-
-/// Reachability Status
-typedef enum {
-  kGULReachabilityUnknown,  ///< Have not yet checked or been notified whether host is reachable.
-  kGULReachabilityNotReachable,  ///< Host is not reachable.
-  kGULReachabilityViaWifi,       ///< Host is reachable via Wifi.
-  kGULReachabilityViaCellular,   ///< Host is reachable via cellular.
-} GULReachabilityStatus;
-
-const NSString *GULReachabilityStatusString(GULReachabilityStatus status);
-
-@class GULReachabilityChecker;
-
-/// Google Analytics iOS Reachability Checker.
-@protocol GULReachabilityDelegate
-@required
-/// Called when network status has changed.
-- (void)reachability:(GULReachabilityChecker *)reachability
-       statusChanged:(GULReachabilityStatus)status;
-@end
-
-/// Google Analytics iOS Network Status Checker.
-@interface GULReachabilityChecker : NSObject
-
-/// The last known reachability status, or GULReachabilityStatusUnknown if the
-/// checker is not active.
-@property(nonatomic, readonly) GULReachabilityStatus reachabilityStatus;
-/// The host to which reachability status is to be checked.
-@property(nonatomic, copy, readonly) NSString *host;
-/// The delegate to be notified of reachability status changes.
-@property(nonatomic, weak) id<GULReachabilityDelegate> reachabilityDelegate;
-/// `YES` if the reachability checker is active, `NO` otherwise.
-@property(nonatomic, readonly) BOOL isActive;
-
-/// Initialize the reachability checker. Note that you must call start to begin checking for and
-/// receiving notifications about network status changes.
-///
-/// @param reachabilityDelegate The delegate to be notified when reachability status to host
-/// changes.
-///
-/// @param host The name of the host.
-///
-- (instancetype)initWithReachabilityDelegate:(id<GULReachabilityDelegate>)reachabilityDelegate
-                                    withHost:(NSString *)host;
-
-- (instancetype)init NS_UNAVAILABLE;
-
-/// Start checking for reachability to the specified host. This has no effect if the status
-/// checker is already checking for connectivity.
-///
-/// @return `YES` if initiating status checking was successful or the status checking has already
-/// been initiated, `NO` otherwise.
-- (BOOL)start;
-
-/// Stop checking for reachability to the specified host. This has no effect if the status
-/// checker is not checking for connectivity.
-- (void)stop;
-
-@end

+ 0 - 24
GoogleUtilities/SwizzlerTestHelpers/GULProxy.h

@@ -1,24 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-/** An example NSProxy that could be used to wrap an object that we have to ISA Swizzle. */
-@interface GULProxy : NSProxy
-
-+ (instancetype)proxyWithDelegate:(id)delegate;
-
-@end

+ 0 - 95
GoogleUtilities/SwizzlerTestHelpers/GULProxy.m

@@ -1,95 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import "GoogleUtilities/SwizzlerTestHelpers/GULProxy.h"
-
-@interface GULProxy ()
-
-@property(nonatomic, strong) id delegateObject;
-
-@end
-
-@implementation GULProxy
-
-- (instancetype)initWithDelegate:(id)delegate {
-  _delegateObject = delegate;
-  return self;
-}
-
-+ (instancetype)proxyWithDelegate:(id)delegate {
-  return [[GULProxy alloc] initWithDelegate:delegate];
-}
-
-- (id)forwardingTargetForSelector:(SEL)selector {
-  return _delegateObject;
-}
-
-- (void)forwardInvocation:(NSInvocation *)invocation {
-  if (_delegateObject != nil) {
-    [invocation setTarget:_delegateObject];
-    [invocation invoke];
-  }
-}
-
-- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
-  return [_delegateObject instanceMethodSignatureForSelector:selector];
-}
-
-- (BOOL)respondsToSelector:(SEL)aSelector {
-  return [_delegateObject respondsToSelector:aSelector];
-}
-
-- (BOOL)isEqual:(id)object {
-  return [_delegateObject isEqual:object];
-}
-
-- (NSUInteger)hash {
-  return [_delegateObject hash];
-}
-
-- (Class)superclass {
-  return [_delegateObject superclass];
-}
-
-- (Class)class {
-  return [_delegateObject class];
-}
-
-- (BOOL)isKindOfClass:(Class)aClass {
-  return [_delegateObject isKindOfClass:aClass];
-}
-
-- (BOOL)isMemberOfClass:(Class)aClass {
-  return [_delegateObject isMemberOfClass:aClass];
-}
-
-- (BOOL)conformsToProtocol:(Protocol *)aProtocol {
-  return [_delegateObject conformsToProtocol:aProtocol];
-}
-
-- (BOOL)isProxy {
-  return YES;
-}
-
-- (NSString *)description {
-  return [_delegateObject description];
-}
-
-- (NSString *)debugDescription {
-  return [_delegateObject debugDescription];
-}
-
-@end

+ 0 - 44
GoogleUtilities/SwizzlerTestHelpers/GULRuntimeClassDiff.h

@@ -1,44 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-/** A simple container class for representing the diff of a class. */
-@interface GULRuntimeClassDiff : NSObject
-
-/** The class this diff is with respect to. */
-@property(nonatomic, nullable, weak) Class aClass;
-
-/** The added class properties (as opposed to instance properties). */
-@property(nonatomic) NSSet<NSString *> *addedClassProperties;
-
-/** The added instance properties. */
-@property(nonatomic) NSSet<NSString *> *addedInstanceProperties;
-
-/** The added class selectors. */
-@property(nonatomic) NSSet<NSString *> *addedClassSelectors;
-
-/** The added instance selectors. */
-@property(nonatomic) NSSet<NSString *> *addedInstanceSelectors;
-
-/** The modified imps. */
-@property(nonatomic) NSSet<NSString *> *modifiedImps;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 82
GoogleUtilities/SwizzlerTestHelpers/GULRuntimeClassDiff.m

@@ -1,82 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import "GoogleUtilities/SwizzlerTestHelpers/GULRuntimeClassDiff.h"
-
-/** Computes the equality of possibly nil or empty NSSets.
- *
- *  @param firstSet The first set of strings.
- *  @param secondSet The second set of strings.
- *  @return YES if both sets are zero length or nil, or the result of `isEqualToSet:`.
- */
-FOUNDATION_STATIC_INLINE
-BOOL IsEqual(NSSet *firstSet, NSSet *secondSet) {
-  return ((!firstSet || firstSet.count == 0) && (!secondSet || secondSet.count == 0)) ||
-         [firstSet isEqualToSet:secondSet];
-}
-
-@implementation GULRuntimeClassDiff
-
-- (NSUInteger)hash {
-  return [_aClass hash] ^ [_addedClassProperties hash] ^ [_addedInstanceProperties hash] ^
-         [_addedClassSelectors hash] ^ [_addedInstanceSelectors hash] ^ [_modifiedImps hash];
-}
-
-- (BOOL)isEqual:(id)object {
-  GULRuntimeClassDiff *otherObject = (GULRuntimeClassDiff *)object;
-  return _aClass == otherObject->_aClass &&
-         IsEqual(_addedClassProperties, otherObject->_addedClassProperties) &&
-         IsEqual(_addedInstanceProperties, otherObject->_addedInstanceProperties) &&
-         IsEqual(_addedClassSelectors, otherObject->_addedClassSelectors) &&
-         IsEqual(_addedInstanceSelectors, otherObject->_addedInstanceSelectors) &&
-         IsEqual(_modifiedImps, otherObject->_modifiedImps);
-}
-
-- (NSString *)description {
-  NSMutableString *description = [[NSMutableString alloc] init];
-  [description appendFormat:@"%@:\n", NSStringFromClass(self.aClass)];
-  if (_addedClassProperties.count) {
-    [description appendString:@"\tAdded class properties:\n"];
-    for (NSString *addedClassProperty in _addedClassProperties) {
-      [description appendFormat:@"\t\t%@\n", addedClassProperty];
-    }
-  }
-  if (_addedInstanceProperties.count) {
-    [description appendString:@"\tAdded instance properties:\n"];
-    for (NSString *addedInstanceProperty in _addedInstanceProperties) {
-      [description appendFormat:@"\t\t%@\n", addedInstanceProperty];
-    }
-  }
-  if (_addedClassSelectors.count) {
-    [description appendString:@"\tAdded class selectors:\n"];
-    for (NSString *addedClassSelector in _addedClassSelectors) {
-      [description appendFormat:@"\t\t%@\n", addedClassSelector];
-    }
-  }
-  if (_addedInstanceSelectors.count) {
-    [description appendString:@"\tAdded instance selectors:\n"];
-    for (NSString *addedInstanceSelector in _addedInstanceSelectors) {
-      [description appendFormat:@"\t\t%@\n", addedInstanceSelector];
-    }
-  }
-  if (_modifiedImps.count) {
-    [description appendString:@"\tModified IMPs:\n"];
-    for (NSString *modifiedImp in _modifiedImps) {
-      [description appendFormat:@"\t\t%@\n", modifiedImp];
-    }
-  }
-  return description;
-}
-
-@end

+ 0 - 48
GoogleUtilities/SwizzlerTestHelpers/GULRuntimeClassSnapshot.h

@@ -1,48 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-@class GULRuntimeClassDiff;
-
-NS_ASSUME_NONNULL_BEGIN
-
-/** This class is able to capture the runtime state of a given class. */
-@interface GULRuntimeClassSnapshot : NSObject
-
-- (instancetype)init NS_UNAVAILABLE;
-
-/** Instantiates an instance of this class with the given class.
- *
- *  @param aClass The class that will be snapshot.
- *  @return An instance of this class.
- */
-- (instancetype)initWithClass:(Class)aClass NS_DESIGNATED_INITIALIZER;
-
-/** Captures the runtime state of this class. */
-- (void)capture;
-
-/** Calculates the diff between snapshots and returns a diff object populated with information.
- *
- *  @param otherClassSnapshot The other snapshot to compare it to. It's assumed that the
- *      otherClassSnapshot was created after the caller.
- *  @return A diff object representing the diff between the two snapshots.
- */
-- (GULRuntimeClassDiff *)diff:(GULRuntimeClassSnapshot *)otherClassSnapshot;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 211
GoogleUtilities/SwizzlerTestHelpers/GULRuntimeClassSnapshot.m

@@ -1,211 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import "GoogleUtilities/SwizzlerTestHelpers/GULRuntimeClassSnapshot.h"
-
-#import <objc/runtime.h>
-
-#import "GoogleUtilities/SwizzlerTestHelpers/GULRuntimeClassDiff.h"
-
-@implementation GULRuntimeClassSnapshot {
-  /** The class this snapshot is related to. */
-  Class _aClass;
-
-  /** The metaclass of aClass. */
-  Class _metaclass;
-
-  /** The current set of class properties on aClass. */
-  NSMutableSet<NSString *> *_classProperties;
-
-  /** The current set of instance properties on aClass. */
-  NSMutableSet<NSString *> *_instanceProperties;
-
-  /** The current set of class selectors on aClass. */
-  NSMutableSet<NSString *> *_classSelectors;
-
-  /** The current set of instance selectors on aClass. */
-  NSMutableSet<NSString *> *_instanceSelectors;
-
-  /** The current set of class and instance selector IMPs on aClass. */
-  NSMutableSet<NSString *> *_imps;
-
-  /** The current hash of this object, updated as the state of this instance changes. */
-  NSUInteger _runningHash;
-}
-
-- (instancetype)init {
-  NSAssert(NO, @"Please use the designated initializer.");
-  return nil;
-}
-
-- (instancetype)initWithClass:(Class)aClass {
-  self = [super init];
-  if (self) {
-    _aClass = aClass;
-    _metaclass = object_getClass(aClass);
-    _classProperties = [[NSMutableSet alloc] init];
-    _instanceProperties = [[NSMutableSet alloc] init];
-    _instanceSelectors = [[NSMutableSet alloc] init];
-    _classSelectors = [[NSMutableSet alloc] init];
-    _imps = [[NSMutableSet alloc] init];
-    _runningHash = [NSStringFromClass(_aClass) hash] ^ [NSStringFromClass(_metaclass) hash];
-  }
-  return self;
-}
-
-- (void)capture {
-  [self captureProperties];
-  [self captureSelectorsAndImps];
-}
-
-- (GULRuntimeClassDiff *)diff:(GULRuntimeClassSnapshot *)otherClassSnapshot {
-  GULRuntimeClassDiff *classDiff = [[GULRuntimeClassDiff alloc] init];
-  if (_runningHash != [otherClassSnapshot hash]) {
-    classDiff.aClass = _aClass;
-    [self computeDiffOfProperties:otherClassSnapshot withClassDiff:classDiff];
-    [self computeDiffOfSelectorsAndImps:otherClassSnapshot withClassDiff:classDiff];
-  }
-  return classDiff;
-}
-
-- (NSUInteger)hash {
-  return _runningHash;
-}
-
-- (BOOL)isEqual:(id)object {
-  return self->_runningHash == ((GULRuntimeClassSnapshot *)object)->_runningHash;
-}
-
-- (NSString *)description {
-  return [NSString stringWithFormat:@"<%@> Hash: 0x%lX", _aClass, (unsigned long)[self hash]];
-}
-
-#pragma mark - Private methods below -
-
-#pragma mark State capturing methods
-
-/** Captures class and instance properties and saves state in ivars. */
-- (void)captureProperties {
-  // Capture instance properties.
-  unsigned int outCount;
-  objc_property_t *instanceProperties = class_copyPropertyList(_aClass, &outCount);
-  for (int i = 0; i < outCount; i++) {
-    objc_property_t property = instanceProperties[i];
-    NSString *propertyString = [NSString stringWithUTF8String:property_getName(property)];
-    [_instanceProperties addObject:propertyString];
-    _runningHash ^= [propertyString hash];
-  }
-  free(instanceProperties);
-
-  // Capture class properties.
-  outCount = 0;
-  objc_property_t *classProperties = class_copyPropertyList(_metaclass, &outCount);
-  for (int i = 0; i < outCount; i++) {
-    objc_property_t property = classProperties[i];
-    NSString *propertyString = [NSString stringWithUTF8String:property_getName(property)];
-    [_classProperties addObject:propertyString];
-    _runningHash ^= [propertyString hash];
-  }
-  free(classProperties);
-}
-
-/** Captures the class and instance selectors and their IMPs and saves their state in ivars. */
-- (void)captureSelectorsAndImps {
-  // Capture instance methods and their IMPs.
-  unsigned int outCount;
-  Method *instanceMethods = class_copyMethodList(_aClass, &outCount);
-  for (int i = 0; i < outCount; i++) {
-    Method method = instanceMethods[i];
-    NSString *methodString = NSStringFromSelector(method_getName(method));
-    [_instanceSelectors addObject:methodString];
-    IMP imp = method_getImplementation(method);
-    NSString *impString =
-        [NSString stringWithFormat:@"%p -[%@ %@]", imp, NSStringFromClass(_aClass), methodString];
-    if (![_imps containsObject:impString]) {
-      [_imps addObject:impString];
-    }
-    _runningHash ^= [impString hash];
-  }
-  free(instanceMethods);
-
-  // Capture class methods and their IMPs.
-  outCount = 0;
-  Method *classMethods = class_copyMethodList(_metaclass, &outCount);
-  for (int i = 0; i < outCount; i++) {
-    Method method = classMethods[i];
-    NSString *methodString = NSStringFromSelector(method_getName(method));
-    [_classSelectors addObject:methodString];
-    IMP imp = method_getImplementation(method);
-    NSString *impString = [NSString
-        stringWithFormat:@"%p +[%@ %@]", imp, NSStringFromClass(_metaclass), methodString];
-    NSAssert(![_imps containsObject:impString],
-             @"This IMP/method combination has already been captured: %@:%@",
-             NSStringFromClass(_aClass), impString);
-    [_imps addObject:impString];
-    _runningHash ^= [impString hash];
-  }
-  free(classMethods);
-}
-
-#pragma mark Diff computation methods
-
-/** Compute the diff of class and instance properties and populates the classDiff with that info.
- *
- *  @param otherClassSnapshot The other class snapshot to diff against.
- *  @param classDiff The diff object to modify.
- */
-- (void)computeDiffOfProperties:(GULRuntimeClassSnapshot *)otherClassSnapshot
-                  withClassDiff:(GULRuntimeClassDiff *)classDiff {
-  if ([_classProperties hash] != [otherClassSnapshot->_classProperties hash]) {
-    classDiff.addedClassProperties = [otherClassSnapshot->_classProperties
-        objectsPassingTest:^BOOL(NSString *_Nonnull obj, BOOL *_Nonnull stop) {
-          return ![self->_classProperties containsObject:obj];
-        }];
-  }
-  if ([_instanceProperties hash] != [otherClassSnapshot->_instanceProperties hash]) {
-    classDiff.addedInstanceProperties = [otherClassSnapshot->_instanceProperties
-        objectsPassingTest:^BOOL(NSString *_Nonnull obj, BOOL *_Nonnull stop) {
-          return ![self->_instanceProperties containsObject:obj];
-        }];
-  }
-}
-
-/** Computes the diff of class and instance selectors and their IMPs and populates the classDiff.
- *
- *  @param otherClassSnapshot The other class snapshot to diff against.
- *  @param classDiff The diff object to modify.
- */
-- (void)computeDiffOfSelectorsAndImps:(GULRuntimeClassSnapshot *)otherClassSnapshot
-                        withClassDiff:(GULRuntimeClassDiff *)classDiff {
-  if ([_classSelectors hash] != [otherClassSnapshot->_classSelectors hash]) {
-    classDiff.addedClassSelectors = [otherClassSnapshot->_classSelectors
-        objectsPassingTest:^BOOL(NSString *_Nonnull obj, BOOL *_Nonnull stop) {
-          return ![self->_classSelectors containsObject:obj];
-        }];
-  }
-  if ([_instanceSelectors hash] != [otherClassSnapshot->_instanceSelectors hash]) {
-    classDiff.addedInstanceSelectors = [otherClassSnapshot->_instanceSelectors
-        objectsPassingTest:^BOOL(NSString *_Nonnull obj, BOOL *_Nonnull stop) {
-          return ![self->_instanceSelectors containsObject:obj];
-        }];
-  }
-
-  // modifiedImps contains the prior IMP address, not the current IMP address.
-  classDiff.modifiedImps =
-      [_imps objectsPassingTest:^BOOL(NSString *_Nonnull obj, BOOL *_Nonnull stop) {
-        return ![otherClassSnapshot->_imps containsObject:obj];
-      }];
-}
-
-@end

+ 0 - 37
GoogleUtilities/SwizzlerTestHelpers/GULRuntimeDiff.h

@@ -1,37 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-@class GULRuntimeClassDiff;
-
-NS_ASSUME_NONNULL_BEGIN
-
-/** A simple container class for storing the diff of some runtime state. */
-@interface GULRuntimeDiff : NSObject
-
-/** The added classes. */
-@property(nonatomic) NSSet<NSString *> *addedClasses;
-
-/** The removed classes. */
-@property(nonatomic) NSSet<NSString *> *removedClasses;
-
-/** The diff objects for modified classes. */
-@property(nonatomic) NSSet<GULRuntimeClassDiff *> *classDiffs;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 69
GoogleUtilities/SwizzlerTestHelpers/GULRuntimeDiff.m

@@ -1,69 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import "GoogleUtilities/SwizzlerTestHelpers/GULRuntimeDiff.h"
-
-#import "GoogleUtilities/SwizzlerTestHelpers/GULRuntimeClassDiff.h"
-
-/** Computes the equality of possibly nil or empty NSSets.
- *
- *  @param firstSet The first set of strings.
- *  @param secondSet The second set of strings.
- *  @return YES if both sets are zero length or nil, or the result of `isEqualToSet:`.
- */
-FOUNDATION_STATIC_INLINE
-BOOL IsEqual(NSSet *firstSet, NSSet *secondSet) {
-  return ((!firstSet || firstSet.count == 0) && (!secondSet || secondSet.count == 0)) ||
-         [firstSet isEqualToSet:secondSet];
-}
-
-@implementation GULRuntimeDiff
-
-- (NSUInteger)hash {
-  return [_addedClasses hash] ^ [_removedClasses hash] ^ [_classDiffs hash];
-}
-
-- (BOOL)isEqual:(id)object {
-  GULRuntimeDiff *otherObject = (GULRuntimeDiff *)object;
-  return IsEqual(_addedClasses, otherObject->_addedClasses) &&
-         IsEqual(_removedClasses, otherObject->_removedClasses) &&
-         IsEqual(_classDiffs, otherObject->_classDiffs);
-}
-
-- (NSString *)description {
-  NSMutableString *description = [[NSMutableString alloc] init];
-  if (_addedClasses.count) {
-    [description appendString:@"Added classes:\n"];
-    for (NSString *classString in _addedClasses) {
-      [description appendFormat:@"\t%@\n", classString];
-    }
-  }
-  if (_removedClasses.count) {
-    [description appendString:@"\nRemoved classes:\n"];
-    for (NSString *classString in _removedClasses) {
-      [description appendFormat:@"\t%@\n", classString];
-    }
-  }
-  if (_classDiffs.count) {
-    [description appendString:@"\nClass diffs:\n"];
-    for (GULRuntimeClassDiff *classDiff in _classDiffs) {
-      NSString *classDiffDescription =
-          [[classDiff description] stringByReplacingOccurrencesOfString:@"\n" withString:@"\n\t"];
-      [description appendFormat:@"\t%@\n", classDiffDescription];
-    }
-  }
-  return description;
-}
-
-@end

+ 0 - 46
GoogleUtilities/SwizzlerTestHelpers/GULRuntimeSnapshot.h

@@ -1,46 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-@class GULRuntimeClassSnapshot;
-@class GULRuntimeDiff;
-
-NS_ASSUME_NONNULL_BEGIN
-
-/** This class captures various aspects the current state of the Objective-C runtime. */
-@interface GULRuntimeSnapshot : NSObject
-
-/** Initializes an instance of this class. The designated initializer.
- *
- *  @param classes The set of classes to track. If nil or empty, all ObjC classes are tracked.
- *  @return An instance of this class.
- */
-- (instancetype)initWithClasses:(nullable NSSet<Class> *)classes NS_DESIGNATED_INITIALIZER;
-
-/** Captures the state of the class set. */
-- (void)capture;
-
-/** Computes the diff between this snapshot and another snapshot.
- *
- *  @param otherSnapshot The other snapshot, assumed to be more recent than self.
- *  @return A diff object populated with the diff.
- */
-- (GULRuntimeDiff *)diff:(GULRuntimeSnapshot *)otherSnapshot;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 129
GoogleUtilities/SwizzlerTestHelpers/GULRuntimeSnapshot.m

@@ -1,129 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import "GoogleUtilities/SwizzlerTestHelpers/GULRuntimeSnapshot.h"
-
-#import <objc/runtime.h>
-
-#import "GoogleUtilities/SwizzlerTestHelpers/GULRuntimeClassDiff.h"
-#import "GoogleUtilities/SwizzlerTestHelpers/GULRuntimeClassSnapshot.h"
-#import "GoogleUtilities/SwizzlerTestHelpers/GULRuntimeDiff.h"
-
-@implementation GULRuntimeSnapshot {
-  /** The set of tracked classes. */
-  NSSet<Class> *__nullable _classes;
-
-  /** The class snapshots for each tracked class. */
-  NSMutableDictionary<NSString *, GULRuntimeClassSnapshot *> *_classSnapshots;
-
-  /** The hash value of this object. */
-  NSUInteger _runningHash;
-}
-
-- (instancetype)init {
-  return [self initWithClasses:nil];
-}
-
-- (instancetype)initWithClasses:(nullable NSSet<Class> *)classes {
-  self = [super init];
-  if (self) {
-    _classSnapshots = [[NSMutableDictionary alloc] init];
-    _classes = classes;
-    _runningHash = [_classes hash] ^ [_classSnapshots hash];
-  }
-  return self;
-}
-
-- (NSUInteger)hash {
-  return _runningHash;
-}
-
-- (BOOL)isEqual:(id)object {
-  return [self hash] == [object hash];
-}
-
-- (NSString *)description {
-  return [[super description] stringByAppendingFormat:@" Hash: 0x%lX", (unsigned long)[self hash]];
-}
-
-- (void)capture {
-  int numberOfClasses = objc_getClassList(NULL, 0);
-  Class *classList = (Class *)malloc(numberOfClasses * sizeof(Class));
-  numberOfClasses = objc_getClassList(classList, numberOfClasses);
-
-  // If we should track specific classes, then there's no need to figure out all ObjC classes.
-  if (_classes) {
-    for (Class aClass in _classes) {
-      NSString *classString = NSStringFromClass(aClass);
-      GULRuntimeClassSnapshot *classSnapshot =
-          [[GULRuntimeClassSnapshot alloc] initWithClass:aClass];
-      _classSnapshots[classString] = classSnapshot;
-      [classSnapshot capture];
-      _runningHash ^= [classSnapshot hash];
-    }
-  } else {
-    for (int i = 0; i < numberOfClasses; i++) {
-      Class aClass = classList[i];
-      NSString *classString = NSStringFromClass(aClass);
-      GULRuntimeClassSnapshot *classSnapshot =
-          [[GULRuntimeClassSnapshot alloc] initWithClass:aClass];
-      _classSnapshots[classString] = classSnapshot;
-      [classSnapshot capture];
-      _runningHash ^= [classSnapshot hash];
-    }
-  }
-  free(classList);
-}
-
-- (GULRuntimeDiff *)diff:(GULRuntimeSnapshot *)otherSnapshot {
-  GULRuntimeDiff *runtimeDiff = [[GULRuntimeDiff alloc] init];
-  NSSet *setOne = [NSSet setWithArray:[_classSnapshots allKeys]];
-  NSSet *setTwo = [NSSet setWithArray:[otherSnapshot->_classSnapshots allKeys]];
-
-  // All items contained within setOne, but not in setTwo.
-  NSSet *removedClasses = [setOne
-      filteredSetUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(
-                                                 id _Nullable evaluatedObject,
-                                                 NSDictionary<NSString *, id> *_Nullable bindings) {
-        return ![setTwo containsObject:evaluatedObject];
-      }]];
-
-  // All items contained within setTwo, but not in setOne.
-  NSSet *addedClasses = [setTwo
-      filteredSetUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(
-                                                 id _Nullable evaluatedObject,
-                                                 NSDictionary<NSString *, id> *_Nullable bindings) {
-        return ![setOne containsObject:evaluatedObject];
-      }]];
-  runtimeDiff.removedClasses = removedClasses;
-  runtimeDiff.addedClasses = addedClasses;
-
-  NSMutableSet<GULRuntimeClassDiff *> *classDiffs = [[NSMutableSet alloc] init];
-  [_classSnapshots
-      enumerateKeysAndObjectsUsingBlock:^(
-          NSString *_Nonnull key, GULRuntimeClassSnapshot *_Nonnull obj, BOOL *_Nonnull stop) {
-        GULRuntimeClassSnapshot *classSnapshot = self->_classSnapshots[key];
-        GULRuntimeClassSnapshot *otherClassSnapshot = otherSnapshot->_classSnapshots[key];
-        GULRuntimeClassDiff *classDiff = [classSnapshot diff:otherClassSnapshot];
-        if ([classDiff hash]) {
-          NSAssert(![classDiffs containsObject:classDiff],
-                   @"An equivalent class diff has already been stored.");
-          [classDiffs addObject:classDiff];
-        }
-      }];
-  runtimeDiff.classDiffs = classDiffs;
-  return runtimeDiff;
-}
-
-@end

+ 0 - 50
GoogleUtilities/SwizzlerTestHelpers/GULRuntimeStateHelper.h

@@ -1,50 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-#import "GoogleUtilities/SwizzlerTestHelpers/GULRuntimeClassDiff.h"
-#import "GoogleUtilities/SwizzlerTestHelpers/GULRuntimeDiff.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-/** A helper class that enables the snapshotting and diffing of ObjC runtime state. */
-@interface GULRuntimeStateHelper : NSObject
-
-/** Captures the current state of the entire runtime and returns the snapshot number.
- *
- *  @return The snapshot number corresponding to this capture.
- */
-+ (NSUInteger)captureRuntimeState;
-
-/** Captures the current state of the runtime for the provided classes.
- *
- *  @param classes The classes whose state should be snapshotted.
- *  @return The snapshot number corresponding to this capture.
- */
-+ (NSUInteger)captureRuntimeStateOfClasses:(NSSet<Class> *)classes;
-
-/** Prints the diff between two snapshot numbers.
- *
- *  @param firstSnapshot The first runtime snapshot, as provided by captureRuntimeState.
- *  @param secondSnapshot The runtime snapshot sometime after firstSnapshot.
- *  @return An instance of GULRuntimeDiff that contains the diff information.
- */
-+ (GULRuntimeDiff *)diffBetween:(NSUInteger)firstSnapshot secondSnapshot:(NSUInteger)secondSnapshot;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 56
GoogleUtilities/SwizzlerTestHelpers/GULRuntimeStateHelper.m

@@ -1,56 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import "GoogleUtilities/SwizzlerTestHelpers/GULRuntimeStateHelper.h"
-
-#import <objc/runtime.h>
-
-#import "GoogleUtilities/SwizzlerTestHelpers/GULRuntimeSnapshot.h"
-
-@implementation GULRuntimeStateHelper
-
-/** Initializes and returns the snapshot cache.
- *
- *  @return A singleton snapshot cache.
- */
-+ (NSMutableArray<GULRuntimeSnapshot *> *)snapshotCache {
-  static NSMutableArray<GULRuntimeSnapshot *> *snapshots;
-  static dispatch_once_t onceToken;
-  dispatch_once(&onceToken, ^{
-    snapshots = [[NSMutableArray<GULRuntimeSnapshot *> alloc] init];
-  });
-  return snapshots;
-}
-
-+ (NSUInteger)captureRuntimeState {
-  GULRuntimeSnapshot *snapshot = [[GULRuntimeSnapshot alloc] init];
-  [snapshot capture];
-  [[self snapshotCache] addObject:snapshot];
-  return [self snapshotCache].count - 1;
-}
-
-+ (NSUInteger)captureRuntimeStateOfClasses:(NSSet<Class> *)classes {
-  GULRuntimeSnapshot *snapshot = [[GULRuntimeSnapshot alloc] initWithClasses:classes];
-  [snapshot capture];
-  [[self snapshotCache] addObject:snapshot];
-  return [self snapshotCache].count - 1;
-}
-
-+ (GULRuntimeDiff *)diffBetween:(NSUInteger)firstSnapshot
-                 secondSnapshot:(NSUInteger)secondSnapshot {
-  NSArray *snapshotCache = [self snapshotCache];
-  return [snapshotCache[firstSnapshot] diff:snapshotCache[secondSnapshot]];
-}
-
-@end

+ 0 - 63
GoogleUtilities/SwizzlerTestHelpers/GULSwizzler+Unswizzle.m

@@ -1,63 +0,0 @@
-// Copyright 2019 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import "GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/GULSwizzler.h"
-
-#import <objc/runtime.h>
-
-#import "GoogleUtilities/SwizzlerTestHelpers/GULSwizzlingCache.h"
-
-extern dispatch_queue_t GetGULSwizzlingQueue(void);
-
-@implementation GULSwizzler (Unswizzle)
-
-+ (void)unswizzleClass:(Class)aClass selector:(SEL)selector isClassSelector:(BOOL)isClassSelector {
-  dispatch_sync(GetGULSwizzlingQueue(), ^{
-    NSAssert(aClass != nil && selector != nil, @"You cannot unswizzle a nil class or selector.");
-    Method method = nil;
-    Class resolvedClass = aClass;
-    if (isClassSelector) {
-      resolvedClass = object_getClass(aClass);
-      method = class_getClassMethod(aClass, selector);
-    } else {
-      method = class_getInstanceMethod(aClass, selector);
-    }
-    NSAssert(method, @"Couldn't find the method you're unswizzling in the runtime.");
-    IMP originalImp = [[GULSwizzlingCache sharedInstance] cachedIMPForClass:resolvedClass
-                                                               withSelector:selector];
-    NSAssert(originalImp, @"This class/selector combination hasn't been swizzled");
-    IMP currentImp = method_setImplementation(method, originalImp);
-    __unused BOOL didRemoveBlock = imp_removeBlock(currentImp);
-    NSAssert(didRemoveBlock, @"Wasn't able to remove the block of a swizzled IMP.");
-    [[GULSwizzlingCache sharedInstance] clearCacheForSwizzledIMP:currentImp
-                                                        selector:selector
-                                                          aClass:resolvedClass];
-  });
-}
-
-+ (nullable IMP)originalImplementationForClass:(Class)aClass
-                                      selector:(SEL)selector
-                               isClassSelector:(BOOL)isClassSelector {
-  __block IMP originalImp = nil;
-  dispatch_sync(GetGULSwizzlingQueue(), ^{
-    Class resolvedClass = isClassSelector ? object_getClass(aClass) : aClass;
-    originalImp = [[GULSwizzlingCache sharedInstance] cachedIMPForClass:resolvedClass
-                                                           withSelector:selector];
-    NSAssert(originalImp, @"The IMP for this class/selector combo doesn't exist (%@, %@).",
-             NSStringFromClass(resolvedClass), NSStringFromSelector(selector));
-  });
-  return originalImp;
-}
-
-@end

+ 0 - 76
GoogleUtilities/SwizzlerTestHelpers/GULSwizzlingCache.h

@@ -1,76 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-/** This class handles the caching and retreival of IMPs as we swizzle and unswizzle them. It uses
- *  two C++ STL unordered_maps as the underlying data store. This class is NOT thread safe.
- */
-@interface GULSwizzlingCache : NSObject
-
-/** Singleton initializer.
- *
- *  @return a singleton GULSwizzlingCache.
- */
-+ (instancetype)sharedInstance;
-
-/** Save the existing IMP that exists before we install the new IMP for a class, selector combo.
- *  If the currentIMP is something that we put there, it will ignore it and instead point newIMP
- *  to what existed before we swizzled.
- *
- *  @param newIMP new The IMP that is going to replace the current IMP.
- *  @param currentIMP The IMP returned by class_getMethodImplementation.
- *  @param aClass The class that we're swizzling.
- *  @param selector The selector we're swizzling.
- */
-- (void)cacheCurrentIMP:(IMP)currentIMP
-              forNewIMP:(IMP)newIMP
-               forClass:(Class)aClass
-           withSelector:(SEL)selector;
-
-/** Save the existing IMP that exists before we install the new IMP for a class, selector combo.
- *  If the currentIMP is something that we put there, it will ignore it and instead point newIMP
- *  to what existed before we swizzled.
- *
- *  @param newIMP new The IMP that is going to replace the current IMP.
- *  @param currentIMP The IMP returned by class_getMethodImplementation.
- *  @param aClass The class that we're swizzling.
- *  @param selector The selector we're swizzling.
- */
-+ (void)cacheCurrentIMP:(IMP)currentIMP
-              forNewIMP:(IMP)newIMP
-               forClass:(Class)aClass
-           withSelector:(SEL)selector;
-
-/** Returns the cached IMP that would be invoked with the class and selector combo had we
- *  never swizzled.
- *
- *  @param aClass The class the selector would be invoked on.
- *  @param selector The selector
- *  @return The original IMP i.e. the one that existed right before GULSwizzler swizzled either
- *  this or a superclass.
- */
-- (IMP)cachedIMPForClass:(Class)aClass withSelector:(SEL)selector;
-
-/** Clears the cache of values we no longer need because we've unswizzled the relevant method.
- *
- *  @param swizzledIMP The IMP we replaced the existing IMP with.
- *  @param selector The selector which that we swizzled for.
- *  @param aClass The class that we're swizzling.
- */
-- (void)clearCacheForSwizzledIMP:(IMP)swizzledIMP selector:(SEL)selector aClass:(Class)aClass;
-
-@end

+ 0 - 134
GoogleUtilities/SwizzlerTestHelpers/GULSwizzlingCache.m

@@ -1,134 +0,0 @@
-// Copyright 2018 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import "GoogleUtilities/SwizzlerTestHelpers/GULSwizzlingCache.h"
-
-#import <objc/runtime.h>
-
-@interface GULSwizzlingCache ()
-- (IMP)originalIMPOfCurrentIMP:(IMP)currentIMP;
-@end
-
-@implementation GULSwizzlingCache {
-  /** A mapping from the new IMP to the original IMP. */
-  CFMutableDictionaryRef _newToOriginalImps;
-
-  /** A mapping from a Class and SEL (stored in a CFArray) to the original IMP that existed for it.
-   */
-  CFMutableDictionaryRef _originalImps;
-}
-
-+ (instancetype)sharedInstance {
-  static GULSwizzlingCache *sharedInstance;
-  static dispatch_once_t token;
-  dispatch_once(&token, ^{
-    sharedInstance = [[GULSwizzlingCache alloc] init];
-  });
-  return sharedInstance;
-}
-
-- (instancetype)init {
-  self = [super init];
-  if (self) {
-    _newToOriginalImps = CFDictionaryCreateMutable(kCFAllocatorDefault,
-                                                   0,      // Size.
-                                                   NULL,   // Keys are pointers, so this is NULL.
-                                                   NULL);  // Values are pointers so this is NULL.
-    _originalImps = CFDictionaryCreateMutable(kCFAllocatorDefault,
-                                              0,                               // Size.
-                                              &kCFTypeDictionaryKeyCallBacks,  // Keys are CFArrays.
-                                              NULL);  // Values are pointers so this is NULL.
-  }
-  return self;
-}
-
-- (void)dealloc {
-  CFRelease(_newToOriginalImps);
-  CFRelease(_originalImps);
-}
-
-- (void)cacheCurrentIMP:(IMP)currentIMP
-              forNewIMP:(IMP)newIMP
-               forClass:(Class)aClass
-           withSelector:(SEL)selector {
-  IMP originalIMP = [self originalIMPOfCurrentIMP:currentIMP];
-  CFDictionaryAddValue(_newToOriginalImps, newIMP, originalIMP);
-
-  const void *classSELCArray[2] = {(__bridge void *)(aClass), selector};
-  CFArrayRef classSELPair = CFArrayCreate(kCFAllocatorDefault, classSELCArray,
-                                          2,      // Size.
-                                          NULL);  // Elements are pointers so this is NULL.
-  CFDictionaryAddValue(_originalImps, classSELPair, originalIMP);
-  CFRelease(classSELPair);
-}
-
-+ (void)cacheCurrentIMP:(IMP)currentIMP
-              forNewIMP:(IMP)newIMP
-               forClass:(Class)aClass
-           withSelector:(SEL)selector {
-  [[GULSwizzlingCache sharedInstance] cacheCurrentIMP:currentIMP
-                                            forNewIMP:newIMP
-                                             forClass:aClass
-                                         withSelector:selector];
-}
-
-- (IMP)cachedIMPForClass:(Class)aClass withSelector:(SEL)selector {
-  const void *classSELCArray[2] = {(__bridge void *)(aClass), selector};
-  CFArrayRef classSELPair = CFArrayCreate(kCFAllocatorDefault, classSELCArray,
-                                          2,      // Size.
-                                          NULL);  // Elements are pointers so this is NULL.
-  const void *returnedIMP = CFDictionaryGetValue(_originalImps, classSELPair);
-  CFRelease(classSELPair);
-  return (IMP)returnedIMP;
-}
-
-- (void)clearCacheForSwizzledIMP:(IMP)swizzledIMP selector:(SEL)selector aClass:(Class)aClass {
-  CFDictionaryRemoveValue(_newToOriginalImps, swizzledIMP);
-  const void *classSELCArray[2] = {(__bridge void *)(aClass), selector};
-  CFArrayRef classSELPair = CFArrayCreate(kCFAllocatorDefault, classSELCArray,
-                                          2,      // Size.
-                                          NULL);  // Elements are pointers so this is NULL.
-  CFDictionaryRemoveValue(_originalImps, classSELPair);
-  CFRelease(classSELPair);
-}
-
-- (IMP)originalIMPOfCurrentIMP:(IMP)currentIMP {
-  const void *returnedIMP = CFDictionaryGetValue(_newToOriginalImps, currentIMP);
-  if (returnedIMP != NULL) {
-    return (IMP)returnedIMP;
-  } else {
-    return currentIMP;
-  }
-}
-
-+ (IMP)originalIMPOfCurrentIMP:(IMP)currentIMP {
-  return [[GULSwizzlingCache sharedInstance] originalIMPOfCurrentIMP:currentIMP];
-}
-
-#pragma mark - Helper methods for testing
-
-- (void)clearCache {
-  CFDictionaryRemoveAllValues(_originalImps);
-  CFDictionaryRemoveAllValues(_newToOriginalImps);
-}
-
-- (CFMutableDictionaryRef)originalImps {
-  return _originalImps;
-}
-
-- (CFMutableDictionaryRef)newToOriginalImps {
-  return _newToOriginalImps;
-}
-
-@end

+ 0 - 46
GoogleUtilities/SwizzlerTestHelpers/GULSwizzlingCache_Private.h

@@ -1,46 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-@interface GULSwizzlingCache ()
-
-/** Checks if we've swizzled the currentIMP and returns the original IMP that would be invoked if
- *  we hadn't swizzled it in the first place. This method is private because consumers don't need it
- *  to cache or retrive any IMPs. It is used internally and for certain asserts in GULSwizzler.
- *
- *  @param currentIMP The IMP returned by class_getMethodImplementation.
- *  @return The original IMP that would be invoked if we hadn't swizzled at all, and in cases where
- *      currentIMP is not something that we put there, just returns currentIMP.
- */
-+ (IMP)originalIMPOfCurrentIMP:(IMP)currentIMP;
-
-#pragma mark - Helper methods for testing
-
-/** Clears all the cache data structures. */
-- (void)clearCache;
-
-/** Allows tests access to the originalImps CFMutableDictionaryRef.
- *
- *  @returns the originalImps CFMutableDictionaryRef.
- */
-- (CFMutableDictionaryRef)originalImps;
-
-/** Allows tests access to the newToOriginalImps CFMutableDictionaryRef.
- *
- *  @returns the newToOriginalImps CFMutableDictionaryRef.
- */
-- (CFMutableDictionaryRef)newToOriginalImps;
-
-@end

+ 0 - 47
GoogleUtilities/SwizzlerTestHelpers/Public/GoogleUtilities/GULSwizzler+Unswizzle.h

@@ -1,47 +0,0 @@
-/*
- * Copyright 2019 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-/** This category adds methods for unswizzling that are only used for testing.
- */
-@interface GULSwizzler (Unswizzle)
-
-/** Restores the original implementation.
- *
- *  @param aClass The class to unswizzle.
- *  @param selector The selector to restore the original implementation of.
- *  @param isClassSelector A BOOL specifying whether the selector is a class or instance selector.
- */
-+ (void)unswizzleClass:(Class)aClass selector:(SEL)selector isClassSelector:(BOOL)isClassSelector;
-
-/** Returns the original IMP for the given class and selector.
- *
- *  @param aClass The class to use.
- *  @param selector The selector to find the implementation of.
- *  @param isClassSelector A BOOL specifying whether the selector is a class or instance selector.
- *  @return The implementation of the selector in the runtime before any consumer or GULSwizzler
- *          swizzled.
- */
-+ (nullable IMP)originalImplementationForClass:(Class)aClass
-                                      selector:(SEL)selector
-                               isClassSelector:(BOOL)isClassSelector;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 24
GoogleUtilities/Tests/SwiftUnit/GULAppEnvironmentUtilTest.swift

@@ -1,24 +0,0 @@
-/*
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import XCTest
-@testable import GoogleUtilities
-
-class GULAppEnvironmentUtilTest: XCTestCase {
-  func testHasSwiftRuntime() throws {
-    XCTAssertTrue(GULAppEnvironmentUtil.hasSwiftRuntime())
-  }
-}

+ 0 - 108
GoogleUtilities/Tests/Unit/Environment/GULAppEnvironmentUtilTest.m

@@ -1,108 +0,0 @@
-// Copyright 2018 Google
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import <Foundation/Foundation.h>
-#import <XCTest/XCTest.h>
-#import "OCMock.h"
-
-#import "GoogleUtilities/Environment/Public/GoogleUtilities/GULAppEnvironmentUtil.h"
-
-@interface GULAppEnvironmentUtilTest : XCTestCase
-
-@property(nonatomic) id processInfoMock;
-
-@end
-
-@implementation GULAppEnvironmentUtilTest
-
-- (void)setUp {
-  [super setUp];
-
-  _processInfoMock = OCMPartialMock([NSProcessInfo processInfo]);
-}
-
-- (void)tearDown {
-  [super tearDown];
-
-  [_processInfoMock stopMocking];
-}
-
-// Remove the #if when iOS can remove iOS 7 support and also use processInfo instead of UIKit.
-#if TARGET_OS_OSX || TARGET_OS_TV
-
-- (void)testSystemVersionInfoMajorOnly {
-  NSOperatingSystemVersion osTen = {.majorVersion = 10, .minorVersion = 0, .patchVersion = 0};
-  OCMStub([self.processInfoMock operatingSystemVersion]).andReturn(osTen);
-
-  XCTAssertTrue([[GULAppEnvironmentUtil systemVersion] isEqualToString:@"10.0"]);
-}
-
-- (void)testSystemVersionInfoMajorMinor {
-  NSOperatingSystemVersion osTenTwo = {.majorVersion = 10, .minorVersion = 2, .patchVersion = 0};
-  OCMStub([self.processInfoMock operatingSystemVersion]).andReturn(osTenTwo);
-
-  XCTAssertTrue([[GULAppEnvironmentUtil systemVersion] isEqualToString:@"10.2"]);
-}
-
-- (void)testSystemVersionInfoMajorMinorPatch {
-  NSOperatingSystemVersion osTenTwoOne = {.majorVersion = 10, .minorVersion = 2, .patchVersion = 1};
-  OCMStub([self.processInfoMock operatingSystemVersion]).andReturn(osTenTwoOne);
-
-  XCTAssertTrue([[GULAppEnvironmentUtil systemVersion] isEqualToString:@"10.2.1"]);
-}
-#endif
-
-- (void)testDeploymentType {
-#if SWIFT_PACKAGE
-  NSString *deploymentType = @"swiftpm";
-#elif FIREBASE_BUILD_CARTHAGE
-  NSString *deploymentType = @"carthage";
-#elif FIREBASE_BUILD_ZIP_FILE
-  NSString *deploymentType = @"zip";
-#else
-  NSString *deploymentType = @"cocoapods";
-#endif
-
-  XCTAssertEqualObjects([GULAppEnvironmentUtil deploymentType], deploymentType);
-}
-
-- (void)testApplePlatform {
-  // When a Catalyst app is run on macOS then both `TARGET_OS_MACCATALYST` and `TARGET_OS_IOS` are
-  // `true`.
-#if TARGET_OS_MACCATALYST
-  NSString *expectedPlatform = @"maccatalyst";
-#elif TARGET_OS_IOS
-  NSString *expectedPlatform = @"ios";
-#endif  // TARGET_OS_MACCATALYST
-
-#if TARGET_OS_TV
-  NSString *expectedPlatform = @"tvos";
-#endif  // TARGET_OS_TV
-
-#if TARGET_OS_OSX
-  NSString *expectedPlatform = @"macos";
-#endif  // TARGET_OS_OSX
-
-#if TARGET_OS_WATCH
-  NSString *expectedPlatform = @"watchos";
-#endif  // TARGET_OS_WATCH
-
-  XCTAssertEqualObjects([GULAppEnvironmentUtil applePlatform], expectedPlatform);
-}
-
-- (void)testHasSwiftRuntime {
-  XCTAssertFalse([GULAppEnvironmentUtil hasSwiftRuntime]);
-}
-
-@end

+ 0 - 90
GoogleUtilities/Tests/Unit/Environment/GULHeartbeatDateStorageTest.m

@@ -1,90 +0,0 @@
-/*
- * Copyright 2019 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <XCTest/XCTest.h>
-#import "GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorage.h"
-
-@interface GULHeartbeatDateStorageTest : XCTestCase
-@property(nonatomic) GULHeartbeatDateStorage *storage;
-@end
-
-static NSString *const kTestFileName = @"GULStorageHeartbeatTest";
-
-@implementation GULHeartbeatDateStorageTest
-
-- (void)setUp {
-#if TARGET_OS_TV
-  NSArray *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
-#else
-  NSArray *path =
-      NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
-#endif
-  NSString *rootPath = [path firstObject];
-  XCTAssertNotNil(rootPath);
-  NSURL *rootURL = [NSURL fileURLWithPath:rootPath];
-
-  NSError *error;
-  if (![rootURL checkResourceIsReachableAndReturnError:&error]) {
-    XCTAssert([[NSFileManager defaultManager] createDirectoryAtURL:rootURL
-                                       withIntermediateDirectories:YES
-                                                        attributes:nil
-                                                             error:&error],
-              @"Error: %@", error);
-  }
-
-  self.storage = [[GULHeartbeatDateStorage alloc] initWithFileName:kTestFileName];
-
-  [self assertInitializationDoesNotAccessFileSystem];
-}
-
-- (void)tearDown {
-  [[NSFileManager defaultManager] removeItemAtURL:[self.storage fileURL] error:nil];
-  self.storage = nil;
-}
-
-- (void)testHeartbeatDateForTag {
-  NSDate *now = [NSDate date];
-  [self.storage setHearbeatDate:now forTag:@"fire-iid"];
-  XCTAssertEqual([now timeIntervalSinceReferenceDate],
-                 [[self.storage heartbeatDateForTag:@"fire-iid"] timeIntervalSinceReferenceDate]);
-}
-
-#pragma mark - Private Helpers
-
-- (void)assertInitializationDoesNotAccessFileSystem {
-  NSURL *fileURL = [self heartbeatFileURL];
-  NSError *error;
-  BOOL fileIsReachable = [fileURL checkResourceIsReachableAndReturnError:&error];
-  XCTAssertFalse(fileIsReachable,
-                 @"GULHeartbeatDateStorage initialization should not access the file system.");
-  XCTAssertNotNil(error, @"Error: %@", error);
-}
-
-- (NSURL *)heartbeatFileURL {
-#if TARGET_OS_TV
-  NSArray *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
-#else
-  NSArray *path =
-      NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
-#endif
-  NSString *rootPath = [path firstObject];
-  NSArray<NSString *> *components = @[ rootPath, @"Google/FIRApp", kTestFileName ];
-  NSString *fileString = [NSString pathWithComponents:components];
-  NSURL *fileURL = [NSURL fileURLWithPath:fileString];
-  return fileURL;
-}
-
-@end

+ 0 - 207
GoogleUtilities/Tests/Unit/Environment/GULKeychainStorageTests.m

@@ -1,207 +0,0 @@
-/*
- * Copyright 2019 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <TargetConditionals.h>
-#if !TARGET_OS_MACCATALYST
-// Skip keychain tests on Catalyst.
-
-#import <XCTest/XCTest.h>
-
-#import "FBLPromise+Testing.h"
-#import "GoogleUtilities/Tests/Unit/Utils/GULTestKeychain.h"
-#import "OCMock.h"
-
-#import "GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainStorage.h"
-
-@interface GULKeychainStorage (Tests)
-- (instancetype)initWithService:(NSString *)service cache:(NSCache *)cache;
-- (void)resetInMemoryCache;
-@end
-
-@interface GULKeychainStorageTests : XCTestCase
-@property(nonatomic, strong) GULKeychainStorage *storage;
-@property(nonatomic, strong) NSCache *cache;
-@property(nonatomic, strong) id mockCache;
-
-#if TARGET_OS_OSX
-@property(nonatomic) GULTestKeychain *privateKeychain;
-#endif  // TARGET_OSX
-
-@end
-
-@implementation GULKeychainStorageTests
-
-- (void)setUp {
-  self.cache = [[NSCache alloc] init];
-  self.mockCache = OCMPartialMock(self.cache);
-  self.storage = [[GULKeychainStorage alloc] initWithService:@"com.tests.GULKeychainStorageTests"
-                                                       cache:self.mockCache];
-
-#if TARGET_OS_OSX
-  self.privateKeychain = [[GULTestKeychain alloc] init];
-  self.storage.keychainRef = self.privateKeychain.testKeychainRef;
-#endif  // TARGET_OSX
-}
-
-- (void)tearDown {
-  self.storage = nil;
-  self.mockCache = nil;
-  self.cache = nil;
-
-#if TARGET_OS_OSX
-  self.privateKeychain = nil;
-#endif  // TARGET_OSX
-}
-
-- (void)testSetGetObjectForKey {
-  // 1. Write and read object initially.
-  [self assertSuccessWriteObject:@[ @1, @2 ] forKey:@"test-key1"];
-  [self assertSuccessReadObject:@[ @1, @2 ]
-                         forKey:@"test-key1"
-                          class:[NSArray class]
-                  existsInCache:YES];
-
-  //  // 2. Override existing object.
-  [self assertSuccessWriteObject:@{@"key" : @"value"} forKey:@"test-key1"];
-  [self assertSuccessReadObject:@{@"key" : @"value"}
-                         forKey:@"test-key1"
-                          class:[NSDictionary class]
-                  existsInCache:YES];
-
-  // 3. Read existing object which is not present in in-memory cache.
-  [self.cache removeAllObjects];
-  [self assertSuccessReadObject:@{@"key" : @"value"}
-                         forKey:@"test-key1"
-                          class:[NSDictionary class]
-                  existsInCache:NO];
-
-  // 4. Write and read an object for another key.
-  [self assertSuccessWriteObject:@{@"key" : @"value"} forKey:@"test-key2"];
-  [self assertSuccessReadObject:@{@"key" : @"value"}
-                         forKey:@"test-key2"
-                          class:[NSDictionary class]
-                  existsInCache:YES];
-}
-
-- (void)testGetNonExistingObject {
-  [self assertNonExistingObjectForKey:[NSUUID UUID].UUIDString class:[NSArray class]];
-}
-
-- (void)testGetExistingObjectClassMismatch {
-  NSString *key = [NSUUID UUID].UUIDString;
-
-  // Write.
-  [self assertSuccessWriteObject:@[ @8 ] forKey:key];
-
-  // Read.
-  // Skip in-memory cache because the error is relevant only for Keychain.
-  OCMExpect([self.mockCache objectForKey:key]).andReturn(nil);
-
-  FBLPromise<id<NSSecureCoding>> *getPromise = [self.storage getObjectForKey:key
-                                                                 objectClass:[NSString class]
-                                                                 accessGroup:nil];
-
-  XCTAssert(FBLWaitForPromisesWithTimeout(1));
-  XCTAssertNil(getPromise.value);
-  XCTAssertNotNil(getPromise.error);
-  // TODO: Test for particular error.
-
-  OCMVerifyAll(self.mockCache);
-}
-
-- (void)testRemoveExistingObject {
-  NSString *key = @"testRemoveExistingObject";
-  // Store the object.
-  [self assertSuccessWriteObject:@[ @5 ] forKey:(NSString *)key];
-
-  // Remove object.
-  [self assertRemoveObjectForKey:key];
-
-  // Check if object is still stored.
-  [self assertNonExistingObjectForKey:key class:[NSArray class]];
-}
-
-- (void)testRemoveNonExistingObject {
-  NSString *key = [NSUUID UUID].UUIDString;
-  [self assertRemoveObjectForKey:key];
-  [self assertNonExistingObjectForKey:key class:[NSArray class]];
-}
-
-#pragma mark - Common
-
-- (void)assertSuccessWriteObject:(id<NSSecureCoding>)object forKey:(NSString *)key {
-  OCMExpect([self.mockCache setObject:object forKey:key]).andForwardToRealObject();
-
-  FBLPromise<NSNull *> *setPromise = [self.storage setObject:object forKey:key accessGroup:nil];
-
-  XCTAssert(FBLWaitForPromisesWithTimeout(1));
-  XCTAssertNil(setPromise.error, @"%@", self.name);
-
-  OCMVerifyAll(self.mockCache);
-
-  // Check in-memory cache.
-  XCTAssertEqualObjects([self.cache objectForKey:key], object);
-}
-
-- (void)assertSuccessReadObject:(id<NSSecureCoding>)object
-                         forKey:(NSString *)key
-                          class:(Class)class
-                  existsInCache:(BOOL)existisInCache {
-  OCMExpect([self.mockCache objectForKey:key]).andForwardToRealObject();
-
-  if (!existisInCache) {
-    OCMExpect([self.mockCache setObject:object forKey:key]).andForwardToRealObject();
-  }
-
-  FBLPromise<id<NSSecureCoding>> *getPromise =
-      [self.storage getObjectForKey:key objectClass:class accessGroup:nil];
-
-  XCTAssert(FBLWaitForPromisesWithTimeout(1), @"%@", self.name);
-  XCTAssertEqualObjects(getPromise.value, object, @"%@", self.name);
-  XCTAssertNil(getPromise.error, @"%@", self.name);
-
-  OCMVerifyAll(self.mockCache);
-
-  // Check in-memory cache.
-  XCTAssertEqualObjects([self.cache objectForKey:key], object, @"%@", self.name);
-}
-
-- (void)assertNonExistingObjectForKey:(NSString *)key class:(Class)class {
-  OCMExpect([self.mockCache objectForKey:key]).andForwardToRealObject();
-
-  FBLPromise<id<NSSecureCoding>> *promise =
-      [self.storage getObjectForKey:key objectClass:class accessGroup:nil];
-
-  XCTAssert(FBLWaitForPromisesWithTimeout(1));
-  XCTAssertNil(promise.error, @"%@", self.name);
-  XCTAssertNil(promise.value, @"%@", self.name);
-
-  OCMVerifyAll(self.mockCache);
-}
-
-- (void)assertRemoveObjectForKey:(NSString *)key {
-  OCMExpect([self.mockCache removeObjectForKey:key]).andForwardToRealObject();
-
-  FBLPromise<NSNull *> *removePromise = [self.storage removeObjectForKey:key accessGroup:nil];
-  XCTAssert(FBLWaitForPromisesWithTimeout(1));
-  XCTAssertNil(removePromise.error);
-
-  OCMVerifyAll(self.mockCache);
-}
-
-@end
-
-#endif  // TARGET_OS_MACCATALYST

+ 0 - 100
GoogleUtilities/Tests/Unit/Environment/NSURLSession+GULPromisesTests.m

@@ -1,100 +0,0 @@
-/*
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#import <XCTest/XCTest.h>
-
-#import "FBLPromise+Testing.h"
-#import "OCMock.h"
-#import "SharedTestUtilities/URLSession/FIRURLSessionOCMockStub.h"
-
-#import "GoogleUtilities/Environment/Public/GoogleUtilities/GULURLSessionDataResponse.h"
-#import "GoogleUtilities/Environment/Public/GoogleUtilities/NSURLSession+GULPromises.h"
-
-@interface NSURLSession_GULPromisesTests : XCTestCase
-@property(nonatomic) NSURLSession *URLSession;
-@property(nonatomic) id URLSessionMock;
-@end
-
-@implementation NSURLSession_GULPromisesTests
-
-- (void)setUp {
-  self.URLSession = [NSURLSession
-      sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]];
-  self.URLSessionMock = OCMPartialMock(self.URLSession);
-}
-
-- (void)tearDown {
-  [self.URLSessionMock stopMocking];
-  self.URLSessionMock = nil;
-  self.URLSession = nil;
-}
-
-- (void)testDataTaskPromiseWithRequestSuccess {
-  NSURL *url = [NSURL URLWithString:@"https://localhost"];
-  NSURLRequest *request = [NSURLRequest requestWithURL:url];
-
-  NSHTTPURLResponse *expectedResponse = [[NSHTTPURLResponse alloc] initWithURL:url
-                                                                    statusCode:200
-                                                                   HTTPVersion:@"1.1"
-                                                                  headerFields:nil];
-  NSData *expectedBody = [@"body" dataUsingEncoding:NSUTF8StringEncoding];
-
-  [FIRURLSessionOCMockStub
-      stubURLSessionDataTaskWithResponse:expectedResponse
-                                    body:expectedBody
-                                   error:nil
-                          URLSessionMock:self.URLSessionMock
-                  requestValidationBlock:^BOOL(NSURLRequest *_Nonnull sentRequest) {
-                    return [sentRequest isEqual:request];
-                  }];
-
-  __auto_type taskPromise = [self.URLSessionMock gul_dataTaskPromiseWithRequest:request];
-
-  XCTAssert(FBLWaitForPromisesWithTimeout(0.5));
-
-  XCTAssertTrue(taskPromise.isFulfilled);
-  XCTAssertNil(taskPromise.error);
-  XCTAssertEqualObjects(taskPromise.value.HTTPResponse, expectedResponse);
-  XCTAssertEqualObjects(taskPromise.value.HTTPBody, expectedBody);
-}
-
-- (void)testDataTaskPromiseWithRequestError {
-  NSURL *url = [NSURL URLWithString:@"https://localhost"];
-  NSURLRequest *request = [NSURLRequest requestWithURL:url];
-
-  NSError *expectedError = [NSError errorWithDomain:@"testDataTaskPromiseWithRequestError"
-                                               code:-1
-                                           userInfo:nil];
-
-  [FIRURLSessionOCMockStub
-      stubURLSessionDataTaskWithResponse:nil
-                                    body:nil
-                                   error:expectedError
-                          URLSessionMock:self.URLSessionMock
-                  requestValidationBlock:^BOOL(NSURLRequest *_Nonnull sentRequest) {
-                    return [sentRequest isEqual:request];
-                  }];
-
-  __auto_type taskPromise = [self.URLSessionMock gul_dataTaskPromiseWithRequest:request];
-
-  XCTAssert(FBLWaitForPromisesWithTimeout(0.5));
-
-  XCTAssertTrue(taskPromise.isRejected);
-  XCTAssertEqualObjects(taskPromise.error, expectedError);
-  XCTAssertNil(taskPromise.value);
-}
-
-@end

+ 0 - 117
GoogleUtilities/Tests/Unit/Logger/GULLoggerTest.m

@@ -1,117 +0,0 @@
-// Copyright 2018 Google
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifdef DEBUG
-// The tests depend upon library methods only built with #ifdef DEBUG
-
-#import <XCTest/XCTest.h>
-#import "OCMock.h"
-
-#import "GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h"
-
-#import <asl.h>
-
-extern const char *kGULLoggerASLClientFacilityName;
-
-extern void GULResetLogger(void);
-
-extern aslclient getGULLoggerClient(void);
-
-extern dispatch_queue_t getGULClientQueue(void);
-
-extern BOOL getGULLoggerDebugMode(void);
-
-static NSString *const kMessageCode = @"I-COR000001";
-
-@interface GULLoggerTest : XCTestCase
-
-@property(nonatomic) NSString *randomLogString;
-
-@property(nonatomic, strong) NSUserDefaults *defaults;
-
-@end
-
-@implementation GULLoggerTest
-
-- (void)setUp {
-  [super setUp];
-  GULResetLogger();
-
-  // Stub NSUserDefaults for cleaner testing.
-  _defaults = [[NSUserDefaults alloc] initWithSuiteName:@"com.google.logger_test"];
-}
-
-- (void)tearDown {
-  [super tearDown];
-
-  _defaults = nil;
-}
-
-- (void)testMessageCodeFormat {
-  // Valid case.
-  XCTAssertNoThrow(GULLogError(@"my service", NO, @"I-APP000001", @"Message."));
-
-  // An extra dash or missing dash should fail.
-  XCTAssertThrows(GULLogError(@"my service", NO, @"I-APP-000001", @"Message."));
-  XCTAssertThrows(GULLogError(@"my service", NO, @"IAPP000001", @"Message."));
-
-  // Wrong number of digits should fail.
-  XCTAssertThrows(GULLogError(@"my service", NO, @"I-APP00001", @"Message."));
-  XCTAssertThrows(GULLogError(@"my service", NO, @"I-APP0000001", @"Message."));
-
-  // Lowercase should fail.
-  XCTAssertThrows(GULLogError(@"my service", NO, @"I-app000001", @"Message."));
-
-// nil or empty message code should fail.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wnonnull"
-  XCTAssertThrows(GULLogError(@"my service", NO, nil, @"Message."));
-#pragma clang diagnostic pop
-
-  XCTAssertThrows(GULLogError(@"my service", NO, @"", @"Message."));
-
-  // Android message code should fail.
-  XCTAssertThrows(GULLogError(@"my service", NO, @"A-APP000001", @"Message."));
-}
-
-- (void)testLoggerInterface {
-  XCTAssertNoThrow(GULLogError(@"my service", NO, kMessageCode, @"Message."));
-  XCTAssertNoThrow(GULLogError(@"my service", NO, kMessageCode, @"Configure %@.", @"blah"));
-
-  XCTAssertNoThrow(GULLogWarning(@"my service", NO, kMessageCode, @"Message."));
-  XCTAssertNoThrow(GULLogWarning(@"my service", NO, kMessageCode, @"Configure %@.", @"blah"));
-
-  XCTAssertNoThrow(GULLogNotice(@"my service", NO, kMessageCode, @"Message."));
-  XCTAssertNoThrow(GULLogNotice(@"my service", NO, kMessageCode, @"Configure %@.", @"blah"));
-
-  XCTAssertNoThrow(GULLogInfo(@"my service", NO, kMessageCode, @"Message."));
-  XCTAssertNoThrow(GULLogInfo(@"my service", NO, kMessageCode, @"Configure %@.", @"blah"));
-
-  XCTAssertNoThrow(GULLogDebug(@"my service", NO, kMessageCode, @"Message."));
-  XCTAssertNoThrow(GULLogDebug(@"my service", NO, kMessageCode, @"Configure %@.", @"blah"));
-}
-
-// The GULLoggerLevel enum must match the ASL_LEVEL_* constants, but we manually redefine
-// them in GULLoggerLevel.h since we cannot include <asl.h> (see b/34976089 for more details).
-// This test ensures the constants match.
-- (void)testGULLoggerLevelValues {
-  XCTAssertEqual(GULLoggerLevelError, ASL_LEVEL_ERR);
-  XCTAssertEqual(GULLoggerLevelWarning, ASL_LEVEL_WARNING);
-  XCTAssertEqual(GULLoggerLevelNotice, ASL_LEVEL_NOTICE);
-  XCTAssertEqual(GULLoggerLevelInfo, ASL_LEVEL_INFO);
-  XCTAssertEqual(GULLoggerLevelDebug, ASL_LEVEL_DEBUG);
-}
-
-@end
-#endif

+ 0 - 87
GoogleUtilities/Tests/Unit/Network/GULMutableDictionaryTest.m

@@ -1,87 +0,0 @@
-// Copyright 2018 Google
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import <XCTest/XCTest.h>
-
-#import "GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h"
-
-const static NSString *const kKey = @"testKey1";
-const static NSString *const kValue = @"testValue1";
-const static NSString *const kKey2 = @"testKey2";
-const static NSString *const kValue2 = @"testValue2";
-
-@interface GULMutableDictionaryTest : XCTestCase
-@property(nonatomic) GULMutableDictionary *dictionary;
-@end
-
-@implementation GULMutableDictionaryTest
-
-- (void)setUp {
-  [super setUp];
-  self.dictionary = [[GULMutableDictionary alloc] init];
-}
-
-- (void)tearDown {
-  self.dictionary = nil;
-  [super tearDown];
-}
-
-- (void)testSetGetAndRemove {
-  XCTAssertNil([self.dictionary objectForKey:kKey]);
-  [self.dictionary setObject:kValue forKey:kKey];
-  XCTAssertEqual(kValue, [self.dictionary objectForKey:kKey]);
-  [self.dictionary removeObjectForKey:kKey];
-  XCTAssertNil([self.dictionary objectForKey:kKey]);
-}
-
-- (void)testSetGetAndRemoveKeyed {
-  XCTAssertNil(self.dictionary[kKey]);
-  self.dictionary[kKey] = kValue;
-  XCTAssertEqual(kValue, self.dictionary[kKey]);
-  [self.dictionary removeObjectForKey:kKey];
-  XCTAssertNil(self.dictionary[kKey]);
-}
-
-- (void)testRemoveAll {
-  XCTAssertNil(self.dictionary[kKey]);
-  XCTAssertNil(self.dictionary[kKey2]);
-  self.dictionary[kKey] = kValue;
-  self.dictionary[kKey2] = kValue2;
-  [self.dictionary removeAllObjects];
-  XCTAssertNil(self.dictionary[kKey]);
-  XCTAssertNil(self.dictionary[kKey2]);
-}
-
-- (void)testCount {
-  XCTAssertEqual([self.dictionary count], 0);
-  self.dictionary[kKey] = kValue;
-  XCTAssertEqual([self.dictionary count], 1);
-  self.dictionary[kKey2] = kValue2;
-  XCTAssertEqual([self.dictionary count], 2);
-  [self.dictionary removeAllObjects];
-  XCTAssertEqual([self.dictionary count], 0);
-}
-
-- (void)testUnderlyingDictionary {
-  XCTAssertEqual([self.dictionary count], 0);
-  self.dictionary[kKey] = kValue;
-  self.dictionary[kKey2] = kValue2;
-
-  NSDictionary *dict = self.dictionary.dictionary;
-  XCTAssertEqual([dict count], 2);
-  XCTAssertEqual(dict[kKey], kValue);
-  XCTAssertEqual(dict[kKey2], kValue2);
-}
-
-@end

+ 0 - 1015
GoogleUtilities/Tests/Unit/Network/GULNetworkTest.m

@@ -1,1015 +0,0 @@
-// Copyright 2018 Google
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#import "GoogleUtilities/Tests/Unit/Network/third_party/GTMHTTPServer.h"
-
-#import <XCTest/XCTest.h>
-#import "OCMock.h"
-
-#if !TARGET_OS_MACCATALYST
-// These tests are flaky on Catalyst. One of the tests typically fails.
-
-#import "GoogleUtilities/NSData+zlib/Public/GoogleUtilities/GULNSData+zlib.h"
-#import "GoogleUtilities/Network/Public/GoogleUtilities/GULNetwork.h"
-#import "GoogleUtilities/Reachability/Public/GoogleUtilities/GULReachabilityChecker.h"
-
-@interface GULNetwork ()
-
-- (void)reachability:(GULReachabilityChecker *)reachability
-       statusChanged:(GULReachabilityStatus)status;
-
-@end
-
-@interface GULNetworkURLSession ()
-
-- (void)maybeRemoveTempFilesAtURL:(NSURL *)tempFile expiringTime:(NSTimeInterval)expiringTime;
-
-@end
-
-@interface GULNetworkTest : XCTestCase <GULNetworkReachabilityDelegate>
-@end
-
-@implementation GULNetworkTest {
-  dispatch_queue_t _backgroundQueue;
-  GULNetwork *_network;
-
-  /// Fake Server.
-  GTMHTTPServer *_httpServer;
-  GTMHTTPRequestMessage *_request;
-  int _statusCode;
-
-  // For network reachability test.
-  BOOL _fakeNetworkIsReachable;
-  BOOL _currentNetworkStatus;
-  GULReachabilityStatus _fakeReachabilityStatus;
-}
-
-#pragma mark - Setup and teardown
-
-- (void)setUp {
-  [super setUp];
-
-  _fakeNetworkIsReachable = YES;
-  _statusCode = 200;
-  _request = nil;
-
-  _httpServer = [[GTMHTTPServer alloc] initWithDelegate:self];
-
-  // Start the server.
-  NSError *error = nil;
-  XCTAssertTrue([_httpServer start:&error], @"Failed to start HTTP server: %@", error);
-
-  _network = [[GULNetwork alloc] init];
-  _backgroundQueue = dispatch_queue_create("Test queue", DISPATCH_QUEUE_SERIAL);
-
-  _request = nil;
-}
-
-- (void)tearDown {
-  _network = nil;
-  _backgroundQueue = nil;
-  _request = nil;
-
-  [_httpServer stop];
-  _httpServer = nil;
-
-  [super tearDown];
-}
-
-#pragma mark - Test reachability
-
-- (void)testReachability {
-  _network.reachabilityDelegate = self;
-
-  id reachability = [_network valueForKey:@"_reachability"];
-  XCTAssertNotNil(reachability);
-
-  id reachabilityMock = OCMPartialMock(reachability);
-  [[[reachabilityMock stub] andCall:@selector(reachabilityStatus)
-                           onObject:self] reachabilityStatus];
-
-  // Fake scenario with connectivity.
-  _fakeNetworkIsReachable = YES;
-  _fakeReachabilityStatus = kGULReachabilityViaWifi;
-  [_network reachability:reachabilityMock statusChanged:[reachabilityMock reachabilityStatus]];
-  XCTAssertTrue([_network isNetworkConnected]);
-  XCTAssertEqual(_currentNetworkStatus, _fakeNetworkIsReachable);
-
-  // Fake scenario without connectivity.
-  _fakeNetworkIsReachable = NO;
-  _fakeReachabilityStatus = kGULReachabilityNotReachable;
-  [_network reachability:reachabilityMock statusChanged:[reachabilityMock reachabilityStatus]];
-  XCTAssertFalse([_network isNetworkConnected]);
-  XCTAssertEqual(_currentNetworkStatus, _fakeNetworkIsReachable);
-
-  [reachabilityMock stopMocking];
-  reachabilityMock = nil;
-}
-
-#pragma mark - Test POST Foreground
-
-- (void)testSessionNetwork_POST_foreground {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-
-  NSData *uncompressedData = [@"Google" dataUsingEncoding:NSUTF8StringEncoding];
-
-  NSURL *url =
-      [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%d/2", _httpServer.port]];
-  _statusCode = 200;
-
-  [_network postURL:url
-                     payload:uncompressedData
-                       queue:_backgroundQueue
-      usingBackgroundSession:NO
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertNotNil(data);
-             NSString *responseBody = [[NSString alloc] initWithData:data
-                                                            encoding:NSUTF8StringEncoding];
-             XCTAssertEqualObjects(responseBody, @"<html><body>Hello, World!</body></html>");
-             [self verifyResponse:response error:error];
-             [self verifyRequest];
-             XCTAssertFalse(self->_network.hasUploadInProgress, "There must be no pending request");
-             [expectation fulfill];
-           }];
-  XCTAssertTrue(self->_network.hasUploadInProgress, "There must be a pending request");
-  // Wait a little bit so the server has enough time to respond.
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testSessionNetworkShouldReturnError_POST_foreground {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-
-  NSData *uncompressedData = [@"Google" dataUsingEncoding:NSUTF8StringEncoding];
-  NSURL *url =
-      [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%d/3", _httpServer.port]];
-  _statusCode = 500;
-
-  [_network postURL:url
-                     payload:uncompressedData
-                       queue:_backgroundQueue
-      usingBackgroundSession:NO
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertEqual(((NSHTTPURLResponse *)response).statusCode, 500);
-             XCTAssertFalse(self->_network.hasUploadInProgress, "There must be no pending request");
-             [expectation fulfill];
-           }];
-  XCTAssertTrue(self->_network.hasUploadInProgress, "There must be a pending request");
-  // Wait a little bit so the server has enough time to respond.
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testNilURLNSURLSession_POST_foreground {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-
-  NSData *uncompressedData = [@"Google" dataUsingEncoding:NSUTF8StringEncoding];
-  _statusCode = 200;
-
-  [_network postURL:nil
-                     payload:uncompressedData
-                       queue:_backgroundQueue
-      usingBackgroundSession:NO
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertEqual(error.code, GULErrorCodeNetworkInvalidURL);
-             XCTAssertFalse(self->_network.hasUploadInProgress, "There must be no pending request");
-             [expectation fulfill];
-           }];
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testEmptyURLNSURLSession_POST_foreground {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-  NSData *uncompressedData = [@"Google" dataUsingEncoding:NSUTF8StringEncoding];
-  _statusCode = 200;
-
-  [_network postURL:[NSURL URLWithString:@""]
-                     payload:uncompressedData
-                       queue:_backgroundQueue
-      usingBackgroundSession:NO
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertEqual(error.code, GULErrorCodeNetworkInvalidURL);
-             XCTAssertFalse(self->_network.hasUploadInProgress, "There must be no pending request");
-             [expectation fulfill];
-           }];
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testEmptyPayloadNSURLSession_POST_foreground {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-  NSData *uncompressedData = [[NSData alloc] init];
-  NSURL *url =
-      [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%d/2", _httpServer.port]];
-  _statusCode = 200;
-
-  [_network postURL:url
-                     payload:uncompressedData
-                       queue:_backgroundQueue
-      usingBackgroundSession:NO
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertNil(error);
-             XCTAssertNotNil(self->_request);
-             XCTAssertEqualObjects([self->_request.URL absoluteString], [url absoluteString]);
-             XCTAssertFalse(self->_network.hasUploadInProgress, "There must be no pending request");
-             [expectation fulfill];
-           }];
-  XCTAssertTrue(self->_network.hasUploadInProgress, "There must be a pending request");
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testNilQueueNSURLSession_POST_foreground {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-
-  NSData *uncompressedData = [@"Google" dataUsingEncoding:NSUTF8StringEncoding];
-  NSURL *url =
-      [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%d/1", _httpServer.port]];
-  _statusCode = 200;
-
-  [_network postURL:url
-                     payload:uncompressedData
-                       queue:nil
-      usingBackgroundSession:NO
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             [self verifyResponse:response error:error];
-             [self verifyRequest];
-             [expectation fulfill];
-           }];
-
-  // Wait a little bit so the server has enough time to respond.
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testHasRequestPendingNSURLSession_POST_foreground {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-  NSData *uncompressedData = [@"Google" dataUsingEncoding:NSUTF8StringEncoding];
-  NSURL *url =
-      [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%d/hasRequestPending",
-                                                      _httpServer.port]];
-  _statusCode = 200;
-
-  [_network postURL:url
-                     payload:uncompressedData
-                       queue:_backgroundQueue
-      usingBackgroundSession:NO
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             [self verifyResponse:response error:error];
-             [self verifyRequest];
-
-             XCTAssertFalse(self->_network.hasUploadInProgress,
-                            @"hasUploadInProgress must be false");
-             [expectation fulfill];
-           }];
-
-  XCTAssertTrue(self->_network.hasUploadInProgress, @"hasUploadInProgress must be true");
-  // Wait a little bit so the server has enough time to respond.
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-#pragma mark - Test POST Background
-
-- (void)testSessionNetwork_POST_background {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-
-  NSData *uncompressedData = [@"Google" dataUsingEncoding:NSUTF8StringEncoding];
-  NSURL *url =
-      [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%d/2", _httpServer.port]];
-  _statusCode = 200;
-
-  [_network postURL:url
-                     payload:uncompressedData
-                       queue:_backgroundQueue
-      usingBackgroundSession:YES
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertNotNil(data);
-             NSString *responseBody = [[NSString alloc] initWithData:data
-                                                            encoding:NSUTF8StringEncoding];
-             XCTAssertEqualObjects(responseBody, @"<html><body>Hello, World!</body></html>");
-             [self verifyResponse:response error:error];
-             [self verifyRequest];
-             XCTAssertFalse(self->_network.hasUploadInProgress, "There must be no pending request");
-             [expectation fulfill];
-           }];
-  XCTAssertTrue(self->_network.hasUploadInProgress, "There must be a pending request");
-  // Wait a little bit so the server has enough time to respond.
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testSessionNetworkShouldReturnError_POST_background {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-
-  NSData *uncompressedData = [@"Google" dataUsingEncoding:NSUTF8StringEncoding];
-  NSURL *url =
-      [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%d/3", _httpServer.port]];
-  _statusCode = 500;
-
-  [_network postURL:url
-                     payload:uncompressedData
-                       queue:_backgroundQueue
-      usingBackgroundSession:YES
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertEqual(((NSHTTPURLResponse *)response).statusCode, 500);
-             XCTAssertFalse(self->_network.hasUploadInProgress, "There must be no pending request");
-             [expectation fulfill];
-           }];
-  XCTAssertTrue(self->_network.hasUploadInProgress, "There must be a pending request");
-  // Wait a little bit so the server has enough time to respond.
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testNilURLNSURLSession_POST_background {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-
-  NSData *uncompressedData = [@"Google" dataUsingEncoding:NSUTF8StringEncoding];
-  _statusCode = 200;
-
-  [_network postURL:nil
-                     payload:uncompressedData
-                       queue:_backgroundQueue
-      usingBackgroundSession:YES
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertEqual(error.code, GULErrorCodeNetworkInvalidURL);
-             XCTAssertFalse(self->_network.hasUploadInProgress, "There must be no pending request");
-             [expectation fulfill];
-           }];
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testEmptyURLNSURLSession_POST_background {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-  NSData *uncompressedData = [@"Google" dataUsingEncoding:NSUTF8StringEncoding];
-  _statusCode = 200;
-
-  [_network postURL:[NSURL URLWithString:@""]
-                     payload:uncompressedData
-                       queue:_backgroundQueue
-      usingBackgroundSession:YES
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertEqual(error.code, GULErrorCodeNetworkInvalidURL);
-             XCTAssertFalse(self->_network.hasUploadInProgress, "There must be no pending request");
-             [expectation fulfill];
-           }];
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testEmptyPayloadNSURLSession_POST_background {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-  NSData *uncompressedData = [[NSData alloc] init];
-  NSURL *url =
-      [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%d/2", _httpServer.port]];
-  _statusCode = 200;
-
-  [_network postURL:url
-                     payload:uncompressedData
-                       queue:_backgroundQueue
-      usingBackgroundSession:YES
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertNil(error);
-             XCTAssertNotNil(self->_request);
-             XCTAssertEqualObjects([self->_request.URL absoluteString], [url absoluteString]);
-             XCTAssertFalse(self->_network.hasUploadInProgress, "There must be no pending request");
-             [expectation fulfill];
-           }];
-  XCTAssertTrue(self->_network.hasUploadInProgress, "There must be a pending request");
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testNilQueueNSURLSession_POST_background {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-
-  NSData *uncompressedData = [@"Google" dataUsingEncoding:NSUTF8StringEncoding];
-  NSURL *url =
-      [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%d/1", _httpServer.port]];
-  _statusCode = 200;
-
-  [_network postURL:url
-                     payload:uncompressedData
-                       queue:nil
-      usingBackgroundSession:YES
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             [self verifyResponse:response error:error];
-             [self verifyRequest];
-             [expectation fulfill];
-           }];
-
-  // Wait a little bit so the server has enough time to respond.
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testHasRequestPendingNSURLSession_POST_background {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-  NSData *uncompressedData = [@"Google" dataUsingEncoding:NSUTF8StringEncoding];
-  NSURL *url =
-      [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%d/hasRequestPending",
-                                                      _httpServer.port]];
-  _statusCode = 200;
-
-  [_network postURL:url
-                     payload:uncompressedData
-                       queue:_backgroundQueue
-      usingBackgroundSession:YES
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             [self verifyResponse:response error:error];
-             [self verifyRequest];
-
-             XCTAssertFalse(self->_network.hasUploadInProgress,
-                            @"hasUploadInProgress must be false");
-             [expectation fulfill];
-           }];
-
-  XCTAssertTrue(self->_network.hasUploadInProgress, @"hasUploadInProgress must be true");
-  // Wait a little bit so the server has enough time to respond.
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-#pragma mark - GET Methods Foreground
-
-- (void)testSessionNetworkAsync_GET_foreground {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-
-  NSURL *url =
-      [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%d/2", _httpServer.port]];
-  _statusCode = 200;
-
-  [_network getURL:url
-                     headers:nil
-                       queue:_backgroundQueue
-      usingBackgroundSession:NO
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertNotNil(data);
-             NSString *responseBody = [[NSString alloc] initWithData:data
-                                                            encoding:NSUTF8StringEncoding];
-             XCTAssertEqualObjects(responseBody, @"<html><body>Hello, World!</body></html>");
-             XCTAssertNil(error);
-             XCTAssertFalse(self->_network.hasUploadInProgress, "There must be no pending request");
-             [expectation fulfill];
-           }];
-  XCTAssertTrue(self->_network.hasUploadInProgress, "There must be a pending request");
-  // Wait a little bit so the server has enough time to respond.
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testSessionNetworkShouldReturnError_GET_foreground {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-  NSURL *url =
-      [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%d/3", _httpServer.port]];
-  _statusCode = 500;
-
-  [_network getURL:url
-                     headers:nil
-                       queue:_backgroundQueue
-      usingBackgroundSession:NO
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertEqual(((NSHTTPURLResponse *)response).statusCode, 500);
-             XCTAssertFalse(self->_network.hasUploadInProgress, "There must be no pending request");
-             [expectation fulfill];
-           }];
-  XCTAssertTrue(self->_network.hasUploadInProgress, "There must be a pending request");
-  // Wait a little bit so the server has enough time to respond.
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testNilURLNSURLSession_GET_foreground {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-  _statusCode = 200;
-
-  [_network getURL:nil
-                     headers:nil
-                       queue:_backgroundQueue
-      usingBackgroundSession:NO
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertEqual(error.code, GULErrorCodeNetworkInvalidURL);
-             XCTAssertFalse(self->_network.hasUploadInProgress, "There must be no pending request");
-             [expectation fulfill];
-           }];
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testEmptyURLNSURLSession_GET_foreground {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-  _statusCode = 200;
-
-  [_network getURL:[NSURL URLWithString:@""]
-                     headers:nil
-                       queue:_backgroundQueue
-      usingBackgroundSession:NO
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertEqual(error.code, GULErrorCodeNetworkInvalidURL);
-             XCTAssertFalse(self->_network.hasUploadInProgress, "There must be no pending request");
-             [expectation fulfill];
-           }];
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testNilQueueNSURLSession_GET_foreground {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-
-  NSURL *url =
-      [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%d/1", _httpServer.port]];
-  _statusCode = 200;
-
-  [_network getURL:url
-                     headers:nil
-                       queue:nil
-      usingBackgroundSession:NO
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertNotNil(data);
-             NSString *responseBody = [[NSString alloc] initWithData:data
-                                                            encoding:NSUTF8StringEncoding];
-             XCTAssertEqualObjects(responseBody, @"<html><body>Hello, World!</body></html>");
-             XCTAssertNil(error);
-             XCTAssertFalse(self->_network.hasUploadInProgress, "There must be no pending request");
-             [expectation fulfill];
-           }];
-  XCTAssertTrue(self->_network.hasUploadInProgress, "There must be a pending request");
-  // Wait a little bit so the server has enough time to respond.
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testHasRequestPendingNSURLSession_GET_foreground {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-  NSURL *url =
-      [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%d/hasRequestPending",
-                                                      _httpServer.port]];
-  _statusCode = 200;
-
-  [_network getURL:url
-                     headers:nil
-                       queue:_backgroundQueue
-      usingBackgroundSession:NO
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertNotNil(data);
-             NSString *responseBody = [[NSString alloc] initWithData:data
-                                                            encoding:NSUTF8StringEncoding];
-             XCTAssertEqualObjects(responseBody, @"<html><body>Hello, World!</body></html>");
-             XCTAssertNil(error);
-             XCTAssertFalse(self->_network.hasUploadInProgress,
-                            @"hasUploadInProgress must be false");
-             [expectation fulfill];
-           }];
-
-  XCTAssertTrue(self->_network.hasUploadInProgress, @"hasUploadInProgress must be true");
-  // Wait a little bit so the server has enough time to respond.
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testHeaders_foreground {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-
-  NSURL *url =
-      [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%d/3", _httpServer.port]];
-  _statusCode = 200;
-
-  NSDictionary *headers = @{@"Version" : @"123"};
-
-  [_network getURL:url
-                     headers:headers
-                       queue:_backgroundQueue
-      usingBackgroundSession:NO
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertNotNil(data);
-             NSString *responseBody = [[NSString alloc] initWithData:data
-                                                            encoding:NSUTF8StringEncoding];
-             XCTAssertEqualObjects(responseBody, @"<html><body>Hello, World!</body></html>");
-             XCTAssertNil(error);
-
-             NSString *version = [self->_request.allHeaderFieldValues valueForKey:@"Version"];
-             XCTAssertEqualObjects(version, @"123");
-
-             [expectation fulfill];
-           }];
-
-  // Wait a little bit so the server has enough time to respond.
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-#pragma mark - GET Methods Background
-
-- (void)testSessionNetworkAsync_GET_background {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-
-  NSURL *url =
-      [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%d/2", _httpServer.port]];
-  _statusCode = 200;
-
-  [_network getURL:url
-                     headers:nil
-                       queue:_backgroundQueue
-      usingBackgroundSession:YES
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertNotNil(data);
-             NSString *responseBody = [[NSString alloc] initWithData:data
-                                                            encoding:NSUTF8StringEncoding];
-             XCTAssertEqualObjects(responseBody, @"<html><body>Hello, World!</body></html>");
-             XCTAssertNil(error);
-             XCTAssertFalse(self->_network.hasUploadInProgress, "There must be no pending request");
-             [expectation fulfill];
-           }];
-  XCTAssertTrue(self->_network.hasUploadInProgress, "There must be a pending request");
-  // Wait a little bit so the server has enough time to respond.
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testSessionNetworkShouldReturnError_GET_background {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-  NSURL *url =
-      [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%d/3", _httpServer.port]];
-  _statusCode = 500;
-
-  [_network getURL:url
-                     headers:nil
-                       queue:_backgroundQueue
-      usingBackgroundSession:YES
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertEqual(((NSHTTPURLResponse *)response).statusCode, 500);
-             XCTAssertFalse(self->_network.hasUploadInProgress, "There must be no pending request");
-             [expectation fulfill];
-           }];
-  XCTAssertTrue(self->_network.hasUploadInProgress, "There must be a pending request");
-  // Wait a little bit so the server has enough time to respond.
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testNilURLNSURLSession_GET_background {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-  _statusCode = 200;
-
-  [_network getURL:nil
-                     headers:nil
-                       queue:_backgroundQueue
-      usingBackgroundSession:YES
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertEqual(error.code, GULErrorCodeNetworkInvalidURL);
-             XCTAssertFalse(self->_network.hasUploadInProgress, "There must be no pending request");
-             [expectation fulfill];
-           }];
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testEmptyURLNSURLSession_GET_background {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-  _statusCode = 200;
-
-  [_network getURL:[NSURL URLWithString:@""]
-                     headers:nil
-                       queue:_backgroundQueue
-      usingBackgroundSession:YES
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertEqual(error.code, GULErrorCodeNetworkInvalidURL);
-             XCTAssertFalse(self->_network.hasUploadInProgress, "There must be no pending request");
-             [expectation fulfill];
-           }];
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testNilQueueNSURLSession_GET_background {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-
-  NSURL *url =
-      [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%d/1", _httpServer.port]];
-  _statusCode = 200;
-
-  [_network getURL:url
-                     headers:nil
-                       queue:nil
-      usingBackgroundSession:YES
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertNotNil(data);
-             NSString *responseBody = [[NSString alloc] initWithData:data
-                                                            encoding:NSUTF8StringEncoding];
-             XCTAssertEqualObjects(responseBody, @"<html><body>Hello, World!</body></html>");
-             XCTAssertNil(error);
-             XCTAssertFalse(self->_network.hasUploadInProgress, "There must be no pending request");
-             [expectation fulfill];
-           }];
-  XCTAssertTrue(self->_network.hasUploadInProgress, "There must be a pending request");
-  // Wait a little bit so the server has enough time to respond.
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testHasRequestPendingNSURLSession_GET_background {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-  NSURL *url =
-      [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%d/hasRequestPending",
-                                                      _httpServer.port]];
-  _statusCode = 200;
-
-  [_network getURL:url
-                     headers:nil
-                       queue:_backgroundQueue
-      usingBackgroundSession:YES
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertNotNil(data);
-             NSString *responseBody = [[NSString alloc] initWithData:data
-                                                            encoding:NSUTF8StringEncoding];
-             XCTAssertEqualObjects(responseBody, @"<html><body>Hello, World!</body></html>");
-             XCTAssertNil(error);
-             XCTAssertFalse(self->_network.hasUploadInProgress,
-                            @"hasUploadInProgress must be false");
-             [expectation fulfill];
-           }];
-
-  XCTAssertTrue(self->_network.hasUploadInProgress, @"hasUploadInProgress must be true");
-  // Wait a little bit so the server has enough time to respond.
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-- (void)testHeaders_background {
-  XCTestExpectation *expectation = [self expectationWithDescription:@"Expect block is called"];
-
-  NSURL *url =
-      [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%d/3", _httpServer.port]];
-  _statusCode = 200;
-
-  NSDictionary *headers = @{@"Version" : @"123"};
-
-  [_network getURL:url
-                     headers:headers
-                       queue:_backgroundQueue
-      usingBackgroundSession:YES
-           completionHandler:^(NSHTTPURLResponse *response, NSData *data, NSError *error) {
-             XCTAssertNotNil(data);
-             NSString *responseBody = [[NSString alloc] initWithData:data
-                                                            encoding:NSUTF8StringEncoding];
-             XCTAssertEqualObjects(responseBody, @"<html><body>Hello, World!</body></html>");
-             XCTAssertNil(error);
-
-             NSString *version = [self->_request.allHeaderFieldValues valueForKey:@"Version"];
-             XCTAssertEqualObjects(version, @"123");
-
-             [expectation fulfill];
-           }];
-
-  // Wait a little bit so the server has enough time to respond.
-  [self waitForExpectationsWithTimeout:10
-                               handler:^(NSError *error) {
-                                 if (error) {
-                                   XCTFail(@"Timeout Error: %@", error);
-                                 }
-                               }];
-}
-
-#pragma mark - Test clean up files
-
-- (void)testRemoveExpiredFiles {
-  NSError *writeError = nil;
-  NSFileManager *fileManager = [NSFileManager defaultManager];
-
-  GULNetworkURLSession *session = [[GULNetworkURLSession alloc]
-      initWithNetworkLoggerDelegate:(id<GULNetworkLoggerDelegate>)_network];
-#if TARGET_OS_TV
-  NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
-#else
-  NSArray *paths =
-      NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
-#endif
-  NSString *applicationSupportDirectory = paths.firstObject;
-  NSArray *tempPathComponents = @[
-    applicationSupportDirectory, kGULNetworkApplicationSupportSubdirectory,
-    @"GULNetworkTemporaryDirectory"
-  ];
-  NSURL *folderURL = [NSURL fileURLWithPathComponents:tempPathComponents];
-  [fileManager createDirectoryAtURL:folderURL
-        withIntermediateDirectories:YES
-                         attributes:nil
-                              error:&writeError];
-
-  NSURL *tempFile1 = [folderURL URLByAppendingPathComponent:@"FIRUpload_temp_123"];
-  [self createTempFileAtURL:tempFile1];
-  NSURL *tempFile2 = [folderURL URLByAppendingPathComponent:@"FIRUpload_temp_456"];
-  [self createTempFileAtURL:tempFile2];
-
-  XCTAssertTrue([fileManager fileExistsAtPath:tempFile1.path]);
-  XCTAssertTrue([fileManager fileExistsAtPath:tempFile2.path]);
-
-  NSDate *now =
-      [[NSDate date] dateByAddingTimeInterval:1];  // Start mocking the clock to avoid flakiness.
-  id mockDate = OCMStrictClassMock([NSDate class]);
-  [[[mockDate stub] andReturn:now] date];
-
-  // The file should not be removed since it is not expired yet.
-  [session maybeRemoveTempFilesAtURL:folderURL expiringTime:20];
-  XCTAssertTrue([fileManager fileExistsAtPath:tempFile1.path]);
-  XCTAssertTrue([fileManager fileExistsAtPath:tempFile2.path]);
-
-  [mockDate stopMocking];
-  mockDate = nil;
-
-  now = [[NSDate date] dateByAddingTimeInterval:100];  // Move forward in time 100s.
-  mockDate = OCMStrictClassMock([NSDate class]);
-  [[[mockDate stub] andReturn:now] date];
-
-  [session maybeRemoveTempFilesAtURL:folderURL expiringTime:20];
-  XCTAssertFalse([fileManager fileExistsAtPath:tempFile1.path]);
-  XCTAssertFalse([fileManager fileExistsAtPath:tempFile2.path]);
-  [mockDate stopMocking];
-  mockDate = nil;
-}
-
-#pragma mark - Internal Methods
-
-- (void)createTempFileAtURL:(NSURL *)fileURL {
-  // Create a dictionary and write it to file.
-  NSDictionary *someContent = @{@"object" : @"key"};
-  [someContent writeToURL:fileURL atomically:YES];
-}
-
-- (void)verifyResponse:(NSHTTPURLResponse *)response error:(NSError *)error {
-  XCTAssertNil(error, @"Error is not expected");
-  XCTAssertNotNil(response, @"Error is not expected");
-}
-
-- (void)verifyRequest {
-  XCTAssertNotNil(_request, @"Request cannot be nil");
-
-  // Test whether the request is compressed correctly.
-  NSData *requestBody = [_request body];
-  NSData *decompressedRequestData = [NSData gul_dataByInflatingGzippedData:requestBody error:NULL];
-  NSString *requestString = [[NSString alloc] initWithData:decompressedRequestData
-                                                  encoding:NSUTF8StringEncoding];
-  XCTAssertEqualObjects(requestString, @"Google", @"Request is not compressed correctly.");
-
-  // The request has to be a POST.
-  XCTAssertEqualObjects([_request method], @"POST", @"Request method has to be POST");
-
-  // Content length has to be set correctly.
-  NSString *contentLength = [_request.allHeaderFieldValues valueForKey:@"Content-Length"];
-  XCTAssertEqualObjects(contentLength, @"26", @"Content Length is incorrect");
-
-  NSString *contentEncoding = [_request.allHeaderFieldValues valueForKey:@"Content-Encoding"];
-  XCTAssertEqualObjects(contentEncoding, @"gzip", @"Content Encoding is incorrect");
-}
-
-#pragma mark - Helper Methods
-
-- (GTMHTTPResponseMessage *)httpServer:(GTMHTTPServer *)server
-                         handleRequest:(GTMHTTPRequestMessage *)request {
-  _request = request;
-
-  NSData *html =
-      [@"<html><body>Hello, World!</body></html>" dataUsingEncoding:NSUTF8StringEncoding];
-  return [GTMHTTPResponseMessage responseWithBody:html
-                                      contentType:@"text/html; charset=UTF-8"
-                                       statusCode:_statusCode];
-}
-
-- (BOOL)isReachable {
-  return _fakeNetworkIsReachable;
-}
-
-- (GULReachabilityStatus)reachabilityStatus {
-  return _fakeReachabilityStatus;
-}
-
-#pragma mark - FIRReachabilityDelegate
-
-- (void)reachabilityDidChange {
-  _currentNetworkStatus = _fakeNetworkIsReachable;
-}
-
-@end
-
-#endif  // TARGET_OS_MACCATALYST

+ 0 - 173
GoogleUtilities/Tests/Unit/Network/third_party/GTMHTTPServer.h

@@ -1,173 +0,0 @@
-/* Copyright 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//
-//  GTMHTTPServer.h
-//
-//  This is a *very* *simple* webserver that can be built into something, it is
-//  not meant to stand up a site, it sends all requests to its delegate for
-//  processing on the main thread.  It does not support pipelining, etc.  It's
-//  great for places where you need a simple webserver to unittest some code
-//  that hits a server.
-//
-//  NOTE: there are several TODOs left in here as markers for things that could
-//  be done if one wanted to add more to this class.
-//
-//  Based a little on HTTPServer, part of the CocoaHTTPServer sample code found at
-//  https://opensource.apple.com/source/HTTPServer/HTTPServer-11/CocoaHTTPServer/
-//  License for the CocoaHTTPServer sample code:
-//
-//  Software License Agreement (BSD License)
-//
-//  Copyright (c) 2011, Deusty, LLC
-//  All rights reserved.
-//
-//  Redistribution and use of this software 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.
-//
-//  * Neither the name of Deusty nor the names of its
-//  contributors may be used to endorse or promote products
-//  derived from this software without specific prior
-//  written permission of Deusty, LLC.
-//
-//  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.
-
-#import <Foundation/Foundation.h>
-
-#if GTM_IPHONE_SDK
-#import <CFNetwork/CFNetwork.h>
-#endif  // GTM_IPHONE_SDK
-
-// Global contants needed for errors from start
-
-#undef _EXTERN
-#undef _INITIALIZE_AS
-#ifdef GTMHTTPSERVER_DEFINE_GLOBALS
-#define _EXTERN
-#define _INITIALIZE_AS(x) = x
-#else
-#define _EXTERN extern
-#define _INITIALIZE_AS(x)
-#endif
-
-_EXTERN NSString *const kGTMHTTPServerErrorDomain
-    _INITIALIZE_AS(@"com.google.mactoolbox.HTTPServerDomain");
-enum {
-  kGTMHTTPServerSocketCreateFailedError = -100,
-  kGTMHTTPServerBindFailedError = -101,
-  kGTMHTTPServerListenFailedError = -102,
-  kGTMHTTPServerHandleCreateFailedError = -103,
-};
-
-@class GTMHTTPRequestMessage, GTMHTTPResponseMessage;
-
-// ----------------------------------------------------------------------------
-
-// See comment at top of file for the intened use of this class.
-@interface GTMHTTPServer : NSObject {
- @private
-  id delegate_;  // WEAK
-  uint16_t port_;
-  BOOL reusePort_;
-  BOOL localhostOnly_;
-  NSFileHandle *listenHandle_;
-  NSMutableArray *connections_;
-}
-
-// The delegate must support the httpServer:handleRequest: method in
-// NSObject(GTMHTTPServerDelegateMethods) below.
-- (id)initWithDelegate:(id)delegate;
-
-- (id)delegate;
-
-// Passing port zero will let one get assigned.
-- (uint16_t)port;
-- (void)setPort:(uint16_t)port;
-
-// Controls listening socket behavior: SO_REUSEADDR vs SO_REUSEPORT.
-// The default is NO (SO_REUSEADDR)
-- (BOOL)reusePort;
-- (void)setReusePort:(BOOL)reusePort;
-
-// Receive connections on the localHost loopback address only or on all
-// interfaces for this machine.  The default is to only listen on localhost.
-- (BOOL)localhostOnly;
-- (void)setLocalhostOnly:(BOOL)yesno;
-
-// Start/Stop the web server.  If there is an error starting up the server, |NO|
-// is returned, and the specific startup failure can be returned in |error| (see
-// above for the error domain and error codes).  If the server is started, |YES|
-// is returned and the server's delegate is called for any requests that come
-// in.
-- (BOOL)start:(NSError **)error;
-- (void)stop;
-
-// returns the number of requests currently active in the server (i.e.-being
-// read in, sent replies).
-- (NSUInteger)activeRequestCount;
-
-@end
-
-@interface NSObject (GTMHTTPServerDelegateMethods)
-- (GTMHTTPResponseMessage *)httpServer:(GTMHTTPServer *)server
-                         handleRequest:(GTMHTTPRequestMessage *)request;
-@end
-
-// ----------------------------------------------------------------------------
-
-// Encapsulates an http request, one of these is sent to the server's delegate
-// for each request.
-@interface GTMHTTPRequestMessage : NSObject {
- @private
-  CFHTTPMessageRef message_;
-}
-- (NSString *)version;
-- (NSURL *)URL;
-- (NSString *)method;
-- (NSData *)body;
-- (NSDictionary *)allHeaderFieldValues;
-@end
-
-// ----------------------------------------------------------------------------
-
-// Encapsulates an http response, the server's delegate should return one for
-// each request received.
-@interface GTMHTTPResponseMessage : NSObject {
- @private
-  CFHTTPMessageRef message_;
-}
-+ (instancetype)responseWithString:(NSString *)plainText;
-+ (instancetype)responseWithHTMLString:(NSString *)htmlString;
-+ (instancetype)responseWithBody:(NSData *)body
-                     contentType:(NSString *)contentType
-                      statusCode:(int)statusCode;
-+ (instancetype)emptyResponseWithCode:(int)statusCode;
-// TODO: class method for redirections?
-// TODO: add helper for expire/no-cache
-- (void)setValue:(NSString *)value forHeaderField:(NSString *)headerField;
-- (void)setHeaderValuesFromDictionary:(NSDictionary *)dict;
-@end

Някои файлове не бяха показани, защото твърде много файлове са промени