diff --git a/HD wallpaper.xcworkspace/xcuserdata/aaa.xcuserdatad/UserInterfaceState.xcuserstate b/HD wallpaper.xcworkspace/xcuserdata/aaa.xcuserdatad/UserInterfaceState.xcuserstate index c53dfc0..f6bc499 100644 Binary files a/HD wallpaper.xcworkspace/xcuserdata/aaa.xcuserdatad/UserInterfaceState.xcuserstate and b/HD wallpaper.xcworkspace/xcuserdata/aaa.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/HDwallpaper/AppDelegate.m b/HDwallpaper/AppDelegate.m index 7092888..8da4dd2 100644 --- a/HDwallpaper/AppDelegate.m +++ b/HDwallpaper/AppDelegate.m @@ -11,7 +11,9 @@ #import #import "AWM_NetManager.h" -#import +#import +#import +#import @interface AppDelegate () @property (nonatomic,strong) NSTimer *attTimer; @end @@ -77,7 +79,9 @@ NSDateFormatter *unfasten_4 = [NSDateFormatter new]; NSString *noble_W = [unfasten_4 stringFromDate:[NSDate date]]; [[NSUserDefaults standardUserDefaults] setObject:noble_W forKey:@"shack_k"]; + [FIRApp configure]; + // [AWM_NetManager requestRemoteIp]; // // [[AWM_WallPapaerADManager shareInstance] configureAD]; diff --git a/HDwallpaper/GoogleService-Info.plist b/HDwallpaper/GoogleService-Info.plist new file mode 100644 index 0000000..759435d --- /dev/null +++ b/HDwallpaper/GoogleService-Info.plist @@ -0,0 +1,30 @@ + + + + + API_KEY + AIzaSyDPPWoejci3wTaQ5UT15vNZpdNR36Xd1YU + GCM_SENDER_ID + 690216584185 + PLIST_VERSION + 1 + BUNDLE_ID + com.digi.art.wallpaper + PROJECT_ID + artwallpapers-ef985 + STORAGE_BUCKET + artwallpapers-ef985.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:690216584185:ios:de81097f50ecb5118cf328 + + \ No newline at end of file diff --git a/Podfile b/Podfile index 8ccb251..b30862f 100644 --- a/Podfile +++ b/Podfile @@ -1,10 +1,26 @@ # Uncomment the next line to define a global platform for your project # platform :ios, '9.0' -target 'HD wallpaper' do +target 'TallPaper' do # Comment the next line if you don't want to use dynamic frameworks use_frameworks! # Pods for HD wallpaper # pod 'AppLovinSDK' +pod 'Firebase/AnalyticsWithoutAdIdSupport' +pod 'FirebaseRemoteConfig' + +post_install do |installer| + installer.generated_projects.each do |project| + project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0' + end + end + end end + + +end + + diff --git a/Podfile.lock b/Podfile.lock index bd90c1d..32f7bd1 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,3 +1,117 @@ -PODFILE CHECKSUM: 8bd30fbf8fb43ccff22be3db42a9e910ca8a34af +PODS: + - Firebase/AnalyticsWithoutAdIdSupport (10.28.1): + - Firebase/CoreOnly + - FirebaseAnalytics/WithoutAdIdSupport (~> 10.28.0) + - Firebase/CoreOnly (10.28.1): + - FirebaseCore (= 10.28.1) + - FirebaseABTesting (10.28.0): + - FirebaseCore (~> 10.0) + - FirebaseAnalytics/WithoutAdIdSupport (10.28.0): + - FirebaseCore (~> 10.0) + - FirebaseInstallations (~> 10.0) + - GoogleAppMeasurement/WithoutAdIdSupport (= 10.28.0) + - GoogleUtilities/AppDelegateSwizzler (~> 7.11) + - GoogleUtilities/MethodSwizzler (~> 7.11) + - GoogleUtilities/Network (~> 7.11) + - "GoogleUtilities/NSData+zlib (~> 7.11)" + - nanopb (< 2.30911.0, >= 2.30908.0) + - FirebaseCore (10.28.1): + - FirebaseCoreInternal (~> 10.0) + - GoogleUtilities/Environment (~> 7.12) + - GoogleUtilities/Logger (~> 7.12) + - FirebaseCoreInternal (10.28.0): + - "GoogleUtilities/NSData+zlib (~> 7.8)" + - FirebaseInstallations (10.28.0): + - FirebaseCore (~> 10.0) + - GoogleUtilities/Environment (~> 7.8) + - GoogleUtilities/UserDefaults (~> 7.8) + - PromisesObjC (~> 2.1) + - FirebaseRemoteConfig (10.28.0): + - FirebaseABTesting (~> 10.0) + - FirebaseCore (~> 10.0) + - FirebaseInstallations (~> 10.0) + - FirebaseRemoteConfigInterop (~> 10.23) + - FirebaseSharedSwift (~> 10.0) + - GoogleUtilities/Environment (~> 7.8) + - "GoogleUtilities/NSData+zlib (~> 7.8)" + - FirebaseRemoteConfigInterop (10.28.0) + - FirebaseSharedSwift (10.28.0) + - GoogleAppMeasurement/WithoutAdIdSupport (10.28.0): + - GoogleUtilities/AppDelegateSwizzler (~> 7.11) + - GoogleUtilities/MethodSwizzler (~> 7.11) + - GoogleUtilities/Network (~> 7.11) + - "GoogleUtilities/NSData+zlib (~> 7.11)" + - nanopb (< 2.30911.0, >= 2.30908.0) + - GoogleUtilities/AppDelegateSwizzler (7.13.3): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Privacy + - GoogleUtilities/Environment (7.13.3): + - GoogleUtilities/Privacy + - PromisesObjC (< 3.0, >= 1.2) + - GoogleUtilities/Logger (7.13.3): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - GoogleUtilities/MethodSwizzler (7.13.3): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/Network (7.13.3): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Privacy + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (7.13.3)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (7.13.3) + - GoogleUtilities/Reachability (7.13.3): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/UserDefaults (7.13.3): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - nanopb (2.30910.0): + - nanopb/decode (= 2.30910.0) + - nanopb/encode (= 2.30910.0) + - nanopb/decode (2.30910.0) + - nanopb/encode (2.30910.0) + - PromisesObjC (2.4.0) + +DEPENDENCIES: + - Firebase/AnalyticsWithoutAdIdSupport + - FirebaseRemoteConfig + +SPEC REPOS: + trunk: + - Firebase + - FirebaseABTesting + - FirebaseAnalytics + - FirebaseCore + - FirebaseCoreInternal + - FirebaseInstallations + - FirebaseRemoteConfig + - FirebaseRemoteConfigInterop + - FirebaseSharedSwift + - GoogleAppMeasurement + - GoogleUtilities + - nanopb + - PromisesObjC + +SPEC CHECKSUMS: + Firebase: 49e62242b3ae422a002ab647a7e62a332a8c3ec1 + FirebaseABTesting: 589bc28c0ab3e5554336895a34aa262e24276665 + FirebaseAnalytics: 1e06fe7d246af7230b08d1d9cdca54a4624dd461 + FirebaseCore: dfc33f0dffba05f76181da9cc0151171ebb3bd10 + FirebaseCoreInternal: 58d07f1362fddeb0feb6a857d1d1d1c5e558e698 + FirebaseInstallations: 60c1d3bc1beef809fd1ad1189a8057a040c59f2e + FirebaseRemoteConfig: f0879a8dccf4e8905716ed849569130efaeab3e2 + FirebaseRemoteConfigInterop: 70d200c6956ef3b5c3592a95e824c1210682d785 + FirebaseSharedSwift: 48de4aec81a6b79bb30404e5e6db43ea74848fed + GoogleAppMeasurement: 55a4a3c8000c1280d68bf4c084adbfef20c49db1 + GoogleUtilities: ea963c370a38a8069cc5f7ba4ca849a60b6d7d15 + nanopb: 438bc412db1928dac798aa6fd75726007be04262 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + +PODFILE CHECKSUM: 2f2e5df210dba6ae9a689623ed2ba20922376bc0 COCOAPODS: 1.15.2 diff --git a/Pods/Firebase/CoreOnly/Sources/Firebase.h b/Pods/Firebase/CoreOnly/Sources/Firebase.h new file mode 100755 index 0000000..8a7420d --- /dev/null +++ b/Pods/Firebase/CoreOnly/Sources/Firebase.h @@ -0,0 +1,81 @@ +// 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 + +#if !defined(__has_include) + #error "Firebase.h won't import anything if your compiler doesn't support __has_include. Please \ + import the headers individually." +#else + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include("FirebaseFunctions-umbrella.h") + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include("FirebaseStorage-umbrella.h") + #import + #endif + +#endif // defined(__has_include) diff --git a/Pods/Firebase/CoreOnly/Sources/module.modulemap b/Pods/Firebase/CoreOnly/Sources/module.modulemap new file mode 100755 index 0000000..3685b54 --- /dev/null +++ b/Pods/Firebase/CoreOnly/Sources/module.modulemap @@ -0,0 +1,4 @@ +module Firebase { + export * + header "Firebase.h" +} \ No newline at end of file diff --git a/Pods/Firebase/LICENSE b/Pods/Firebase/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/Pods/Firebase/LICENSE @@ -0,0 +1,202 @@ + + 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. diff --git a/Pods/Firebase/README.md b/Pods/Firebase/README.md new file mode 100644 index 0000000..4c915ab --- /dev/null +++ b/Pods/Firebase/README.md @@ -0,0 +1,297 @@ +

+ + + + + + + + +
+ + + + + + +

+ +# Firebase Apple Open Source Development + +This repository contains the source code for all Apple platform Firebase SDKs except FirebaseAnalytics. + +Firebase is an app development platform with tools to help you build, grow, and +monetize your app. More information about Firebase can be found on the +[official Firebase website](https://firebase.google.com). + +## Installation + +See the subsections below for details about the different installation methods. Where +available, it's recommended to install any libraries with a `Swift` suffix to get the +best experience when writing your app in Swift. + +1. [Standard pod install](#standard-pod-install) +2. [Swift Package Manager](#swift-package-manager) +3. [Installing from the GitHub repo](#installing-from-github) +4. [Experimental Carthage](#carthage-ios-only) + +### Standard pod install + +For instructions on the standard pod install, visit: +[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup). + +### Swift Package Manager + +Instructions for [Swift Package Manager](https://swift.org/package-manager/) support can be +found in the [SwiftPackageManager.md](SwiftPackageManager.md) Markdown file. + +### Installing from GitHub + +These instructions can be used to access the Firebase repo at other branches, +tags, or commits. + +#### Background + +See [the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod) +for instructions and options about overriding pod source locations. + +#### Accessing Firebase Source Snapshots + +All official releases are tagged in this repo and available via CocoaPods. To access a local +source snapshot or unreleased branch, use Podfile directives like the following: + +To access FirebaseFirestore via a branch: +```ruby +pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'main' +pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'main' +``` + +To access FirebaseMessaging via a checked-out version of the firebase-ios-sdk repo: +```ruby +pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk' +pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk' +``` + +### Carthage (iOS only) + +Instructions for the experimental Carthage distribution can be found at +[Carthage.md](Carthage.md). + +### Using Firebase from a Framework or a library + +For details on using Firebase from a Framework or a library, refer to [firebase_in_libraries.md](docs/firebase_in_libraries.md). + +## Development + +To develop Firebase software in this repository, ensure that you have at least +the following software: + +* Xcode 15.2 (or later) + +CocoaPods is still the canonical way to develop, but much of the repo now supports +development with Swift Package Manager. + +### CocoaPods + +Install the following: +* CocoaPods 1.12.0 (or later) +* [CocoaPods generate](https://github.com/square/cocoapods-generate) + +For the pod that you want to develop: + +```ruby +pod gen Firebase{name here}.podspec --local-sources=./ --auto-open --platforms=ios +``` + +Note: If the CocoaPods cache is out of date, you may need to run +`pod repo update` before the `pod gen` command. + +Note: Set the `--platforms` option to `macos` or `tvos` to develop/test for +those platforms. Since 10.2, Xcode does not properly handle multi-platform +CocoaPods workspaces. + +Firestore has a self-contained Xcode project. See +[Firestore/README](Firestore/README.md) Markdown file. + +#### Development for Catalyst +* `pod gen {name here}.podspec --local-sources=./ --auto-open --platforms=ios` +* Check the Mac box in the App-iOS Build Settings +* Sign the App in the Settings Signing & Capabilities tab +* Click Pods in the Project Manager +* Add Signing to the iOS host app and unit test targets +* Select the Unit-unit scheme +* Run it to build and test + +Alternatively, disable signing in each target: +* Go to Build Settings tab +* Click `+` +* Select `Add User-Defined Setting` +* Add `CODE_SIGNING_REQUIRED` setting with a value of `NO` + +### Swift Package Manager +* To enable test schemes: `./scripts/setup_spm_tests.sh` +* `open Package.swift` or double click `Package.swift` in Finder. +* Xcode will open the project + * Choose a scheme for a library to build or test suite to run + * Choose a target platform by selecting the run destination along with the scheme + +### Adding a New Firebase Pod + +Refer to [AddNewPod](AddNewPod.md) Markdown file for details. + +### Managing Headers and Imports + +For information about managing headers and imports, see [HeadersImports](HeadersImports.md) Markdown file. + +### Code Formatting + +To ensure that the code is formatted consistently, run the script +[./scripts/check.sh](https://github.com/firebase/firebase-ios-sdk/blob/main/scripts/check.sh) +before creating a pull request (PR). + +GitHub Actions will verify that any code changes are done in a style-compliant +way. Install `clang-format` and `mint`: + +```console +brew install clang-format@18 +brew install mint +``` + +### Running Unit Tests + +Select a scheme and press Command-u to build a component and run its unit tests. + +### Running Sample Apps +To run the sample apps and integration tests, you'll need a valid +`GoogleService-Info.plist +` file. The Firebase Xcode project contains dummy plist +files without real values, but they can be replaced with real plist files. To get your own +`GoogleService-Info.plist` files: + +1. Go to the [Firebase Console](https://console.firebase.google.com/) +2. Create a new Firebase project, if you don't already have one +3. For each sample app you want to test, create a new Firebase app with the sample app's bundle +identifier (e.g., `com.google.Database-Example`) +4. Download the resulting `GoogleService-Info.plist` and add it to the Xcode project. + +### Coverage Report Generation + +For coverage report generation instructions, see [scripts/code_coverage_report/README](scripts/code_coverage_report/README.md) Markdown file. + +## Specific Component Instructions +See the sections below for any special instructions for those components. + +### Firebase Auth + +For specific Firebase Auth development, refer to the [Auth Sample README](FirebaseAuth/Tests/Sample/README.md) for instructions about +building and running the FirebaseAuth pod along with various samples and tests. + +### Firebase Database + +The Firebase Database Integration tests can be run against a locally running Database Emulator +or against a production instance. + +To run against a local emulator instance, invoke `./scripts/run_database_emulator.sh start` before +running the integration test. + +To run against a production instance, provide a valid `GoogleServices-Info.plist` and copy it to +`FirebaseDatabase/Tests/Resources/GoogleService-Info.plist`. Your Security Rule must be set to +[public](https://firebase.google.com/docs/database/security/quickstart) while your tests are +running. + +### Firebase Dynamic Links + +Firebase Dynamic Links is **deprecated** and should not be used in new projects. The service will shut down on August 25, 2025. + +Please see our [Dynamic Links Deprecation FAQ documentation](https://firebase.google.com/support/dynamic-links-faq) for more guidance. + +### Firebase Performance Monitoring + +For specific Firebase Performance Monitoring development, see +[the Performance README](FirebasePerformance/README.md) for instructions about building the SDK +and [the Performance TestApp README](FirebasePerformance/Tests/TestApp/README.md) for instructions about +integrating Performance with the dev test App. + +### Firebase Storage + +To run the Storage Integration tests, follow the instructions in +[StorageIntegration.swift](FirebaseStorage/Tests/Integration/StorageIntegration.swift). + +#### Push Notifications + +Push notifications can only be delivered to specially provisioned App IDs in the developer portal. +In order to test receiving push notifications, you will need to: + +1. Change the bundle identifier of the sample app to something you own in your Apple Developer +account and enable that App ID for push notifications. +2. You'll also need to +[upload your APNs Provider Authentication Key or certificate to the +Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs) +at **Project Settings > Cloud Messaging > [Your Firebase App]**. +3. Ensure your iOS device is added to your Apple Developer portal as a test device. + +#### iOS Simulator + +The iOS Simulator cannot register for remote notifications and will not receive push notifications. +To receive push notifications, follow the steps above and run the app on a physical device. + +## Building with Firebase on Apple platforms + +Firebase provides official beta support for macOS, Catalyst, and tvOS. visionOS and watchOS +are community supported. Thanks to community contributions for many of the multi-platform PRs. + +At this time, most of Firebase's products are available across Apple platforms. There are still +a few gaps, especially on visionOS and watchOS. For details about the current support matrix, see +[this chart](https://firebase.google.com/docs/ios/learn-more#firebase_library_support_by_platform) +in Firebase's documentation. + +### visionOS + +Where supported, visionOS works as expected with the exception of Firestore via Swift Package +Manager where it is required to use the source distribution. + +To enable the Firestore source distribution, quit Xcode and open the desired +project from the command line with the `FIREBASE_SOURCE_FIRESTORE` environment +variable: `open --env FIREBASE_SOURCE_FIRESTORE /path/to/project.xcodeproj`. +To go back to using the binary distribution of Firestore, quit Xcode and open +Xcode like normal, without the environment variable. + +### watchOS +Thanks to contributions from the community, many of Firebase SDKs now compile, run unit tests, and +work on watchOS. See the [Independent Watch App Sample](Example/watchOSSample). + +Keep in mind that watchOS is not officially supported by Firebase. While we can catch basic unit +test issues with GitHub Actions, there may be some changes where the SDK no longer works as expected +on watchOS. If you encounter this, please +[file an issue](https://github.com/firebase/firebase-ios-sdk/issues). + +During app setup in the console, you may get to a step that mentions something like "Checking if the +app has communicated with our servers". This relies on Analytics and will not work on watchOS. +**It's safe to ignore the message and continue**, the rest of the SDKs will work as expected. + +#### Additional Crashlytics Notes +* watchOS has limited support. Due to watchOS restrictions, mach exceptions and signal crashes are +not recorded. (Crashes in SwiftUI are generated as mach exceptions, so will not be recorded) + +## Combine +Thanks to contributions from the community, _FirebaseCombineSwift_ contains support for Apple's Combine +framework. This module is currently under development and not yet supported for use in production +environments. For more details, please refer to the [docs](FirebaseCombineSwift/README.md). + +## Roadmap + +See [Roadmap](ROADMAP.md) for more about the Firebase Apple SDK Open Source +plans and directions. + +## Contributing + +See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase +Apple SDK. + +## License + +The contents of this repository are licensed under the +[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +Your use of Firebase is governed by the +[Terms of Service for Firebase Services](https://firebase.google.com/terms/). diff --git a/Pods/FirebaseABTesting/FirebaseABTesting/Sources/ABTConditionalUserPropertyController.h b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/ABTConditionalUserPropertyController.h new file mode 100644 index 0000000..54e10b0 --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/ABTConditionalUserPropertyController.h @@ -0,0 +1,79 @@ +// 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 +#import "FirebaseABTesting/Sources/Private/ABTExperimentPayload.h" + +#import "Interop/Analytics/Public/FIRAnalyticsInterop.h" + +NS_ASSUME_NONNULL_BEGIN + +@class FIRLifecycleEvents; + +/// This class dynamically calls Firebase Analytics API to collect or update experiments +/// information. +/// The experiment in Firebase Analytics is named as conditional user property (CUP) object defined +/// in FIRAConditionalUserProperty.h. +@interface ABTConditionalUserPropertyController : NSObject + +/// Returns the ABTConditionalUserPropertyController singleton. ++ (instancetype)sharedInstanceWithAnalytics:(id _Nullable)analytics; + +/// Returns the list of currently set experiments from Firebase Analytics for the provided origin. +- (NSArray *)experimentsWithOrigin:(NSString *)origin; + +/// Returns the experiment ID from Firebase Analytics given an experiment object. Returns empty +/// string if can't find Firebase Analytics service. +- (NSString *)experimentIDOfExperiment:(nullable id)experiment; + +/// Returns the variant ID from Firebase Analytics given an experiment object. Returns empty string +/// if can't find Firebase Analytics service. +- (NSString *)variantIDOfExperiment:(nullable id)experiment; + +/// Returns whether the experiment is the same as the one in the provided payload. +- (BOOL)isExperiment:(id)experiment theSameAsPayload:(ABTExperimentPayload *)payload; + +/// Clears the experiment in Firebase Analytics. +/// @param experimentID Experiment ID to clear. +/// @param variantID Variant ID to clear. +/// @param origin Impacted originating service, it is defined at Firebase Analytics +/// FIREventOrigins.h. +/// @param payload Payload to overwrite event name in events. DO NOT use payload's experiment +/// ID and variant ID as the experiment to clear. +/// @param events Events name for clearing the experiment. +- (void)clearExperiment:(NSString *)experimentID + variantID:(NSString *)variantID + withOrigin:(NSString *)origin + payload:(nullable ABTExperimentPayload *)payload + events:(FIRLifecycleEvents *)events; + +/// Sets the experiment in Firebase Analytics. +/// @param origin Impacted originating service, it is defined at Firebase Analytics +/// FIREventOrigins.h. +/// @param payload Payload to overwrite event name in events. DO NOT use payload's experiment +/// ID and variant ID as the experiment to set. +/// @param events Events name for setting the experiment. +/// @param policy Overflow policy when the number of experiments is over the limit. +- (void)setExperimentWithOrigin:(NSString *)origin + payload:(ABTExperimentPayload *)payload + events:(FIRLifecycleEvents *)events + policy:(ABTExperimentPayloadExperimentOverflowPolicy)policy; + +/** + * Unavailable. Use sharedInstanceWithAnalytics: instead. + */ +- (instancetype)init __attribute__((unavailable("Use +sharedInstanceWithAnalytics: instead."))); +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseABTesting/FirebaseABTesting/Sources/ABTConditionalUserPropertyController.m b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/ABTConditionalUserPropertyController.m new file mode 100644 index 0000000..e555826 --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/ABTConditionalUserPropertyController.m @@ -0,0 +1,288 @@ +// 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 "FirebaseABTesting/Sources/ABTConditionalUserPropertyController.h" + +#import "FirebaseABTesting/Sources/ABTConstants.h" +#import "FirebaseABTesting/Sources/Public/FirebaseABTesting/FIRLifecycleEvents.h" +#import "FirebaseCore/Extension/FirebaseCoreInternal.h" +#import "Interop/Analytics/Public/FIRAnalyticsInterop.h" + +@implementation ABTConditionalUserPropertyController { + dispatch_queue_t _analyticOperationQueue; + id _Nullable _analytics; +} + +/// Returns the ABTConditionalUserPropertyController singleton. ++ (instancetype)sharedInstanceWithAnalytics:(id _Nullable)analytics { + static ABTConditionalUserPropertyController *sharedInstance = nil; + static dispatch_once_t onceToken = 0; + dispatch_once(&onceToken, ^{ + sharedInstance = [[ABTConditionalUserPropertyController alloc] initWithAnalytics:analytics]; + }); + return sharedInstance; +} + +- (instancetype)initWithAnalytics:(id _Nullable)analytics { + self = [super init]; + if (self) { + _analyticOperationQueue = + dispatch_queue_create("com.google.FirebaseABTesting.analytics", DISPATCH_QUEUE_SERIAL); + _analytics = analytics; + } + return self; +} + +#pragma mark - experiments proxy methods on Firebase Analytics + +- (NSArray *)experimentsWithOrigin:(NSString *)origin { + return [_analytics conditionalUserProperties:origin propertyNamePrefix:@""]; +} + +- (void)clearExperiment:(NSString *)experimentID + variantID:(NSString *)variantID + withOrigin:(NSString *)origin + payload:(ABTExperimentPayload *)payload + events:(FIRLifecycleEvents *)events { + // Payload always overwrite event names. + NSString *clearExperimentEventName = events.clearExperimentEventName; + if (payload && payload.clearEventToLog && payload.clearEventToLog.length) { + clearExperimentEventName = payload.clearEventToLog; + } + + [_analytics clearConditionalUserProperty:experimentID + forOrigin:origin + clearEventName:clearExperimentEventName + clearEventParameters:@{experimentID : variantID}]; + + FIRLogDebug(kFIRLoggerABTesting, @"I-ABT000015", @"Clear Experiment ID %@, variant ID %@.", + experimentID, variantID); +} + +- (void)setExperimentWithOrigin:(NSString *)origin + payload:(ABTExperimentPayload *)payload + events:(FIRLifecycleEvents *)events + policy:(ABTExperimentPayloadExperimentOverflowPolicy)policy { + NSInteger maxNumOfExperiments = [self maxNumberOfExperimentsOfOrigin:origin]; + if (maxNumOfExperiments < 0) { + return; + } + + // Clear experiments if overflow + NSArray *experiments = [self experimentsWithOrigin:origin]; + if (!experiments) { + FIRLogInfo(kFIRLoggerABTesting, @"I-ABT000003", + @"Failed to get conditional user properties from Firebase Analytics."); + return; + } + + if (payload.experimentId == nil) { + // When doing experiment test on devices, the payload could be empty. Returning here to prevent + // app crash. + FIRLogInfo(kFIRLoggerABTesting, @"I-ABT000020", @"Experiment Id in payload is empty."); + return; + } + + if (maxNumOfExperiments <= experiments.count) { + ABTExperimentPayloadExperimentOverflowPolicy overflowPolicy = + [self overflowPolicyWithPayload:payload originalPolicy:policy]; + id experimentToClear = experiments.firstObject; + if (overflowPolicy == ABTExperimentPayloadExperimentOverflowPolicyDiscardOldest && + experimentToClear) { + NSString *expID = [self experimentIDOfExperiment:experimentToClear]; + NSString *varID = [self variantIDOfExperiment:experimentToClear]; + + [self clearExperiment:expID variantID:varID withOrigin:origin payload:payload events:events]; + FIRLogDebug(kFIRLoggerABTesting, @"I-ABT000016", + @"Clear experiment ID %@ variant ID %@ due to " + @"overflow policy.", + expID, varID); + + } else { + FIRLogDebug(kFIRLoggerABTesting, @"I-ABT000017", + @"Experiment ID %@ variant ID %@ won't be set due to " + @"overflow policy.", + payload.experimentId, payload.variantId); + + return; + } + } + + // Clear experiment if other variant ID exists. + NSString *experimentID = payload.experimentId; + NSString *variantID = payload.variantId; + for (id experiment in experiments) { + NSString *expID = [self experimentIDOfExperiment:experiment]; + NSString *varID = [self variantIDOfExperiment:experiment]; + if ([expID isEqualToString:experimentID] && ![varID isEqualToString:variantID]) { + FIRLogDebug(kFIRLoggerABTesting, @"I-ABT000018", + @"Clear experiment ID %@ with variant ID %@ because " + @"only one variant ID can be existed " + @"at any time.", + expID, varID); + [self clearExperiment:expID variantID:varID withOrigin:origin payload:payload events:events]; + } + } + + // Set experiment + NSDictionary *experiment = [self createExperimentFromOrigin:origin + payload:payload + events:events]; + + [_analytics setConditionalUserProperty:experiment]; + + FIRLogDebug(kFIRLoggerABTesting, @"I-ABT000019", + @"Set conditional user property, experiment ID %@ with " + @"variant ID %@ triggered event %@.", + experimentID, variantID, payload.triggerEvent); + + // Log setEvent (experiment lifecycle event to be set when an experiment is set) + [self logEventWithOrigin:origin payload:payload events:events]; +} + +- (NSMutableDictionary *)createExperimentFromOrigin:(NSString *)origin + payload:(ABTExperimentPayload *)payload + events:(FIRLifecycleEvents *)events { + NSMutableDictionary *experiment = [[NSMutableDictionary alloc] init]; + NSString *experimentID = payload.experimentId; + NSString *variantID = payload.variantId; + + NSDictionary *eventParams = @{experimentID : variantID}; + + [experiment setValue:origin forKey:kABTExperimentDictionaryOriginKey]; + + NSTimeInterval creationTimestamp = (double)(payload.experimentStartTimeMillis / ABT_MSEC_PER_SEC); + [experiment setValue:@(creationTimestamp) forKey:kABTExperimentDictionaryCreationTimestampKey]; + [experiment setValue:experimentID forKey:kABTExperimentDictionaryExperimentIDKey]; + [experiment setValue:variantID forKey:kABTExperimentDictionaryVariantIDKey]; + + // For the experiment to be immediately activated/triggered, its trigger event must be null. + // Double check if payload's trigger event is empty string, it must be set to null to trigger. + if (payload && payload.triggerEvent && payload.triggerEvent.length) { + [experiment setValue:payload.triggerEvent forKey:kABTExperimentDictionaryTriggeredEventNameKey]; + } else { + [experiment setValue:nil forKey:kABTExperimentDictionaryTriggeredEventNameKey]; + } + + // Set timeout event name and params. + NSString *timeoutEventName = events.timeoutExperimentEventName; + if (payload && payload.timeoutEventToLog && payload.timeoutEventToLog.length) { + timeoutEventName = payload.timeoutEventToLog; + } + NSDictionary *timeoutEvent = [self eventDictionaryWithOrigin:origin + eventName:timeoutEventName + params:eventParams]; + [experiment setValue:timeoutEvent forKey:kABTExperimentDictionaryTimedOutEventKey]; + + // Set trigger timeout information on how long to wait for trigger event. + NSTimeInterval triggerTimeout = (double)(payload.triggerTimeoutMillis / ABT_MSEC_PER_SEC); + [experiment setValue:@(triggerTimeout) forKey:kABTExperimentDictionaryTriggerTimeoutKey]; + + // Set activate event name and params. + NSString *activateEventName = events.activateExperimentEventName; + if (payload && payload.activateEventToLog && payload.activateEventToLog.length) { + activateEventName = payload.activateEventToLog; + } + NSDictionary *triggeredEvent = [self eventDictionaryWithOrigin:origin + eventName:activateEventName + params:eventParams]; + [experiment setValue:triggeredEvent forKey:kABTExperimentDictionaryTriggeredEventKey]; + + // Set time to live information for how long the experiment lasts. + NSTimeInterval timeToLive = (double)(payload.timeToLiveMillis / ABT_MSEC_PER_SEC); + [experiment setValue:@(timeToLive) forKey:kABTExperimentDictionaryTimeToLiveKey]; + + // Set expired event name and params. + NSString *expiredEventName = events.expireExperimentEventName; + if (payload && payload.ttlExpiryEventToLog && payload.ttlExpiryEventToLog.length) { + expiredEventName = payload.ttlExpiryEventToLog; + } + NSDictionary *expiredEvent = [self eventDictionaryWithOrigin:origin + eventName:expiredEventName + params:eventParams]; + [experiment setValue:expiredEvent forKey:kABTExperimentDictionaryExpiredEventKey]; + return experiment; +} + +- (NSDictionary *) + eventDictionaryWithOrigin:(nonnull NSString *)origin + eventName:(nonnull NSString *)eventName + params:(nonnull NSDictionary *)params { + return @{ + kABTEventDictionaryOriginKey : origin, + kABTEventDictionaryNameKey : eventName, + kABTEventDictionaryTimestampKey : @([NSDate date].timeIntervalSince1970), + kABTEventDictionaryParametersKey : params + }; +} + +#pragma mark - experiment properties +- (NSString *)experimentIDOfExperiment:(id)experiment { + if (!experiment) { + return @""; + } + return [experiment valueForKey:kABTExperimentDictionaryExperimentIDKey]; +} + +- (NSString *)variantIDOfExperiment:(id)experiment { + if (!experiment) { + return @""; + } + return [experiment valueForKey:kABTExperimentDictionaryVariantIDKey]; +} + +- (NSInteger)maxNumberOfExperimentsOfOrigin:(NSString *)origin { + if (!_analytics) { + return 0; + } + return [_analytics maxUserProperties:origin]; +} + +#pragma mark - analytics internal methods + +- (void)logEventWithOrigin:(NSString *)origin + payload:(ABTExperimentPayload *)payload + events:(FIRLifecycleEvents *)events { + NSString *setExperimentEventName = events.setExperimentEventName; + if (payload && payload.setEventToLog && payload.setEventToLog.length) { + setExperimentEventName = payload.setEventToLog; + } + NSDictionary *params; + params = payload.experimentId ? @{payload.experimentId : payload.variantId} : @{}; + [_analytics logEventWithOrigin:origin name:setExperimentEventName parameters:params]; +} + +#pragma mark - helper + +- (BOOL)isExperiment:(id)experiment theSameAsPayload:(ABTExperimentPayload *)payload { + NSString *experimentID = [self experimentIDOfExperiment:experiment]; + NSString *variantID = [self variantIDOfExperiment:experiment]; + return [experimentID isEqualToString:payload.experimentId] && + [variantID isEqualToString:payload.variantId]; +} + +- (ABTExperimentPayloadExperimentOverflowPolicy) + overflowPolicyWithPayload:(ABTExperimentPayload *)payload + originalPolicy:(ABTExperimentPayloadExperimentOverflowPolicy)originalPolicy { + if ([payload overflowPolicyIsValid]) { + return payload.overflowPolicy; + } + if (originalPolicy == ABTExperimentPayloadExperimentOverflowPolicyIgnoreNewest || + originalPolicy == ABTExperimentPayloadExperimentOverflowPolicyDiscardOldest) { + return originalPolicy; + } + return ABTExperimentPayloadExperimentOverflowPolicyDiscardOldest; +} + +@end diff --git a/Pods/FirebaseABTesting/FirebaseABTesting/Sources/ABTConstants.h b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/ABTConstants.h new file mode 100644 index 0000000..4edca5e --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/ABTConstants.h @@ -0,0 +1,50 @@ +// 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 +#import "FirebaseCore/Extension/FIRLogger.h" + +#define ABT_MSEC_PER_SEC 1000ull + +#pragma mark - Keys for experiment dictionaries. + +static NSString *const kABTExperimentDictionaryCreationTimestampKey = @"creationTimestamp"; +static NSString *const kABTExperimentDictionaryExperimentIDKey = @"name"; +static NSString *const kABTExperimentDictionaryExpiredEventKey = @"expiredEvent"; +static NSString *const kABTExperimentDictionaryOriginKey = @"origin"; +static NSString *const kABTExperimentDictionaryTimedOutEventKey = @"timedOutEvent"; +static NSString *const kABTExperimentDictionaryTimeToLiveKey = @"timeToLive"; +static NSString *const kABTExperimentDictionaryTriggeredEventKey = @"triggeredEvent"; +static NSString *const kABTExperimentDictionaryTriggeredEventNameKey = @"triggerEventName"; +static NSString *const kABTExperimentDictionaryTriggerTimeoutKey = @"triggerTimeout"; +static NSString *const kABTExperimentDictionaryVariantIDKey = @"value"; + +#pragma mark - Keys for event dictionaries. + +static NSString *const kABTEventDictionaryNameKey = @"name"; +static NSString *const kABTEventDictionaryOriginKey = @"origin"; +static NSString *const kABTEventDictionaryParametersKey = @"parameters"; +static NSString *const kABTEventDictionaryTimestampKey = @"timestamp"; + +#pragma mark - Errors + +static NSString *const kABTErrorDomain = @"com.google.abtesting"; + +typedef NS_ENUM(NSUInteger, ABTInternalErrorCode) { + kABTInternalErrorFailedToFetchConditionalUserProperties = 1 +}; + +#pragma mark - Logger Service String + +extern FIRLoggerService kFIRLoggerABTesting; diff --git a/Pods/FirebaseABTesting/FirebaseABTesting/Sources/ABTExperimentPayload.m b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/ABTExperimentPayload.m new file mode 100644 index 0000000..6bc2aaa --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/ABTExperimentPayload.m @@ -0,0 +1,151 @@ +// 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 "FirebaseABTesting/Sources/Private/ABTExperimentPayload.h" + +static NSString *const kExperimentPayloadKeyExperimentID = @"experimentId"; +static NSString *const kExperimentPayloadKeyVariantID = @"variantId"; + +// Start time can either be a date string or integer (milliseconds since 1970). +static NSString *const kExperimentPayloadKeyExperimentStartTime = @"experimentStartTime"; +static NSString *const kExperimentPayloadKeyExperimentStartTimeMillis = + @"experimentStartTimeMillis"; +static NSString *const kExperimentPayloadKeyTriggerEvent = @"triggerEvent"; +static NSString *const kExperimentPayloadKeyTriggerTimeoutMillis = @"triggerTimeoutMillis"; +static NSString *const kExperimentPayloadKeyTimeToLiveMillis = @"timeToLiveMillis"; +static NSString *const kExperimentPayloadKeySetEventToLog = @"setEventToLog"; +static NSString *const kExperimentPayloadKeyActivateEventToLog = @"activateEventToLog"; +static NSString *const kExperimentPayloadKeyClearEventToLog = @"clearEventToLog"; +static NSString *const kExperimentPayloadKeyTimeoutEventToLog = @"timeoutEventToLog"; +static NSString *const kExperimentPayloadKeyTTLExpiryEventToLog = @"ttlExpiryEventToLog"; + +static NSString *const kExperimentPayloadKeyOverflowPolicy = @"overflowPolicy"; +static NSString *const kExperimentPayloadValueDiscardOldestOverflowPolicy = @"DISCARD_OLDEST"; +static NSString *const kExperimentPayloadValueIgnoreNewestOverflowPolicy = @"IGNORE_NEWEST"; + +static NSString *const kExperimentPayloadKeyOngoingExperiments = @"ongoingExperiments"; + +@implementation ABTExperimentLite + +- (instancetype)initWithExperimentId:(NSString *)experimentId { + if (self = [super init]) { + _experimentId = experimentId; + } + return self; +} + +@end + +@implementation ABTExperimentPayload + ++ (NSDateFormatter *)experimentStartTimeFormatter { + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"]; + [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; + // Locale needs to be hardcoded. See + // https://developer.apple.com/library/ios/#qa/qa1480/_index.html for more details. + [dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]]; + [dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]; + return dateFormatter; +} + ++ (nullable instancetype)parseFromData:(NSData *)data { + NSError *error; + NSDictionary *experimentDictionary = + [NSJSONSerialization JSONObjectWithData:data + options:NSJSONReadingAllowFragments + error:&error]; + if (error != nil) { + return nil; + } else { + return [[ABTExperimentPayload alloc] initWithDictionary:experimentDictionary]; + } +} + +- (instancetype)initWithDictionary:(NSDictionary *)dictionary { + if (self = [super init]) { + _experimentId = dictionary[kExperimentPayloadKeyExperimentID]; + _variantId = dictionary[kExperimentPayloadKeyVariantID]; + _triggerEvent = dictionary[kExperimentPayloadKeyTriggerEvent]; + _setEventToLog = dictionary[kExperimentPayloadKeySetEventToLog]; + _activateEventToLog = dictionary[kExperimentPayloadKeyActivateEventToLog]; + _clearEventToLog = dictionary[kExperimentPayloadKeyClearEventToLog]; + _timeoutEventToLog = dictionary[kExperimentPayloadKeyTimeoutEventToLog]; + _ttlExpiryEventToLog = dictionary[kExperimentPayloadKeyTTLExpiryEventToLog]; + + // Experiment start time can either be in the form of a date string or milliseconds since 1970. + if (dictionary[kExperimentPayloadKeyExperimentStartTime]) { + // Convert from date string. + NSDate *experimentStartTime = [[[self class] experimentStartTimeFormatter] + dateFromString:dictionary[kExperimentPayloadKeyExperimentStartTime]]; + _experimentStartTimeMillis = + [@([experimentStartTime timeIntervalSince1970] * 1000) longLongValue]; + } else if (dictionary[kExperimentPayloadKeyExperimentStartTimeMillis]) { + // Simply store milliseconds. + _experimentStartTimeMillis = + [dictionary[kExperimentPayloadKeyExperimentStartTimeMillis] longLongValue]; + ; + } + + _triggerTimeoutMillis = [dictionary[kExperimentPayloadKeyTriggerTimeoutMillis] longLongValue]; + _timeToLiveMillis = [dictionary[kExperimentPayloadKeyTimeToLiveMillis] longLongValue]; + + // Overflow policy can be an integer, or string e.g. "DISCARD_OLDEST" or "IGNORE_NEWEST". + if ([dictionary[kExperimentPayloadKeyOverflowPolicy] isKindOfClass:[NSString class]]) { + // If it's a string, pick against the preset string values. + NSString *policy = dictionary[kExperimentPayloadKeyOverflowPolicy]; + if ([policy isEqualToString:kExperimentPayloadValueDiscardOldestOverflowPolicy]) { + _overflowPolicy = ABTExperimentPayloadExperimentOverflowPolicyDiscardOldest; + } else if ([policy isEqualToString:kExperimentPayloadValueIgnoreNewestOverflowPolicy]) { + _overflowPolicy = ABTExperimentPayloadExperimentOverflowPolicyIgnoreNewest; + } else { + _overflowPolicy = ABTExperimentPayloadExperimentOverflowPolicyUnrecognizedValue; + } + } else { + _overflowPolicy = [dictionary[kExperimentPayloadKeyOverflowPolicy] intValue]; + } + + NSMutableArray *ongoingExperiments = [[NSMutableArray alloc] init]; + + NSArray *> *ongoingExperimentsArray = + dictionary[kExperimentPayloadKeyOngoingExperiments]; + + for (NSDictionary *experimentDictionary in ongoingExperimentsArray) { + NSString *experimentId = experimentDictionary[kExperimentPayloadKeyExperimentID]; + if (experimentId) { + ABTExperimentLite *liteExperiment = + [[ABTExperimentLite alloc] initWithExperimentId:experimentId]; + [ongoingExperiments addObject:liteExperiment]; + } + } + + _ongoingExperiments = [ongoingExperiments copy]; + } + return self; +} + +- (void)clearTriggerEvent { + _triggerEvent = nil; +} + +- (BOOL)overflowPolicyIsValid { + return self.overflowPolicy == ABTExperimentPayloadExperimentOverflowPolicyIgnoreNewest || + self.overflowPolicy == ABTExperimentPayloadExperimentOverflowPolicyDiscardOldest; +} + +- (void)setOverflowPolicy:(ABTExperimentPayloadExperimentOverflowPolicy)overflowPolicy { + _overflowPolicy = overflowPolicy; +} + +@end diff --git a/Pods/FirebaseABTesting/FirebaseABTesting/Sources/FIRExperimentController.m b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/FIRExperimentController.m new file mode 100644 index 0000000..e40989f --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/FIRExperimentController.m @@ -0,0 +1,313 @@ +// 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 "FirebaseABTesting/Sources/Public/FirebaseABTesting/FIRExperimentController.h" + +#import "FirebaseABTesting/Sources/ABTConditionalUserPropertyController.h" +#import "FirebaseABTesting/Sources/ABTConstants.h" +#import "FirebaseABTesting/Sources/Private/ABTExperimentPayload.h" +#import "FirebaseABTesting/Sources/Public/FirebaseABTesting/FIRLifecycleEvents.h" +#import "FirebaseCore/Extension/FirebaseCoreInternal.h" + +#import "Interop/Analytics/Public/FIRAnalyticsInterop.h" + +/// Logger Service String. +FIRLoggerService kFIRLoggerABTesting = @"[FirebaseABTesting]"; + +/// Default experiment overflow policy. +const ABTExperimentPayloadExperimentOverflowPolicy FIRDefaultExperimentOverflowPolicy = + ABTExperimentPayloadExperimentOverflowPolicyDiscardOldest; + +/// Deserialize the experiment payloads. +ABTExperimentPayload *ABTDeserializeExperimentPayload(NSData *payload) { + // Verify that we have a JSON object. + NSError *error; + id JSONObject = [NSJSONSerialization JSONObjectWithData:payload options:kNilOptions error:&error]; + if (JSONObject == nil) { + FIRLogError(kFIRLoggerABTesting, @"I-ABT000001", @"Failed to parse experiment payload: %@", + error.debugDescription); + } + return [ABTExperimentPayload parseFromData:payload]; +} + +/// Returns a list of experiments to be set given the payloads and current list of experiments from +/// Firebase Analytics. If an experiment is in payloads but not in experiments, it should be set to +/// Firebase Analytics. +NSArray *ABTExperimentsToSetFromPayloads( + NSArray *payloads, + NSArray *> *experiments, + id _Nullable analytics) { + NSArray *payloadsCopy = [payloads copy]; + NSArray *experimentsCopy = [experiments copy]; + NSMutableArray *experimentsToSet = [[NSMutableArray alloc] init]; + ABTConditionalUserPropertyController *controller = + [ABTConditionalUserPropertyController sharedInstanceWithAnalytics:analytics]; + + // Check if the experiment is in payloads but not in experiments. + for (NSData *payload in payloadsCopy) { + ABTExperimentPayload *experimentPayload = ABTDeserializeExperimentPayload(payload); + if (!experimentPayload) { + FIRLogInfo(kFIRLoggerABTesting, @"I-ABT000002", + @"Either payload is not set or it cannot be deserialized."); + continue; + } + + BOOL isExperimentSet = NO; + for (id experiment in experimentsCopy) { + if ([controller isExperiment:experiment theSameAsPayload:experimentPayload]) { + isExperimentSet = YES; + break; + } + } + + if (!isExperimentSet) { + [experimentsToSet addObject:experimentPayload]; + } + } + return [experimentsToSet copy]; +} + +/// Returns a list of experiments to be cleared given the payloads and current list of +/// experiments from Firebase Analytics. If an experiment is in experiments but not in payloads, it +/// should be cleared in Firebase Analytics. +NSArray *ABTExperimentsToClearFromPayloads( + NSArray *payloads, + NSArray *> *experiments, + id _Nullable analytics) { + NSMutableArray *experimentsToClear = [[NSMutableArray alloc] init]; + ABTConditionalUserPropertyController *controller = + [ABTConditionalUserPropertyController sharedInstanceWithAnalytics:analytics]; + + // Check if the experiment is in experiments but not payloads. + for (id experiment in [experiments copy]) { + BOOL doesExperimentNoLongerExist = YES; + for (NSData *payload in [payloads copy]) { + ABTExperimentPayload *experimentPayload = ABTDeserializeExperimentPayload(payload); + if (!experimentPayload) { + FIRLogInfo(kFIRLoggerABTesting, @"I-ABT000002", + @"Either payload is not set or it cannot be deserialized."); + continue; + } + + if ([controller isExperiment:experiment theSameAsPayload:experimentPayload]) { + doesExperimentNoLongerExist = NO; + } + } + if (doesExperimentNoLongerExist) { + [experimentsToClear addObject:experiment]; + } + } + return experimentsToClear; +} + +// ABT doesn't provide any functionality to other components, +// so it provides a private, empty protocol that it conforms to and use it for registration. + +@protocol FIRABTInstanceProvider +@end + +@interface FIRExperimentController () +@property(nonatomic, readwrite, strong) id _Nullable analytics; +@end + +@implementation FIRExperimentController + ++ (void)load { + [FIRApp registerInternalLibrary:(Class)self withName:@"fire-abt"]; +} + ++ (nonnull NSArray *)componentsToRegister { + FIRDependency *analyticsDep = [FIRDependency dependencyWithProtocol:@protocol(FIRAnalyticsInterop) + isRequired:NO]; + FIRComponentCreationBlock creationBlock = + ^id _Nullable(FIRComponentContainer *container, BOOL *isCacheable) { + // Ensure it's cached so it returns the same instance every time ABTesting is called. + *isCacheable = YES; + id analytics = FIR_COMPONENT(FIRAnalyticsInterop, container); + return [[FIRExperimentController alloc] initWithAnalytics:analytics]; + }; + FIRComponent *abtProvider = [FIRComponent componentWithProtocol:@protocol(FIRABTInstanceProvider) + instantiationTiming:FIRInstantiationTimingLazy + dependencies:@[ analyticsDep ] + creationBlock:creationBlock]; + + return @[ abtProvider ]; +} + +- (instancetype)initWithAnalytics:(nullable id)analytics { + self = [super init]; + if (self != nil) { + _analytics = analytics; + } + return self; +} + ++ (FIRExperimentController *)sharedInstance { + FIRApp *defaultApp = [FIRApp defaultApp]; // Missing configure will be logged here. + id instance = FIR_COMPONENT(FIRABTInstanceProvider, defaultApp.container); + + // We know the instance coming from the container is a FIRExperimentController instance, cast it. + return (FIRExperimentController *)instance; +} + +- (void)updateExperimentsWithServiceOrigin:(NSString *)origin + events:(FIRLifecycleEvents *)events + policy:(ABTExperimentPayloadExperimentOverflowPolicy)policy + lastStartTime:(NSTimeInterval)lastStartTime + payloads:(NSArray *)payloads + completionHandler: + (nullable void (^)(NSError *_Nullable error))completionHandler { + FIRExperimentController *__weak weakSelf = self; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ + FIRExperimentController *strongSelf = weakSelf; + [strongSelf updateExperimentConditionalUserPropertiesWithServiceOrigin:origin + events:events + policy:policy + lastStartTime:lastStartTime + payloads:payloads + completionHandler:completionHandler]; + }); +} + +- (void) + updateExperimentConditionalUserPropertiesWithServiceOrigin:(NSString *)origin + events:(FIRLifecycleEvents *)events + policy: + (ABTExperimentPayloadExperimentOverflowPolicy) + policy + lastStartTime:(NSTimeInterval)lastStartTime + payloads:(NSArray *)payloads + completionHandler: + (nullable void (^)(NSError *_Nullable error)) + completionHandler { + ABTConditionalUserPropertyController *controller = + [ABTConditionalUserPropertyController sharedInstanceWithAnalytics:_analytics]; + + // Get the list of expriments from Firebase Analytics. + NSArray *experiments = [controller experimentsWithOrigin:origin]; + if (!experiments) { + NSString *errorDescription = + @"Failed to get conditional user properties from Firebase Analytics."; + FIRLogInfo(kFIRLoggerABTesting, @"I-ABT000003", @"%@", errorDescription); + + if (completionHandler) { + completionHandler([NSError + errorWithDomain:kABTErrorDomain + code:kABTInternalErrorFailedToFetchConditionalUserProperties + userInfo:@{NSLocalizedDescriptionKey : errorDescription}]); + } + + return; + } + NSArray *experimentsToSet = + ABTExperimentsToSetFromPayloads(payloads, experiments, _analytics); + NSArray *> *experimentsToClear = + ABTExperimentsToClearFromPayloads(payloads, experiments, _analytics); + + for (id experiment in experimentsToClear) { + NSString *experimentID = [controller experimentIDOfExperiment:experiment]; + NSString *variantID = [controller variantIDOfExperiment:experiment]; + [controller clearExperiment:experimentID + variantID:variantID + withOrigin:origin + payload:nil + events:events]; + } + + for (ABTExperimentPayload *experimentPayload in experimentsToSet) { + if (experimentPayload.experimentStartTimeMillis > lastStartTime * ABT_MSEC_PER_SEC) { + [controller setExperimentWithOrigin:origin + payload:experimentPayload + events:events + policy:policy]; + FIRLogInfo(kFIRLoggerABTesting, @"I-ABT000008", + @"Set Experiment ID %@, variant ID %@ to Firebase Analytics.", + experimentPayload.experimentId, experimentPayload.variantId); + + } else { + FIRLogInfo(kFIRLoggerABTesting, @"I-ABT000009", + @"Not setting experiment ID %@, variant ID %@ due to the last update time %lld.", + experimentPayload.experimentId, experimentPayload.variantId, + (long)lastStartTime * ABT_MSEC_PER_SEC); + } + } + + if (completionHandler) { + completionHandler(nil); + } +} + +- (NSTimeInterval)latestExperimentStartTimestampBetweenTimestamp:(NSTimeInterval)timestamp + andPayloads:(NSArray *)payloads { + for (NSData *payload in [payloads copy]) { + ABTExperimentPayload *experimentPayload = ABTDeserializeExperimentPayload(payload); + if (!experimentPayload) { + FIRLogInfo(kFIRLoggerABTesting, @"I-ABT000002", + @"Either payload is not set or it cannot be deserialized."); + continue; + } + if (experimentPayload.experimentStartTimeMillis > timestamp * ABT_MSEC_PER_SEC) { + timestamp = (double)(experimentPayload.experimentStartTimeMillis / ABT_MSEC_PER_SEC); + } + } + return timestamp; +} + +- (void)validateRunningExperimentsForServiceOrigin:(NSString *)origin + runningExperimentPayloads:(NSArray *)payloads { + ABTConditionalUserPropertyController *controller = + [ABTConditionalUserPropertyController sharedInstanceWithAnalytics:_analytics]; + + FIRLifecycleEvents *lifecycleEvents = [[FIRLifecycleEvents alloc] init]; + + // Get the list of experiments from Firebase Analytics. + NSArray *> *activeExperiments = + [controller experimentsWithOrigin:origin]; + + NSMutableSet *runningExperimentIDs = [NSMutableSet setWithCapacity:payloads.count]; + for (ABTExperimentPayload *payload in payloads) { + [runningExperimentIDs addObject:payload.experimentId]; + } + + for (NSDictionary *activeExperimentDictionary in activeExperiments) { + NSString *experimentID = activeExperimentDictionary[@"name"]; + if (![runningExperimentIDs containsObject:experimentID]) { + NSString *variantID = activeExperimentDictionary[@"value"]; + + [controller clearExperiment:experimentID + variantID:variantID + withOrigin:origin + payload:nil + events:lifecycleEvents]; + } + } +} + +- (void)activateExperiment:(ABTExperimentPayload *)experimentPayload + forServiceOrigin:(NSString *)origin { + ABTConditionalUserPropertyController *controller = + [ABTConditionalUserPropertyController sharedInstanceWithAnalytics:_analytics]; + + FIRLifecycleEvents *lifecycleEvents = [[FIRLifecycleEvents alloc] init]; + + // Ensure that trigger event is nil, which will immediately set the experiment to active. + [experimentPayload clearTriggerEvent]; + + [controller setExperimentWithOrigin:origin + payload:experimentPayload + events:lifecycleEvents + policy:experimentPayload.overflowPolicy]; +} + +@end diff --git a/Pods/FirebaseABTesting/FirebaseABTesting/Sources/FIRLifecycleEvents.m b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/FIRLifecycleEvents.m new file mode 100644 index 0000000..95b25ae --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/FIRLifecycleEvents.m @@ -0,0 +1,88 @@ +// 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 "FirebaseABTesting/Sources/Public/FirebaseABTesting/FIRLifecycleEvents.h" + +#import "FirebaseABTesting/Sources/Public/FirebaseABTesting/FIRExperimentController.h" + +/// Default name of the analytics event to be logged when an experiment is set. +NSString *const FIRSetExperimentEventName = @"_exp_set"; +/// Default name of the analytics event to be logged when an experiment is activated. +NSString *const FIRActivateExperimentEventName = @"_exp_activate"; +/// Default name of the analytics event to be logged when an experiment is cleared. +NSString *const FIRClearExperimentEventName = @"_exp_clear"; +/// Default name of the analytics event to be logged when an experiment times out for being +/// activated. +NSString *const FIRTimeoutExperimentEventName = @"_exp_timeout"; +/// Default name of the analytics event to be logged when an experiment is expired as it reaches the +/// end of TTL. +NSString *const FIRExpireExperimentEventName = @"_exp_expire"; +/// Prefix for lifecycle event names. +static NSString *const kLifecycleEventPrefix = @"_"; + +@implementation FIRLifecycleEvents +- (instancetype)init { + self = [super init]; + if (self) { + _setExperimentEventName = FIRSetExperimentEventName; + _activateExperimentEventName = FIRActivateExperimentEventName; + _clearExperimentEventName = FIRClearExperimentEventName; + _timeoutExperimentEventName = FIRTimeoutExperimentEventName; + _expireExperimentEventName = FIRExpireExperimentEventName; + } + return self; +} + +- (void)setSetExperimentEventName:(NSString *)setExperimentEventName { + if (setExperimentEventName && [setExperimentEventName hasPrefix:kLifecycleEventPrefix]) { + _setExperimentEventName = setExperimentEventName; + } else { + _setExperimentEventName = FIRSetExperimentEventName; + } +} + +- (void)setActivateExperimentEventName:(NSString *)activateExperimentEventName { + if (activateExperimentEventName && + [activateExperimentEventName hasPrefix:kLifecycleEventPrefix]) { + _activateExperimentEventName = activateExperimentEventName; + } else { + _activateExperimentEventName = FIRActivateExperimentEventName; + } +} + +- (void)setClearExperimentEventName:(NSString *)clearExperimentEventName { + if (clearExperimentEventName && [clearExperimentEventName hasPrefix:kLifecycleEventPrefix]) { + _clearExperimentEventName = clearExperimentEventName; + } else { + _clearExperimentEventName = FIRClearExperimentEventName; + } +} + +- (void)setTimeoutExperimentEventName:(NSString *)timeoutExperimentEventName { + if (timeoutExperimentEventName && [timeoutExperimentEventName hasPrefix:kLifecycleEventPrefix]) { + _timeoutExperimentEventName = timeoutExperimentEventName; + } else { + _timeoutExperimentEventName = FIRTimeoutExperimentEventName; + } +} + +- (void)setExpireExperimentEventName:(NSString *)expireExperimentEventName { + if (expireExperimentEventName && [_timeoutExperimentEventName hasPrefix:kLifecycleEventPrefix]) { + _expireExperimentEventName = expireExperimentEventName; + } else { + _expireExperimentEventName = FIRExpireExperimentEventName; + } +} + +@end diff --git a/Pods/FirebaseABTesting/FirebaseABTesting/Sources/Private/ABTExperimentPayload.h b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/Private/ABTExperimentPayload.h new file mode 100644 index 0000000..b2f2da0 --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/Private/ABTExperimentPayload.h @@ -0,0 +1,96 @@ +// 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 + +NS_ASSUME_NONNULL_BEGIN + +/// Policy for handling the case where there's an overflow of experiments for an installation +/// instance. +typedef NS_ENUM(int32_t, ABTExperimentPayloadExperimentOverflowPolicy) { + ABTExperimentPayloadExperimentOverflowPolicyUnrecognizedValue = 999, + ABTExperimentPayloadExperimentOverflowPolicyUnspecified = 0, + ABTExperimentPayloadExperimentOverflowPolicyDiscardOldest = 1, + ABTExperimentPayloadExperimentOverflowPolicyIgnoreNewest = 2, +}; + +@interface ABTExperimentLite : NSObject +@property(nonatomic, readonly, copy) NSString *experimentId; + +- (instancetype)initWithExperimentId:(NSString *)experimentId NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +@end + +@interface ABTExperimentPayload : NSObject + +/// Unique identifier for this experiment. +@property(nonatomic, readonly, copy) NSString *experimentId; + +/// Unique identifier for the variant to which an installation instance has been assigned. +@property(nonatomic, readonly, copy) NSString *variantId; + +/// Epoch time that represents when the experiment was started. +@property(nonatomic, readonly) int64_t experimentStartTimeMillis; + +/// The event that triggers this experiment into ON state. +@property(nonatomic, nullable, readonly, copy) NSString *triggerEvent; + +/// Duration in milliseconds for which the experiment can stay in STANDBY state (un-triggered). +@property(nonatomic, readonly) int64_t triggerTimeoutMillis; + +/// Duration in milliseconds for which the experiment can stay in ON state (triggered). +@property(nonatomic, readonly) int64_t timeToLiveMillis; + +/// The event logged when impact service sets the experiment. +@property(nonatomic, readonly, copy) NSString *setEventToLog; + +/// The event logged when an experiment goes to the ON state. +@property(nonatomic, readonly, copy) NSString *activateEventToLog; + +/// The event logged when an experiment is cleared. +@property(nonatomic, readonly, copy) NSString *clearEventToLog; + +/// The event logged when an experiment times out after `triggerTimeoutMillis` milliseconds. +@property(nonatomic, readonly, copy) NSString *timeoutEventToLog; + +/// The event logged when an experiment times out after `timeToLiveMillis` milliseconds. +@property(nonatomic, readonly, copy) NSString *ttlExpiryEventToLog; + +@property(nonatomic, readonly) ABTExperimentPayloadExperimentOverflowPolicy overflowPolicy; + +/// A list of all other ongoing (started, and not yet stopped) experiments at the time this +/// experiment was started. Does not include this experiment; only the others. +@property(nonatomic, readonly) NSArray *ongoingExperiments; + +/// Parses an ABTExperimentPayload directly from JSON data. +/// @param data JSON object as NSData. Must be reconstructible as an NSDictionary. ++ (nullable instancetype)parseFromData:(NSData *)data; + +/// Initializes an ABTExperimentPayload from a dictionary with experiment metadata. +- (instancetype)initWithDictionary:(NSDictionary *)dictionary + NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +/// Clears the trigger event associated with this payload. +- (void)clearTriggerEvent; + +/// Checks if the overflow policy is a valid enum object. +- (BOOL)overflowPolicyIsValid; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseABTesting/FirebaseABTesting/Sources/Private/FirebaseABTestingInternal.h b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/Private/FirebaseABTestingInternal.h new file mode 100644 index 0000000..7259e08 --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/Private/FirebaseABTestingInternal.h @@ -0,0 +1,20 @@ +// 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. + +// An umbrella header, for any other libraries in this repo to access Firebase Public and Private +// headers. Any package manager complexity should be handled here. + +#import + +#import "FirebaseABTesting/Sources/Private/ABTExperimentPayload.h" diff --git a/Pods/FirebaseABTesting/FirebaseABTesting/Sources/Public/FirebaseABTesting/FIRExperimentController.h b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/Public/FirebaseABTesting/FIRExperimentController.h new file mode 100644 index 0000000..3bd757d --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/Public/FirebaseABTesting/FIRExperimentController.h @@ -0,0 +1,83 @@ +// 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 + +@class ABTExperimentPayload; + +// Forward declaration to avoid importing into the module header +typedef NS_ENUM(int32_t, ABTExperimentPayloadExperimentOverflowPolicy); + +NS_ASSUME_NONNULL_BEGIN + +@class FIRLifecycleEvents; + +/// The default experiment overflow policy, that is to discard the experiment with the oldest start +/// time when users start the experiment on the web console. +extern const ABTExperimentPayloadExperimentOverflowPolicy FIRDefaultExperimentOverflowPolicy; + +/// This class is for Firebase services to handle experiments updates to Firebase Analytics. +/// Experiments can be set, cleared and updated through this controller. +NS_SWIFT_NAME(ExperimentController) +@interface FIRExperimentController : NSObject + +/// Returns the FIRExperimentController singleton. ++ (FIRExperimentController *)sharedInstance; + +/// Updates the list of experiments with an optional completion handler. Experiments already +/// existing in payloads are not affected, whose state and payload is preserved. This method +/// compares whether the experiments have changed or not by their variant ID. This runs in a +/// background queue and calls the completion handler when finished executing. +/// @param origin The originating service affected by the experiment. +/// @param events A list of event names to be used for logging experiment lifecycle events, +/// if they are not defined in the payload. +/// @param policy The policy to handle new experiments when slots are full. +/// @param lastStartTime The last known experiment start timestamp for this affected service. +/// (Timestamps are specified by the number of seconds from 00:00:00 UTC on 1 +/// January 1970.). +/// @param payloads List of experiment metadata. +/// @param completionHandler Code to be executed after experiments are updated in the background +/// thread. +- (void)updateExperimentsWithServiceOrigin:(NSString *)origin + events:(FIRLifecycleEvents *)events + policy:(ABTExperimentPayloadExperimentOverflowPolicy)policy + lastStartTime:(NSTimeInterval)lastStartTime + payloads:(NSArray *)payloads + completionHandler: + (nullable void (^)(NSError *_Nullable error))completionHandler; + +/// Returns the latest experiment start timestamp given a current latest timestamp and a list of +/// experiment payloads. Timestamps are specified by the number of seconds from 00:00:00 UTC on 1 +/// January 1970. +/// @param timestamp Current latest experiment start timestamp. If not known, affected service +/// should specify -1; +/// @param payloads List of experiment metadata. +- (NSTimeInterval)latestExperimentStartTimestampBetweenTimestamp:(NSTimeInterval)timestamp + andPayloads:(NSArray *)payloads; + +/// Expires experiments that aren't in the list of running experiment payloads. +/// @param origin The originating service affected by the experiment. +/// @param payloads The list of valid, running experiments. +- (void)validateRunningExperimentsForServiceOrigin:(NSString *)origin + runningExperimentPayloads:(NSArray *)payloads; + +/// Directly sets a given experiment to be active. +/// @param experimentPayload The payload for the experiment that should be activated. +/// @param origin The originating service affected by the experiment. +- (void)activateExperiment:(ABTExperimentPayload *)experimentPayload + forServiceOrigin:(NSString *)origin; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseABTesting/FirebaseABTesting/Sources/Public/FirebaseABTesting/FIRLifecycleEvents.h b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/Public/FirebaseABTesting/FIRLifecycleEvents.h new file mode 100644 index 0000000..e20f9a3 --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/Public/FirebaseABTesting/FIRLifecycleEvents.h @@ -0,0 +1,66 @@ +// 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 + +NS_ASSUME_NONNULL_BEGIN + +/// Default event name for when an experiment is set. +extern NSString *const FIRSetExperimentEventName NS_SWIFT_NAME(DefaultSetExperimentEventName); +/// Default event name for when an experiment is activated. +// clang-format off +// clang-format12 will merge lines and exceed 100 character limit. +extern NSString *const FIRActivateExperimentEventName + NS_SWIFT_NAME(DefaultActivateExperimentEventName); +/// Default event name for when an experiment is cleared. +extern NSString *const FIRClearExperimentEventName NS_SWIFT_NAME(DefaultClearExperimentEventName); +/// Default event name for when an experiment times out for being activated. +extern NSString *const FIRTimeoutExperimentEventName + NS_SWIFT_NAME(DefaultTimeoutExperimentEventName); +// clang-format on +/// Default event name for when an experiment is expired as it reaches the end of TTL. +extern NSString *const FIRExpireExperimentEventName NS_SWIFT_NAME(DefaultExpireExperimentEventName); + +/// An Experiment Lifecycle Event Object that specifies the name of the experiment event to be +/// logged by Firebase Analytics. +NS_SWIFT_NAME(LifecycleEvents) +@interface FIRLifecycleEvents : NSObject + +/// Event name for when an experiment is set. It defaults to `SetExperimentEventName` and can be +/// overridden. If experiment payload has a valid string of this field, always use +/// experiment payload. +@property(nonatomic, copy) NSString *setExperimentEventName; + +/// Event name for when an experiment is activated. It defaults to `ActivateExperimentEventName` +/// and can be overridden. If experiment payload has a valid string of this field, always use +/// experiment payload. +@property(nonatomic, copy) NSString *activateExperimentEventName; + +/// Event name for when an experiment is cleared. It is default to `ClearExperimentEventName` and +/// can be overridden. If experiment payload has a valid string of this field, always use experiment +/// payload. +@property(nonatomic, copy) NSString *clearExperimentEventName; +/// Event name for when an experiment is timeout from being STANDBY. It is default to +/// `TimeoutExperimentEventName` and can be overridden. If experiment payload has a valid string +/// of this field, always use experiment payload. +@property(nonatomic, copy) NSString *timeoutExperimentEventName; + +/// Event name when an experiment is expired when it reaches the end of its TTL. +/// It is default to `ExpireExperimentEventName` and can be overridden. If experiment payload has a +/// valid string of this field, always use experiment payload. +@property(nonatomic, copy) NSString *expireExperimentEventName; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseABTesting/FirebaseABTesting/Sources/Public/FirebaseABTesting/FirebaseABTesting.h b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/Public/FirebaseABTesting/FirebaseABTesting.h new file mode 100755 index 0000000..cfa99b4 --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/Public/FirebaseABTesting/FirebaseABTesting.h @@ -0,0 +1,16 @@ +// 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 "FIRExperimentController.h" +#import "FIRLifecycleEvents.h" diff --git a/Pods/FirebaseABTesting/FirebaseABTesting/Sources/Resources/PrivacyInfo.xcprivacy b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/Resources/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..c89c88f --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseABTesting/Sources/Resources/PrivacyInfo.xcprivacy @@ -0,0 +1,18 @@ + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + + NSPrivacyCollectedDataTypes + + + NSPrivacyAccessedAPITypes + + + + + diff --git a/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRAppInternal.h b/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRAppInternal.h new file mode 100644 index 0000000..49104f0 --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRAppInternal.h @@ -0,0 +1,159 @@ +/* + * 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 + +@class FIRComponentContainer; +@class FIRHeartbeatLogger; +@protocol FIRLibrary; + +/** + * The internal interface to `FirebaseApp`. This is meant for first-party integrators, who need to + * receive `FirebaseApp` notifications, log info about the success or failure of their + * configuration, and access other internal functionality of `FirebaseApp`. + */ +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSInteger, FIRConfigType) { + FIRConfigTypeCore = 1, + FIRConfigTypeSDK = 2, +}; + +extern NSString *const kFIRDefaultAppName; +extern NSString *const kFIRAppReadyToConfigureSDKNotification; +extern NSString *const kFIRAppDeleteNotification; +extern NSString *const kFIRAppIsDefaultAppKey; +extern NSString *const kFIRAppNameKey; +extern NSString *const kFIRGoogleAppIDKey; +extern NSString *const kFirebaseCoreErrorDomain; + +/** The `UserDefaults` suite name for `FirebaseCore`, for those storage locations that use it. */ +extern NSString *const kFirebaseCoreDefaultsSuiteName; + +/** + * The format string for the `UserDefaults` key used for storing the data collection enabled flag. + * This includes formatting to append the `FirebaseApp`'s name. + */ +extern NSString *const kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat; + +/** + * The plist key used for storing the data collection enabled flag. + */ +extern NSString *const kFIRGlobalAppDataCollectionEnabledPlistKey; + +/** @var FirebaseAuthStateDidChangeInternalNotification + @brief The name of the @c NotificationCenter notification which is posted when the auth state + changes (e.g. a new token has been produced, a user logs in or out). The object parameter of + the notification is a dictionary possibly containing the key: + @c FirebaseAuthStateDidChangeInternalNotificationTokenKey (the new access token.) If it does not + contain this key it indicates a sign-out event took place. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotification; + +/** @var FirebaseAuthStateDidChangeInternalNotificationTokenKey + @brief A key present in the dictionary object parameter of the + @c FirebaseAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the new access token. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationTokenKey; + +/** @var FirebaseAuthStateDidChangeInternalNotificationAppKey + @brief A key present in the dictionary object parameter of the + @c FirebaseAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the FirebaseApp associated with the auth instance. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationAppKey; + +/** @var FirebaseAuthStateDidChangeInternalNotificationUIDKey + @brief A key present in the dictionary object parameter of the + @c FirebaseAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the new user's UID (or nil if there is no longer a user signed in). + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationUIDKey; + +@interface FIRApp () + +/** + * A flag indicating if this is the default app (has the default app name). + */ +@property(nonatomic, readonly) BOOL isDefaultApp; + +/** + * The container of interop SDKs for this app. + */ +@property(nonatomic) FIRComponentContainer *container; + +/** + * The heartbeat logger associated with this app. + * + * Firebase apps have a 1:1 relationship with heartbeat loggers. + */ +@property(readonly) FIRHeartbeatLogger *heartbeatLogger; + +/** + * Checks if the default app is configured without trying to configure it. + */ ++ (BOOL)isDefaultAppConfigured; + +/** + * Registers a given third-party library with the given version number to be reported for + * analytics. + * + * @param name Name of the library. + * @param version Version of the library. + */ ++ (void)registerLibrary:(nonnull NSString *)name withVersion:(nonnull NSString *)version; + +/** + * Registers a given internal library to be reported for analytics. + * + * @param library Optional parameter for component registration. + * @param name Name of the library. + */ ++ (void)registerInternalLibrary:(nonnull Class)library + withName:(nonnull NSString *)name; + +/** + * Registers a given internal library with the given version number to be reported for + * analytics. This should only be used for non-Firebase libraries that have their own versioning + * scheme. + * + * @param library Optional parameter for component registration. + * @param name Name of the library. + * @param version Version of the library. + */ ++ (void)registerInternalLibrary:(nonnull Class)library + withName:(nonnull NSString *)name + withVersion:(nonnull NSString *)version; + +/** + * A concatenated string representing all the third-party libraries and version numbers. + */ ++ (NSString *)firebaseUserAgent; + +/** + * Can be used by the unit tests in each SDK to reset `FirebaseApp`. This method is thread unsafe. + */ ++ (void)resetApps; + +/** + * Can be used by the unit tests in each SDK to set customized options. + */ +- (instancetype)initInstanceWithName:(NSString *)name options:(FIROptions *)options; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRComponent.h b/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRComponent.h new file mode 100644 index 0000000..e4c8a27 --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRComponent.h @@ -0,0 +1,91 @@ +/* + * 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 + +@class FIRApp; +@class FIRComponentContainer; + +NS_ASSUME_NONNULL_BEGIN + +/// Provides a system to clean up cached instances returned from the component system. +NS_SWIFT_NAME(ComponentLifecycleMaintainer) +@protocol FIRComponentLifecycleMaintainer +/// The associated app will be deleted, clean up any resources as they are about to be deallocated. +- (void)appWillBeDeleted:(FIRApp *)app; +@end + +typedef _Nullable id (^FIRComponentCreationBlock)(FIRComponentContainer *container, + BOOL *isCacheable) + NS_SWIFT_NAME(ComponentCreationBlock); + +@class FIRDependency; + +/// Describes the timing of instantiation. Note: new components should default to lazy unless there +/// is a strong reason to be eager. +typedef NS_ENUM(NSInteger, FIRInstantiationTiming) { + FIRInstantiationTimingLazy, + FIRInstantiationTimingAlwaysEager, + FIRInstantiationTimingEagerInDefaultApp +} NS_SWIFT_NAME(InstantiationTiming); + +/// A component that can be used from other Firebase SDKs. +NS_SWIFT_NAME(Component) +@interface FIRComponent : NSObject + +/// The protocol describing functionality provided from the `Component`. +@property(nonatomic, strong, readonly) Protocol *protocol; + +/// The timing of instantiation. +@property(nonatomic, readonly) FIRInstantiationTiming instantiationTiming; + +/// An array of dependencies for the component. +@property(nonatomic, copy, readonly) NSArray *dependencies; + +/// A block to instantiate an instance of the component with the appropriate dependencies. +@property(nonatomic, copy, readonly) FIRComponentCreationBlock creationBlock; + +// There's an issue with long NS_SWIFT_NAMES that causes compilation to fail, disable clang-format +// for the next two methods. +// clang-format off + +/// Creates a component with no dependencies that will be lazily initialized. ++ (instancetype)componentWithProtocol:(Protocol *)protocol + creationBlock:(FIRComponentCreationBlock)creationBlock +NS_SWIFT_NAME(init(_:creationBlock:)); + +/// Creates a component to be registered with the component container. +/// +/// @param protocol - The protocol describing functionality provided by the component. +/// @param instantiationTiming - When the component should be initialized. Use .lazy unless there's +/// a good reason to be instantiated earlier. +/// @param dependencies - Any dependencies the `implementingClass` has, optional or required. +/// @param creationBlock - A block to instantiate the component with a container, and if +/// @return A component that can be registered with the component container. ++ (instancetype)componentWithProtocol:(Protocol *)protocol + instantiationTiming:(FIRInstantiationTiming)instantiationTiming + dependencies:(NSArray *)dependencies + creationBlock:(FIRComponentCreationBlock)creationBlock +NS_SWIFT_NAME(init(_:instantiationTiming:dependencies:creationBlock:)); + +// clang-format on + +/// Unavailable. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRComponentContainer.h b/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRComponentContainer.h new file mode 100644 index 0000000..6ec6147 --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRComponentContainer.h @@ -0,0 +1,45 @@ +/* + * 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 + +NS_ASSUME_NONNULL_BEGIN + +/// A type-safe macro to retrieve a component from a container. This should be used to retrieve +/// components instead of using the container directly. +#define FIR_COMPONENT(type, container) \ + [FIRComponentType> instanceForProtocol:@protocol(type) inContainer:container] + +@class FIRApp; + +/// A container that holds different components that are registered via the +/// `registerAsComponentRegistrant` call. These classes should conform to `ComponentRegistrant` +/// in order to properly register components for Core. +NS_SWIFT_NAME(FirebaseComponentContainer) +@interface FIRComponentContainer : NSObject + +/// A weak reference to the app that an instance of the container belongs to. +@property(nonatomic, weak, readonly) FIRApp *app; + +// TODO: See if we can get improved type safety here. +/// A Swift only API for fetching an instance since the top macro isn't available. +- (nullable id)__instanceForProtocol:(Protocol *)protocol NS_SWIFT_NAME(instance(for:)); + +/// Unavailable. Use the `container` property on `FirebaseApp`. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRComponentType.h b/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRComponentType.h new file mode 100644 index 0000000..c69085d --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRComponentType.h @@ -0,0 +1,35 @@ +/* + * 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 + +@class FIRComponentContainer; + +NS_ASSUME_NONNULL_BEGIN + +/// Do not use directly. A placeholder type in order to provide a macro that will warn users of +/// mis-matched protocols. +NS_SWIFT_NAME(ComponentType) +@interface FIRComponentType<__covariant T> : NSObject + +/// Do not use directly. A factory method to retrieve an instance that provides a specific +/// functionality. ++ (nullable T)instanceForProtocol:(Protocol *)protocol + inContainer:(FIRComponentContainer *)container; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRDependency.h b/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRDependency.h new file mode 100644 index 0000000..a070557 --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRDependency.h @@ -0,0 +1,45 @@ +/* + * 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 + +NS_ASSUME_NONNULL_BEGIN + +/// A dependency on a specific protocol's functionality. +NS_SWIFT_NAME(Dependency) +@interface FIRDependency : NSObject + +/// The protocol describing functionality being depended on. +@property(nonatomic, strong, readonly) Protocol *protocol; + +/// A flag to specify if the dependency is required or not. +@property(nonatomic, readonly) BOOL isRequired; + +/// Initializes a dependency that is required. Calls `init(protocol:isRequired:)` with true for +/// the required parameter. +/// Creates a required dependency on the specified protocol's functionality. ++ (instancetype)dependencyWithProtocol:(Protocol *)protocol; + +/// Creates a dependency on the specified protocol's functionality and specify if it's required for +/// the class's functionality. ++ (instancetype)dependencyWithProtocol:(Protocol *)protocol isRequired:(BOOL)required; + +/// Use `init(withProtocol:isRequired:)` instead. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRHeartbeatLogger.h b/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRHeartbeatLogger.h new file mode 100644 index 0000000..0f39ad9 --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRHeartbeatLogger.h @@ -0,0 +1,90 @@ +// Copyright 2021 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 + +NS_ASSUME_NONNULL_BEGIN + +#ifndef FIREBASE_BUILD_CMAKE +@class FIRHeartbeatsPayload; +#endif // FIREBASE_BUILD_CMAKE + +/// Enum representing different daily heartbeat codes. +/// This enum is only used by clients using platform logging V1. This is because +/// the V1 payload only supports a single daily heartbeat. +typedef NS_ENUM(NSInteger, FIRDailyHeartbeatCode) { + /// Represents the absence of a daily heartbeat. + FIRDailyHeartbeatCodeNone = 0, + /// Represents the presence of a daily heartbeat. + FIRDailyHeartbeatCodeSome = 2, +}; + +@protocol FIRHeartbeatLoggerProtocol + +/// Asynchronously logs a heartbeat. +- (void)log; + +#ifndef FIREBASE_BUILD_CMAKE +/// Flushes heartbeats from storage into a structured payload of heartbeats. +- (FIRHeartbeatsPayload *)flushHeartbeatsIntoPayload; +#endif // FIREBASE_BUILD_CMAKE + +/// Gets the heartbeat code for today. +- (FIRDailyHeartbeatCode)heartbeatCodeForToday; + +@end + +#ifndef FIREBASE_BUILD_CMAKE +/// Returns a nullable string header value from a given heartbeats payload. +/// +/// This API returns `nil` when the given heartbeats payload is considered empty. +/// +/// @param heartbeatsPayload The heartbeats payload. +NSString *_Nullable FIRHeaderValueFromHeartbeatsPayload(FIRHeartbeatsPayload *heartbeatsPayload); +#endif // FIREBASE_BUILD_CMAKE + +/// A thread safe, synchronized object that logs and flushes platform logging info. +@interface FIRHeartbeatLogger : NSObject + +/// Designated initializer. +/// +/// @param appID The app ID that this heartbeat logger corresponds to. +- (instancetype)initWithAppID:(NSString *)appID; + +/// Asynchronously logs a new heartbeat corresponding to the Firebase User Agent, if needed. +/// +/// @note This API is thread-safe. +- (void)log; + +#ifndef FIREBASE_BUILD_CMAKE +/// Flushes heartbeats from storage into a structured payload of heartbeats. +/// +/// This API is for clients using platform logging V2. +/// +/// @note This API is thread-safe. +/// @return A payload of heartbeats. +- (FIRHeartbeatsPayload *)flushHeartbeatsIntoPayload; +#endif // FIREBASE_BUILD_CMAKE + +/// Gets today's corresponding heartbeat code. +/// +/// This API is for clients using platform logging V1. +/// +/// @note This API is thread-safe. +/// @return Heartbeat code indicating whether or not there is an unsent global heartbeat. +- (FIRDailyHeartbeatCode)heartbeatCodeForToday; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRLibrary.h b/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRLibrary.h new file mode 100644 index 0000000..15e2865 --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRLibrary.h @@ -0,0 +1,44 @@ +/* + * 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. + */ + +#ifndef FIRLibrary_h +#define FIRLibrary_h + +#import + +@class FIRApp; +@class FIRComponent; + +NS_ASSUME_NONNULL_BEGIN + +/// Provide an interface to register a library for userAgent logging and availability to others. +NS_SWIFT_NAME(Library) +@protocol FIRLibrary + +/// Returns one or more Components that will be registered in +/// FirebaseApp and participate in dependency resolution and injection. ++ (NSArray *)componentsToRegister; + +@optional +/// Implement this method if the library needs notifications for lifecycle events. This method is +/// called when the developer calls `FirebaseApp.configure()`. ++ (void)configureWithApp:(FIRApp *)app; + +@end + +NS_ASSUME_NONNULL_END + +#endif /* FIRLibrary_h */ diff --git a/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRLogger.h b/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRLogger.h new file mode 100644 index 0000000..41c5653 --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseCore/Extension/FIRLogger.h @@ -0,0 +1,193 @@ +/* + * 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 + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * The Firebase services used in Firebase logger. + */ +typedef NSString *const FIRLoggerService; + +extern FIRLoggerService kFIRLoggerAnalytics; +extern FIRLoggerService kFIRLoggerCrash; +extern FIRLoggerService kFIRLoggerCore; +extern FIRLoggerService kFIRLoggerRemoteConfig; + +/** + * The key used to store the logger's error count. + */ +extern NSString *const kFIRLoggerErrorCountKey; + +/** + * The key used to store the logger's warning count. + */ +extern NSString *const kFIRLoggerWarningCountKey; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * Enables or disables Analytics debug mode. + * If set to true, the logging level for Analytics will be set to FirebaseLoggerLevelDebug. + * Enabling the debug mode has no effect if the app is running from App Store. + * (required) analytics debug mode flag. + */ +void FIRSetAnalyticsDebugMode(BOOL analyticsDebugMode); + +/** + * Gets the current FIRLoggerLevel. + */ +FIRLoggerLevel FIRGetLoggerLevel(void); + +/** + * Changes the default logging level of FirebaseLoggerLevelNotice to a user-specified level. + * The default level cannot be set above FirebaseLoggerLevelNotice if the app is running from App + * Store. (required) log level (one of the FirebaseLoggerLevel enum values). + */ +void FIRSetLoggerLevel(FIRLoggerLevel loggerLevel); + +/** + * Checks if the specified logger level is loggable given the current settings. + * (required) log level (one of the FirebaseLoggerLevel enum values). + * (required) whether or not this function is called from the Analytics component. + */ +BOOL FIRIsLoggableLevel(FIRLoggerLevel loggerLevel, BOOL analyticsComponent); + +/** + * 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 FirebaseLoggerLevelNotice to avoid log spamming. + * (required) log level (one of the FirebaseLoggerLevel enum values). + * (required) service name of type FirebaseLoggerService. + * (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 FIRLogBasic(FIRLoggerLevel level, + FIRLoggerService service, + 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 FirebaseLoggerService. + * (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: + * FirebaseLogError(kFirebaseLoggerCore, @"I-COR000001", @"Configuration of %@ failed.", app.name); + */ +extern void FIRLogError(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogWarning(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogNotice(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogInfo(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogDebug(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); + +// TODO: Come up with a better logging scheme for Swift. +/** + * Logs a debug message to the Xcode console and the device log. If running from AppStore, will + * not log any messages with a level higher than FirebaseLoggerLevelNotice to avoid log spamming. + * This function is intended to be used by Swift clients that do not support variadic parameters. + * + * @param service The service name of type `FirebaseLoggerService`. + * @param messageCode The mesage 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". + * @param message The message string. + */ +extern void FIRLogDebugSwift(FIRLoggerService service, NSString *messageCode, NSString *message); + +/** + * Logs a warning message to the Xcode console and the device log. If running from AppStore, will + * not log any messages with a level higher than FirebaseLoggerLevelNotice to avoid log spamming. + * This function is intended to be used by Swift clients that do not support variadic parameters. + * + * @param service The service name of type `FirebaseLoggerService`. + * @param messageCode The mesage 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". + * @param message The message string. + */ +extern void FIRLogWarningSwift(FIRLoggerService service, NSString *messageCode, NSString *message); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +NS_SWIFT_NAME(FirebaseLogger) +@interface FIRLoggerWrapper : NSObject + +/// Logs a given message at a given log level. This API is effectively a wrapper for the +/// `FIRLogBasic` C API. +/// +/// - Parameters: +/// - level: The log level to use (defined by `FirebaseLoggerLevel` enum values). +/// - service: The service name of type `FirebaseLoggerService`. +/// - code: The mesage 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". +/// - message: Formatted string to be used as the log's message. +/// - args: Arguments list obtained from calling `va_start`, used when message is a format string. ++ (void)logWithLevel:(FIRLoggerLevel)level + withService:(FIRLoggerService)service + withCode:(NSString *)messageCode + withMessage:(NSString *)message + withArgs:(va_list)args; + +/// Logs a given message at a given log level. +/// +/// - Parameters: +/// - level: The log level to use (defined by `FirebaseLoggerLevel` enum values). +/// - service: The service name of type `FirebaseLoggerService`. +/// - code: The mesage 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". +/// - message: Formatted string to be used as the log's message. +/// - args: Arguments list obtained from calling `va_start`, used when message is a format string. ++ (void)logWithLevel:(FIRLoggerLevel)level + service:(FIRLoggerService)service + code:(NSString *)code + message:(NSString *)message + __attribute__((__swift_name__("log(level:service:code:message:)"))); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseABTesting/FirebaseCore/Extension/FIROptionsInternal.h b/Pods/FirebaseABTesting/FirebaseCore/Extension/FIROptionsInternal.h new file mode 100644 index 0000000..93a03d6 --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseCore/Extension/FIROptionsInternal.h @@ -0,0 +1,106 @@ +/* + * 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 + +/** + * Keys for the strings in the plist file. + */ +extern NSString *const kFIRAPIKey; +extern NSString *const kFIRTrackingID; +extern NSString *const kFIRGoogleAppID; +extern NSString *const kFIRClientID; +extern NSString *const kFIRGCMSenderID; +extern NSString *const kFIRAndroidClientID; +extern NSString *const kFIRDatabaseURL; +extern NSString *const kFIRStorageBucket; +extern NSString *const kFIRBundleID; +extern NSString *const kFIRProjectID; + +/** + * Keys for the plist file name + */ +extern NSString *const kServiceInfoFileName; + +extern NSString *const kServiceInfoFileType; + +/** + * This header file exposes the initialization of FirebaseOptions to internal use. + */ +@interface FIROptions () + +/** + * `resetDefaultOptions` and `initInternalWithOptionsDictionary` are exposed only for unit tests. + */ ++ (void)resetDefaultOptions; + +/** + * Initializes the options with dictionary. The above strings are the keys of the dictionary. + * This is the designated initializer. + */ +- (instancetype)initInternalWithOptionsDictionary:(NSDictionary *)serviceInfoDictionary + NS_DESIGNATED_INITIALIZER; + +/** + * `defaultOptions` and `defaultOptionsDictionary` are exposed in order to be used in FirebaseApp + * and other first party services. + */ ++ (FIROptions *)defaultOptions; + ++ (NSDictionary *)defaultOptionsDictionary; + +/** + * Indicates whether or not Analytics collection was explicitly enabled via a plist flag or at + * runtime. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionExplicitlySet; + +/** + * Whether or not Analytics Collection was enabled. Analytics Collection is enabled unless + * explicitly disabled in GoogleService-Info.plist. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionEnabled; + +/** + * Whether or not Analytics Collection was completely disabled. If true, then + * isAnalyticsCollectionEnabled will be false. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionDeactivated; + +/** + * The version ID of the client library, e.g. @"1100000". + */ +@property(nonatomic, readonly, copy) NSString *libraryVersionID; + +/** + * The flag indicating whether this object was constructed with the values in the default plist + * file. + */ +@property(nonatomic) BOOL usingOptionsFromDefaultPlist; + +/** + * Whether or not Measurement was enabled. Measurement is enabled unless explicitly disabled in + * GoogleService-Info.plist. + */ +@property(nonatomic, readonly) BOOL isMeasurementEnabled; + +/** + * Whether or not editing is locked. This should occur after `FirebaseOptions` has been set on a + * `FirebaseApp`. + */ +@property(nonatomic, getter=isEditingLocked) BOOL editingLocked; + +@end diff --git a/Pods/FirebaseABTesting/FirebaseCore/Extension/FirebaseCoreInternal.h b/Pods/FirebaseABTesting/FirebaseCore/Extension/FirebaseCoreInternal.h new file mode 100644 index 0000000..0669ae6 --- /dev/null +++ b/Pods/FirebaseABTesting/FirebaseCore/Extension/FirebaseCoreInternal.h @@ -0,0 +1,25 @@ +// 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 FirebaseCore; + +#import "FIRAppInternal.h" +#import "FIRComponent.h" +#import "FIRComponentContainer.h" +#import "FIRComponentType.h" +#import "FIRDependency.h" +#import "FIRHeartbeatLogger.h" +#import "FIRLibrary.h" +#import "FIRLogger.h" +#import "FIROptionsInternal.h" diff --git a/Pods/FirebaseABTesting/Interop/Analytics/Public/FIRAnalyticsInterop.h b/Pods/FirebaseABTesting/Interop/Analytics/Public/FIRAnalyticsInterop.h new file mode 100644 index 0000000..3b49733 --- /dev/null +++ b/Pods/FirebaseABTesting/Interop/Analytics/Public/FIRAnalyticsInterop.h @@ -0,0 +1,68 @@ +/* + * 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 + +@protocol FIRAnalyticsInteropListener; + +NS_ASSUME_NONNULL_BEGIN + +/// Block typedef callback parameter to `getUserProperties(with:)`. +typedef void (^FIRAInteropUserPropertiesCallback)(NSDictionary *userProperties) + NS_SWIFT_UNAVAILABLE("Use Swift's closure syntax instead."); + +/// Connector for bridging communication between Firebase SDKs and FirebaseAnalytics APIs. +@protocol FIRAnalyticsInterop + +/// Sets user property when trigger event is logged. This API is only available in the SDK. +- (void)setConditionalUserProperty:(NSDictionary *)conditionalUserProperty; + +/// Clears user property if set. +- (void)clearConditionalUserProperty:(NSString *)userPropertyName + forOrigin:(NSString *)origin + clearEventName:(NSString *)clearEventName + clearEventParameters:(NSDictionary *)clearEventParameters; + +/// Returns currently set user properties. +- (NSArray *> *)conditionalUserProperties:(NSString *)origin + propertyNamePrefix: + (NSString *)propertyNamePrefix; + +/// Returns the maximum number of user properties. +- (NSInteger)maxUserProperties:(NSString *)origin; + +/// Returns the user properties to a callback function. +- (void)getUserPropertiesWithCallback: + (void (^)(NSDictionary *userProperties))callback; + +/// Logs events. +- (void)logEventWithOrigin:(NSString *)origin + name:(NSString *)name + parameters:(nullable NSDictionary *)parameters; + +/// Sets user property. +- (void)setUserPropertyWithOrigin:(NSString *)origin name:(NSString *)name value:(id)value; + +/// Registers an Analytics listener for the given origin. +- (void)registerAnalyticsListener:(id)listener + withOrigin:(NSString *)origin; + +/// Unregisters an Analytics listener for the given origin. +- (void)unregisterAnalyticsListenerWithOrigin:(NSString *)origin; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseABTesting/Interop/Analytics/Public/FIRAnalyticsInteropListener.h b/Pods/FirebaseABTesting/Interop/Analytics/Public/FIRAnalyticsInteropListener.h new file mode 100644 index 0000000..327aefd --- /dev/null +++ b/Pods/FirebaseABTesting/Interop/Analytics/Public/FIRAnalyticsInteropListener.h @@ -0,0 +1,24 @@ +/* + * 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. + */ + +/// Handles events and messages from Analytics. +@protocol FIRAnalyticsInteropListener + +/// Triggers when an Analytics event happens for the registered origin with +/// FirebaseAnalyticsInterop`s `registerAnalyticsListener(_:withOrigin:)`. +- (void)messageTriggered:(NSString *)name parameters:(NSDictionary *)parameters; + +@end diff --git a/Pods/FirebaseABTesting/Interop/Analytics/Public/FIRInteropEventNames.h b/Pods/FirebaseABTesting/Interop/Analytics/Public/FIRInteropEventNames.h new file mode 100644 index 0000000..efc54ab --- /dev/null +++ b/Pods/FirebaseABTesting/Interop/Analytics/Public/FIRInteropEventNames.h @@ -0,0 +1,28 @@ +/* + * 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. + */ + +/// @file FIRInteropEventNames.h + +#import + +/// Notification open event name. +static NSString *const kFIRIEventNotificationOpen = @"_no"; + +/// Notification foreground event name. +static NSString *const kFIRIEventNotificationForeground = @"_nf"; + +/// Campaign event name. +static NSString *const kFIRIEventFirebaseCampaign = @"_cmp"; diff --git a/Pods/FirebaseABTesting/Interop/Analytics/Public/FIRInteropParameterNames.h b/Pods/FirebaseABTesting/Interop/Analytics/Public/FIRInteropParameterNames.h new file mode 100644 index 0000000..f640702 --- /dev/null +++ b/Pods/FirebaseABTesting/Interop/Analytics/Public/FIRInteropParameterNames.h @@ -0,0 +1,73 @@ +/* + * 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 + +/// @file FIRInteropParameterNames.h +/// +/// Predefined event parameter names used by Firebase. This file is a subset of the +/// FirebaseAnalytics FIRParameterNames.h public header. +/// +/// The origin of your traffic, such as an Ad network (for example, google) or partner (urban +/// airship). Identify the advertiser, site, publication, etc. that is sending traffic to your +/// property. Highly recommended (String). +///
+///     let params = [
+///       kFIRParameterSource : "InMobi",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRIParameterSource NS_SWIFT_NAME(AnalyticsParameterSource) = @"source"; + +/// The advertising or marketing medium, for example: cpc, banner, email, push. Highly recommended +/// (String). +///
+///     let params = [
+///       kFIRParameterMedium : "email",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRIParameterMedium NS_SWIFT_NAME(AnalyticsParameterMedium) = @"medium"; + +/// The individual campaign name, slogan, promo code, etc. Some networks have pre-defined macro to +/// capture campaign information, otherwise can be populated by developer. Highly Recommended +/// (String). +///
+///     let params = [
+///       kFIRParameterCampaign : "winter_promotion",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRIParameterCampaign NS_SWIFT_NAME(AnalyticsParameterCampaign) = + @"campaign"; + +/// Message identifier. +static NSString *const kFIRIParameterMessageIdentifier = @"_nmid"; + +/// Message name. +static NSString *const kFIRIParameterMessageName = @"_nmn"; + +/// Message send time. +static NSString *const kFIRIParameterMessageTime = @"_nmt"; + +/// Message device time. +static NSString *const kFIRIParameterMessageDeviceTime = @"_ndt"; + +/// Topic message. +static NSString *const kFIRIParameterTopic = @"_nt"; + +/// Stores the message_id of the last notification opened by the app. +static NSString *const kFIRIUserPropertyLastNotification = @"_ln"; diff --git a/Pods/FirebaseABTesting/LICENSE b/Pods/FirebaseABTesting/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/Pods/FirebaseABTesting/LICENSE @@ -0,0 +1,202 @@ + + 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. diff --git a/Pods/FirebaseABTesting/README.md b/Pods/FirebaseABTesting/README.md new file mode 100644 index 0000000..4c915ab --- /dev/null +++ b/Pods/FirebaseABTesting/README.md @@ -0,0 +1,297 @@ +

+ + + + + + + + +
+ + + + + + +

+ +# Firebase Apple Open Source Development + +This repository contains the source code for all Apple platform Firebase SDKs except FirebaseAnalytics. + +Firebase is an app development platform with tools to help you build, grow, and +monetize your app. More information about Firebase can be found on the +[official Firebase website](https://firebase.google.com). + +## Installation + +See the subsections below for details about the different installation methods. Where +available, it's recommended to install any libraries with a `Swift` suffix to get the +best experience when writing your app in Swift. + +1. [Standard pod install](#standard-pod-install) +2. [Swift Package Manager](#swift-package-manager) +3. [Installing from the GitHub repo](#installing-from-github) +4. [Experimental Carthage](#carthage-ios-only) + +### Standard pod install + +For instructions on the standard pod install, visit: +[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup). + +### Swift Package Manager + +Instructions for [Swift Package Manager](https://swift.org/package-manager/) support can be +found in the [SwiftPackageManager.md](SwiftPackageManager.md) Markdown file. + +### Installing from GitHub + +These instructions can be used to access the Firebase repo at other branches, +tags, or commits. + +#### Background + +See [the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod) +for instructions and options about overriding pod source locations. + +#### Accessing Firebase Source Snapshots + +All official releases are tagged in this repo and available via CocoaPods. To access a local +source snapshot or unreleased branch, use Podfile directives like the following: + +To access FirebaseFirestore via a branch: +```ruby +pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'main' +pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'main' +``` + +To access FirebaseMessaging via a checked-out version of the firebase-ios-sdk repo: +```ruby +pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk' +pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk' +``` + +### Carthage (iOS only) + +Instructions for the experimental Carthage distribution can be found at +[Carthage.md](Carthage.md). + +### Using Firebase from a Framework or a library + +For details on using Firebase from a Framework or a library, refer to [firebase_in_libraries.md](docs/firebase_in_libraries.md). + +## Development + +To develop Firebase software in this repository, ensure that you have at least +the following software: + +* Xcode 15.2 (or later) + +CocoaPods is still the canonical way to develop, but much of the repo now supports +development with Swift Package Manager. + +### CocoaPods + +Install the following: +* CocoaPods 1.12.0 (or later) +* [CocoaPods generate](https://github.com/square/cocoapods-generate) + +For the pod that you want to develop: + +```ruby +pod gen Firebase{name here}.podspec --local-sources=./ --auto-open --platforms=ios +``` + +Note: If the CocoaPods cache is out of date, you may need to run +`pod repo update` before the `pod gen` command. + +Note: Set the `--platforms` option to `macos` or `tvos` to develop/test for +those platforms. Since 10.2, Xcode does not properly handle multi-platform +CocoaPods workspaces. + +Firestore has a self-contained Xcode project. See +[Firestore/README](Firestore/README.md) Markdown file. + +#### Development for Catalyst +* `pod gen {name here}.podspec --local-sources=./ --auto-open --platforms=ios` +* Check the Mac box in the App-iOS Build Settings +* Sign the App in the Settings Signing & Capabilities tab +* Click Pods in the Project Manager +* Add Signing to the iOS host app and unit test targets +* Select the Unit-unit scheme +* Run it to build and test + +Alternatively, disable signing in each target: +* Go to Build Settings tab +* Click `+` +* Select `Add User-Defined Setting` +* Add `CODE_SIGNING_REQUIRED` setting with a value of `NO` + +### Swift Package Manager +* To enable test schemes: `./scripts/setup_spm_tests.sh` +* `open Package.swift` or double click `Package.swift` in Finder. +* Xcode will open the project + * Choose a scheme for a library to build or test suite to run + * Choose a target platform by selecting the run destination along with the scheme + +### Adding a New Firebase Pod + +Refer to [AddNewPod](AddNewPod.md) Markdown file for details. + +### Managing Headers and Imports + +For information about managing headers and imports, see [HeadersImports](HeadersImports.md) Markdown file. + +### Code Formatting + +To ensure that the code is formatted consistently, run the script +[./scripts/check.sh](https://github.com/firebase/firebase-ios-sdk/blob/main/scripts/check.sh) +before creating a pull request (PR). + +GitHub Actions will verify that any code changes are done in a style-compliant +way. Install `clang-format` and `mint`: + +```console +brew install clang-format@18 +brew install mint +``` + +### Running Unit Tests + +Select a scheme and press Command-u to build a component and run its unit tests. + +### Running Sample Apps +To run the sample apps and integration tests, you'll need a valid +`GoogleService-Info.plist +` file. The Firebase Xcode project contains dummy plist +files without real values, but they can be replaced with real plist files. To get your own +`GoogleService-Info.plist` files: + +1. Go to the [Firebase Console](https://console.firebase.google.com/) +2. Create a new Firebase project, if you don't already have one +3. For each sample app you want to test, create a new Firebase app with the sample app's bundle +identifier (e.g., `com.google.Database-Example`) +4. Download the resulting `GoogleService-Info.plist` and add it to the Xcode project. + +### Coverage Report Generation + +For coverage report generation instructions, see [scripts/code_coverage_report/README](scripts/code_coverage_report/README.md) Markdown file. + +## Specific Component Instructions +See the sections below for any special instructions for those components. + +### Firebase Auth + +For specific Firebase Auth development, refer to the [Auth Sample README](FirebaseAuth/Tests/Sample/README.md) for instructions about +building and running the FirebaseAuth pod along with various samples and tests. + +### Firebase Database + +The Firebase Database Integration tests can be run against a locally running Database Emulator +or against a production instance. + +To run against a local emulator instance, invoke `./scripts/run_database_emulator.sh start` before +running the integration test. + +To run against a production instance, provide a valid `GoogleServices-Info.plist` and copy it to +`FirebaseDatabase/Tests/Resources/GoogleService-Info.plist`. Your Security Rule must be set to +[public](https://firebase.google.com/docs/database/security/quickstart) while your tests are +running. + +### Firebase Dynamic Links + +Firebase Dynamic Links is **deprecated** and should not be used in new projects. The service will shut down on August 25, 2025. + +Please see our [Dynamic Links Deprecation FAQ documentation](https://firebase.google.com/support/dynamic-links-faq) for more guidance. + +### Firebase Performance Monitoring + +For specific Firebase Performance Monitoring development, see +[the Performance README](FirebasePerformance/README.md) for instructions about building the SDK +and [the Performance TestApp README](FirebasePerformance/Tests/TestApp/README.md) for instructions about +integrating Performance with the dev test App. + +### Firebase Storage + +To run the Storage Integration tests, follow the instructions in +[StorageIntegration.swift](FirebaseStorage/Tests/Integration/StorageIntegration.swift). + +#### Push Notifications + +Push notifications can only be delivered to specially provisioned App IDs in the developer portal. +In order to test receiving push notifications, you will need to: + +1. Change the bundle identifier of the sample app to something you own in your Apple Developer +account and enable that App ID for push notifications. +2. You'll also need to +[upload your APNs Provider Authentication Key or certificate to the +Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs) +at **Project Settings > Cloud Messaging > [Your Firebase App]**. +3. Ensure your iOS device is added to your Apple Developer portal as a test device. + +#### iOS Simulator + +The iOS Simulator cannot register for remote notifications and will not receive push notifications. +To receive push notifications, follow the steps above and run the app on a physical device. + +## Building with Firebase on Apple platforms + +Firebase provides official beta support for macOS, Catalyst, and tvOS. visionOS and watchOS +are community supported. Thanks to community contributions for many of the multi-platform PRs. + +At this time, most of Firebase's products are available across Apple platforms. There are still +a few gaps, especially on visionOS and watchOS. For details about the current support matrix, see +[this chart](https://firebase.google.com/docs/ios/learn-more#firebase_library_support_by_platform) +in Firebase's documentation. + +### visionOS + +Where supported, visionOS works as expected with the exception of Firestore via Swift Package +Manager where it is required to use the source distribution. + +To enable the Firestore source distribution, quit Xcode and open the desired +project from the command line with the `FIREBASE_SOURCE_FIRESTORE` environment +variable: `open --env FIREBASE_SOURCE_FIRESTORE /path/to/project.xcodeproj`. +To go back to using the binary distribution of Firestore, quit Xcode and open +Xcode like normal, without the environment variable. + +### watchOS +Thanks to contributions from the community, many of Firebase SDKs now compile, run unit tests, and +work on watchOS. See the [Independent Watch App Sample](Example/watchOSSample). + +Keep in mind that watchOS is not officially supported by Firebase. While we can catch basic unit +test issues with GitHub Actions, there may be some changes where the SDK no longer works as expected +on watchOS. If you encounter this, please +[file an issue](https://github.com/firebase/firebase-ios-sdk/issues). + +During app setup in the console, you may get to a step that mentions something like "Checking if the +app has communicated with our servers". This relies on Analytics and will not work on watchOS. +**It's safe to ignore the message and continue**, the rest of the SDKs will work as expected. + +#### Additional Crashlytics Notes +* watchOS has limited support. Due to watchOS restrictions, mach exceptions and signal crashes are +not recorded. (Crashes in SwiftUI are generated as mach exceptions, so will not be recorded) + +## Combine +Thanks to contributions from the community, _FirebaseCombineSwift_ contains support for Apple's Combine +framework. This module is currently under development and not yet supported for use in production +environments. For more details, please refer to the [docs](FirebaseCombineSwift/README.md). + +## Roadmap + +See [Roadmap](ROADMAP.md) for more about the Firebase Apple SDK Open Source +plans and directions. + +## Contributing + +See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase +Apple SDK. + +## License + +The contents of this repository are licensed under the +[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +Your use of Firebase is governed by the +[Terms of Service for Firebase Services](https://firebase.google.com/terms/). diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/Info.plist b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/Info.plist new file mode 100644 index 0000000..ed2ba70 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/Info.plist @@ -0,0 +1,107 @@ + + + + + AvailableLibraries + + + BinaryPath + FirebaseAnalytics.framework/FirebaseAnalytics + LibraryIdentifier + ios-arm64 + LibraryPath + FirebaseAnalytics.framework + SupportedArchitectures + + arm64 + + SupportedPlatform + ios + + + BinaryPath + FirebaseAnalytics.framework/FirebaseAnalytics + LibraryIdentifier + tvos-arm64_x86_64-simulator + LibraryPath + FirebaseAnalytics.framework + SupportedArchitectures + + arm64 + x86_64 + + SupportedPlatform + tvos + SupportedPlatformVariant + simulator + + + BinaryPath + FirebaseAnalytics.framework/Versions/A/FirebaseAnalytics + LibraryIdentifier + macos-arm64_x86_64 + LibraryPath + FirebaseAnalytics.framework + SupportedArchitectures + + arm64 + x86_64 + + SupportedPlatform + macos + + + BinaryPath + FirebaseAnalytics.framework/Versions/A/FirebaseAnalytics + LibraryIdentifier + ios-arm64_x86_64-maccatalyst + LibraryPath + FirebaseAnalytics.framework + SupportedArchitectures + + arm64 + x86_64 + + SupportedPlatform + ios + SupportedPlatformVariant + maccatalyst + + + BinaryPath + FirebaseAnalytics.framework/FirebaseAnalytics + LibraryIdentifier + ios-arm64_x86_64-simulator + LibraryPath + FirebaseAnalytics.framework + SupportedArchitectures + + arm64 + x86_64 + + SupportedPlatform + ios + SupportedPlatformVariant + simulator + + + BinaryPath + FirebaseAnalytics.framework/FirebaseAnalytics + LibraryIdentifier + tvos-arm64 + LibraryPath + FirebaseAnalytics.framework + SupportedArchitectures + + arm64 + + SupportedPlatform + tvos + + + CFBundlePackageType + XFWK + XCFrameworkFormatVersion + 1.0 + + diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/_CodeSignature/CodeDirectory b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/_CodeSignature/CodeDirectory new file mode 100644 index 0000000..f8dabde Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/_CodeSignature/CodeDirectory differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/_CodeSignature/CodeRequirements b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/_CodeSignature/CodeRequirements new file mode 100644 index 0000000..665b37e Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/_CodeSignature/CodeRequirements differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/_CodeSignature/CodeRequirements-1 b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/_CodeSignature/CodeRequirements-1 new file mode 100644 index 0000000..9f3be91 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/_CodeSignature/CodeRequirements-1 differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/_CodeSignature/CodeResources b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/_CodeSignature/CodeResources new file mode 100644 index 0000000..1e72952 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/_CodeSignature/CodeResources @@ -0,0 +1,2068 @@ + + + + + files + + ios-arm64/FirebaseAnalytics.framework/FirebaseAnalytics + + Wvq8dMa4Z+fLjCdthUk93AXDjYs= + + ios-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h + + JxSy4BVIpZB3s+tbI3EgcIVsvN0= + + ios-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h + + IN4riVkldIj3MlPpvlUuU1i+I8w= + + ios-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+OnDevice.h + + 58LqQ/Y9jqPGz3JttzK0z7jPLLc= + + ios-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics.h + + B+YLaEHhiOu6tTPZaB5wWy4n95U= + + ios-arm64/FirebaseAnalytics.framework/Headers/FIREventNames.h + + HrzLufMtB3E5zAfPXZTkYQdGyHI= + + ios-arm64/FirebaseAnalytics.framework/Headers/FIRParameterNames.h + + SztBbCRZ5QE523pdMx4HZt0AYKE= + + ios-arm64/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h + + 33ogzLW88kbc3XVXJp9Opq9Znmc= + + ios-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-Swift.h + + 0nWXABx/HRqcUMkqMxRdJuHxqQU= + + ios-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-umbrella.h + + wE8Bjq1o5wGq1TFJb0gCJUmRelQ= + + ios-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h + + 6tM+QmAiCFyFHMaFXgWsH/uYosM= + + ios-arm64/FirebaseAnalytics.framework/Info.plist + + VFXUkFwI/Qttaci0byyKDL6gUFw= + + ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-ios.swiftsourceinfo + + OgZ030oAOOjfCpM84QtaJVaCIUA= + + ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios.abi.json + + 5Fu2Bze8ZWR5SLeF8QjMttSgRDs= + + ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios.private.swiftinterface + + PTzHQuWqC1lwO+qReE+xp0WO1no= + + ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios.swiftdoc + + OaDLqia2HgSvNF2HhREihK6wwYI= + + ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios.swiftinterface + + PTzHQuWqC1lwO+qReE+xp0WO1no= + + ios-arm64/FirebaseAnalytics.framework/Modules/module.modulemap + + uLysK0T5K1GSoqJmcXx9AnZ9lqY= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/FirebaseAnalytics + + kB1G1t2FFQAyJHX0rlDAa1oEgsY= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+AppDelegate.h + + JxSy4BVIpZB3s+tbI3EgcIVsvN0= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+Consent.h + + IN4riVkldIj3MlPpvlUuU1i+I8w= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+OnDevice.h + + 58LqQ/Y9jqPGz3JttzK0z7jPLLc= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics.h + + B+YLaEHhiOu6tTPZaB5wWy4n95U= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIREventNames.h + + HrzLufMtB3E5zAfPXZTkYQdGyHI= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRParameterNames.h + + SztBbCRZ5QE523pdMx4HZt0AYKE= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRUserPropertyNames.h + + 33ogzLW88kbc3XVXJp9Opq9Znmc= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics-Swift.h + + cu0mXcU7RrT9nKAMSamYxQcZ8MA= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics-umbrella.h + + wE8Bjq1o5wGq1TFJb0gCJUmRelQ= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics.h + + 6tM+QmAiCFyFHMaFXgWsH/uYosM= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-ios-macabi.swiftsourceinfo + + C1nKyqfCOB2LX0Gu2ZbsQsJ9FzU= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/Project/x86_64-apple-ios-macabi.swiftsourceinfo + + bKmx/X4by/kc9nGZb8TWGhQgX0o= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-macabi.abi.json + + 5Fu2Bze8ZWR5SLeF8QjMttSgRDs= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-macabi.private.swiftinterface + + 4gR6vGh9NGCOc8NqbJitBi4PYMc= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-macabi.swiftdoc + + qhoelsD3haNmZEE9NM8xvtK9mEY= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-macabi.swiftinterface + + 4gR6vGh9NGCOc8NqbJitBi4PYMc= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-macabi.abi.json + + 5Fu2Bze8ZWR5SLeF8QjMttSgRDs= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-macabi.private.swiftinterface + + R1LVVji18GwfW9nhhjO5aFGB1+k= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-macabi.swiftdoc + + /8RdTbctZKCA1/OIwmZLl2oWnCk= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-macabi.swiftinterface + + R1LVVji18GwfW9nhhjO5aFGB1+k= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/module.modulemap + + uLysK0T5K1GSoqJmcXx9AnZ9lqY= + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Resources/Info.plist + + PokZODiJA9FvpxlhHEwzwdhYxG8= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/FirebaseAnalytics + + IW0Z41e3u4jFO3dWrHueL7+sOsE= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h + + JxSy4BVIpZB3s+tbI3EgcIVsvN0= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h + + IN4riVkldIj3MlPpvlUuU1i+I8w= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+OnDevice.h + + 58LqQ/Y9jqPGz3JttzK0z7jPLLc= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics.h + + B+YLaEHhiOu6tTPZaB5wWy4n95U= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIREventNames.h + + HrzLufMtB3E5zAfPXZTkYQdGyHI= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRParameterNames.h + + SztBbCRZ5QE523pdMx4HZt0AYKE= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h + + 33ogzLW88kbc3XVXJp9Opq9Znmc= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-Swift.h + + cu0mXcU7RrT9nKAMSamYxQcZ8MA= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-umbrella.h + + wE8Bjq1o5wGq1TFJb0gCJUmRelQ= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h + + 6tM+QmAiCFyFHMaFXgWsH/uYosM= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Info.plist + + f7OOZ7FpS2qZMILVP+TdB9Rgs6o= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-ios-simulator.swiftsourceinfo + + wjE2XgmPvvXCThyeZW9pQrTXowg= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/x86_64-apple-ios-simulator.swiftsourceinfo + + m3QKTcwbax3hyBx6DzXIfQ0RAEA= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-simulator.abi.json + + 5Fu2Bze8ZWR5SLeF8QjMttSgRDs= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface + + QinHhX49jrG/LCXfKglixhg2PPE= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-simulator.swiftdoc + + 2uhhvWC34TCjqIKVVlqG/EycMGY= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-simulator.swiftinterface + + QinHhX49jrG/LCXfKglixhg2PPE= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-simulator.abi.json + + 5Fu2Bze8ZWR5SLeF8QjMttSgRDs= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface + + 0qZBNnrrWfJHxGSgyJ0H3df9gbQ= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-simulator.swiftdoc + + lW9AObcye0EJ2DSm5O07/pplg2Y= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-simulator.swiftinterface + + 0qZBNnrrWfJHxGSgyJ0H3df9gbQ= + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/module.modulemap + + uLysK0T5K1GSoqJmcXx9AnZ9lqY= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/FirebaseAnalytics + + 7O0kMuuNAG8G1YWYS/lPXc8jgs8= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+AppDelegate.h + + JxSy4BVIpZB3s+tbI3EgcIVsvN0= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+Consent.h + + IN4riVkldIj3MlPpvlUuU1i+I8w= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+OnDevice.h + + 58LqQ/Y9jqPGz3JttzK0z7jPLLc= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics.h + + B+YLaEHhiOu6tTPZaB5wWy4n95U= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIREventNames.h + + HrzLufMtB3E5zAfPXZTkYQdGyHI= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRParameterNames.h + + SztBbCRZ5QE523pdMx4HZt0AYKE= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRUserPropertyNames.h + + 33ogzLW88kbc3XVXJp9Opq9Znmc= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics-Swift.h + + cu0mXcU7RrT9nKAMSamYxQcZ8MA= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics-umbrella.h + + sXk7jWhcfsvb8eJb7/NDl2Dy2RQ= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics.h + + 6tM+QmAiCFyFHMaFXgWsH/uYosM= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-macos.swiftsourceinfo + + 19H4e00yK3doVQpp4IFe2/QrlZE= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/Project/x86_64-apple-macos.swiftsourceinfo + + Ttm12DpOfwq26vt3GrLUUoAHpnM= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-macos.abi.json + + 5Fu2Bze8ZWR5SLeF8QjMttSgRDs= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-macos.private.swiftinterface + + 8GJRLSkXpWDzmNzbFI7E5MPaxHs= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-macos.swiftdoc + + /do/AsQ2BlA5B8FGwqiGoGnBanw= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-macos.swiftinterface + + 8GJRLSkXpWDzmNzbFI7E5MPaxHs= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-macos.abi.json + + 5Fu2Bze8ZWR5SLeF8QjMttSgRDs= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-macos.private.swiftinterface + + IEN4ZkUAv93Vhe3Ywy2Ti9s/jSw= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-macos.swiftdoc + + bobvJ33JqODvJfRuJhtThgX6/9U= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-macos.swiftinterface + + IEN4ZkUAv93Vhe3Ywy2Ti9s/jSw= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/module.modulemap + + jWZ+azdgXQdH9z56z25NptmWlq4= + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Resources/Info.plist + + eIWWX8YW0LsfjLjWVUkaq6ohsgo= + + tvos-arm64/FirebaseAnalytics.framework/FirebaseAnalytics + + 9EC4Tt53LRy3c1nDv8xPkfmWGCI= + + tvos-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h + + JxSy4BVIpZB3s+tbI3EgcIVsvN0= + + tvos-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h + + IN4riVkldIj3MlPpvlUuU1i+I8w= + + tvos-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+OnDevice.h + + 58LqQ/Y9jqPGz3JttzK0z7jPLLc= + + tvos-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics.h + + B+YLaEHhiOu6tTPZaB5wWy4n95U= + + tvos-arm64/FirebaseAnalytics.framework/Headers/FIREventNames.h + + HrzLufMtB3E5zAfPXZTkYQdGyHI= + + tvos-arm64/FirebaseAnalytics.framework/Headers/FIRParameterNames.h + + SztBbCRZ5QE523pdMx4HZt0AYKE= + + tvos-arm64/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h + + 33ogzLW88kbc3XVXJp9Opq9Znmc= + + tvos-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-Swift.h + + 0nWXABx/HRqcUMkqMxRdJuHxqQU= + + tvos-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-umbrella.h + + wE8Bjq1o5wGq1TFJb0gCJUmRelQ= + + tvos-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h + + 6tM+QmAiCFyFHMaFXgWsH/uYosM= + + tvos-arm64/FirebaseAnalytics.framework/Info.plist + + dRfPceuTUosTksVNz/0Ri36DqLU= + + tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-tvos.swiftsourceinfo + + yVqIfrmeZWeToHR1kv1cCRuo4m0= + + tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos.abi.json + + 5Fu2Bze8ZWR5SLeF8QjMttSgRDs= + + tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos.private.swiftinterface + + w4z4Z/v+RhKvKZ9rpQwngKxdIv8= + + tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos.swiftdoc + + hXtRlFapwJDHg4NuSRJKOZnPtf4= + + tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos.swiftinterface + + w4z4Z/v+RhKvKZ9rpQwngKxdIv8= + + tvos-arm64/FirebaseAnalytics.framework/Modules/module.modulemap + + uLysK0T5K1GSoqJmcXx9AnZ9lqY= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/FirebaseAnalytics + + KVkX9v0mFY4HqO2SOzHDP83bkAI= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h + + JxSy4BVIpZB3s+tbI3EgcIVsvN0= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h + + IN4riVkldIj3MlPpvlUuU1i+I8w= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+OnDevice.h + + 58LqQ/Y9jqPGz3JttzK0z7jPLLc= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics.h + + B+YLaEHhiOu6tTPZaB5wWy4n95U= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIREventNames.h + + HrzLufMtB3E5zAfPXZTkYQdGyHI= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRParameterNames.h + + SztBbCRZ5QE523pdMx4HZt0AYKE= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h + + 33ogzLW88kbc3XVXJp9Opq9Znmc= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-Swift.h + + cu0mXcU7RrT9nKAMSamYxQcZ8MA= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-umbrella.h + + wE8Bjq1o5wGq1TFJb0gCJUmRelQ= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h + + 6tM+QmAiCFyFHMaFXgWsH/uYosM= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Info.plist + + vst0ZWR1zNmVpTjgw64kDxX6uW8= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-tvos-simulator.swiftsourceinfo + + +1k66yI96SUoo8vxSL9n1634pdU= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/x86_64-apple-tvos-simulator.swiftsourceinfo + + zaOWjx7mSjW5NKT1uOmvVl3QJgA= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos-simulator.abi.json + + 5Fu2Bze8ZWR5SLeF8QjMttSgRDs= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos-simulator.private.swiftinterface + + Hf8XfWJzIeEvfdJv/6AMdURHy9k= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos-simulator.swiftdoc + + 6OlHbfwffHQPeO54yIdFziP5xxg= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos-simulator.swiftinterface + + Hf8XfWJzIeEvfdJv/6AMdURHy9k= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-tvos-simulator.abi.json + + 5Fu2Bze8ZWR5SLeF8QjMttSgRDs= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-tvos-simulator.private.swiftinterface + + /J9MSWx/8Fj0oVu98k1n8XZmnUE= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-tvos-simulator.swiftdoc + + foK4LqUJlIKa+nt0y/51HYQeK8I= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-tvos-simulator.swiftinterface + + /J9MSWx/8Fj0oVu98k1n8XZmnUE= + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/module.modulemap + + uLysK0T5K1GSoqJmcXx9AnZ9lqY= + + + files2 + + ios-arm64/FirebaseAnalytics.framework/FirebaseAnalytics + + hash + + Wvq8dMa4Z+fLjCdthUk93AXDjYs= + + hash2 + + Pch0gv/glz421v/WC+wTGCCuldb42lAvcjxUPKewT6Y= + + + ios-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h + + hash + + JxSy4BVIpZB3s+tbI3EgcIVsvN0= + + hash2 + + HSPmaeLSu5PqNTtlwUWfRT4cyVX65JmeB/oed8f0pdU= + + + ios-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h + + hash + + IN4riVkldIj3MlPpvlUuU1i+I8w= + + hash2 + + ebGwpP2JZ0Rp6BdXhKiLUYOq6nJG7la5O0y/wEKfyak= + + + ios-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+OnDevice.h + + hash + + 58LqQ/Y9jqPGz3JttzK0z7jPLLc= + + hash2 + + 67S/czxwflT8GxF7bVp32FLgu2W97zH06W6zv8/VILU= + + + ios-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics.h + + hash + + B+YLaEHhiOu6tTPZaB5wWy4n95U= + + hash2 + + wmpxZuP80odiQUX5Ts7GaPkhE7UeuzmDMrvTcOS0vLQ= + + + ios-arm64/FirebaseAnalytics.framework/Headers/FIREventNames.h + + hash + + HrzLufMtB3E5zAfPXZTkYQdGyHI= + + hash2 + + mNgPvQJ0O5ZQ/EINmxz+zoQHoxj/O70iH5crkbhGU3g= + + + ios-arm64/FirebaseAnalytics.framework/Headers/FIRParameterNames.h + + hash + + SztBbCRZ5QE523pdMx4HZt0AYKE= + + hash2 + + hwLb6dR4Q5L+j2vYcsXcc8sr2yoS1X9vyl7T/PjcHow= + + + ios-arm64/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h + + hash + + 33ogzLW88kbc3XVXJp9Opq9Znmc= + + hash2 + + z0lD0Agt0NzOZdG+xd6QpXvGS+06dK4A3RYK0Wu1OKw= + + + ios-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-Swift.h + + hash + + 0nWXABx/HRqcUMkqMxRdJuHxqQU= + + hash2 + + DmmG7v+JGyWpcKQl1BeGd8rqz4HV3b+PToUt+aM45bY= + + + ios-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-umbrella.h + + hash + + wE8Bjq1o5wGq1TFJb0gCJUmRelQ= + + hash2 + + LOiywMHEh60MswGEzs9lM8P6m3oohYp+IWaiZtbwVVM= + + + ios-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h + + hash + + 6tM+QmAiCFyFHMaFXgWsH/uYosM= + + hash2 + + VS1dxfDwCZeRcJYgkkEUhmdXx6ch9X/E8YjKBX367WY= + + + ios-arm64/FirebaseAnalytics.framework/Info.plist + + hash + + VFXUkFwI/Qttaci0byyKDL6gUFw= + + hash2 + + 1Np+yT0NXuiDaUO+aL7joo717gcywiQCPu26hm/Md6s= + + + ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-ios.swiftsourceinfo + + hash + + OgZ030oAOOjfCpM84QtaJVaCIUA= + + hash2 + + dQW/uuyLkjV41t0Z75F2bCob+KF+Bg8EWkdxjTP0Qe0= + + + ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios.abi.json + + hash + + 5Fu2Bze8ZWR5SLeF8QjMttSgRDs= + + hash2 + + 7CzYzmp6tqardcv/16+L0vtiGC6DQvp2nkfdDVAvkjg= + + + ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios.private.swiftinterface + + hash + + PTzHQuWqC1lwO+qReE+xp0WO1no= + + hash2 + + br3Ok7WRBarJfQ21BS7G8x+55vkZ8wHoYLQ086ewiPU= + + + ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios.swiftdoc + + hash + + OaDLqia2HgSvNF2HhREihK6wwYI= + + hash2 + + QxJ+lhdiHfZw4EPYjEQiZ/RpfCYC6szHehjJqzqtgU4= + + + ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios.swiftinterface + + hash + + PTzHQuWqC1lwO+qReE+xp0WO1no= + + hash2 + + br3Ok7WRBarJfQ21BS7G8x+55vkZ8wHoYLQ086ewiPU= + + + ios-arm64/FirebaseAnalytics.framework/Modules/module.modulemap + + hash + + uLysK0T5K1GSoqJmcXx9AnZ9lqY= + + hash2 + + vxNgOuI61t45Sed09vILAKePFm9riTp4aZ48hjDRPIQ= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/FirebaseAnalytics + + symlink + Versions/Current/FirebaseAnalytics + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Headers + + symlink + Versions/Current/Headers + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Modules + + symlink + Versions/Current/Modules + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Resources + + symlink + Versions/Current/Resources + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/FirebaseAnalytics + + hash + + kB1G1t2FFQAyJHX0rlDAa1oEgsY= + + hash2 + + xPD+6kltIuawoQSXVpZGLnRlqqcjOm+AsfpVCOMk+Wg= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+AppDelegate.h + + hash + + JxSy4BVIpZB3s+tbI3EgcIVsvN0= + + hash2 + + HSPmaeLSu5PqNTtlwUWfRT4cyVX65JmeB/oed8f0pdU= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+Consent.h + + hash + + IN4riVkldIj3MlPpvlUuU1i+I8w= + + hash2 + + ebGwpP2JZ0Rp6BdXhKiLUYOq6nJG7la5O0y/wEKfyak= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+OnDevice.h + + hash + + 58LqQ/Y9jqPGz3JttzK0z7jPLLc= + + hash2 + + 67S/czxwflT8GxF7bVp32FLgu2W97zH06W6zv8/VILU= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics.h + + hash + + B+YLaEHhiOu6tTPZaB5wWy4n95U= + + hash2 + + wmpxZuP80odiQUX5Ts7GaPkhE7UeuzmDMrvTcOS0vLQ= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIREventNames.h + + hash + + HrzLufMtB3E5zAfPXZTkYQdGyHI= + + hash2 + + mNgPvQJ0O5ZQ/EINmxz+zoQHoxj/O70iH5crkbhGU3g= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRParameterNames.h + + hash + + SztBbCRZ5QE523pdMx4HZt0AYKE= + + hash2 + + hwLb6dR4Q5L+j2vYcsXcc8sr2yoS1X9vyl7T/PjcHow= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRUserPropertyNames.h + + hash + + 33ogzLW88kbc3XVXJp9Opq9Znmc= + + hash2 + + z0lD0Agt0NzOZdG+xd6QpXvGS+06dK4A3RYK0Wu1OKw= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics-Swift.h + + hash + + cu0mXcU7RrT9nKAMSamYxQcZ8MA= + + hash2 + + 4mnxjtoRMyo5TIjTieqzJLBQ4m0noIZqWhmI5a2a3QE= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics-umbrella.h + + hash + + wE8Bjq1o5wGq1TFJb0gCJUmRelQ= + + hash2 + + LOiywMHEh60MswGEzs9lM8P6m3oohYp+IWaiZtbwVVM= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics.h + + hash + + 6tM+QmAiCFyFHMaFXgWsH/uYosM= + + hash2 + + VS1dxfDwCZeRcJYgkkEUhmdXx6ch9X/E8YjKBX367WY= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-ios-macabi.swiftsourceinfo + + hash + + C1nKyqfCOB2LX0Gu2ZbsQsJ9FzU= + + hash2 + + amtIu0T5c75kIpgCLt7ucs2o8E+9XdeAq3hQrNmCYTY= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/Project/x86_64-apple-ios-macabi.swiftsourceinfo + + hash + + bKmx/X4by/kc9nGZb8TWGhQgX0o= + + hash2 + + bKSa7X1zXPPZXcAaqCOHEaCwcQBbJxNEe/eBnH5Gm9s= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-macabi.abi.json + + hash + + 5Fu2Bze8ZWR5SLeF8QjMttSgRDs= + + hash2 + + 7CzYzmp6tqardcv/16+L0vtiGC6DQvp2nkfdDVAvkjg= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-macabi.private.swiftinterface + + hash + + 4gR6vGh9NGCOc8NqbJitBi4PYMc= + + hash2 + + sBsGCsKt/qVMlUX2JkA5hB1ko0klhw7cNGdqgUlwGW4= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-macabi.swiftdoc + + hash + + qhoelsD3haNmZEE9NM8xvtK9mEY= + + hash2 + + ORG2lGLtqMk9O/g5fSRsgM0vkRuCeApJ2rKBJUOAyQY= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-macabi.swiftinterface + + hash + + 4gR6vGh9NGCOc8NqbJitBi4PYMc= + + hash2 + + sBsGCsKt/qVMlUX2JkA5hB1ko0klhw7cNGdqgUlwGW4= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-macabi.abi.json + + hash + + 5Fu2Bze8ZWR5SLeF8QjMttSgRDs= + + hash2 + + 7CzYzmp6tqardcv/16+L0vtiGC6DQvp2nkfdDVAvkjg= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-macabi.private.swiftinterface + + hash + + R1LVVji18GwfW9nhhjO5aFGB1+k= + + hash2 + + 8sleA8PWyFsmq4UfIdcmC5GkHeUcPvp/kAytxpjR9N0= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-macabi.swiftdoc + + hash + + /8RdTbctZKCA1/OIwmZLl2oWnCk= + + hash2 + + zgcFlEjAeUx/3gKqZtb0j32k5wK3ScunLgYWrpCZ8YY= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-macabi.swiftinterface + + hash + + R1LVVji18GwfW9nhhjO5aFGB1+k= + + hash2 + + 8sleA8PWyFsmq4UfIdcmC5GkHeUcPvp/kAytxpjR9N0= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/module.modulemap + + hash + + uLysK0T5K1GSoqJmcXx9AnZ9lqY= + + hash2 + + vxNgOuI61t45Sed09vILAKePFm9riTp4aZ48hjDRPIQ= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Resources/Info.plist + + hash + + PokZODiJA9FvpxlhHEwzwdhYxG8= + + hash2 + + qkDJJz/87uWQWeRlK5zGLY2cYoRL8kyOub/irlrq4Iw= + + + ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/Current + + symlink + A + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/FirebaseAnalytics + + hash + + IW0Z41e3u4jFO3dWrHueL7+sOsE= + + hash2 + + GRJMVjx00eHHdbqtInffL+/mLyJxQY/vQ8BuoC0IAUU= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h + + hash + + JxSy4BVIpZB3s+tbI3EgcIVsvN0= + + hash2 + + HSPmaeLSu5PqNTtlwUWfRT4cyVX65JmeB/oed8f0pdU= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h + + hash + + IN4riVkldIj3MlPpvlUuU1i+I8w= + + hash2 + + ebGwpP2JZ0Rp6BdXhKiLUYOq6nJG7la5O0y/wEKfyak= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+OnDevice.h + + hash + + 58LqQ/Y9jqPGz3JttzK0z7jPLLc= + + hash2 + + 67S/czxwflT8GxF7bVp32FLgu2W97zH06W6zv8/VILU= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics.h + + hash + + B+YLaEHhiOu6tTPZaB5wWy4n95U= + + hash2 + + wmpxZuP80odiQUX5Ts7GaPkhE7UeuzmDMrvTcOS0vLQ= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIREventNames.h + + hash + + HrzLufMtB3E5zAfPXZTkYQdGyHI= + + hash2 + + mNgPvQJ0O5ZQ/EINmxz+zoQHoxj/O70iH5crkbhGU3g= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRParameterNames.h + + hash + + SztBbCRZ5QE523pdMx4HZt0AYKE= + + hash2 + + hwLb6dR4Q5L+j2vYcsXcc8sr2yoS1X9vyl7T/PjcHow= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h + + hash + + 33ogzLW88kbc3XVXJp9Opq9Znmc= + + hash2 + + z0lD0Agt0NzOZdG+xd6QpXvGS+06dK4A3RYK0Wu1OKw= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-Swift.h + + hash + + cu0mXcU7RrT9nKAMSamYxQcZ8MA= + + hash2 + + 4mnxjtoRMyo5TIjTieqzJLBQ4m0noIZqWhmI5a2a3QE= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-umbrella.h + + hash + + wE8Bjq1o5wGq1TFJb0gCJUmRelQ= + + hash2 + + LOiywMHEh60MswGEzs9lM8P6m3oohYp+IWaiZtbwVVM= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h + + hash + + 6tM+QmAiCFyFHMaFXgWsH/uYosM= + + hash2 + + VS1dxfDwCZeRcJYgkkEUhmdXx6ch9X/E8YjKBX367WY= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Info.plist + + hash + + f7OOZ7FpS2qZMILVP+TdB9Rgs6o= + + hash2 + + HiMDw90tuR5UvM8L0u5E5GT5buujqbo/JjXO6lEYv5Y= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-ios-simulator.swiftsourceinfo + + hash + + wjE2XgmPvvXCThyeZW9pQrTXowg= + + hash2 + + rocEnMjwRIzIzEaO8rFR7WkSZSo2lmn5E1Ur7skREGY= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/x86_64-apple-ios-simulator.swiftsourceinfo + + hash + + m3QKTcwbax3hyBx6DzXIfQ0RAEA= + + hash2 + + 40AWp53ARH5JVg4v5H2ANVX8wPZPg0BJq3V28SSwUs0= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-simulator.abi.json + + hash + + 5Fu2Bze8ZWR5SLeF8QjMttSgRDs= + + hash2 + + 7CzYzmp6tqardcv/16+L0vtiGC6DQvp2nkfdDVAvkjg= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface + + hash + + QinHhX49jrG/LCXfKglixhg2PPE= + + hash2 + + TlTGbdekTMP/MKLUWM3I9V2KTXERNtHCAgztCGg7v4g= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-simulator.swiftdoc + + hash + + 2uhhvWC34TCjqIKVVlqG/EycMGY= + + hash2 + + 9vcaXzpRIBFJPDzlyoFUMY+TisZbde7d06MG8QD5Ucc= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-simulator.swiftinterface + + hash + + QinHhX49jrG/LCXfKglixhg2PPE= + + hash2 + + TlTGbdekTMP/MKLUWM3I9V2KTXERNtHCAgztCGg7v4g= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-simulator.abi.json + + hash + + 5Fu2Bze8ZWR5SLeF8QjMttSgRDs= + + hash2 + + 7CzYzmp6tqardcv/16+L0vtiGC6DQvp2nkfdDVAvkjg= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface + + hash + + 0qZBNnrrWfJHxGSgyJ0H3df9gbQ= + + hash2 + + NIoF41mM+5NzuoQ+Lx9c6KvvJoqHCMreUqxMD+kS84w= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-simulator.swiftdoc + + hash + + lW9AObcye0EJ2DSm5O07/pplg2Y= + + hash2 + + 7oUz7+K/zFoxTeMYF6mlBUWZWez922QqrjcxTxecVQc= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-simulator.swiftinterface + + hash + + 0qZBNnrrWfJHxGSgyJ0H3df9gbQ= + + hash2 + + NIoF41mM+5NzuoQ+Lx9c6KvvJoqHCMreUqxMD+kS84w= + + + ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/module.modulemap + + hash + + uLysK0T5K1GSoqJmcXx9AnZ9lqY= + + hash2 + + vxNgOuI61t45Sed09vILAKePFm9riTp4aZ48hjDRPIQ= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/FirebaseAnalytics + + symlink + Versions/Current/FirebaseAnalytics + + macos-arm64_x86_64/FirebaseAnalytics.framework/Headers + + symlink + Versions/Current/Headers + + macos-arm64_x86_64/FirebaseAnalytics.framework/Modules + + symlink + Versions/Current/Modules + + macos-arm64_x86_64/FirebaseAnalytics.framework/Resources + + symlink + Versions/Current/Resources + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/FirebaseAnalytics + + hash + + 7O0kMuuNAG8G1YWYS/lPXc8jgs8= + + hash2 + + 9p0p0b4Zc4QbaW7tq7fsfXOUl+cjxKQZ7X1QM13/MPE= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+AppDelegate.h + + hash + + JxSy4BVIpZB3s+tbI3EgcIVsvN0= + + hash2 + + HSPmaeLSu5PqNTtlwUWfRT4cyVX65JmeB/oed8f0pdU= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+Consent.h + + hash + + IN4riVkldIj3MlPpvlUuU1i+I8w= + + hash2 + + ebGwpP2JZ0Rp6BdXhKiLUYOq6nJG7la5O0y/wEKfyak= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+OnDevice.h + + hash + + 58LqQ/Y9jqPGz3JttzK0z7jPLLc= + + hash2 + + 67S/czxwflT8GxF7bVp32FLgu2W97zH06W6zv8/VILU= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics.h + + hash + + B+YLaEHhiOu6tTPZaB5wWy4n95U= + + hash2 + + wmpxZuP80odiQUX5Ts7GaPkhE7UeuzmDMrvTcOS0vLQ= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIREventNames.h + + hash + + HrzLufMtB3E5zAfPXZTkYQdGyHI= + + hash2 + + mNgPvQJ0O5ZQ/EINmxz+zoQHoxj/O70iH5crkbhGU3g= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRParameterNames.h + + hash + + SztBbCRZ5QE523pdMx4HZt0AYKE= + + hash2 + + hwLb6dR4Q5L+j2vYcsXcc8sr2yoS1X9vyl7T/PjcHow= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRUserPropertyNames.h + + hash + + 33ogzLW88kbc3XVXJp9Opq9Znmc= + + hash2 + + z0lD0Agt0NzOZdG+xd6QpXvGS+06dK4A3RYK0Wu1OKw= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics-Swift.h + + hash + + cu0mXcU7RrT9nKAMSamYxQcZ8MA= + + hash2 + + 4mnxjtoRMyo5TIjTieqzJLBQ4m0noIZqWhmI5a2a3QE= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics-umbrella.h + + hash + + sXk7jWhcfsvb8eJb7/NDl2Dy2RQ= + + hash2 + + E6EdPyZp5cQbOObE0CPO9/R+QvTIYlDIOHvuzam/9H8= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics.h + + hash + + 6tM+QmAiCFyFHMaFXgWsH/uYosM= + + hash2 + + VS1dxfDwCZeRcJYgkkEUhmdXx6ch9X/E8YjKBX367WY= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-macos.swiftsourceinfo + + hash + + 19H4e00yK3doVQpp4IFe2/QrlZE= + + hash2 + + xw7jhZ/Z/ug3Dmv55LEwZ6nxrgSHrkWvONGEdf07TQ0= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/Project/x86_64-apple-macos.swiftsourceinfo + + hash + + Ttm12DpOfwq26vt3GrLUUoAHpnM= + + hash2 + + 3ND6xNDL75dle5uSfk7/1rXu4kgJ2te8R+4F5Z3QWSk= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-macos.abi.json + + hash + + 5Fu2Bze8ZWR5SLeF8QjMttSgRDs= + + hash2 + + 7CzYzmp6tqardcv/16+L0vtiGC6DQvp2nkfdDVAvkjg= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-macos.private.swiftinterface + + hash + + 8GJRLSkXpWDzmNzbFI7E5MPaxHs= + + hash2 + + e2hx6o7dBwggM/REp3KsbbHHOSCXakob3UTMbtQSxmQ= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-macos.swiftdoc + + hash + + /do/AsQ2BlA5B8FGwqiGoGnBanw= + + hash2 + + sC/kNiIq68DXBpk2mHvINyOXPLhWhZYdt1nrYgyPno4= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-macos.swiftinterface + + hash + + 8GJRLSkXpWDzmNzbFI7E5MPaxHs= + + hash2 + + e2hx6o7dBwggM/REp3KsbbHHOSCXakob3UTMbtQSxmQ= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-macos.abi.json + + hash + + 5Fu2Bze8ZWR5SLeF8QjMttSgRDs= + + hash2 + + 7CzYzmp6tqardcv/16+L0vtiGC6DQvp2nkfdDVAvkjg= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-macos.private.swiftinterface + + hash + + IEN4ZkUAv93Vhe3Ywy2Ti9s/jSw= + + hash2 + + nNMkbhWYh8cQ2Al4vTVQUuiZ28HKOA1BRk6Ao7x9eqA= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-macos.swiftdoc + + hash + + bobvJ33JqODvJfRuJhtThgX6/9U= + + hash2 + + s/GI6pRR4LifbiY3tDjp006X3w5vfsCnwrbTEnUzqbk= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-macos.swiftinterface + + hash + + IEN4ZkUAv93Vhe3Ywy2Ti9s/jSw= + + hash2 + + nNMkbhWYh8cQ2Al4vTVQUuiZ28HKOA1BRk6Ao7x9eqA= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/module.modulemap + + hash + + jWZ+azdgXQdH9z56z25NptmWlq4= + + hash2 + + e4a41Axjw7BAywMms/GuOcqrdwPIVYuMRsPznqQS0X8= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Resources/Info.plist + + hash + + eIWWX8YW0LsfjLjWVUkaq6ohsgo= + + hash2 + + LxbH3WEjVjxvqAXX7K6EiBwELu79EAqjkuMLrWbE3So= + + + macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/Current + + symlink + A + + tvos-arm64/FirebaseAnalytics.framework/FirebaseAnalytics + + hash + + 9EC4Tt53LRy3c1nDv8xPkfmWGCI= + + hash2 + + zkVd2wrK9oj9ZpacowjrOiRjngbDGdi2DJd/1ifZeKY= + + + tvos-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h + + hash + + JxSy4BVIpZB3s+tbI3EgcIVsvN0= + + hash2 + + HSPmaeLSu5PqNTtlwUWfRT4cyVX65JmeB/oed8f0pdU= + + + tvos-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h + + hash + + IN4riVkldIj3MlPpvlUuU1i+I8w= + + hash2 + + ebGwpP2JZ0Rp6BdXhKiLUYOq6nJG7la5O0y/wEKfyak= + + + tvos-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+OnDevice.h + + hash + + 58LqQ/Y9jqPGz3JttzK0z7jPLLc= + + hash2 + + 67S/czxwflT8GxF7bVp32FLgu2W97zH06W6zv8/VILU= + + + tvos-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics.h + + hash + + B+YLaEHhiOu6tTPZaB5wWy4n95U= + + hash2 + + wmpxZuP80odiQUX5Ts7GaPkhE7UeuzmDMrvTcOS0vLQ= + + + tvos-arm64/FirebaseAnalytics.framework/Headers/FIREventNames.h + + hash + + HrzLufMtB3E5zAfPXZTkYQdGyHI= + + hash2 + + mNgPvQJ0O5ZQ/EINmxz+zoQHoxj/O70iH5crkbhGU3g= + + + tvos-arm64/FirebaseAnalytics.framework/Headers/FIRParameterNames.h + + hash + + SztBbCRZ5QE523pdMx4HZt0AYKE= + + hash2 + + hwLb6dR4Q5L+j2vYcsXcc8sr2yoS1X9vyl7T/PjcHow= + + + tvos-arm64/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h + + hash + + 33ogzLW88kbc3XVXJp9Opq9Znmc= + + hash2 + + z0lD0Agt0NzOZdG+xd6QpXvGS+06dK4A3RYK0Wu1OKw= + + + tvos-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-Swift.h + + hash + + 0nWXABx/HRqcUMkqMxRdJuHxqQU= + + hash2 + + DmmG7v+JGyWpcKQl1BeGd8rqz4HV3b+PToUt+aM45bY= + + + tvos-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-umbrella.h + + hash + + wE8Bjq1o5wGq1TFJb0gCJUmRelQ= + + hash2 + + LOiywMHEh60MswGEzs9lM8P6m3oohYp+IWaiZtbwVVM= + + + tvos-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h + + hash + + 6tM+QmAiCFyFHMaFXgWsH/uYosM= + + hash2 + + VS1dxfDwCZeRcJYgkkEUhmdXx6ch9X/E8YjKBX367WY= + + + tvos-arm64/FirebaseAnalytics.framework/Info.plist + + hash + + dRfPceuTUosTksVNz/0Ri36DqLU= + + hash2 + + Db7zChRoYOj2o+3ar0pR9UQ+/gOlwayPWbqgYLc6kNQ= + + + tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-tvos.swiftsourceinfo + + hash + + yVqIfrmeZWeToHR1kv1cCRuo4m0= + + hash2 + + gVTxwC8/8a89eDWZjsOYZ4KuYldJWTKMYeS2CR5LuW8= + + + tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos.abi.json + + hash + + 5Fu2Bze8ZWR5SLeF8QjMttSgRDs= + + hash2 + + 7CzYzmp6tqardcv/16+L0vtiGC6DQvp2nkfdDVAvkjg= + + + tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos.private.swiftinterface + + hash + + w4z4Z/v+RhKvKZ9rpQwngKxdIv8= + + hash2 + + Sfi67ylcgLV25NSmMgDoWPHJOM5fdckJgZxpO7ao65Q= + + + tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos.swiftdoc + + hash + + hXtRlFapwJDHg4NuSRJKOZnPtf4= + + hash2 + + MX02TrGF3PcXcv2k6L48iDd2uiemvkpx5z0huyC97yI= + + + tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos.swiftinterface + + hash + + w4z4Z/v+RhKvKZ9rpQwngKxdIv8= + + hash2 + + Sfi67ylcgLV25NSmMgDoWPHJOM5fdckJgZxpO7ao65Q= + + + tvos-arm64/FirebaseAnalytics.framework/Modules/module.modulemap + + hash + + uLysK0T5K1GSoqJmcXx9AnZ9lqY= + + hash2 + + vxNgOuI61t45Sed09vILAKePFm9riTp4aZ48hjDRPIQ= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/FirebaseAnalytics + + hash + + KVkX9v0mFY4HqO2SOzHDP83bkAI= + + hash2 + + 4fP5kwLJ8pOH5cP4rtie6fepACfhc0rMt8Go3p0vMWE= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h + + hash + + JxSy4BVIpZB3s+tbI3EgcIVsvN0= + + hash2 + + HSPmaeLSu5PqNTtlwUWfRT4cyVX65JmeB/oed8f0pdU= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h + + hash + + IN4riVkldIj3MlPpvlUuU1i+I8w= + + hash2 + + ebGwpP2JZ0Rp6BdXhKiLUYOq6nJG7la5O0y/wEKfyak= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+OnDevice.h + + hash + + 58LqQ/Y9jqPGz3JttzK0z7jPLLc= + + hash2 + + 67S/czxwflT8GxF7bVp32FLgu2W97zH06W6zv8/VILU= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics.h + + hash + + B+YLaEHhiOu6tTPZaB5wWy4n95U= + + hash2 + + wmpxZuP80odiQUX5Ts7GaPkhE7UeuzmDMrvTcOS0vLQ= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIREventNames.h + + hash + + HrzLufMtB3E5zAfPXZTkYQdGyHI= + + hash2 + + mNgPvQJ0O5ZQ/EINmxz+zoQHoxj/O70iH5crkbhGU3g= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRParameterNames.h + + hash + + SztBbCRZ5QE523pdMx4HZt0AYKE= + + hash2 + + hwLb6dR4Q5L+j2vYcsXcc8sr2yoS1X9vyl7T/PjcHow= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h + + hash + + 33ogzLW88kbc3XVXJp9Opq9Znmc= + + hash2 + + z0lD0Agt0NzOZdG+xd6QpXvGS+06dK4A3RYK0Wu1OKw= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-Swift.h + + hash + + cu0mXcU7RrT9nKAMSamYxQcZ8MA= + + hash2 + + 4mnxjtoRMyo5TIjTieqzJLBQ4m0noIZqWhmI5a2a3QE= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-umbrella.h + + hash + + wE8Bjq1o5wGq1TFJb0gCJUmRelQ= + + hash2 + + LOiywMHEh60MswGEzs9lM8P6m3oohYp+IWaiZtbwVVM= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h + + hash + + 6tM+QmAiCFyFHMaFXgWsH/uYosM= + + hash2 + + VS1dxfDwCZeRcJYgkkEUhmdXx6ch9X/E8YjKBX367WY= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Info.plist + + hash + + vst0ZWR1zNmVpTjgw64kDxX6uW8= + + hash2 + + v+8y+EKm6c0K/9zdznVd1I1Oi82SVEXxNF8xIoa2IVg= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-tvos-simulator.swiftsourceinfo + + hash + + +1k66yI96SUoo8vxSL9n1634pdU= + + hash2 + + bRgyTViEP0c7ki2+xT0G9KhdMKrOy8vyLsZQz9MRrpc= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/x86_64-apple-tvos-simulator.swiftsourceinfo + + hash + + zaOWjx7mSjW5NKT1uOmvVl3QJgA= + + hash2 + + MXuBEkC6EY1pkdteCZaOaXP2gDQFnksQFezfrgMTb34= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos-simulator.abi.json + + hash + + 5Fu2Bze8ZWR5SLeF8QjMttSgRDs= + + hash2 + + 7CzYzmp6tqardcv/16+L0vtiGC6DQvp2nkfdDVAvkjg= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos-simulator.private.swiftinterface + + hash + + Hf8XfWJzIeEvfdJv/6AMdURHy9k= + + hash2 + + J12IabDa2wBWnzPjUNWL2pBviYvTzf1rbHBRVuWs1yM= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos-simulator.swiftdoc + + hash + + 6OlHbfwffHQPeO54yIdFziP5xxg= + + hash2 + + qLojQ1uaKdXtuP2lnuY8lqCxNQJtWP1gKD2DOEiofqI= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos-simulator.swiftinterface + + hash + + Hf8XfWJzIeEvfdJv/6AMdURHy9k= + + hash2 + + J12IabDa2wBWnzPjUNWL2pBviYvTzf1rbHBRVuWs1yM= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-tvos-simulator.abi.json + + hash + + 5Fu2Bze8ZWR5SLeF8QjMttSgRDs= + + hash2 + + 7CzYzmp6tqardcv/16+L0vtiGC6DQvp2nkfdDVAvkjg= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-tvos-simulator.private.swiftinterface + + hash + + /J9MSWx/8Fj0oVu98k1n8XZmnUE= + + hash2 + + Ql4EhD2ABm1fyH6xOVmiypvWz+aa/1H7xcVrRLBvdN4= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-tvos-simulator.swiftdoc + + hash + + foK4LqUJlIKa+nt0y/51HYQeK8I= + + hash2 + + T5Y6leTow01MGnnXreNqyewOJuClXDew2dg53dtVmDU= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-tvos-simulator.swiftinterface + + hash + + /J9MSWx/8Fj0oVu98k1n8XZmnUE= + + hash2 + + Ql4EhD2ABm1fyH6xOVmiypvWz+aa/1H7xcVrRLBvdN4= + + + tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/module.modulemap + + hash + + uLysK0T5K1GSoqJmcXx9AnZ9lqY= + + hash2 + + vxNgOuI61t45Sed09vILAKePFm9riTp4aZ48hjDRPIQ= + + + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/_CodeSignature/CodeSignature b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/_CodeSignature/CodeSignature new file mode 100644 index 0000000..59bce68 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/_CodeSignature/CodeSignature differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/FirebaseAnalytics b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/FirebaseAnalytics new file mode 100644 index 0000000..835ac77 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/FirebaseAnalytics differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h new file mode 100644 index 0000000..cb1e407 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h @@ -0,0 +1,80 @@ +#import + +#import "FIRAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +/// Provides App Delegate handlers to be used in your App Delegate. +/// +/// To save time integrating Firebase Analytics in an application, Firebase Analytics does not +/// require delegation implementation from the AppDelegate if neither SwiftUI nor UIScene lifecycle +/// is adopted. Instead this is automatically done by Firebase Analytics. Should you choose instead +/// to delegate manually, you can turn off the App Delegate Proxy by adding +/// FirebaseAppDelegateProxyEnabled into your app's Info.plist and setting it to boolean `NO`, and +/// adding the methods in this category to corresponding delegation handlers. +/// +/// To handle Universal Links, you must return `true` in +/// `UIApplicationDelegate.application(_:didFinishLaunchingWithOptions:)`. +@interface FIRAnalytics (AppDelegate) + +/// Handles events related to a URL session that are waiting to be processed. +/// +/// 1. If SwiftUI lifecycle is adopted, call this method from +/// `UIApplicationDelegate.application(_:handleEventsForBackgroundURLSession:completionHandler:)` +/// in your app delegate. +/// +/// 2. If SwiftUI lifecycle is not adopted, Firebase Analytics does not require delegation +/// implementation from the AppDelegate. If you choose instead to delegate manually, you can set +/// FirebaseAppDelegateProxyEnabled to boolean `NO` in your app's Info.plist and call this method +/// from +/// `UIApplicationDelegate.application(_:handleEventsForBackgroundURLSession:completionHandler:)` +/// in your app delegate. +/// +/// @param identifier The identifier of the URL session requiring attention. +/// @param completionHandler The completion handler to call when you finish processing the events. +/// Calling this completion handler lets the system know that your app's user interface is +/// updated and a new snapshot can be taken. ++ (void)handleEventsForBackgroundURLSession:(NSString *)identifier + completionHandler:(nullable void (^)(void))completionHandler; + +/// Handles the event when the app is launched by a URL (custom URL scheme or universal link). +/// +/// 1. If SwiftUI lifecycle is adopted, use `onOpenURL(perform:)` to register a handler and call +/// this method in the handler. +/// +/// 2. If UIScene lifecycle is adopted, call this method from +/// `UISceneDelegate.scene(_:willConnectTo:options:)` and +/// `UISceneDelegate.scene(_:openURLContexts:)` when the URL contexts are available. +/// +/// 3. If neither SwiftUI nor UIScene lifecycle is adopted, Firebase Analytics does not require +/// delegation implementation from the AppDelegate. If you choose instead to delegate manually, you +/// can set FirebaseAppDelegateProxyEnabled to boolean `NO` in your app's Info.plist and call this +/// method from `UIApplicationDelegate.application(_:open:options:)` in your app delegate. +/// +/// @param url The URL resource to open. This resource can be a network resource or a file. ++ (void)handleOpenURL:(NSURL *)url; + +/// Handles the event when the app receives data associated with user activity that includes a +/// Universal Link. +/// +/// 1. If SwiftUI lifecycle is adopted, use `onOpenURL(perform:)` to register a handler and call +/// `Analytics.handleOpen(_:)` instead in the handler. +/// +/// 2. If UIScene lifecycle is adopted, call this method from +/// `UISceneDelegate.scene(_:willConnectTo:options:)` and `UISceneDelegate.scene(_:continue:)` when +/// NSUserActivity is available. See the [Apple +/// doc](https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app) for +/// more details. +/// +/// 3. If neither SwiftUI nor UIScene lifecycle is adopted, Firebase Analytics does not require +/// delegation implementation from the AppDelegate. If you choose instead to delegate manually, you +/// can set FirebaseAppDelegateProxyEnabled to boolean `NO` in your app's Info.plist and call this +/// method from `UIApplication.application(_:continue:restorationHandler:)` in your app delegate. +/// +/// @param userActivity The activity object containing the data associated with the task the user +/// was performing. ++ (void)handleUserActivity:(id)userActivity; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h new file mode 100644 index 0000000..7758390 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h @@ -0,0 +1,51 @@ +#import + +#import "FIRAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +/// The type of consent to set. Supported consent types are `ConsentType.adStorage`, +/// `ConsentType.analyticsStorage`, `ConsentType.adUserData`, and `ConsentType.adPersonalization`. +/// Omitting a type retains its previous status. +typedef NSString *FIRConsentType NS_TYPED_ENUM NS_SWIFT_NAME(ConsentType); + +/// Enables storage (such as device identifiers) related to advertising. +extern FIRConsentType const FIRConsentTypeAdStorage; + +/// Enables storage (such as app identifiers) related to analytics, e.g. visit duration. +extern FIRConsentType const FIRConsentTypeAnalyticsStorage; + +/// Sets consent for sending user data to Google for advertising purposes. +extern FIRConsentType const FIRConsentTypeAdUserData; + +/// Sets consent for personalized advertising. +extern FIRConsentType const FIRConsentTypeAdPersonalization; + +/// The status value of the consent type. Supported statuses are `ConsentStatus.granted` and +/// `ConsentStatus.denied`. +typedef NSString *FIRConsentStatus NS_TYPED_ENUM NS_SWIFT_NAME(ConsentStatus); + +/// Consent status indicating consent is denied. For an overview of which data is sent when consent +/// is denied, see [SDK behavior with consent +/// mode](https://developers.google.com/tag-platform/security/concepts/consent-mode#tag-behavior). +extern FIRConsentStatus const FIRConsentStatusDenied; + +/// Consent status indicating consent is granted. +extern FIRConsentStatus const FIRConsentStatusGranted; + +/// Sets the applicable end user consent state. +@interface FIRAnalytics (Consent) + +/// Sets the applicable end user consent state (e.g. for device identifiers) for this app on this +/// device. Use the consent settings to specify individual consent type values. Settings are +/// persisted across app sessions. By default consent types are set to `ConsentStatus.granted`. +/// +/// @param consentSettings A Dictionary of consent types. Supported consent type keys are +/// `ConsentType.adStorage`, `ConsentType.analyticsStorage`, `ConsentType.adUserData`, and +/// `ConsentType.adPersonalization`. Valid values are `ConsentStatus.granted` and +/// `ConsentStatus.denied`. ++ (void)setConsent:(NSDictionary *)consentSettings; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+OnDevice.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+OnDevice.h new file mode 100644 index 0000000..0bfec88 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+OnDevice.h @@ -0,0 +1,44 @@ +#import + +#import "FIRAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +API_UNAVAILABLE(macCatalyst, macos, tvos, watchos) +@interface FIRAnalytics (OnDevice) + +/// Initiates on-device conversion measurement given a user email address. Requires dependency +/// GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a no-op. +/// @param emailAddress User email address. Include a domain name for all email addresses +/// (e.g. gmail.com or hotmail.co.jp). ++ (void)initiateOnDeviceConversionMeasurementWithEmailAddress:(NSString *)emailAddress + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(emailAddress:)); + +/// Initiates on-device conversion measurement given a phone number in E.164 format. Requires +/// dependency GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a no-op. +/// @param phoneNumber User phone number. Must be in E.164 format, which means it must be +/// limited to a maximum of 15 digits and must include a plus sign (+) prefix and country code +/// with no dashes, parentheses, or spaces. ++ (void)initiateOnDeviceConversionMeasurementWithPhoneNumber:(NSString *)phoneNumber + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(phoneNumber:)); + +/// Initiates on-device conversion measurement given a sha256-hashed user email address. Requires +/// dependency GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a no-op. +/// @param hashedEmailAddress User email address as a UTF8-encoded string normalized and hashed +/// according to the instructions at +/// https://firebase.google.com/docs/tutorials/ads-ios-on-device-measurement/step-3. ++ (void)initiateOnDeviceConversionMeasurementWithHashedEmailAddress:(NSData *)hashedEmailAddress + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(hashedEmailAddress:)); + +/// Initiates on-device conversion measurement given a sha256-hashed phone number in E.164 format. +/// Requires dependency GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a +/// no-op. +/// @param hashedPhoneNumber UTF8-encoded user phone number in E.164 format and then hashed +/// according to the instructions at +/// https://firebase.google.com/docs/tutorials/ads-ios-on-device-measurement/step-3. ++ (void)initiateOnDeviceConversionMeasurementWithHashedPhoneNumber:(NSData *)hashedPhoneNumber + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(hashedPhoneNumber:)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics.h new file mode 100644 index 0000000..e58d7dd --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics.h @@ -0,0 +1,155 @@ +#import + +#import "FIREventNames.h" +#import "FIRParameterNames.h" +#import "FIRUserPropertyNames.h" + +NS_ASSUME_NONNULL_BEGIN + +/// The top level Firebase Analytics singleton that provides methods for logging events and setting +/// user properties. See the developer guides for general +/// information on using Firebase Analytics in your apps. +/// +/// @note The Analytics SDK uses SQLite to persist events and other app-specific data. Calling +/// certain thread-unsafe global SQLite methods like `sqlite3_shutdown()` can result in +/// unexpected crashes at runtime. +NS_SWIFT_NAME(Analytics) +@interface FIRAnalytics : NSObject + +/// Logs an app event. The event can have up to 25 parameters. Events with the same name must have +/// the same parameters. Up to 500 event names are supported. Using predefined events and/or +/// parameters is recommended for optimal reporting. +/// +/// The following event names are reserved and cannot be used: +///
    +///
  • ad_activeview
  • +///
  • ad_click
  • +///
  • ad_exposure
  • +///
  • ad_query
  • +///
  • ad_reward
  • +///
  • adunit_exposure
  • +///
  • app_clear_data
  • +///
  • app_exception
  • +///
  • app_remove
  • +///
  • app_store_refund
  • +///
  • app_store_subscription_cancel
  • +///
  • app_store_subscription_convert
  • +///
  • app_store_subscription_renew
  • +///
  • app_update
  • +///
  • app_upgrade
  • +///
  • dynamic_link_app_open
  • +///
  • dynamic_link_app_update
  • +///
  • dynamic_link_first_open
  • +///
  • error
  • +///
  • firebase_campaign
  • +///
  • first_open
  • +///
  • first_visit
  • +///
  • in_app_purchase
  • +///
  • notification_dismiss
  • +///
  • notification_foreground
  • +///
  • notification_open
  • +///
  • notification_receive
  • +///
  • os_update
  • +///
  • session_start
  • +///
  • session_start_with_rollout
  • +///
  • user_engagement
  • +///
+/// +/// @param name The name of the event. Should contain 1 to 40 alphanumeric characters or +/// underscores. The name must start with an alphabetic character. Some event names are +/// reserved. See FIREventNames.h for the list of reserved event names. The "firebase_", +/// "google_", and "ga_" prefixes are reserved and should not be used. Note that event names are +/// case-sensitive and that logging two events whose names differ only in case will result in +/// two distinct events. To manually log screen view events, use the `screen_view` event name. +/// @param parameters The dictionary of event parameters. Passing `nil` indicates that the event has +/// no parameters. Parameter names can be up to 40 characters long and must start with an +/// alphabetic character and contain only alphanumeric characters and underscores. Only String, +/// Int, and Double parameter types are supported. String parameter values can be up to 100 +/// characters long for standard Google Analytics properties, and up to 500 characters long for +/// Google Analytics 360 properties. The "firebase_", "google_", and "ga_" prefixes are reserved +/// and should not be used for parameter names. ++ (void)logEventWithName:(NSString *)name + parameters:(nullable NSDictionary *)parameters + NS_SWIFT_NAME(logEvent(_:parameters:)); + +/// Sets a user property to a given value. Up to 25 user property names are supported. Once set, +/// user property values persist throughout the app lifecycle and across sessions. +/// +/// The following user property names are reserved and cannot be used: +///
    +///
  • first_open_time
  • +///
  • last_deep_link_referrer
  • +///
  • user_id
  • +///
+/// +/// @param value The value of the user property. Values can be up to 36 characters long. Setting the +/// value to `nil` removes the user property. +/// @param name The name of the user property to set. Should contain 1 to 24 alphanumeric characters +/// or underscores and must start with an alphabetic character. The "firebase_", "google_", and +/// "ga_" prefixes are reserved and should not be used for user property names. ++ (void)setUserPropertyString:(nullable NSString *)value forName:(NSString *)name + NS_SWIFT_NAME(setUserProperty(_:forName:)); + +/// Sets the user ID property. This feature must be used in accordance with +/// Google's Privacy Policy +/// +/// @param userID The user ID to ascribe to the user of this app on this device, which must be +/// non-empty and no more than 256 characters long. Setting userID to `nil` removes the user ID. ++ (void)setUserID:(nullable NSString *)userID; + +/// Sets whether analytics collection is enabled for this app on this device. This setting is +/// persisted across app sessions. By default it is enabled. +/// +/// @param analyticsCollectionEnabled A flag that enables or disables Analytics collection. ++ (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled; + +/// Sets the interval of inactivity in seconds that terminates the current session. The default +/// value is 1800 seconds (30 minutes). +/// +/// @param sessionTimeoutInterval The custom time of inactivity in seconds before the current +/// session terminates. ++ (void)setSessionTimeoutInterval:(NSTimeInterval)sessionTimeoutInterval; + +/// Asynchronously retrieves the identifier of the current app session. +/// +/// The session ID retrieval could fail due to Analytics collection disabled, app session expired, +/// etc. +/// +/// @param completion The completion handler to call when the session ID retrieval is complete. This +/// handler is executed on a system-defined global concurrent queue. +/// This completion handler takes the following parameters: +/// sessionID The identifier of the current app session. The value is undefined if the +/// request failed. +/// error An error object that indicates why the request failed, or `nil` if the request +/// was successful. ++ (void)sessionIDWithCompletion:(void (^)(int64_t sessionID, NSError *_Nullable error))completion; + +/// Returns the unique ID for this instance of the application or `nil` if +/// `ConsentType.analyticsStorage` has been set to `ConsentStatus.denied`. +/// +/// @see `FIRAnalytics+Consent.h` ++ (nullable NSString *)appInstanceID; + +/// Clears all analytics data for this instance from the device and resets the app instance ID. ++ (void)resetAnalyticsData; + +/// Adds parameters that will be set on every event logged from the SDK, including automatic ones. +/// The values passed in the parameters dictionary will be added to the dictionary of default event +/// parameters. These parameters persist across app runs. They are of lower precedence than event +/// parameters, so if an event parameter and a parameter set using this API have the same name, the +/// value of the event parameter will be used. The same limitations on event parameters apply to +/// default event parameters. +/// +/// @param parameters Parameters to be added to the dictionary of parameters added to every event. +/// They will be added to the dictionary of default event parameters, replacing any existing +/// parameter with the same name. Valid parameters are String, Int, and Double. Setting a key's +/// value to `NSNull()` will clear that parameter. Passing in a `nil` dictionary will clear all +/// parameters. ++ (void)setDefaultEventParameters:(nullable NSDictionary *)parameters; + +/// Unavailable. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIREventNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIREventNames.h new file mode 100644 index 0000000..1e69a44 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIREventNames.h @@ -0,0 +1,418 @@ +/// @file FIREventNames.h +/// +/// Predefined event names. +/// +/// An Event is an important occurrence in your app that you want to measure. You can report up to +/// 500 different types of Events per app and you can associate up to 25 unique parameters with each +/// Event type. Some common events are suggested below, but you may also choose to specify custom +/// Event types that are associated with your specific app. Each event type is identified by a +/// unique name. Event names can be up to 40 characters long, may only contain alphanumeric +/// characters and underscores ("_"), and must start with an alphabetic character. The "firebase_", +/// "google_", and "ga_" prefixes are reserved and should not be used. + +#import + +/// Ad Impression event. This event signifies when a user sees an ad impression. Note: If you supply +/// the @c AnalyticsParameterValue parameter, you must also supply the @c AnalyticsParameterCurrency +/// parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterAdPlatform (String) (optional)
  • +///
  • @c AnalyticsParameterAdFormat (String) (optional)
  • +///
  • @c AnalyticsParameterAdSource (String) (optional)
  • +///
  • @c AnalyticsParameterAdUnitName (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAdImpression NS_SWIFT_NAME(AnalyticsEventAdImpression) = + @"ad_impression"; + +/// Add Payment Info event. This event signifies that a user has submitted their payment +/// information. Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply +/// the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterPaymentType (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddPaymentInfo NS_SWIFT_NAME(AnalyticsEventAddPaymentInfo) = + @"add_payment_info"; + +/// Add Shipping Info event. This event signifies that a user has submitted their shipping +/// information. Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply +/// the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterShippingTier (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddShippingInfo NS_SWIFT_NAME(AnalyticsEventAddShippingInfo) = + @"add_shipping_info"; + +/// E-Commerce Add To Cart event. This event signifies that an item(s) was added to a cart for +/// purchase. Add this event to a funnel with @c AnalyticsEventPurchase to gauge the effectiveness +/// of your checkout process. Note: If you supply the @c AnalyticsParameterValue parameter, you must +/// also supply the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed +/// accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddToCart NS_SWIFT_NAME(AnalyticsEventAddToCart) = @"add_to_cart"; + +/// E-Commerce Add To Wishlist event. This event signifies that an item was added to a wishlist. Use +/// this event to identify popular gift items. Note: If you supply the @c AnalyticsParameterValue +/// parameter, you must also supply the @c AnalyticsParameterCurrency parameter so that revenue +/// metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddToWishlist NS_SWIFT_NAME(AnalyticsEventAddToWishlist) = + @"add_to_wishlist"; + +/// App Open event. By logging this event when an App becomes active, developers can understand how +/// often users leave and return during the course of a Session. Although Sessions are automatically +/// reported, this event can provide further clarification around the continuous engagement of +/// app-users. +static NSString *const kFIREventAppOpen NS_SWIFT_NAME(AnalyticsEventAppOpen) = @"app_open"; + +/// E-Commerce Begin Checkout event. This event signifies that a user has begun the process of +/// checking out. Add this event to a funnel with your @c AnalyticsEventPurchase event to gauge the +/// effectiveness of your checkout process. Note: If you supply the @c AnalyticsParameterValue +/// parameter, you must also supply the @c AnalyticsParameterCurrency parameter so that revenue +/// metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventBeginCheckout NS_SWIFT_NAME(AnalyticsEventBeginCheckout) = + @"begin_checkout"; + +/// Campaign Detail event. Log this event to supply the referral details of a re-engagement +/// campaign. Note: you must supply at least one of the required parameters +/// AnalyticsParameterSource, AnalyticsParameterMedium or AnalyticsParameterCampaign. Params: +/// +///
    +///
  • @c AnalyticsParameterSource (String)
  • +///
  • @c AnalyticsParameterMedium (String)
  • +///
  • @c AnalyticsParameterCampaign (String)
  • +///
  • @c AnalyticsParameterTerm (String) (optional)
  • +///
  • @c AnalyticsParameterContent (String) (optional)
  • +///
  • @c AnalyticsParameterAdNetworkClickID (String) (optional)
  • +///
  • @c AnalyticsParameterCP1 (String) (optional)
  • +///
  • @c AnalyticsParameterCampaignID (String) (optional)
  • +///
  • @c AnalyticsParameterCreativeFormat (String) (optional)
  • +///
  • @c AnalyticsParameterMarketingTactic (String) (optional)
  • +///
  • @c AnalyticsParameterSourcePlatform (String) (optional)
  • +///
+static NSString *const kFIREventCampaignDetails NS_SWIFT_NAME(AnalyticsEventCampaignDetails) = + @"campaign_details"; + +/// Earn Virtual Currency event. This event tracks the awarding of virtual currency in your app. Log +/// this along with @c AnalyticsEventSpendVirtualCurrency to better understand your virtual economy. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterVirtualCurrencyName (String)
  • +///
  • @c AnalyticsParameterValue (Int or Double)
  • +///
+static NSString *const kFIREventEarnVirtualCurrency + NS_SWIFT_NAME(AnalyticsEventEarnVirtualCurrency) = @"earn_virtual_currency"; + +/// Generate Lead event. Log this event when a lead has been generated in the app to understand the +/// efficacy of your install and re-engagement campaigns. Note: If you supply the +/// @c AnalyticsParameterValue parameter, you must also supply the @c AnalyticsParameterCurrency +/// parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventGenerateLead NS_SWIFT_NAME(AnalyticsEventGenerateLead) = + @"generate_lead"; + +/// Join Group event. Log this event when a user joins a group such as a guild, team or family. Use +/// this event to analyze how popular certain groups or social features are in your app. Params: +/// +///
    +///
  • @c AnalyticsParameterGroupID (String)
  • +///
+static NSString *const kFIREventJoinGroup NS_SWIFT_NAME(AnalyticsEventJoinGroup) = @"join_group"; + +/// Level End event. Log this event when the user finishes a level. Params: +/// +///
    +///
  • @c AnalyticsParameterLevelName (String)
  • +///
  • @c AnalyticsParameterSuccess (String)
  • +///
+static NSString *const kFIREventLevelEnd NS_SWIFT_NAME(AnalyticsEventLevelEnd) = @"level_end"; + +/// Level Start event. Log this event when the user starts a new level. Params: +/// +///
    +///
  • @c AnalyticsParameterLevelName (String)
  • +///
+static NSString *const kFIREventLevelStart NS_SWIFT_NAME(AnalyticsEventLevelStart) = @"level_start"; + +/// Level Up event. This event signifies that a player has leveled up in your gaming app. It can +/// help you gauge the level distribution of your userbase and help you identify certain levels that +/// are difficult to pass. Params: +/// +///
    +///
  • @c AnalyticsParameterLevel (Int)
  • +///
  • @c AnalyticsParameterCharacter (String) (optional)
  • +///
+static NSString *const kFIREventLevelUp NS_SWIFT_NAME(AnalyticsEventLevelUp) = @"level_up"; + +/// Login event. Apps with a login feature can report this event to signify that a user has logged +/// in. +static NSString *const kFIREventLogin NS_SWIFT_NAME(AnalyticsEventLogin) = @"login"; + +/// Post Score event. Log this event when the user posts a score in your gaming app. This event can +/// help you understand how users are actually performing in your game and it can help you correlate +/// high scores with certain audiences or behaviors. Params: +/// +///
    +///
  • @c AnalyticsParameterScore (Int)
  • +///
  • @c AnalyticsParameterLevel (Int) (optional)
  • +///
  • @c AnalyticsParameterCharacter (String) (optional)
  • +///
+static NSString *const kFIREventPostScore NS_SWIFT_NAME(AnalyticsEventPostScore) = @"post_score"; + +/// E-Commerce Purchase event. This event signifies that an item(s) was purchased by a user. Note: +/// This is different from the in-app purchase event, which is reported automatically for App +/// Store-based apps. Note: If you supply the @c AnalyticsParameterValue parameter, you must also +/// supply the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed +/// accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterAffiliation (String) (optional)
  • +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterEndDate (String) (optional)
  • +///
  • @c AnalyticsParameterItemID (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterShipping (Double) (optional)
  • +///
  • @c AnalyticsParameterStartDate (String) (optional)
  • +///
  • @c AnalyticsParameterTax (Double) (optional)
  • +///
  • @c AnalyticsParameterTransactionID (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventPurchase NS_SWIFT_NAME(AnalyticsEventPurchase) = @"purchase"; + +/// E-Commerce Refund event. This event signifies that a refund was issued. Note: If you supply the +/// @c AnalyticsParameterValue parameter, you must also supply the @c AnalyticsParameterCurrency +/// parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterAffiliation (String) (optional)
  • +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterShipping (Double) (optional)
  • +///
  • @c AnalyticsParameterTax (Double) (optional)
  • +///
  • @c AnalyticsParameterTransactionID (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventRefund NS_SWIFT_NAME(AnalyticsEventRefund) = @"refund"; + +/// E-Commerce Remove from Cart event. This event signifies that an item(s) was removed from a cart. +/// Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply the @c +/// AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventRemoveFromCart NS_SWIFT_NAME(AnalyticsEventRemoveFromCart) = + @"remove_from_cart"; + +/// Screen View event. This event signifies a screen view. Use this when a screen transition occurs. +/// This event can be logged irrespective of whether automatic screen tracking is enabled. Params: +/// +///
    +///
  • @c AnalyticsParameterScreenClass (String) (optional)
  • +///
  • @c AnalyticsParameterScreenName (String) (optional)
  • +///
+static NSString *const kFIREventScreenView NS_SWIFT_NAME(AnalyticsEventScreenView) = @"screen_view"; + +/// Search event. Apps that support search features can use this event to contextualize search +/// operations by supplying the appropriate, corresponding parameters. This event can help you +/// identify the most popular content in your app. Params: +/// +///
    +///
  • @c AnalyticsParameterSearchTerm (String)
  • +///
  • @c AnalyticsParameterStartDate (String) (optional)
  • +///
  • @c AnalyticsParameterEndDate (String) (optional)
  • +///
  • @c AnalyticsParameterNumberOfNights (Int) (optional) for hotel bookings
  • +///
  • @c AnalyticsParameterNumberOfRooms (Int) (optional) for hotel bookings
  • +///
  • @c AnalyticsParameterNumberOfPassengers (Int) (optional) for travel bookings
  • +///
  • @c AnalyticsParameterOrigin (String) (optional)
  • +///
  • @c AnalyticsParameterDestination (String) (optional)
  • +///
  • @c AnalyticsParameterTravelClass (String) (optional) for travel bookings
  • +///
+static NSString *const kFIREventSearch NS_SWIFT_NAME(AnalyticsEventSearch) = @"search"; + +/// Select Content event. This general purpose event signifies that a user has selected some content +/// of a certain type in an app. The content can be any object in your app. This event can help you +/// identify popular content and categories of content in your app. Params: +/// +///
    +///
  • @c AnalyticsParameterContentType (String)
  • +///
  • @c AnalyticsParameterItemID (String)
  • +///
+static NSString *const kFIREventSelectContent NS_SWIFT_NAME(AnalyticsEventSelectContent) = + @"select_content"; + +/// Select Item event. This event signifies that an item was selected by a user from a list. Use the +/// appropriate parameters to contextualize the event. Use this event to discover the most popular +/// items selected. Params: +/// +///
    +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterItemListID (String) (optional)
  • +///
  • @c AnalyticsParameterItemListName (String) (optional)
  • +///
+static NSString *const kFIREventSelectItem NS_SWIFT_NAME(AnalyticsEventSelectItem) = @"select_item"; + +/// Select promotion event. This event signifies that a user has selected a promotion offer. Use the +/// appropriate parameters to contextualize the event, such as the item(s) for which the promotion +/// applies. Params: +/// +///
    +///
  • @c AnalyticsParameterCreativeName (String) (optional)
  • +///
  • @c AnalyticsParameterCreativeSlot (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterLocationID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionName (String) (optional)
  • +///
+static NSString *const kFIREventSelectPromotion NS_SWIFT_NAME(AnalyticsEventSelectPromotion) = + @"select_promotion"; + +/// Share event. Apps with social features can log the Share event to identify the most viral +/// content. Params: +/// +///
    +///
  • @c AnalyticsParameterContentType (String)
  • +///
  • @c AnalyticsParameterItemID (String)
  • +///
+static NSString *const kFIREventShare NS_SWIFT_NAME(AnalyticsEventShare) = @"share"; + +/// Sign Up event. This event indicates that a user has signed up for an account in your app. The +/// parameter signifies the method by which the user signed up. Use this event to understand the +/// different behaviors between logged in and logged out users. Params: +/// +///
    +///
  • @c AnalyticsParameterMethod (String)
  • +///
+static NSString *const kFIREventSignUp NS_SWIFT_NAME(AnalyticsEventSignUp) = @"sign_up"; + +/// Spend Virtual Currency event. This event tracks the sale of virtual goods in your app and can +/// help you identify which virtual goods are the most popular objects of purchase. Params: +/// +///
    +///
  • @c AnalyticsParameterItemName (String)
  • +///
  • @c AnalyticsParameterVirtualCurrencyName (String)
  • +///
  • @c AnalyticsParameterValue (Int or Double)
  • +///
+static NSString *const kFIREventSpendVirtualCurrency + NS_SWIFT_NAME(AnalyticsEventSpendVirtualCurrency) = @"spend_virtual_currency"; + +/// Tutorial Begin event. This event signifies the start of the on-boarding process in your app. Use +/// this in a funnel with @c AnalyticsEventTutorialComplete to understand how many users complete +/// this process and move on to the full app experience. +static NSString *const kFIREventTutorialBegin NS_SWIFT_NAME(AnalyticsEventTutorialBegin) = + @"tutorial_begin"; + +/// Tutorial End event. Use this event to signify the user's completion of your app's on-boarding +/// process. Add this to a funnel with @c AnalyticsEventTutorialBegin to gauge the completion rate +/// of your on-boarding process. +static NSString *const kFIREventTutorialComplete NS_SWIFT_NAME(AnalyticsEventTutorialComplete) = + @"tutorial_complete"; + +/// Unlock Achievement event. Log this event when the user has unlocked an achievement in your +/// game. Since achievements generally represent the breadth of a gaming experience, this event can +/// help you understand how many users are experiencing all that your game has to offer. Params: +/// +///
    +///
  • @c AnalyticsParameterAchievementID (String)
  • +///
+static NSString *const kFIREventUnlockAchievement NS_SWIFT_NAME(AnalyticsEventUnlockAchievement) = + @"unlock_achievement"; + +/// E-commerce View Cart event. This event signifies that a user has viewed their cart. Use this to +/// analyze your purchase funnel. Note: If you supply the @c AnalyticsParameterValue parameter, you +/// must also supply the @c AnalyticsParameterCurrency parameter so that revenue metrics can be +/// computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventViewCart NS_SWIFT_NAME(AnalyticsEventViewCart) = @"view_cart"; + +/// View Item event. This event signifies that a user has viewed an item. Use the appropriate +/// parameters to contextualize the event. Use this event to discover the most popular items viewed +/// in your app. Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply +/// the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventViewItem NS_SWIFT_NAME(AnalyticsEventViewItem) = @"view_item"; + +/// View Item List event. Log this event when a user sees a list of items or offerings. Params: +/// +///
    +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterItemListID (String) (optional)
  • +///
  • @c AnalyticsParameterItemListName (String) (optional)
  • +///
+static NSString *const kFIREventViewItemList NS_SWIFT_NAME(AnalyticsEventViewItemList) = + @"view_item_list"; + +/// View Promotion event. This event signifies that a promotion was shown to a user. Add this event +/// to a funnel with the @c AnalyticsEventAddToCart and @c AnalyticsEventPurchase to gauge your +/// conversion process. Params: +/// +///
    +///
  • @c AnalyticsParameterCreativeName (String) (optional)
  • +///
  • @c AnalyticsParameterCreativeSlot (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterLocationID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionName (String) (optional)
  • +///
+static NSString *const kFIREventViewPromotion NS_SWIFT_NAME(AnalyticsEventViewPromotion) = + @"view_promotion"; + +/// View Search Results event. Log this event when the user has been presented with the results of a +/// search. Params: +/// +///
    +///
  • @c AnalyticsParameterSearchTerm (String)
  • +///
+static NSString *const kFIREventViewSearchResults NS_SWIFT_NAME(AnalyticsEventViewSearchResults) = + @"view_search_results"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIRParameterNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIRParameterNames.h new file mode 100644 index 0000000..58a5a21 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIRParameterNames.h @@ -0,0 +1,722 @@ +/// @file FIRParameterNames.h +/// +/// Predefined event parameter names. +/// +/// Params supply information that contextualize Events. You can associate up to 25 unique Params +/// with each Event type. Some Params are suggested below for certain common Events, but you are +/// not limited to these. You may supply extra Params for suggested Events or custom Params for +/// Custom events. Param names can be up to 40 characters long, may only contain alphanumeric +/// characters and underscores ("_"), and must start with an alphabetic character. Param values can +/// be up to 100 characters long for standard Google Analytics properties and up to 500 characters +/// long for Google Analytics 360 properties. The "firebase_", "google_", and "ga_" prefixes are +/// reserved and should not be used. + +#import + +/// Game achievement ID (String). +///
+///     let params = [
+///       AnalyticsParameterAchievementID : "10_matches_won",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAchievementID NS_SWIFT_NAME(AnalyticsParameterAchievementID) = + @"achievement_id"; + +/// The ad format (e.g. Banner, Interstitial, Rewarded, Native, Rewarded Interstitial, Instream). +/// (String). +///
+///     let params = [
+///       AnalyticsParameterAdFormat : "Banner",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdFormat NS_SWIFT_NAME(AnalyticsParameterAdFormat) = + @"ad_format"; + +/// Ad Network Click ID (String). Used for network-specific click IDs which vary in format. +///
+///     let params = [
+///       AnalyticsParameterAdNetworkClickID : "1234567",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdNetworkClickID + NS_SWIFT_NAME(AnalyticsParameterAdNetworkClickID) = @"aclid"; + +/// The ad platform (e.g. MoPub, IronSource) (String). +///
+///     let params = [
+///       AnalyticsParameterAdPlatform : "MoPub",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdPlatform NS_SWIFT_NAME(AnalyticsParameterAdPlatform) = + @"ad_platform"; + +/// The ad source (e.g. AdColony) (String). +///
+///     let params = [
+///       AnalyticsParameterAdSource : "AdColony",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdSource NS_SWIFT_NAME(AnalyticsParameterAdSource) = + @"ad_source"; + +/// The ad unit name (e.g. Banner_03) (String). +///
+///     let params = [
+///       AnalyticsParameterAdUnitName : "Banner_03",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdUnitName NS_SWIFT_NAME(AnalyticsParameterAdUnitName) = + @"ad_unit_name"; + +/// A product affiliation to designate a supplying company or brick and mortar store location +/// (String).
+///     let params = [
+///       AnalyticsParameterAffiliation : "Google Store",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAffiliation NS_SWIFT_NAME(AnalyticsParameterAffiliation) = + @"affiliation"; + +/// Campaign custom parameter (String). Used as a method of capturing custom data in a campaign. +/// Use varies by network. +///
+///     let params = [
+///       AnalyticsParameterCP1 : "custom_data",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCP1 NS_SWIFT_NAME(AnalyticsParameterCP1) = @"cp1"; + +/// The individual campaign name, slogan, promo code, etc. Some networks have pre-defined macro to +/// capture campaign information, otherwise can be populated by developer. Highly Recommended +/// (String). +///
+///     let params = [
+///       AnalyticsParameterCampaign : "winter_promotion",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCampaign NS_SWIFT_NAME(AnalyticsParameterCampaign) = + @"campaign"; + +/// Campaign ID (String). Used for keyword analysis to identify a specific product promotion or +/// strategic campaign. This is a required key for GA4 data import. +///
+///     let params = [
+///       AnalyticsParameterCampaignID : "7877652710",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCampaignID NS_SWIFT_NAME(AnalyticsParameterCampaignID) = + @"campaign_id"; + +/// Character used in game (String). +///
+///     let params = [
+///       AnalyticsParameterCharacter : "beat_boss",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCharacter NS_SWIFT_NAME(AnalyticsParameterCharacter) = + @"character"; + +/// Campaign content (String). +static NSString *const kFIRParameterContent NS_SWIFT_NAME(AnalyticsParameterContent) = @"content"; + +/// Type of content selected (String). +///
+///     let params = [
+///       AnalyticsParameterContentType : "news article",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterContentType NS_SWIFT_NAME(AnalyticsParameterContentType) = + @"content_type"; + +/// Coupon code used for a purchase (String). +///
+///     let params = [
+///       AnalyticsParameterCoupon : "SUMMER_FUN",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCoupon NS_SWIFT_NAME(AnalyticsParameterCoupon) = @"coupon"; + +/// Creative Format (String). Used to identify the high-level classification of the type of ad +/// served by a specific campaign. +///
+///     let params = [
+///       AnalyticsParameterCreativeFormat : "display",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCreativeFormat NS_SWIFT_NAME(AnalyticsParameterCreativeFormat) = + @"creative_format"; + +/// The name of a creative used in a promotional spot (String). +///
+///     let params = [
+///       AnalyticsParameterCreativeName : "Summer Sale",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCreativeName NS_SWIFT_NAME(AnalyticsParameterCreativeName) = + @"creative_name"; + +/// The name of a creative slot (String). +///
+///     let params = [
+///       AnalyticsParameterCreativeSlot : "summer_banner2",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCreativeSlot NS_SWIFT_NAME(AnalyticsParameterCreativeSlot) = + @"creative_slot"; + +/// Currency of the purchase or items associated with the event, in 3-letter +/// ISO_4217 format (String). +///
+///     let params = [
+///       AnalyticsParameterCurrency : "USD",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCurrency NS_SWIFT_NAME(AnalyticsParameterCurrency) = + @"currency"; + +/// Flight or Travel destination (String). +///
+///     let params = [
+///       AnalyticsParameterDestination : "Mountain View, CA",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterDestination NS_SWIFT_NAME(AnalyticsParameterDestination) = + @"destination"; + +/// Monetary value of discount associated with a purchase (Double). +///
+///     let params = [
+///       AnalyticsParameterDiscount : 2.0,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $2.00 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterDiscount NS_SWIFT_NAME(AnalyticsParameterDiscount) = + @"discount"; + +/// The arrival date, check-out date or rental end date for the item. This should be in +/// YYYY-MM-DD format (String). +///
+///     let params = [
+///       AnalyticsParameterEndDate : "2015-09-14",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterEndDate NS_SWIFT_NAME(AnalyticsParameterEndDate) = @"end_date"; + +/// Indicates that the associated event should either extend the current session or start a new +/// session if no session was active when the event was logged. Specify 1 to extend the current +/// session or to start a new session; any other value will not extend or start a session. +///
+///     let params = [
+///       AnalyticsParameterExtendSession : 1,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterExtendSession NS_SWIFT_NAME(AnalyticsParameterExtendSession) = + @"extend_session"; + +/// Flight number for travel events (String). +///
+///     let params = [
+///       AnalyticsParameterFlightNumber : "ZZ800",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterFlightNumber NS_SWIFT_NAME(AnalyticsParameterFlightNumber) = + @"flight_number"; + +/// Group/clan/guild ID (String). +///
+///     let params = [
+///       AnalyticsParameterGroupID : "g1",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterGroupID NS_SWIFT_NAME(AnalyticsParameterGroupID) = @"group_id"; + +/// The index of the item in a list (Int). +///
+///     let params = [
+///       AnalyticsParameterIndex : 5,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterIndex NS_SWIFT_NAME(AnalyticsParameterIndex) = @"index"; + +/// Item brand (String). +///
+///     let params = [
+///       AnalyticsParameterItemBrand : "Google",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemBrand NS_SWIFT_NAME(AnalyticsParameterItemBrand) = + @"item_brand"; + +/// Item category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory NS_SWIFT_NAME(AnalyticsParameterItemCategory) = + @"item_category"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory2 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory2 NS_SWIFT_NAME(AnalyticsParameterItemCategory2) = + @"item_category2"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory3 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory3 NS_SWIFT_NAME(AnalyticsParameterItemCategory3) = + @"item_category3"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory4 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory4 NS_SWIFT_NAME(AnalyticsParameterItemCategory4) = + @"item_category4"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory5 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory5 NS_SWIFT_NAME(AnalyticsParameterItemCategory5) = + @"item_category5"; + +/// Item ID (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemID : "SKU_12345",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemID NS_SWIFT_NAME(AnalyticsParameterItemID) = @"item_id"; + +/// The ID of the list in which the item was presented to the user (String). +///
+///     let params = [
+///       AnalyticsParameterItemListID : "ABC123",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemListID NS_SWIFT_NAME(AnalyticsParameterItemListID) = + @"item_list_id"; + +/// The name of the list in which the item was presented to the user (String). +///
+///     let params = [
+///       AnalyticsParameterItemListName : "Related products",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemListName NS_SWIFT_NAME(AnalyticsParameterItemListName) = + @"item_list_name"; + +/// Item Name (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemName : "jeggings",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemName NS_SWIFT_NAME(AnalyticsParameterItemName) = + @"item_name"; + +/// Item variant (String). +///
+///     let params = [
+///       AnalyticsParameterItemVariant : "Black",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemVariant NS_SWIFT_NAME(AnalyticsParameterItemVariant) = + @"item_variant"; + +/// The list of items involved in the transaction expressed as `[[String: Any]]`. +///
+///     let params = [
+///       AnalyticsParameterItems : [
+///         [AnalyticsParameterItemName : "jeggings", AnalyticsParameterItemCategory : "pants"],
+///         [AnalyticsParameterItemName : "boots", AnalyticsParameterItemCategory : "shoes"],
+///       ],
+///     ]
+/// 
+static NSString *const kFIRParameterItems NS_SWIFT_NAME(AnalyticsParameterItems) = @"items"; + +/// Level in game (Int). +///
+///     let params = [
+///       AnalyticsParameterLevel : 42,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLevel NS_SWIFT_NAME(AnalyticsParameterLevel) = @"level"; + +/// The name of a level in a game (String). +///
+///     let params = [
+///       AnalyticsParameterLevelName : "room_1",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLevelName NS_SWIFT_NAME(AnalyticsParameterLevelName) = + @"level_name"; + +/// Location (String). The Google Place ID +/// that corresponds to the associated event. Alternatively, you can supply your own custom +/// Location ID. +///
+///     let params = [
+///       AnalyticsParameterLocation : "ChIJiyj437sx3YAR9kUWC8QkLzQ",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLocation NS_SWIFT_NAME(AnalyticsParameterLocation) = + @"location"; + +/// The location associated with the event. Preferred to be the Google +/// Place ID that corresponds to the +/// associated item but could be overridden to a custom location ID string.(String). +///
+///     let params = [
+///       AnalyticsParameterLocationID : "ChIJiyj437sx3YAR9kUWC8QkLzQ",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLocationID NS_SWIFT_NAME(AnalyticsParameterLocationID) = + @"location_id"; + +/// Marketing Tactic (String). Used to identify the targeting criteria applied to a specific +/// campaign. +///
+///     let params = [
+///       AnalyticsParameterMarketingTactic : "Remarketing",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterMarketingTactic + NS_SWIFT_NAME(AnalyticsParameterMarketingTactic) = @"marketing_tactic"; + +/// The advertising or marketing medium, for example: cpc, banner, email, push. Highly recommended +/// (String). +///
+///     let params = [
+///       AnalyticsParameterMedium : "email",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterMedium NS_SWIFT_NAME(AnalyticsParameterMedium) = @"medium"; + +/// A particular approach used in an operation; for example, "facebook" or "email" in the context +/// of a sign_up or login event. (String). +///
+///     let params = [
+///       AnalyticsParameterMethod : "google",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterMethod NS_SWIFT_NAME(AnalyticsParameterMethod) = @"method"; + +/// Number of nights staying at hotel (Int). +///
+///     let params = [
+///       AnalyticsParameterNumberOfNights : 3,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterNumberOfNights + NS_SWIFT_NAME(AnalyticsParameterNumberOfNights) = @"number_of_nights"; + +/// Number of passengers traveling (Int). +///
+///     let params = [
+///       AnalyticsParameterNumberOfPassengers : 11,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterNumberOfPassengers + NS_SWIFT_NAME(AnalyticsParameterNumberOfPassengers) = @"number_of_passengers"; + +/// Number of rooms for travel events (Int). +///
+///     let params = [
+///       AnalyticsParameterNumberOfRooms : 2,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterNumberOfRooms NS_SWIFT_NAME(AnalyticsParameterNumberOfRooms) = + @"number_of_rooms"; + +/// Flight or Travel origin (String). +///
+///     let params = [
+///       AnalyticsParameterOrigin : "Mountain View, CA",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterOrigin NS_SWIFT_NAME(AnalyticsParameterOrigin) = @"origin"; + +/// The chosen method of payment (String). +///
+///     let params = [
+///       AnalyticsParameterPaymentType : "Visa",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPaymentType NS_SWIFT_NAME(AnalyticsParameterPaymentType) = + @"payment_type"; + +/// Purchase price (Double). +///
+///     let params = [
+///       AnalyticsParameterPrice : 1.0,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $1.00 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPrice NS_SWIFT_NAME(AnalyticsParameterPrice) = @"price"; + +/// The ID of a product promotion (String). +///
+///     let params = [
+///       AnalyticsParameterPromotionID : "ABC123",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPromotionID NS_SWIFT_NAME(AnalyticsParameterPromotionID) = + @"promotion_id"; + +/// The name of a product promotion (String). +///
+///     let params = [
+///       AnalyticsParameterPromotionName : "Summer Sale",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPromotionName NS_SWIFT_NAME(AnalyticsParameterPromotionName) = + @"promotion_name"; + +/// Purchase quantity (Int). +///
+///     let params = [
+///       AnalyticsParameterQuantity : 1,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterQuantity NS_SWIFT_NAME(AnalyticsParameterQuantity) = + @"quantity"; + +/// Score in game (Int). +///
+///     let params = [
+///       AnalyticsParameterScore : 4200,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterScore NS_SWIFT_NAME(AnalyticsParameterScore) = @"score"; + +/// Current screen class, such as the class name of the UIViewController, logged with screen_view +/// event and added to every event (String). +///
+///     let params = [
+///       AnalyticsParameterScreenClass : "LoginViewController",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterScreenClass NS_SWIFT_NAME(AnalyticsParameterScreenClass) = + @"screen_class"; + +/// Current screen name, such as the name of the UIViewController, logged with screen_view event and +/// added to every event (String). +///
+///     let params = [
+///       AnalyticsParameterScreenName : "LoginView",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterScreenName NS_SWIFT_NAME(AnalyticsParameterScreenName) = + @"screen_name"; + +/// The search string/keywords used (String). +///
+///     let params = [
+///       AnalyticsParameterSearchTerm : "periodic table",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSearchTerm NS_SWIFT_NAME(AnalyticsParameterSearchTerm) = + @"search_term"; + +/// Shipping cost associated with a transaction (Double). +///
+///     let params = [
+///       AnalyticsParameterShipping : 5.99,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $5.99 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterShipping NS_SWIFT_NAME(AnalyticsParameterShipping) = + @"shipping"; + +/// The shipping tier (e.g. Ground, Air, Next-day) selected for delivery of the purchased item +/// (String). +///
+///     let params = [
+///       AnalyticsParameterShippingTier : "Ground",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterShippingTier NS_SWIFT_NAME(AnalyticsParameterShippingTier) = + @"shipping_tier"; + +/// The origin of your traffic, such as an Ad network (for example, google) or partner (urban +/// airship). Identify the advertiser, site, publication, etc. that is sending traffic to your +/// property. Highly recommended (String). +///
+///     let params = [
+///       AnalyticsParameterSource : "InMobi",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSource NS_SWIFT_NAME(AnalyticsParameterSource) = @"source"; + +/// Source Platform (String). Used to identify the platform responsible for directing traffic to a +/// given Analytics property (e.g., a buying platform where budgets, targeting criteria, etc. are +/// set, a platform for managing organic traffic data, etc.). +///
+///     let params = [
+///       AnalyticsParameterSourcePlatform : "sa360",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSourcePlatform NS_SWIFT_NAME(AnalyticsParameterSourcePlatform) = + @"source_platform"; + +/// The departure date, check-in date or rental start date for the item. This should be in +/// YYYY-MM-DD format (String). +///
+///     let params = [
+///       AnalyticsParameterStartDate : "2015-09-14",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterStartDate NS_SWIFT_NAME(AnalyticsParameterStartDate) = + @"start_date"; + +/// The result of an operation. Specify 1 to indicate success and 0 to indicate failure (Int). +///
+///     let params = [
+///       AnalyticsParameterSuccess : 1,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSuccess NS_SWIFT_NAME(AnalyticsParameterSuccess) = @"success"; + +/// Tax cost associated with a transaction (Double). +///
+///     let params = [
+///       AnalyticsParameterTax : 2.43,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $2.43 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTax NS_SWIFT_NAME(AnalyticsParameterTax) = @"tax"; + +/// If you're manually tagging keyword campaigns, you should use utm_term to specify the keyword +/// (String). +///
+///     let params = [
+///       AnalyticsParameterTerm : "game",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTerm NS_SWIFT_NAME(AnalyticsParameterTerm) = @"term"; + +/// The unique identifier of a transaction (String). +///
+///     let params = [
+///       AnalyticsParameterTransactionID : "T12345",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTransactionID NS_SWIFT_NAME(AnalyticsParameterTransactionID) = + @"transaction_id"; + +/// Travel class (String). +///
+///     let params = [
+///       AnalyticsParameterTravelClass : "business",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTravelClass NS_SWIFT_NAME(AnalyticsParameterTravelClass) = + @"travel_class"; + +/// A context-specific numeric value which is accumulated automatically for each event type. This is +/// a general purpose parameter that is useful for accumulating a key metric that pertains to an +/// event. Examples include revenue, distance, time and points. Value should be specified as Int or +/// Double. +/// Notes: Values for pre-defined currency-related events (such as @c AnalyticsEventAddToCart) +/// should be supplied using Double and must be accompanied by a @c AnalyticsParameterCurrency +/// parameter. The valid range of accumulated values is +/// [-9,223,372,036,854.77, 9,223,372,036,854.77]. Supplying a non-numeric value, omitting the +/// corresponding @c AnalyticsParameterCurrency parameter, or supplying an invalid +/// currency code for conversion events will cause that +/// conversion to be omitted from reporting. +///
+///     let params = [
+///       AnalyticsParameterValue : 3.99,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $3.99 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterValue NS_SWIFT_NAME(AnalyticsParameterValue) = @"value"; + +/// Name of virtual currency type (String). +///
+///     let params = [
+///       AnalyticsParameterVirtualCurrencyName : "virtual_currency_name",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterVirtualCurrencyName + NS_SWIFT_NAME(AnalyticsParameterVirtualCurrencyName) = @"virtual_currency_name"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h new file mode 100644 index 0000000..2442d8a --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h @@ -0,0 +1,28 @@ +/// @file FIRUserPropertyNames.h +/// +/// Predefined user property names. +/// +/// A UserProperty is an attribute that describes the app-user. By supplying UserProperties, you can +/// later analyze different behaviors of various segments of your userbase. You may supply up to 25 +/// unique UserProperties per app, and you can use the name and value of your choosing for each one. +/// UserProperty names can be up to 24 characters long, may only contain alphanumeric characters and +/// underscores ("_"), and must start with an alphabetic character. UserProperty values can be up to +/// 36 characters long. The "firebase_", "google_", and "ga_" prefixes are reserved and should not +/// be used. + +#import + +/// Indicates whether events logged by Google Analytics can be used to personalize ads for the user. +/// Set to "YES" to enable, or "NO" to disable. Default is enabled. See the +/// documentation for +/// more details and information about related settings. +/// +///
+///     Analytics.setUserProperty("NO", forName: AnalyticsUserPropertyAllowAdPersonalizationSignals)
+/// 
+static NSString *const kFIRUserPropertyAllowAdPersonalizationSignals + NS_SWIFT_NAME(AnalyticsUserPropertyAllowAdPersonalizationSignals) = @"allow_personalized_ads"; + +/// The method used to sign in. For example, "google", "facebook" or "twitter". +static NSString *const kFIRUserPropertySignUpMethod + NS_SWIFT_NAME(AnalyticsUserPropertySignUpMethod) = @"sign_up_method"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-Swift.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-Swift.h new file mode 100644 index 0000000..127576f --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-Swift.h @@ -0,0 +1,312 @@ +#if 0 +#elif defined(__arm64__) && __arm64__ +// Generated by Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +#ifndef FIREBASEANALYTICS_SWIFT_H +#define FIREBASEANALYTICS_SWIFT_H +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgcc-compat" + +#if !defined(__has_include) +# define __has_include(x) 0 +#endif +#if !defined(__has_attribute) +# define __has_attribute(x) 0 +#endif +#if !defined(__has_feature) +# define __has_feature(x) 0 +#endif +#if !defined(__has_warning) +# define __has_warning(x) 0 +#endif + +#if __has_include() +# include +#endif + +#pragma clang diagnostic ignored "-Wauto-import" +#if defined(__OBJC__) +#include +#endif +#if defined(__cplusplus) +#include +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#endif +#if defined(__cplusplus) +#if defined(__arm64e__) && __has_include() +# include +#else +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreserved-macro-identifier" +# ifndef __ptrauth_swift_value_witness_function_pointer +# define __ptrauth_swift_value_witness_function_pointer(x) +# endif +# ifndef __ptrauth_swift_class_method_pointer +# define __ptrauth_swift_class_method_pointer(x) +# endif +#pragma clang diagnostic pop +#endif +#endif + +#if !defined(SWIFT_TYPEDEFS) +# define SWIFT_TYPEDEFS 1 +# if __has_include() +# include +# elif !defined(__cplusplus) +typedef uint_least16_t char16_t; +typedef uint_least32_t char32_t; +# endif +typedef float swift_float2 __attribute__((__ext_vector_type__(2))); +typedef float swift_float3 __attribute__((__ext_vector_type__(3))); +typedef float swift_float4 __attribute__((__ext_vector_type__(4))); +typedef double swift_double2 __attribute__((__ext_vector_type__(2))); +typedef double swift_double3 __attribute__((__ext_vector_type__(3))); +typedef double swift_double4 __attribute__((__ext_vector_type__(4))); +typedef int swift_int2 __attribute__((__ext_vector_type__(2))); +typedef int swift_int3 __attribute__((__ext_vector_type__(3))); +typedef int swift_int4 __attribute__((__ext_vector_type__(4))); +typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2))); +typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3))); +typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); +#endif + +#if !defined(SWIFT_PASTE) +# define SWIFT_PASTE_HELPER(x, y) x##y +# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) +#endif +#if !defined(SWIFT_METATYPE) +# define SWIFT_METATYPE(X) Class +#endif +#if !defined(SWIFT_CLASS_PROPERTY) +# if __has_feature(objc_class_property) +# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__ +# else +# define SWIFT_CLASS_PROPERTY(...) +# endif +#endif +#if !defined(SWIFT_RUNTIME_NAME) +# if __has_attribute(objc_runtime_name) +# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) +# else +# define SWIFT_RUNTIME_NAME(X) +# endif +#endif +#if !defined(SWIFT_COMPILE_NAME) +# if __has_attribute(swift_name) +# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) +# else +# define SWIFT_COMPILE_NAME(X) +# endif +#endif +#if !defined(SWIFT_METHOD_FAMILY) +# if __has_attribute(objc_method_family) +# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X))) +# else +# define SWIFT_METHOD_FAMILY(X) +# endif +#endif +#if !defined(SWIFT_NOESCAPE) +# if __has_attribute(noescape) +# define SWIFT_NOESCAPE __attribute__((noescape)) +# else +# define SWIFT_NOESCAPE +# endif +#endif +#if !defined(SWIFT_RELEASES_ARGUMENT) +# if __has_attribute(ns_consumed) +# define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed)) +# else +# define SWIFT_RELEASES_ARGUMENT +# endif +#endif +#if !defined(SWIFT_WARN_UNUSED_RESULT) +# if __has_attribute(warn_unused_result) +# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +# else +# define SWIFT_WARN_UNUSED_RESULT +# endif +#endif +#if !defined(SWIFT_NORETURN) +# if __has_attribute(noreturn) +# define SWIFT_NORETURN __attribute__((noreturn)) +# else +# define SWIFT_NORETURN +# endif +#endif +#if !defined(SWIFT_CLASS_EXTRA) +# define SWIFT_CLASS_EXTRA +#endif +#if !defined(SWIFT_PROTOCOL_EXTRA) +# define SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_ENUM_EXTRA) +# define SWIFT_ENUM_EXTRA +#endif +#if !defined(SWIFT_CLASS) +# if __has_attribute(objc_subclassing_restricted) +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# else +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# endif +#endif +#if !defined(SWIFT_RESILIENT_CLASS) +# if __has_attribute(objc_class_stub) +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub)) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME) +# else +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME) +# endif +#endif +#if !defined(SWIFT_PROTOCOL) +# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_EXTENSION) +# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) +#endif +#if !defined(OBJC_DESIGNATED_INITIALIZER) +# if __has_attribute(objc_designated_initializer) +# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +# else +# define OBJC_DESIGNATED_INITIALIZER +# endif +#endif +#if !defined(SWIFT_ENUM_ATTR) +# if __has_attribute(enum_extensibility) +# define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility))) +# else +# define SWIFT_ENUM_ATTR(_extensibility) +# endif +#endif +#if !defined(SWIFT_ENUM) +# define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# if __has_feature(generalized_swift_name) +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# else +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility) +# endif +#endif +#if !defined(SWIFT_UNAVAILABLE) +# define SWIFT_UNAVAILABLE __attribute__((unavailable)) +#endif +#if !defined(SWIFT_UNAVAILABLE_MSG) +# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg))) +#endif +#if !defined(SWIFT_AVAILABILITY) +# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__))) +#endif +#if !defined(SWIFT_WEAK_IMPORT) +# define SWIFT_WEAK_IMPORT __attribute__((weak_import)) +#endif +#if !defined(SWIFT_DEPRECATED) +# define SWIFT_DEPRECATED __attribute__((deprecated)) +#endif +#if !defined(SWIFT_DEPRECATED_MSG) +# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__))) +#endif +#if !defined(SWIFT_DEPRECATED_OBJC) +# if __has_feature(attribute_diagnose_if_objc) +# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning"))) +# else +# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) +# endif +#endif +#if defined(__OBJC__) +#if !defined(IBSegueAction) +# define IBSegueAction +#endif +#endif +#if !defined(SWIFT_EXTERN) +# if defined(__cplusplus) +# define SWIFT_EXTERN extern "C" +# else +# define SWIFT_EXTERN extern +# endif +#endif +#if !defined(SWIFT_CALL) +# define SWIFT_CALL __attribute__((swiftcall)) +#endif +#if !defined(SWIFT_INDIRECT_RESULT) +# define SWIFT_INDIRECT_RESULT __attribute__((swift_indirect_result)) +#endif +#if !defined(SWIFT_CONTEXT) +# define SWIFT_CONTEXT __attribute__((swift_context)) +#endif +#if !defined(SWIFT_ERROR_RESULT) +# define SWIFT_ERROR_RESULT __attribute__((swift_error_result)) +#endif +#if defined(__cplusplus) +# define SWIFT_NOEXCEPT noexcept +#else +# define SWIFT_NOEXCEPT +#endif +#if !defined(SWIFT_C_INLINE_THUNK) +# if __has_attribute(always_inline) +# if __has_attribute(nodebug) +# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) __attribute__((nodebug)) +# else +# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) +# endif +# else +# define SWIFT_C_INLINE_THUNK inline +# endif +#endif +#if defined(_WIN32) +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL __declspec(dllimport) +#endif +#else +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL +#endif +#endif +#if defined(__OBJC__) +#if __has_feature(objc_modules) +#if __has_warning("-Watimport-in-framework-header") +#pragma clang diagnostic ignored "-Watimport-in-framework-header" +#endif +#endif + +#endif +#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" +#pragma clang diagnostic ignored "-Wduplicate-method-arg" +#if __has_warning("-Wpragma-clang-attribute") +# pragma clang diagnostic ignored "-Wpragma-clang-attribute" +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wnullability" +#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension" + +#if __has_attribute(external_source_symbol) +# pragma push_macro("any") +# undef any +# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="FirebaseAnalytics",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) +# pragma pop_macro("any") +#endif + +#if defined(__OBJC__) + +#endif +#if __has_attribute(external_source_symbol) +# pragma clang attribute pop +#endif +#if defined(__cplusplus) +#endif +#pragma clang diagnostic pop +#endif + +#else +#error unsupported Swift architecture +#endif diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-umbrella.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-umbrella.h new file mode 100644 index 0000000..ad84fbb --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-umbrella.h @@ -0,0 +1,24 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "FIRAnalytics+AppDelegate.h" +#import "FIRAnalytics+Consent.h" +#import "FIRAnalytics+OnDevice.h" +#import "FIRAnalytics.h" +#import "FirebaseAnalytics.h" +#import "FIREventNames.h" +#import "FIRParameterNames.h" +#import "FIRUserPropertyNames.h" + +FOUNDATION_EXPORT double FirebaseAnalyticsVersionNumber; +FOUNDATION_EXPORT const unsigned char FirebaseAnalyticsVersionString[]; + diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h new file mode 100644 index 0000000..351da20 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h @@ -0,0 +1,7 @@ +#import "FIRAnalytics+AppDelegate.h" +#import "FIRAnalytics+Consent.h" +#import "FIRAnalytics+OnDevice.h" +#import "FIRAnalytics.h" +#import "FIREventNames.h" +#import "FIRParameterNames.h" +#import "FIRUserPropertyNames.h" diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Info.plist b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Info.plist new file mode 100644 index 0000000..7d81222 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Info.plist @@ -0,0 +1,57 @@ + + + + + BuildMachineOSBuild + 23F79 + CFBundleDevelopmentRegion + en + CFBundleExecutable + FirebaseAnalytics + CFBundleIdentifier + org.cocoapods.FirebaseAnalytics + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + FirebaseAnalytics + CFBundlePackageType + FMWK + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + iPhoneOS + + CFBundleVersion + 1 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 21C52 + DTPlatformName + iphoneos + DTPlatformVersion + 17.2 + DTSDKBuild + 21C52 + DTSDKName + iphoneos17.2 + DTXcode + 1520 + DTXcodeBuild + 15C500b + MinimumOSVersion + 100.0 + UIDeviceFamily + + 1 + 2 + + UIRequiredDeviceCapabilities + + arm64 + + + diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-ios.swiftsourceinfo b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-ios.swiftsourceinfo new file mode 100644 index 0000000..3edcd88 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-ios.swiftsourceinfo differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios.abi.json b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios.abi.json new file mode 100644 index 0000000..fde2b92 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios.abi.json @@ -0,0 +1,239 @@ +{ + "ABIRoot": { + "kind": "Root", + "name": "TopLevel", + "printedName": "TopLevel", + "children": [ + { + "kind": "Import", + "name": "StoreKit", + "printedName": "StoreKit", + "declKind": "Import", + "moduleName": "FirebaseAnalytics" + }, + { + "kind": "Import", + "name": "SwiftUI", + "printedName": "SwiftUI", + "declKind": "Import", + "moduleName": "FirebaseAnalytics" + }, + { + "kind": "TypeDecl", + "name": "Analytics", + "printedName": "Analytics", + "children": [ + { + "kind": "Function", + "name": "logTransaction", + "printedName": "logTransaction(_:)", + "children": [ + { + "kind": "TypeNominal", + "name": "Void", + "printedName": "()" + }, + { + "kind": "TypeNominal", + "name": "Transaction", + "printedName": "StoreKit.Transaction", + "usr": "s:8StoreKit11TransactionV" + } + ], + "declKind": "Func", + "usr": "s:So12FIRAnalyticsC17FirebaseAnalyticsE14logTransactionyy8StoreKit0E0VFZ", + "mangledName": "$sSo12FIRAnalyticsC17FirebaseAnalyticsE14logTransactionyy8StoreKit0E0VFZ", + "moduleName": "FirebaseAnalytics", + "static": true, + "declAttributes": [ + "Final", + "AccessControl", + "RawDocComment" + ], + "isFromExtension": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Class", + "usr": "c:objc(cs)FIRAnalytics", + "moduleName": "FirebaseAnalytics", + "isOpen": true, + "objc_name": "FIRAnalytics", + "declAttributes": [ + "ObjC", + "Dynamic" + ], + "superclassUsr": "c:objc(cs)NSObject", + "isExternal": true, + "inheritsConvenienceInitializers": true, + "superclassNames": [ + "ObjectiveC.NSObject" + ], + "conformances": [ + { + "kind": "Conformance", + "name": "Equatable", + "printedName": "Equatable", + "usr": "s:SQ", + "mangledName": "$sSQ" + }, + { + "kind": "Conformance", + "name": "Hashable", + "printedName": "Hashable", + "usr": "s:SH", + "mangledName": "$sSH" + }, + { + "kind": "Conformance", + "name": "CVarArg", + "printedName": "CVarArg", + "usr": "s:s7CVarArgP", + "mangledName": "$ss7CVarArgP" + }, + { + "kind": "Conformance", + "name": "_KeyValueCodingAndObservingPublishing", + "printedName": "_KeyValueCodingAndObservingPublishing", + "usr": "s:10Foundation37_KeyValueCodingAndObservingPublishingP", + "mangledName": "$s10Foundation37_KeyValueCodingAndObservingPublishingP" + }, + { + "kind": "Conformance", + "name": "_KeyValueCodingAndObserving", + "printedName": "_KeyValueCodingAndObserving", + "usr": "s:10Foundation27_KeyValueCodingAndObservingP", + "mangledName": "$s10Foundation27_KeyValueCodingAndObservingP" + }, + { + "kind": "Conformance", + "name": "CustomStringConvertible", + "printedName": "CustomStringConvertible", + "usr": "s:s23CustomStringConvertibleP", + "mangledName": "$ss23CustomStringConvertibleP" + }, + { + "kind": "Conformance", + "name": "CustomDebugStringConvertible", + "printedName": "CustomDebugStringConvertible", + "usr": "s:s28CustomDebugStringConvertibleP", + "mangledName": "$ss28CustomDebugStringConvertibleP" + } + ] + }, + { + "kind": "TypeDecl", + "name": "View", + "printedName": "View", + "children": [ + { + "kind": "Function", + "name": "analyticsScreen", + "printedName": "analyticsScreen(name:class:extraParameters:)", + "children": [ + { + "kind": "TypeNominal", + "name": "ModifiedContent", + "printedName": "SwiftUI.ModifiedContent<τ_0_0, FirebaseAnalytics.LoggedAnalyticsModifier>", + "children": [ + { + "kind": "TypeNominal", + "name": "GenericTypeParam", + "printedName": "τ_0_0" + }, + { + "kind": "TypeNominal", + "name": "LoggedAnalyticsModifier", + "printedName": "FirebaseAnalytics.LoggedAnalyticsModifier", + "usr": "s:17FirebaseAnalytics06LoggedB8ModifierV" + } + ], + "usr": "s:7SwiftUI15ModifiedContentV" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "hasDefaultArg": true, + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "Dictionary", + "printedName": "[Swift.String : Any]", + "children": [ + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "ProtocolComposition", + "printedName": "Any" + } + ], + "hasDefaultArg": true, + "usr": "s:SD" + } + ], + "declKind": "Func", + "usr": "s:7SwiftUI4ViewP17FirebaseAnalyticsE15analyticsScreen4name5class15extraParametersQrSS_SSSDySSypGtF", + "mangledName": "$s7SwiftUI4ViewP17FirebaseAnalyticsE15analyticsScreen4name5class15extraParametersQrSS_SSSDySSypGtF", + "moduleName": "FirebaseAnalytics", + "genericSig": "<τ_0_0 where τ_0_0 : SwiftUI.View>", + "sugared_genericSig": "", + "declAttributes": [ + "AccessControl", + "RawDocComment" + ], + "isFromExtension": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Protocol", + "usr": "s:7SwiftUI4ViewP", + "mangledName": "$s7SwiftUI4ViewP", + "moduleName": "SwiftUI", + "genericSig": "<τ_0_0.Body : SwiftUI.View>", + "sugared_genericSig": "", + "intro_Macosx": "10.15", + "intro_iOS": "13.0", + "intro_tvOS": "13.0", + "intro_watchOS": "6.0", + "declAttributes": [ + "TypeEraser", + "Available", + "Available", + "Available", + "Available" + ], + "isExternal": true + } + ], + "json_format_version": 8 + }, + "ConstValues": [ + { + "filePath": "\/Volumes\/google\/src\/cloud\/pdchen\/firebaserelease\/google3\/googlemac\/iPhone\/Firebase\/Analytics\/Sources\/Swift\/Analytics+SwiftUI.swift", + "kind": "StringLiteral", + "offset": 2654, + "length": 6, + "value": "\"View\"" + }, + { + "filePath": "\/Volumes\/google\/src\/cloud\/pdchen\/firebaserelease\/google3\/googlemac\/iPhone\/Firebase\/Analytics\/Sources\/Swift\/Analytics+SwiftUI.swift", + "kind": "Dictionary", + "offset": 2701, + "length": 3, + "value": "[]" + } + ] +} \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios.private.swiftinterface b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios.private.swiftinterface new file mode 100644 index 0000000..f62b1ea --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios.private.swiftinterface @@ -0,0 +1,22 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +// swift-module-flags: -target arm64-apple-ios10.0 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name FirebaseAnalytics +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import FirebaseAnalytics +import StoreKit +import Swift +import SwiftUI +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *) +@available(watchOS, unavailable) +extension FirebaseAnalytics.Analytics { + public static func logTransaction(_ transaction: StoreKit.Transaction) +} +@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *) +@available(watchOS, unavailable) +extension SwiftUI.View { + public func analyticsScreen(name: Swift.String, class: Swift.String = "View", extraParameters: [Swift.String : Any] = [:]) -> some SwiftUI.View + +} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios.swiftdoc b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios.swiftdoc new file mode 100644 index 0000000..c76a452 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios.swiftdoc differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios.swiftinterface b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios.swiftinterface new file mode 100644 index 0000000..f62b1ea --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios.swiftinterface @@ -0,0 +1,22 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +// swift-module-flags: -target arm64-apple-ios10.0 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name FirebaseAnalytics +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import FirebaseAnalytics +import StoreKit +import Swift +import SwiftUI +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *) +@available(watchOS, unavailable) +extension FirebaseAnalytics.Analytics { + public static func logTransaction(_ transaction: StoreKit.Transaction) +} +@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *) +@available(watchOS, unavailable) +extension SwiftUI.View { + public func analyticsScreen(name: Swift.String, class: Swift.String = "View", extraParameters: [Swift.String : Any] = [:]) -> some SwiftUI.View + +} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Modules/module.modulemap b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Modules/module.modulemap new file mode 100644 index 0000000..fa10817 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64/FirebaseAnalytics.framework/Modules/module.modulemap @@ -0,0 +1,16 @@ +framework module FirebaseAnalytics { +umbrella header "FirebaseAnalytics-umbrella.h" +export * +module * { export * } + link framework "Foundation" + link framework "Security" + link framework "SystemConfiguration" + link framework "UIKit" + link "c++" + link "sqlite3" + link "z" +} +module FirebaseAnalytics.Swift { + header "FirebaseAnalytics-Swift.h" + requires objc +} \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/FirebaseAnalytics b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/FirebaseAnalytics new file mode 120000 index 0000000..82502e9 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/FirebaseAnalytics @@ -0,0 +1 @@ +Versions/Current/FirebaseAnalytics \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Headers b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Headers new file mode 120000 index 0000000..a177d2a --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Modules b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Modules new file mode 120000 index 0000000..5736f31 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Modules @@ -0,0 +1 @@ +Versions/Current/Modules \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Resources b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Resources new file mode 120000 index 0000000..953ee36 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/FirebaseAnalytics b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/FirebaseAnalytics new file mode 100644 index 0000000..5a12717 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/FirebaseAnalytics differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+AppDelegate.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+AppDelegate.h new file mode 100644 index 0000000..cb1e407 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+AppDelegate.h @@ -0,0 +1,80 @@ +#import + +#import "FIRAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +/// Provides App Delegate handlers to be used in your App Delegate. +/// +/// To save time integrating Firebase Analytics in an application, Firebase Analytics does not +/// require delegation implementation from the AppDelegate if neither SwiftUI nor UIScene lifecycle +/// is adopted. Instead this is automatically done by Firebase Analytics. Should you choose instead +/// to delegate manually, you can turn off the App Delegate Proxy by adding +/// FirebaseAppDelegateProxyEnabled into your app's Info.plist and setting it to boolean `NO`, and +/// adding the methods in this category to corresponding delegation handlers. +/// +/// To handle Universal Links, you must return `true` in +/// `UIApplicationDelegate.application(_:didFinishLaunchingWithOptions:)`. +@interface FIRAnalytics (AppDelegate) + +/// Handles events related to a URL session that are waiting to be processed. +/// +/// 1. If SwiftUI lifecycle is adopted, call this method from +/// `UIApplicationDelegate.application(_:handleEventsForBackgroundURLSession:completionHandler:)` +/// in your app delegate. +/// +/// 2. If SwiftUI lifecycle is not adopted, Firebase Analytics does not require delegation +/// implementation from the AppDelegate. If you choose instead to delegate manually, you can set +/// FirebaseAppDelegateProxyEnabled to boolean `NO` in your app's Info.plist and call this method +/// from +/// `UIApplicationDelegate.application(_:handleEventsForBackgroundURLSession:completionHandler:)` +/// in your app delegate. +/// +/// @param identifier The identifier of the URL session requiring attention. +/// @param completionHandler The completion handler to call when you finish processing the events. +/// Calling this completion handler lets the system know that your app's user interface is +/// updated and a new snapshot can be taken. ++ (void)handleEventsForBackgroundURLSession:(NSString *)identifier + completionHandler:(nullable void (^)(void))completionHandler; + +/// Handles the event when the app is launched by a URL (custom URL scheme or universal link). +/// +/// 1. If SwiftUI lifecycle is adopted, use `onOpenURL(perform:)` to register a handler and call +/// this method in the handler. +/// +/// 2. If UIScene lifecycle is adopted, call this method from +/// `UISceneDelegate.scene(_:willConnectTo:options:)` and +/// `UISceneDelegate.scene(_:openURLContexts:)` when the URL contexts are available. +/// +/// 3. If neither SwiftUI nor UIScene lifecycle is adopted, Firebase Analytics does not require +/// delegation implementation from the AppDelegate. If you choose instead to delegate manually, you +/// can set FirebaseAppDelegateProxyEnabled to boolean `NO` in your app's Info.plist and call this +/// method from `UIApplicationDelegate.application(_:open:options:)` in your app delegate. +/// +/// @param url The URL resource to open. This resource can be a network resource or a file. ++ (void)handleOpenURL:(NSURL *)url; + +/// Handles the event when the app receives data associated with user activity that includes a +/// Universal Link. +/// +/// 1. If SwiftUI lifecycle is adopted, use `onOpenURL(perform:)` to register a handler and call +/// `Analytics.handleOpen(_:)` instead in the handler. +/// +/// 2. If UIScene lifecycle is adopted, call this method from +/// `UISceneDelegate.scene(_:willConnectTo:options:)` and `UISceneDelegate.scene(_:continue:)` when +/// NSUserActivity is available. See the [Apple +/// doc](https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app) for +/// more details. +/// +/// 3. If neither SwiftUI nor UIScene lifecycle is adopted, Firebase Analytics does not require +/// delegation implementation from the AppDelegate. If you choose instead to delegate manually, you +/// can set FirebaseAppDelegateProxyEnabled to boolean `NO` in your app's Info.plist and call this +/// method from `UIApplication.application(_:continue:restorationHandler:)` in your app delegate. +/// +/// @param userActivity The activity object containing the data associated with the task the user +/// was performing. ++ (void)handleUserActivity:(id)userActivity; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+Consent.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+Consent.h new file mode 100644 index 0000000..7758390 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+Consent.h @@ -0,0 +1,51 @@ +#import + +#import "FIRAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +/// The type of consent to set. Supported consent types are `ConsentType.adStorage`, +/// `ConsentType.analyticsStorage`, `ConsentType.adUserData`, and `ConsentType.adPersonalization`. +/// Omitting a type retains its previous status. +typedef NSString *FIRConsentType NS_TYPED_ENUM NS_SWIFT_NAME(ConsentType); + +/// Enables storage (such as device identifiers) related to advertising. +extern FIRConsentType const FIRConsentTypeAdStorage; + +/// Enables storage (such as app identifiers) related to analytics, e.g. visit duration. +extern FIRConsentType const FIRConsentTypeAnalyticsStorage; + +/// Sets consent for sending user data to Google for advertising purposes. +extern FIRConsentType const FIRConsentTypeAdUserData; + +/// Sets consent for personalized advertising. +extern FIRConsentType const FIRConsentTypeAdPersonalization; + +/// The status value of the consent type. Supported statuses are `ConsentStatus.granted` and +/// `ConsentStatus.denied`. +typedef NSString *FIRConsentStatus NS_TYPED_ENUM NS_SWIFT_NAME(ConsentStatus); + +/// Consent status indicating consent is denied. For an overview of which data is sent when consent +/// is denied, see [SDK behavior with consent +/// mode](https://developers.google.com/tag-platform/security/concepts/consent-mode#tag-behavior). +extern FIRConsentStatus const FIRConsentStatusDenied; + +/// Consent status indicating consent is granted. +extern FIRConsentStatus const FIRConsentStatusGranted; + +/// Sets the applicable end user consent state. +@interface FIRAnalytics (Consent) + +/// Sets the applicable end user consent state (e.g. for device identifiers) for this app on this +/// device. Use the consent settings to specify individual consent type values. Settings are +/// persisted across app sessions. By default consent types are set to `ConsentStatus.granted`. +/// +/// @param consentSettings A Dictionary of consent types. Supported consent type keys are +/// `ConsentType.adStorage`, `ConsentType.analyticsStorage`, `ConsentType.adUserData`, and +/// `ConsentType.adPersonalization`. Valid values are `ConsentStatus.granted` and +/// `ConsentStatus.denied`. ++ (void)setConsent:(NSDictionary *)consentSettings; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+OnDevice.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+OnDevice.h new file mode 100644 index 0000000..0bfec88 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+OnDevice.h @@ -0,0 +1,44 @@ +#import + +#import "FIRAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +API_UNAVAILABLE(macCatalyst, macos, tvos, watchos) +@interface FIRAnalytics (OnDevice) + +/// Initiates on-device conversion measurement given a user email address. Requires dependency +/// GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a no-op. +/// @param emailAddress User email address. Include a domain name for all email addresses +/// (e.g. gmail.com or hotmail.co.jp). ++ (void)initiateOnDeviceConversionMeasurementWithEmailAddress:(NSString *)emailAddress + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(emailAddress:)); + +/// Initiates on-device conversion measurement given a phone number in E.164 format. Requires +/// dependency GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a no-op. +/// @param phoneNumber User phone number. Must be in E.164 format, which means it must be +/// limited to a maximum of 15 digits and must include a plus sign (+) prefix and country code +/// with no dashes, parentheses, or spaces. ++ (void)initiateOnDeviceConversionMeasurementWithPhoneNumber:(NSString *)phoneNumber + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(phoneNumber:)); + +/// Initiates on-device conversion measurement given a sha256-hashed user email address. Requires +/// dependency GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a no-op. +/// @param hashedEmailAddress User email address as a UTF8-encoded string normalized and hashed +/// according to the instructions at +/// https://firebase.google.com/docs/tutorials/ads-ios-on-device-measurement/step-3. ++ (void)initiateOnDeviceConversionMeasurementWithHashedEmailAddress:(NSData *)hashedEmailAddress + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(hashedEmailAddress:)); + +/// Initiates on-device conversion measurement given a sha256-hashed phone number in E.164 format. +/// Requires dependency GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a +/// no-op. +/// @param hashedPhoneNumber UTF8-encoded user phone number in E.164 format and then hashed +/// according to the instructions at +/// https://firebase.google.com/docs/tutorials/ads-ios-on-device-measurement/step-3. ++ (void)initiateOnDeviceConversionMeasurementWithHashedPhoneNumber:(NSData *)hashedPhoneNumber + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(hashedPhoneNumber:)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics.h new file mode 100644 index 0000000..e58d7dd --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics.h @@ -0,0 +1,155 @@ +#import + +#import "FIREventNames.h" +#import "FIRParameterNames.h" +#import "FIRUserPropertyNames.h" + +NS_ASSUME_NONNULL_BEGIN + +/// The top level Firebase Analytics singleton that provides methods for logging events and setting +/// user properties. See the developer guides for general +/// information on using Firebase Analytics in your apps. +/// +/// @note The Analytics SDK uses SQLite to persist events and other app-specific data. Calling +/// certain thread-unsafe global SQLite methods like `sqlite3_shutdown()` can result in +/// unexpected crashes at runtime. +NS_SWIFT_NAME(Analytics) +@interface FIRAnalytics : NSObject + +/// Logs an app event. The event can have up to 25 parameters. Events with the same name must have +/// the same parameters. Up to 500 event names are supported. Using predefined events and/or +/// parameters is recommended for optimal reporting. +/// +/// The following event names are reserved and cannot be used: +///
    +///
  • ad_activeview
  • +///
  • ad_click
  • +///
  • ad_exposure
  • +///
  • ad_query
  • +///
  • ad_reward
  • +///
  • adunit_exposure
  • +///
  • app_clear_data
  • +///
  • app_exception
  • +///
  • app_remove
  • +///
  • app_store_refund
  • +///
  • app_store_subscription_cancel
  • +///
  • app_store_subscription_convert
  • +///
  • app_store_subscription_renew
  • +///
  • app_update
  • +///
  • app_upgrade
  • +///
  • dynamic_link_app_open
  • +///
  • dynamic_link_app_update
  • +///
  • dynamic_link_first_open
  • +///
  • error
  • +///
  • firebase_campaign
  • +///
  • first_open
  • +///
  • first_visit
  • +///
  • in_app_purchase
  • +///
  • notification_dismiss
  • +///
  • notification_foreground
  • +///
  • notification_open
  • +///
  • notification_receive
  • +///
  • os_update
  • +///
  • session_start
  • +///
  • session_start_with_rollout
  • +///
  • user_engagement
  • +///
+/// +/// @param name The name of the event. Should contain 1 to 40 alphanumeric characters or +/// underscores. The name must start with an alphabetic character. Some event names are +/// reserved. See FIREventNames.h for the list of reserved event names. The "firebase_", +/// "google_", and "ga_" prefixes are reserved and should not be used. Note that event names are +/// case-sensitive and that logging two events whose names differ only in case will result in +/// two distinct events. To manually log screen view events, use the `screen_view` event name. +/// @param parameters The dictionary of event parameters. Passing `nil` indicates that the event has +/// no parameters. Parameter names can be up to 40 characters long and must start with an +/// alphabetic character and contain only alphanumeric characters and underscores. Only String, +/// Int, and Double parameter types are supported. String parameter values can be up to 100 +/// characters long for standard Google Analytics properties, and up to 500 characters long for +/// Google Analytics 360 properties. The "firebase_", "google_", and "ga_" prefixes are reserved +/// and should not be used for parameter names. ++ (void)logEventWithName:(NSString *)name + parameters:(nullable NSDictionary *)parameters + NS_SWIFT_NAME(logEvent(_:parameters:)); + +/// Sets a user property to a given value. Up to 25 user property names are supported. Once set, +/// user property values persist throughout the app lifecycle and across sessions. +/// +/// The following user property names are reserved and cannot be used: +///
    +///
  • first_open_time
  • +///
  • last_deep_link_referrer
  • +///
  • user_id
  • +///
+/// +/// @param value The value of the user property. Values can be up to 36 characters long. Setting the +/// value to `nil` removes the user property. +/// @param name The name of the user property to set. Should contain 1 to 24 alphanumeric characters +/// or underscores and must start with an alphabetic character. The "firebase_", "google_", and +/// "ga_" prefixes are reserved and should not be used for user property names. ++ (void)setUserPropertyString:(nullable NSString *)value forName:(NSString *)name + NS_SWIFT_NAME(setUserProperty(_:forName:)); + +/// Sets the user ID property. This feature must be used in accordance with +/// Google's Privacy Policy +/// +/// @param userID The user ID to ascribe to the user of this app on this device, which must be +/// non-empty and no more than 256 characters long. Setting userID to `nil` removes the user ID. ++ (void)setUserID:(nullable NSString *)userID; + +/// Sets whether analytics collection is enabled for this app on this device. This setting is +/// persisted across app sessions. By default it is enabled. +/// +/// @param analyticsCollectionEnabled A flag that enables or disables Analytics collection. ++ (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled; + +/// Sets the interval of inactivity in seconds that terminates the current session. The default +/// value is 1800 seconds (30 minutes). +/// +/// @param sessionTimeoutInterval The custom time of inactivity in seconds before the current +/// session terminates. ++ (void)setSessionTimeoutInterval:(NSTimeInterval)sessionTimeoutInterval; + +/// Asynchronously retrieves the identifier of the current app session. +/// +/// The session ID retrieval could fail due to Analytics collection disabled, app session expired, +/// etc. +/// +/// @param completion The completion handler to call when the session ID retrieval is complete. This +/// handler is executed on a system-defined global concurrent queue. +/// This completion handler takes the following parameters: +/// sessionID The identifier of the current app session. The value is undefined if the +/// request failed. +/// error An error object that indicates why the request failed, or `nil` if the request +/// was successful. ++ (void)sessionIDWithCompletion:(void (^)(int64_t sessionID, NSError *_Nullable error))completion; + +/// Returns the unique ID for this instance of the application or `nil` if +/// `ConsentType.analyticsStorage` has been set to `ConsentStatus.denied`. +/// +/// @see `FIRAnalytics+Consent.h` ++ (nullable NSString *)appInstanceID; + +/// Clears all analytics data for this instance from the device and resets the app instance ID. ++ (void)resetAnalyticsData; + +/// Adds parameters that will be set on every event logged from the SDK, including automatic ones. +/// The values passed in the parameters dictionary will be added to the dictionary of default event +/// parameters. These parameters persist across app runs. They are of lower precedence than event +/// parameters, so if an event parameter and a parameter set using this API have the same name, the +/// value of the event parameter will be used. The same limitations on event parameters apply to +/// default event parameters. +/// +/// @param parameters Parameters to be added to the dictionary of parameters added to every event. +/// They will be added to the dictionary of default event parameters, replacing any existing +/// parameter with the same name. Valid parameters are String, Int, and Double. Setting a key's +/// value to `NSNull()` will clear that parameter. Passing in a `nil` dictionary will clear all +/// parameters. ++ (void)setDefaultEventParameters:(nullable NSDictionary *)parameters; + +/// Unavailable. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIREventNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIREventNames.h new file mode 100644 index 0000000..1e69a44 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIREventNames.h @@ -0,0 +1,418 @@ +/// @file FIREventNames.h +/// +/// Predefined event names. +/// +/// An Event is an important occurrence in your app that you want to measure. You can report up to +/// 500 different types of Events per app and you can associate up to 25 unique parameters with each +/// Event type. Some common events are suggested below, but you may also choose to specify custom +/// Event types that are associated with your specific app. Each event type is identified by a +/// unique name. Event names can be up to 40 characters long, may only contain alphanumeric +/// characters and underscores ("_"), and must start with an alphabetic character. The "firebase_", +/// "google_", and "ga_" prefixes are reserved and should not be used. + +#import + +/// Ad Impression event. This event signifies when a user sees an ad impression. Note: If you supply +/// the @c AnalyticsParameterValue parameter, you must also supply the @c AnalyticsParameterCurrency +/// parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterAdPlatform (String) (optional)
  • +///
  • @c AnalyticsParameterAdFormat (String) (optional)
  • +///
  • @c AnalyticsParameterAdSource (String) (optional)
  • +///
  • @c AnalyticsParameterAdUnitName (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAdImpression NS_SWIFT_NAME(AnalyticsEventAdImpression) = + @"ad_impression"; + +/// Add Payment Info event. This event signifies that a user has submitted their payment +/// information. Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply +/// the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterPaymentType (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddPaymentInfo NS_SWIFT_NAME(AnalyticsEventAddPaymentInfo) = + @"add_payment_info"; + +/// Add Shipping Info event. This event signifies that a user has submitted their shipping +/// information. Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply +/// the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterShippingTier (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddShippingInfo NS_SWIFT_NAME(AnalyticsEventAddShippingInfo) = + @"add_shipping_info"; + +/// E-Commerce Add To Cart event. This event signifies that an item(s) was added to a cart for +/// purchase. Add this event to a funnel with @c AnalyticsEventPurchase to gauge the effectiveness +/// of your checkout process. Note: If you supply the @c AnalyticsParameterValue parameter, you must +/// also supply the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed +/// accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddToCart NS_SWIFT_NAME(AnalyticsEventAddToCart) = @"add_to_cart"; + +/// E-Commerce Add To Wishlist event. This event signifies that an item was added to a wishlist. Use +/// this event to identify popular gift items. Note: If you supply the @c AnalyticsParameterValue +/// parameter, you must also supply the @c AnalyticsParameterCurrency parameter so that revenue +/// metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddToWishlist NS_SWIFT_NAME(AnalyticsEventAddToWishlist) = + @"add_to_wishlist"; + +/// App Open event. By logging this event when an App becomes active, developers can understand how +/// often users leave and return during the course of a Session. Although Sessions are automatically +/// reported, this event can provide further clarification around the continuous engagement of +/// app-users. +static NSString *const kFIREventAppOpen NS_SWIFT_NAME(AnalyticsEventAppOpen) = @"app_open"; + +/// E-Commerce Begin Checkout event. This event signifies that a user has begun the process of +/// checking out. Add this event to a funnel with your @c AnalyticsEventPurchase event to gauge the +/// effectiveness of your checkout process. Note: If you supply the @c AnalyticsParameterValue +/// parameter, you must also supply the @c AnalyticsParameterCurrency parameter so that revenue +/// metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventBeginCheckout NS_SWIFT_NAME(AnalyticsEventBeginCheckout) = + @"begin_checkout"; + +/// Campaign Detail event. Log this event to supply the referral details of a re-engagement +/// campaign. Note: you must supply at least one of the required parameters +/// AnalyticsParameterSource, AnalyticsParameterMedium or AnalyticsParameterCampaign. Params: +/// +///
    +///
  • @c AnalyticsParameterSource (String)
  • +///
  • @c AnalyticsParameterMedium (String)
  • +///
  • @c AnalyticsParameterCampaign (String)
  • +///
  • @c AnalyticsParameterTerm (String) (optional)
  • +///
  • @c AnalyticsParameterContent (String) (optional)
  • +///
  • @c AnalyticsParameterAdNetworkClickID (String) (optional)
  • +///
  • @c AnalyticsParameterCP1 (String) (optional)
  • +///
  • @c AnalyticsParameterCampaignID (String) (optional)
  • +///
  • @c AnalyticsParameterCreativeFormat (String) (optional)
  • +///
  • @c AnalyticsParameterMarketingTactic (String) (optional)
  • +///
  • @c AnalyticsParameterSourcePlatform (String) (optional)
  • +///
+static NSString *const kFIREventCampaignDetails NS_SWIFT_NAME(AnalyticsEventCampaignDetails) = + @"campaign_details"; + +/// Earn Virtual Currency event. This event tracks the awarding of virtual currency in your app. Log +/// this along with @c AnalyticsEventSpendVirtualCurrency to better understand your virtual economy. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterVirtualCurrencyName (String)
  • +///
  • @c AnalyticsParameterValue (Int or Double)
  • +///
+static NSString *const kFIREventEarnVirtualCurrency + NS_SWIFT_NAME(AnalyticsEventEarnVirtualCurrency) = @"earn_virtual_currency"; + +/// Generate Lead event. Log this event when a lead has been generated in the app to understand the +/// efficacy of your install and re-engagement campaigns. Note: If you supply the +/// @c AnalyticsParameterValue parameter, you must also supply the @c AnalyticsParameterCurrency +/// parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventGenerateLead NS_SWIFT_NAME(AnalyticsEventGenerateLead) = + @"generate_lead"; + +/// Join Group event. Log this event when a user joins a group such as a guild, team or family. Use +/// this event to analyze how popular certain groups or social features are in your app. Params: +/// +///
    +///
  • @c AnalyticsParameterGroupID (String)
  • +///
+static NSString *const kFIREventJoinGroup NS_SWIFT_NAME(AnalyticsEventJoinGroup) = @"join_group"; + +/// Level End event. Log this event when the user finishes a level. Params: +/// +///
    +///
  • @c AnalyticsParameterLevelName (String)
  • +///
  • @c AnalyticsParameterSuccess (String)
  • +///
+static NSString *const kFIREventLevelEnd NS_SWIFT_NAME(AnalyticsEventLevelEnd) = @"level_end"; + +/// Level Start event. Log this event when the user starts a new level. Params: +/// +///
    +///
  • @c AnalyticsParameterLevelName (String)
  • +///
+static NSString *const kFIREventLevelStart NS_SWIFT_NAME(AnalyticsEventLevelStart) = @"level_start"; + +/// Level Up event. This event signifies that a player has leveled up in your gaming app. It can +/// help you gauge the level distribution of your userbase and help you identify certain levels that +/// are difficult to pass. Params: +/// +///
    +///
  • @c AnalyticsParameterLevel (Int)
  • +///
  • @c AnalyticsParameterCharacter (String) (optional)
  • +///
+static NSString *const kFIREventLevelUp NS_SWIFT_NAME(AnalyticsEventLevelUp) = @"level_up"; + +/// Login event. Apps with a login feature can report this event to signify that a user has logged +/// in. +static NSString *const kFIREventLogin NS_SWIFT_NAME(AnalyticsEventLogin) = @"login"; + +/// Post Score event. Log this event when the user posts a score in your gaming app. This event can +/// help you understand how users are actually performing in your game and it can help you correlate +/// high scores with certain audiences or behaviors. Params: +/// +///
    +///
  • @c AnalyticsParameterScore (Int)
  • +///
  • @c AnalyticsParameterLevel (Int) (optional)
  • +///
  • @c AnalyticsParameterCharacter (String) (optional)
  • +///
+static NSString *const kFIREventPostScore NS_SWIFT_NAME(AnalyticsEventPostScore) = @"post_score"; + +/// E-Commerce Purchase event. This event signifies that an item(s) was purchased by a user. Note: +/// This is different from the in-app purchase event, which is reported automatically for App +/// Store-based apps. Note: If you supply the @c AnalyticsParameterValue parameter, you must also +/// supply the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed +/// accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterAffiliation (String) (optional)
  • +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterEndDate (String) (optional)
  • +///
  • @c AnalyticsParameterItemID (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterShipping (Double) (optional)
  • +///
  • @c AnalyticsParameterStartDate (String) (optional)
  • +///
  • @c AnalyticsParameterTax (Double) (optional)
  • +///
  • @c AnalyticsParameterTransactionID (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventPurchase NS_SWIFT_NAME(AnalyticsEventPurchase) = @"purchase"; + +/// E-Commerce Refund event. This event signifies that a refund was issued. Note: If you supply the +/// @c AnalyticsParameterValue parameter, you must also supply the @c AnalyticsParameterCurrency +/// parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterAffiliation (String) (optional)
  • +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterShipping (Double) (optional)
  • +///
  • @c AnalyticsParameterTax (Double) (optional)
  • +///
  • @c AnalyticsParameterTransactionID (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventRefund NS_SWIFT_NAME(AnalyticsEventRefund) = @"refund"; + +/// E-Commerce Remove from Cart event. This event signifies that an item(s) was removed from a cart. +/// Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply the @c +/// AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventRemoveFromCart NS_SWIFT_NAME(AnalyticsEventRemoveFromCart) = + @"remove_from_cart"; + +/// Screen View event. This event signifies a screen view. Use this when a screen transition occurs. +/// This event can be logged irrespective of whether automatic screen tracking is enabled. Params: +/// +///
    +///
  • @c AnalyticsParameterScreenClass (String) (optional)
  • +///
  • @c AnalyticsParameterScreenName (String) (optional)
  • +///
+static NSString *const kFIREventScreenView NS_SWIFT_NAME(AnalyticsEventScreenView) = @"screen_view"; + +/// Search event. Apps that support search features can use this event to contextualize search +/// operations by supplying the appropriate, corresponding parameters. This event can help you +/// identify the most popular content in your app. Params: +/// +///
    +///
  • @c AnalyticsParameterSearchTerm (String)
  • +///
  • @c AnalyticsParameterStartDate (String) (optional)
  • +///
  • @c AnalyticsParameterEndDate (String) (optional)
  • +///
  • @c AnalyticsParameterNumberOfNights (Int) (optional) for hotel bookings
  • +///
  • @c AnalyticsParameterNumberOfRooms (Int) (optional) for hotel bookings
  • +///
  • @c AnalyticsParameterNumberOfPassengers (Int) (optional) for travel bookings
  • +///
  • @c AnalyticsParameterOrigin (String) (optional)
  • +///
  • @c AnalyticsParameterDestination (String) (optional)
  • +///
  • @c AnalyticsParameterTravelClass (String) (optional) for travel bookings
  • +///
+static NSString *const kFIREventSearch NS_SWIFT_NAME(AnalyticsEventSearch) = @"search"; + +/// Select Content event. This general purpose event signifies that a user has selected some content +/// of a certain type in an app. The content can be any object in your app. This event can help you +/// identify popular content and categories of content in your app. Params: +/// +///
    +///
  • @c AnalyticsParameterContentType (String)
  • +///
  • @c AnalyticsParameterItemID (String)
  • +///
+static NSString *const kFIREventSelectContent NS_SWIFT_NAME(AnalyticsEventSelectContent) = + @"select_content"; + +/// Select Item event. This event signifies that an item was selected by a user from a list. Use the +/// appropriate parameters to contextualize the event. Use this event to discover the most popular +/// items selected. Params: +/// +///
    +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterItemListID (String) (optional)
  • +///
  • @c AnalyticsParameterItemListName (String) (optional)
  • +///
+static NSString *const kFIREventSelectItem NS_SWIFT_NAME(AnalyticsEventSelectItem) = @"select_item"; + +/// Select promotion event. This event signifies that a user has selected a promotion offer. Use the +/// appropriate parameters to contextualize the event, such as the item(s) for which the promotion +/// applies. Params: +/// +///
    +///
  • @c AnalyticsParameterCreativeName (String) (optional)
  • +///
  • @c AnalyticsParameterCreativeSlot (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterLocationID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionName (String) (optional)
  • +///
+static NSString *const kFIREventSelectPromotion NS_SWIFT_NAME(AnalyticsEventSelectPromotion) = + @"select_promotion"; + +/// Share event. Apps with social features can log the Share event to identify the most viral +/// content. Params: +/// +///
    +///
  • @c AnalyticsParameterContentType (String)
  • +///
  • @c AnalyticsParameterItemID (String)
  • +///
+static NSString *const kFIREventShare NS_SWIFT_NAME(AnalyticsEventShare) = @"share"; + +/// Sign Up event. This event indicates that a user has signed up for an account in your app. The +/// parameter signifies the method by which the user signed up. Use this event to understand the +/// different behaviors between logged in and logged out users. Params: +/// +///
    +///
  • @c AnalyticsParameterMethod (String)
  • +///
+static NSString *const kFIREventSignUp NS_SWIFT_NAME(AnalyticsEventSignUp) = @"sign_up"; + +/// Spend Virtual Currency event. This event tracks the sale of virtual goods in your app and can +/// help you identify which virtual goods are the most popular objects of purchase. Params: +/// +///
    +///
  • @c AnalyticsParameterItemName (String)
  • +///
  • @c AnalyticsParameterVirtualCurrencyName (String)
  • +///
  • @c AnalyticsParameterValue (Int or Double)
  • +///
+static NSString *const kFIREventSpendVirtualCurrency + NS_SWIFT_NAME(AnalyticsEventSpendVirtualCurrency) = @"spend_virtual_currency"; + +/// Tutorial Begin event. This event signifies the start of the on-boarding process in your app. Use +/// this in a funnel with @c AnalyticsEventTutorialComplete to understand how many users complete +/// this process and move on to the full app experience. +static NSString *const kFIREventTutorialBegin NS_SWIFT_NAME(AnalyticsEventTutorialBegin) = + @"tutorial_begin"; + +/// Tutorial End event. Use this event to signify the user's completion of your app's on-boarding +/// process. Add this to a funnel with @c AnalyticsEventTutorialBegin to gauge the completion rate +/// of your on-boarding process. +static NSString *const kFIREventTutorialComplete NS_SWIFT_NAME(AnalyticsEventTutorialComplete) = + @"tutorial_complete"; + +/// Unlock Achievement event. Log this event when the user has unlocked an achievement in your +/// game. Since achievements generally represent the breadth of a gaming experience, this event can +/// help you understand how many users are experiencing all that your game has to offer. Params: +/// +///
    +///
  • @c AnalyticsParameterAchievementID (String)
  • +///
+static NSString *const kFIREventUnlockAchievement NS_SWIFT_NAME(AnalyticsEventUnlockAchievement) = + @"unlock_achievement"; + +/// E-commerce View Cart event. This event signifies that a user has viewed their cart. Use this to +/// analyze your purchase funnel. Note: If you supply the @c AnalyticsParameterValue parameter, you +/// must also supply the @c AnalyticsParameterCurrency parameter so that revenue metrics can be +/// computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventViewCart NS_SWIFT_NAME(AnalyticsEventViewCart) = @"view_cart"; + +/// View Item event. This event signifies that a user has viewed an item. Use the appropriate +/// parameters to contextualize the event. Use this event to discover the most popular items viewed +/// in your app. Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply +/// the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventViewItem NS_SWIFT_NAME(AnalyticsEventViewItem) = @"view_item"; + +/// View Item List event. Log this event when a user sees a list of items or offerings. Params: +/// +///
    +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterItemListID (String) (optional)
  • +///
  • @c AnalyticsParameterItemListName (String) (optional)
  • +///
+static NSString *const kFIREventViewItemList NS_SWIFT_NAME(AnalyticsEventViewItemList) = + @"view_item_list"; + +/// View Promotion event. This event signifies that a promotion was shown to a user. Add this event +/// to a funnel with the @c AnalyticsEventAddToCart and @c AnalyticsEventPurchase to gauge your +/// conversion process. Params: +/// +///
    +///
  • @c AnalyticsParameterCreativeName (String) (optional)
  • +///
  • @c AnalyticsParameterCreativeSlot (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterLocationID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionName (String) (optional)
  • +///
+static NSString *const kFIREventViewPromotion NS_SWIFT_NAME(AnalyticsEventViewPromotion) = + @"view_promotion"; + +/// View Search Results event. Log this event when the user has been presented with the results of a +/// search. Params: +/// +///
    +///
  • @c AnalyticsParameterSearchTerm (String)
  • +///
+static NSString *const kFIREventViewSearchResults NS_SWIFT_NAME(AnalyticsEventViewSearchResults) = + @"view_search_results"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRParameterNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRParameterNames.h new file mode 100644 index 0000000..58a5a21 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRParameterNames.h @@ -0,0 +1,722 @@ +/// @file FIRParameterNames.h +/// +/// Predefined event parameter names. +/// +/// Params supply information that contextualize Events. You can associate up to 25 unique Params +/// with each Event type. Some Params are suggested below for certain common Events, but you are +/// not limited to these. You may supply extra Params for suggested Events or custom Params for +/// Custom events. Param names can be up to 40 characters long, may only contain alphanumeric +/// characters and underscores ("_"), and must start with an alphabetic character. Param values can +/// be up to 100 characters long for standard Google Analytics properties and up to 500 characters +/// long for Google Analytics 360 properties. The "firebase_", "google_", and "ga_" prefixes are +/// reserved and should not be used. + +#import + +/// Game achievement ID (String). +///
+///     let params = [
+///       AnalyticsParameterAchievementID : "10_matches_won",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAchievementID NS_SWIFT_NAME(AnalyticsParameterAchievementID) = + @"achievement_id"; + +/// The ad format (e.g. Banner, Interstitial, Rewarded, Native, Rewarded Interstitial, Instream). +/// (String). +///
+///     let params = [
+///       AnalyticsParameterAdFormat : "Banner",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdFormat NS_SWIFT_NAME(AnalyticsParameterAdFormat) = + @"ad_format"; + +/// Ad Network Click ID (String). Used for network-specific click IDs which vary in format. +///
+///     let params = [
+///       AnalyticsParameterAdNetworkClickID : "1234567",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdNetworkClickID + NS_SWIFT_NAME(AnalyticsParameterAdNetworkClickID) = @"aclid"; + +/// The ad platform (e.g. MoPub, IronSource) (String). +///
+///     let params = [
+///       AnalyticsParameterAdPlatform : "MoPub",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdPlatform NS_SWIFT_NAME(AnalyticsParameterAdPlatform) = + @"ad_platform"; + +/// The ad source (e.g. AdColony) (String). +///
+///     let params = [
+///       AnalyticsParameterAdSource : "AdColony",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdSource NS_SWIFT_NAME(AnalyticsParameterAdSource) = + @"ad_source"; + +/// The ad unit name (e.g. Banner_03) (String). +///
+///     let params = [
+///       AnalyticsParameterAdUnitName : "Banner_03",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdUnitName NS_SWIFT_NAME(AnalyticsParameterAdUnitName) = + @"ad_unit_name"; + +/// A product affiliation to designate a supplying company or brick and mortar store location +/// (String).
+///     let params = [
+///       AnalyticsParameterAffiliation : "Google Store",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAffiliation NS_SWIFT_NAME(AnalyticsParameterAffiliation) = + @"affiliation"; + +/// Campaign custom parameter (String). Used as a method of capturing custom data in a campaign. +/// Use varies by network. +///
+///     let params = [
+///       AnalyticsParameterCP1 : "custom_data",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCP1 NS_SWIFT_NAME(AnalyticsParameterCP1) = @"cp1"; + +/// The individual campaign name, slogan, promo code, etc. Some networks have pre-defined macro to +/// capture campaign information, otherwise can be populated by developer. Highly Recommended +/// (String). +///
+///     let params = [
+///       AnalyticsParameterCampaign : "winter_promotion",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCampaign NS_SWIFT_NAME(AnalyticsParameterCampaign) = + @"campaign"; + +/// Campaign ID (String). Used for keyword analysis to identify a specific product promotion or +/// strategic campaign. This is a required key for GA4 data import. +///
+///     let params = [
+///       AnalyticsParameterCampaignID : "7877652710",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCampaignID NS_SWIFT_NAME(AnalyticsParameterCampaignID) = + @"campaign_id"; + +/// Character used in game (String). +///
+///     let params = [
+///       AnalyticsParameterCharacter : "beat_boss",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCharacter NS_SWIFT_NAME(AnalyticsParameterCharacter) = + @"character"; + +/// Campaign content (String). +static NSString *const kFIRParameterContent NS_SWIFT_NAME(AnalyticsParameterContent) = @"content"; + +/// Type of content selected (String). +///
+///     let params = [
+///       AnalyticsParameterContentType : "news article",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterContentType NS_SWIFT_NAME(AnalyticsParameterContentType) = + @"content_type"; + +/// Coupon code used for a purchase (String). +///
+///     let params = [
+///       AnalyticsParameterCoupon : "SUMMER_FUN",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCoupon NS_SWIFT_NAME(AnalyticsParameterCoupon) = @"coupon"; + +/// Creative Format (String). Used to identify the high-level classification of the type of ad +/// served by a specific campaign. +///
+///     let params = [
+///       AnalyticsParameterCreativeFormat : "display",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCreativeFormat NS_SWIFT_NAME(AnalyticsParameterCreativeFormat) = + @"creative_format"; + +/// The name of a creative used in a promotional spot (String). +///
+///     let params = [
+///       AnalyticsParameterCreativeName : "Summer Sale",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCreativeName NS_SWIFT_NAME(AnalyticsParameterCreativeName) = + @"creative_name"; + +/// The name of a creative slot (String). +///
+///     let params = [
+///       AnalyticsParameterCreativeSlot : "summer_banner2",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCreativeSlot NS_SWIFT_NAME(AnalyticsParameterCreativeSlot) = + @"creative_slot"; + +/// Currency of the purchase or items associated with the event, in 3-letter +/// ISO_4217 format (String). +///
+///     let params = [
+///       AnalyticsParameterCurrency : "USD",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCurrency NS_SWIFT_NAME(AnalyticsParameterCurrency) = + @"currency"; + +/// Flight or Travel destination (String). +///
+///     let params = [
+///       AnalyticsParameterDestination : "Mountain View, CA",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterDestination NS_SWIFT_NAME(AnalyticsParameterDestination) = + @"destination"; + +/// Monetary value of discount associated with a purchase (Double). +///
+///     let params = [
+///       AnalyticsParameterDiscount : 2.0,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $2.00 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterDiscount NS_SWIFT_NAME(AnalyticsParameterDiscount) = + @"discount"; + +/// The arrival date, check-out date or rental end date for the item. This should be in +/// YYYY-MM-DD format (String). +///
+///     let params = [
+///       AnalyticsParameterEndDate : "2015-09-14",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterEndDate NS_SWIFT_NAME(AnalyticsParameterEndDate) = @"end_date"; + +/// Indicates that the associated event should either extend the current session or start a new +/// session if no session was active when the event was logged. Specify 1 to extend the current +/// session or to start a new session; any other value will not extend or start a session. +///
+///     let params = [
+///       AnalyticsParameterExtendSession : 1,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterExtendSession NS_SWIFT_NAME(AnalyticsParameterExtendSession) = + @"extend_session"; + +/// Flight number for travel events (String). +///
+///     let params = [
+///       AnalyticsParameterFlightNumber : "ZZ800",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterFlightNumber NS_SWIFT_NAME(AnalyticsParameterFlightNumber) = + @"flight_number"; + +/// Group/clan/guild ID (String). +///
+///     let params = [
+///       AnalyticsParameterGroupID : "g1",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterGroupID NS_SWIFT_NAME(AnalyticsParameterGroupID) = @"group_id"; + +/// The index of the item in a list (Int). +///
+///     let params = [
+///       AnalyticsParameterIndex : 5,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterIndex NS_SWIFT_NAME(AnalyticsParameterIndex) = @"index"; + +/// Item brand (String). +///
+///     let params = [
+///       AnalyticsParameterItemBrand : "Google",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemBrand NS_SWIFT_NAME(AnalyticsParameterItemBrand) = + @"item_brand"; + +/// Item category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory NS_SWIFT_NAME(AnalyticsParameterItemCategory) = + @"item_category"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory2 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory2 NS_SWIFT_NAME(AnalyticsParameterItemCategory2) = + @"item_category2"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory3 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory3 NS_SWIFT_NAME(AnalyticsParameterItemCategory3) = + @"item_category3"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory4 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory4 NS_SWIFT_NAME(AnalyticsParameterItemCategory4) = + @"item_category4"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory5 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory5 NS_SWIFT_NAME(AnalyticsParameterItemCategory5) = + @"item_category5"; + +/// Item ID (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemID : "SKU_12345",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemID NS_SWIFT_NAME(AnalyticsParameterItemID) = @"item_id"; + +/// The ID of the list in which the item was presented to the user (String). +///
+///     let params = [
+///       AnalyticsParameterItemListID : "ABC123",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemListID NS_SWIFT_NAME(AnalyticsParameterItemListID) = + @"item_list_id"; + +/// The name of the list in which the item was presented to the user (String). +///
+///     let params = [
+///       AnalyticsParameterItemListName : "Related products",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemListName NS_SWIFT_NAME(AnalyticsParameterItemListName) = + @"item_list_name"; + +/// Item Name (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemName : "jeggings",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemName NS_SWIFT_NAME(AnalyticsParameterItemName) = + @"item_name"; + +/// Item variant (String). +///
+///     let params = [
+///       AnalyticsParameterItemVariant : "Black",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemVariant NS_SWIFT_NAME(AnalyticsParameterItemVariant) = + @"item_variant"; + +/// The list of items involved in the transaction expressed as `[[String: Any]]`. +///
+///     let params = [
+///       AnalyticsParameterItems : [
+///         [AnalyticsParameterItemName : "jeggings", AnalyticsParameterItemCategory : "pants"],
+///         [AnalyticsParameterItemName : "boots", AnalyticsParameterItemCategory : "shoes"],
+///       ],
+///     ]
+/// 
+static NSString *const kFIRParameterItems NS_SWIFT_NAME(AnalyticsParameterItems) = @"items"; + +/// Level in game (Int). +///
+///     let params = [
+///       AnalyticsParameterLevel : 42,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLevel NS_SWIFT_NAME(AnalyticsParameterLevel) = @"level"; + +/// The name of a level in a game (String). +///
+///     let params = [
+///       AnalyticsParameterLevelName : "room_1",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLevelName NS_SWIFT_NAME(AnalyticsParameterLevelName) = + @"level_name"; + +/// Location (String). The Google Place ID +/// that corresponds to the associated event. Alternatively, you can supply your own custom +/// Location ID. +///
+///     let params = [
+///       AnalyticsParameterLocation : "ChIJiyj437sx3YAR9kUWC8QkLzQ",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLocation NS_SWIFT_NAME(AnalyticsParameterLocation) = + @"location"; + +/// The location associated with the event. Preferred to be the Google +/// Place ID that corresponds to the +/// associated item but could be overridden to a custom location ID string.(String). +///
+///     let params = [
+///       AnalyticsParameterLocationID : "ChIJiyj437sx3YAR9kUWC8QkLzQ",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLocationID NS_SWIFT_NAME(AnalyticsParameterLocationID) = + @"location_id"; + +/// Marketing Tactic (String). Used to identify the targeting criteria applied to a specific +/// campaign. +///
+///     let params = [
+///       AnalyticsParameterMarketingTactic : "Remarketing",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterMarketingTactic + NS_SWIFT_NAME(AnalyticsParameterMarketingTactic) = @"marketing_tactic"; + +/// The advertising or marketing medium, for example: cpc, banner, email, push. Highly recommended +/// (String). +///
+///     let params = [
+///       AnalyticsParameterMedium : "email",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterMedium NS_SWIFT_NAME(AnalyticsParameterMedium) = @"medium"; + +/// A particular approach used in an operation; for example, "facebook" or "email" in the context +/// of a sign_up or login event. (String). +///
+///     let params = [
+///       AnalyticsParameterMethod : "google",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterMethod NS_SWIFT_NAME(AnalyticsParameterMethod) = @"method"; + +/// Number of nights staying at hotel (Int). +///
+///     let params = [
+///       AnalyticsParameterNumberOfNights : 3,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterNumberOfNights + NS_SWIFT_NAME(AnalyticsParameterNumberOfNights) = @"number_of_nights"; + +/// Number of passengers traveling (Int). +///
+///     let params = [
+///       AnalyticsParameterNumberOfPassengers : 11,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterNumberOfPassengers + NS_SWIFT_NAME(AnalyticsParameterNumberOfPassengers) = @"number_of_passengers"; + +/// Number of rooms for travel events (Int). +///
+///     let params = [
+///       AnalyticsParameterNumberOfRooms : 2,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterNumberOfRooms NS_SWIFT_NAME(AnalyticsParameterNumberOfRooms) = + @"number_of_rooms"; + +/// Flight or Travel origin (String). +///
+///     let params = [
+///       AnalyticsParameterOrigin : "Mountain View, CA",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterOrigin NS_SWIFT_NAME(AnalyticsParameterOrigin) = @"origin"; + +/// The chosen method of payment (String). +///
+///     let params = [
+///       AnalyticsParameterPaymentType : "Visa",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPaymentType NS_SWIFT_NAME(AnalyticsParameterPaymentType) = + @"payment_type"; + +/// Purchase price (Double). +///
+///     let params = [
+///       AnalyticsParameterPrice : 1.0,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $1.00 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPrice NS_SWIFT_NAME(AnalyticsParameterPrice) = @"price"; + +/// The ID of a product promotion (String). +///
+///     let params = [
+///       AnalyticsParameterPromotionID : "ABC123",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPromotionID NS_SWIFT_NAME(AnalyticsParameterPromotionID) = + @"promotion_id"; + +/// The name of a product promotion (String). +///
+///     let params = [
+///       AnalyticsParameterPromotionName : "Summer Sale",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPromotionName NS_SWIFT_NAME(AnalyticsParameterPromotionName) = + @"promotion_name"; + +/// Purchase quantity (Int). +///
+///     let params = [
+///       AnalyticsParameterQuantity : 1,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterQuantity NS_SWIFT_NAME(AnalyticsParameterQuantity) = + @"quantity"; + +/// Score in game (Int). +///
+///     let params = [
+///       AnalyticsParameterScore : 4200,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterScore NS_SWIFT_NAME(AnalyticsParameterScore) = @"score"; + +/// Current screen class, such as the class name of the UIViewController, logged with screen_view +/// event and added to every event (String). +///
+///     let params = [
+///       AnalyticsParameterScreenClass : "LoginViewController",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterScreenClass NS_SWIFT_NAME(AnalyticsParameterScreenClass) = + @"screen_class"; + +/// Current screen name, such as the name of the UIViewController, logged with screen_view event and +/// added to every event (String). +///
+///     let params = [
+///       AnalyticsParameterScreenName : "LoginView",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterScreenName NS_SWIFT_NAME(AnalyticsParameterScreenName) = + @"screen_name"; + +/// The search string/keywords used (String). +///
+///     let params = [
+///       AnalyticsParameterSearchTerm : "periodic table",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSearchTerm NS_SWIFT_NAME(AnalyticsParameterSearchTerm) = + @"search_term"; + +/// Shipping cost associated with a transaction (Double). +///
+///     let params = [
+///       AnalyticsParameterShipping : 5.99,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $5.99 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterShipping NS_SWIFT_NAME(AnalyticsParameterShipping) = + @"shipping"; + +/// The shipping tier (e.g. Ground, Air, Next-day) selected for delivery of the purchased item +/// (String). +///
+///     let params = [
+///       AnalyticsParameterShippingTier : "Ground",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterShippingTier NS_SWIFT_NAME(AnalyticsParameterShippingTier) = + @"shipping_tier"; + +/// The origin of your traffic, such as an Ad network (for example, google) or partner (urban +/// airship). Identify the advertiser, site, publication, etc. that is sending traffic to your +/// property. Highly recommended (String). +///
+///     let params = [
+///       AnalyticsParameterSource : "InMobi",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSource NS_SWIFT_NAME(AnalyticsParameterSource) = @"source"; + +/// Source Platform (String). Used to identify the platform responsible for directing traffic to a +/// given Analytics property (e.g., a buying platform where budgets, targeting criteria, etc. are +/// set, a platform for managing organic traffic data, etc.). +///
+///     let params = [
+///       AnalyticsParameterSourcePlatform : "sa360",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSourcePlatform NS_SWIFT_NAME(AnalyticsParameterSourcePlatform) = + @"source_platform"; + +/// The departure date, check-in date or rental start date for the item. This should be in +/// YYYY-MM-DD format (String). +///
+///     let params = [
+///       AnalyticsParameterStartDate : "2015-09-14",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterStartDate NS_SWIFT_NAME(AnalyticsParameterStartDate) = + @"start_date"; + +/// The result of an operation. Specify 1 to indicate success and 0 to indicate failure (Int). +///
+///     let params = [
+///       AnalyticsParameterSuccess : 1,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSuccess NS_SWIFT_NAME(AnalyticsParameterSuccess) = @"success"; + +/// Tax cost associated with a transaction (Double). +///
+///     let params = [
+///       AnalyticsParameterTax : 2.43,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $2.43 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTax NS_SWIFT_NAME(AnalyticsParameterTax) = @"tax"; + +/// If you're manually tagging keyword campaigns, you should use utm_term to specify the keyword +/// (String). +///
+///     let params = [
+///       AnalyticsParameterTerm : "game",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTerm NS_SWIFT_NAME(AnalyticsParameterTerm) = @"term"; + +/// The unique identifier of a transaction (String). +///
+///     let params = [
+///       AnalyticsParameterTransactionID : "T12345",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTransactionID NS_SWIFT_NAME(AnalyticsParameterTransactionID) = + @"transaction_id"; + +/// Travel class (String). +///
+///     let params = [
+///       AnalyticsParameterTravelClass : "business",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTravelClass NS_SWIFT_NAME(AnalyticsParameterTravelClass) = + @"travel_class"; + +/// A context-specific numeric value which is accumulated automatically for each event type. This is +/// a general purpose parameter that is useful for accumulating a key metric that pertains to an +/// event. Examples include revenue, distance, time and points. Value should be specified as Int or +/// Double. +/// Notes: Values for pre-defined currency-related events (such as @c AnalyticsEventAddToCart) +/// should be supplied using Double and must be accompanied by a @c AnalyticsParameterCurrency +/// parameter. The valid range of accumulated values is +/// [-9,223,372,036,854.77, 9,223,372,036,854.77]. Supplying a non-numeric value, omitting the +/// corresponding @c AnalyticsParameterCurrency parameter, or supplying an invalid +/// currency code for conversion events will cause that +/// conversion to be omitted from reporting. +///
+///     let params = [
+///       AnalyticsParameterValue : 3.99,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $3.99 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterValue NS_SWIFT_NAME(AnalyticsParameterValue) = @"value"; + +/// Name of virtual currency type (String). +///
+///     let params = [
+///       AnalyticsParameterVirtualCurrencyName : "virtual_currency_name",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterVirtualCurrencyName + NS_SWIFT_NAME(AnalyticsParameterVirtualCurrencyName) = @"virtual_currency_name"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRUserPropertyNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRUserPropertyNames.h new file mode 100644 index 0000000..2442d8a --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FIRUserPropertyNames.h @@ -0,0 +1,28 @@ +/// @file FIRUserPropertyNames.h +/// +/// Predefined user property names. +/// +/// A UserProperty is an attribute that describes the app-user. By supplying UserProperties, you can +/// later analyze different behaviors of various segments of your userbase. You may supply up to 25 +/// unique UserProperties per app, and you can use the name and value of your choosing for each one. +/// UserProperty names can be up to 24 characters long, may only contain alphanumeric characters and +/// underscores ("_"), and must start with an alphabetic character. UserProperty values can be up to +/// 36 characters long. The "firebase_", "google_", and "ga_" prefixes are reserved and should not +/// be used. + +#import + +/// Indicates whether events logged by Google Analytics can be used to personalize ads for the user. +/// Set to "YES" to enable, or "NO" to disable. Default is enabled. See the +/// documentation for +/// more details and information about related settings. +/// +///
+///     Analytics.setUserProperty("NO", forName: AnalyticsUserPropertyAllowAdPersonalizationSignals)
+/// 
+static NSString *const kFIRUserPropertyAllowAdPersonalizationSignals + NS_SWIFT_NAME(AnalyticsUserPropertyAllowAdPersonalizationSignals) = @"allow_personalized_ads"; + +/// The method used to sign in. For example, "google", "facebook" or "twitter". +static NSString *const kFIRUserPropertySignUpMethod + NS_SWIFT_NAME(AnalyticsUserPropertySignUpMethod) = @"sign_up_method"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics-Swift.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics-Swift.h new file mode 100644 index 0000000..3dbf01a --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics-Swift.h @@ -0,0 +1,620 @@ +#if 0 +#elif defined(__arm64__) && __arm64__ +// Generated by Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +#ifndef FIREBASEANALYTICS_SWIFT_H +#define FIREBASEANALYTICS_SWIFT_H +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgcc-compat" + +#if !defined(__has_include) +# define __has_include(x) 0 +#endif +#if !defined(__has_attribute) +# define __has_attribute(x) 0 +#endif +#if !defined(__has_feature) +# define __has_feature(x) 0 +#endif +#if !defined(__has_warning) +# define __has_warning(x) 0 +#endif + +#if __has_include() +# include +#endif + +#pragma clang diagnostic ignored "-Wauto-import" +#if defined(__OBJC__) +#include +#endif +#if defined(__cplusplus) +#include +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#endif +#if defined(__cplusplus) +#if defined(__arm64e__) && __has_include() +# include +#else +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreserved-macro-identifier" +# ifndef __ptrauth_swift_value_witness_function_pointer +# define __ptrauth_swift_value_witness_function_pointer(x) +# endif +# ifndef __ptrauth_swift_class_method_pointer +# define __ptrauth_swift_class_method_pointer(x) +# endif +#pragma clang diagnostic pop +#endif +#endif + +#if !defined(SWIFT_TYPEDEFS) +# define SWIFT_TYPEDEFS 1 +# if __has_include() +# include +# elif !defined(__cplusplus) +typedef uint_least16_t char16_t; +typedef uint_least32_t char32_t; +# endif +typedef float swift_float2 __attribute__((__ext_vector_type__(2))); +typedef float swift_float3 __attribute__((__ext_vector_type__(3))); +typedef float swift_float4 __attribute__((__ext_vector_type__(4))); +typedef double swift_double2 __attribute__((__ext_vector_type__(2))); +typedef double swift_double3 __attribute__((__ext_vector_type__(3))); +typedef double swift_double4 __attribute__((__ext_vector_type__(4))); +typedef int swift_int2 __attribute__((__ext_vector_type__(2))); +typedef int swift_int3 __attribute__((__ext_vector_type__(3))); +typedef int swift_int4 __attribute__((__ext_vector_type__(4))); +typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2))); +typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3))); +typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); +#endif + +#if !defined(SWIFT_PASTE) +# define SWIFT_PASTE_HELPER(x, y) x##y +# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) +#endif +#if !defined(SWIFT_METATYPE) +# define SWIFT_METATYPE(X) Class +#endif +#if !defined(SWIFT_CLASS_PROPERTY) +# if __has_feature(objc_class_property) +# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__ +# else +# define SWIFT_CLASS_PROPERTY(...) +# endif +#endif +#if !defined(SWIFT_RUNTIME_NAME) +# if __has_attribute(objc_runtime_name) +# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) +# else +# define SWIFT_RUNTIME_NAME(X) +# endif +#endif +#if !defined(SWIFT_COMPILE_NAME) +# if __has_attribute(swift_name) +# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) +# else +# define SWIFT_COMPILE_NAME(X) +# endif +#endif +#if !defined(SWIFT_METHOD_FAMILY) +# if __has_attribute(objc_method_family) +# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X))) +# else +# define SWIFT_METHOD_FAMILY(X) +# endif +#endif +#if !defined(SWIFT_NOESCAPE) +# if __has_attribute(noescape) +# define SWIFT_NOESCAPE __attribute__((noescape)) +# else +# define SWIFT_NOESCAPE +# endif +#endif +#if !defined(SWIFT_RELEASES_ARGUMENT) +# if __has_attribute(ns_consumed) +# define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed)) +# else +# define SWIFT_RELEASES_ARGUMENT +# endif +#endif +#if !defined(SWIFT_WARN_UNUSED_RESULT) +# if __has_attribute(warn_unused_result) +# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +# else +# define SWIFT_WARN_UNUSED_RESULT +# endif +#endif +#if !defined(SWIFT_NORETURN) +# if __has_attribute(noreturn) +# define SWIFT_NORETURN __attribute__((noreturn)) +# else +# define SWIFT_NORETURN +# endif +#endif +#if !defined(SWIFT_CLASS_EXTRA) +# define SWIFT_CLASS_EXTRA +#endif +#if !defined(SWIFT_PROTOCOL_EXTRA) +# define SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_ENUM_EXTRA) +# define SWIFT_ENUM_EXTRA +#endif +#if !defined(SWIFT_CLASS) +# if __has_attribute(objc_subclassing_restricted) +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# else +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# endif +#endif +#if !defined(SWIFT_RESILIENT_CLASS) +# if __has_attribute(objc_class_stub) +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub)) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME) +# else +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME) +# endif +#endif +#if !defined(SWIFT_PROTOCOL) +# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_EXTENSION) +# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) +#endif +#if !defined(OBJC_DESIGNATED_INITIALIZER) +# if __has_attribute(objc_designated_initializer) +# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +# else +# define OBJC_DESIGNATED_INITIALIZER +# endif +#endif +#if !defined(SWIFT_ENUM_ATTR) +# if __has_attribute(enum_extensibility) +# define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility))) +# else +# define SWIFT_ENUM_ATTR(_extensibility) +# endif +#endif +#if !defined(SWIFT_ENUM) +# define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# if __has_feature(generalized_swift_name) +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# else +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility) +# endif +#endif +#if !defined(SWIFT_UNAVAILABLE) +# define SWIFT_UNAVAILABLE __attribute__((unavailable)) +#endif +#if !defined(SWIFT_UNAVAILABLE_MSG) +# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg))) +#endif +#if !defined(SWIFT_AVAILABILITY) +# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__))) +#endif +#if !defined(SWIFT_WEAK_IMPORT) +# define SWIFT_WEAK_IMPORT __attribute__((weak_import)) +#endif +#if !defined(SWIFT_DEPRECATED) +# define SWIFT_DEPRECATED __attribute__((deprecated)) +#endif +#if !defined(SWIFT_DEPRECATED_MSG) +# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__))) +#endif +#if !defined(SWIFT_DEPRECATED_OBJC) +# if __has_feature(attribute_diagnose_if_objc) +# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning"))) +# else +# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) +# endif +#endif +#if defined(__OBJC__) +#if !defined(IBSegueAction) +# define IBSegueAction +#endif +#endif +#if !defined(SWIFT_EXTERN) +# if defined(__cplusplus) +# define SWIFT_EXTERN extern "C" +# else +# define SWIFT_EXTERN extern +# endif +#endif +#if !defined(SWIFT_CALL) +# define SWIFT_CALL __attribute__((swiftcall)) +#endif +#if !defined(SWIFT_INDIRECT_RESULT) +# define SWIFT_INDIRECT_RESULT __attribute__((swift_indirect_result)) +#endif +#if !defined(SWIFT_CONTEXT) +# define SWIFT_CONTEXT __attribute__((swift_context)) +#endif +#if !defined(SWIFT_ERROR_RESULT) +# define SWIFT_ERROR_RESULT __attribute__((swift_error_result)) +#endif +#if defined(__cplusplus) +# define SWIFT_NOEXCEPT noexcept +#else +# define SWIFT_NOEXCEPT +#endif +#if !defined(SWIFT_C_INLINE_THUNK) +# if __has_attribute(always_inline) +# if __has_attribute(nodebug) +# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) __attribute__((nodebug)) +# else +# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) +# endif +# else +# define SWIFT_C_INLINE_THUNK inline +# endif +#endif +#if defined(_WIN32) +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL __declspec(dllimport) +#endif +#else +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL +#endif +#endif +#if defined(__OBJC__) +#if __has_feature(objc_modules) +#if __has_warning("-Watimport-in-framework-header") +#pragma clang diagnostic ignored "-Watimport-in-framework-header" +#endif +#endif + +#endif +#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" +#pragma clang diagnostic ignored "-Wduplicate-method-arg" +#if __has_warning("-Wpragma-clang-attribute") +# pragma clang diagnostic ignored "-Wpragma-clang-attribute" +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wnullability" +#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension" + +#if __has_attribute(external_source_symbol) +# pragma push_macro("any") +# undef any +# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="FirebaseAnalytics",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) +# pragma pop_macro("any") +#endif + +#if defined(__OBJC__) + +#endif +#if __has_attribute(external_source_symbol) +# pragma clang attribute pop +#endif +#if defined(__cplusplus) +#endif +#pragma clang diagnostic pop +#endif + +#elif defined(__x86_64__) && __x86_64__ +// Generated by Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +#ifndef FIREBASEANALYTICS_SWIFT_H +#define FIREBASEANALYTICS_SWIFT_H +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgcc-compat" + +#if !defined(__has_include) +# define __has_include(x) 0 +#endif +#if !defined(__has_attribute) +# define __has_attribute(x) 0 +#endif +#if !defined(__has_feature) +# define __has_feature(x) 0 +#endif +#if !defined(__has_warning) +# define __has_warning(x) 0 +#endif + +#if __has_include() +# include +#endif + +#pragma clang diagnostic ignored "-Wauto-import" +#if defined(__OBJC__) +#include +#endif +#if defined(__cplusplus) +#include +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#endif +#if defined(__cplusplus) +#if defined(__arm64e__) && __has_include() +# include +#else +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreserved-macro-identifier" +# ifndef __ptrauth_swift_value_witness_function_pointer +# define __ptrauth_swift_value_witness_function_pointer(x) +# endif +# ifndef __ptrauth_swift_class_method_pointer +# define __ptrauth_swift_class_method_pointer(x) +# endif +#pragma clang diagnostic pop +#endif +#endif + +#if !defined(SWIFT_TYPEDEFS) +# define SWIFT_TYPEDEFS 1 +# if __has_include() +# include +# elif !defined(__cplusplus) +typedef uint_least16_t char16_t; +typedef uint_least32_t char32_t; +# endif +typedef float swift_float2 __attribute__((__ext_vector_type__(2))); +typedef float swift_float3 __attribute__((__ext_vector_type__(3))); +typedef float swift_float4 __attribute__((__ext_vector_type__(4))); +typedef double swift_double2 __attribute__((__ext_vector_type__(2))); +typedef double swift_double3 __attribute__((__ext_vector_type__(3))); +typedef double swift_double4 __attribute__((__ext_vector_type__(4))); +typedef int swift_int2 __attribute__((__ext_vector_type__(2))); +typedef int swift_int3 __attribute__((__ext_vector_type__(3))); +typedef int swift_int4 __attribute__((__ext_vector_type__(4))); +typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2))); +typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3))); +typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); +#endif + +#if !defined(SWIFT_PASTE) +# define SWIFT_PASTE_HELPER(x, y) x##y +# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) +#endif +#if !defined(SWIFT_METATYPE) +# define SWIFT_METATYPE(X) Class +#endif +#if !defined(SWIFT_CLASS_PROPERTY) +# if __has_feature(objc_class_property) +# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__ +# else +# define SWIFT_CLASS_PROPERTY(...) +# endif +#endif +#if !defined(SWIFT_RUNTIME_NAME) +# if __has_attribute(objc_runtime_name) +# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) +# else +# define SWIFT_RUNTIME_NAME(X) +# endif +#endif +#if !defined(SWIFT_COMPILE_NAME) +# if __has_attribute(swift_name) +# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) +# else +# define SWIFT_COMPILE_NAME(X) +# endif +#endif +#if !defined(SWIFT_METHOD_FAMILY) +# if __has_attribute(objc_method_family) +# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X))) +# else +# define SWIFT_METHOD_FAMILY(X) +# endif +#endif +#if !defined(SWIFT_NOESCAPE) +# if __has_attribute(noescape) +# define SWIFT_NOESCAPE __attribute__((noescape)) +# else +# define SWIFT_NOESCAPE +# endif +#endif +#if !defined(SWIFT_RELEASES_ARGUMENT) +# if __has_attribute(ns_consumed) +# define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed)) +# else +# define SWIFT_RELEASES_ARGUMENT +# endif +#endif +#if !defined(SWIFT_WARN_UNUSED_RESULT) +# if __has_attribute(warn_unused_result) +# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +# else +# define SWIFT_WARN_UNUSED_RESULT +# endif +#endif +#if !defined(SWIFT_NORETURN) +# if __has_attribute(noreturn) +# define SWIFT_NORETURN __attribute__((noreturn)) +# else +# define SWIFT_NORETURN +# endif +#endif +#if !defined(SWIFT_CLASS_EXTRA) +# define SWIFT_CLASS_EXTRA +#endif +#if !defined(SWIFT_PROTOCOL_EXTRA) +# define SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_ENUM_EXTRA) +# define SWIFT_ENUM_EXTRA +#endif +#if !defined(SWIFT_CLASS) +# if __has_attribute(objc_subclassing_restricted) +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# else +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# endif +#endif +#if !defined(SWIFT_RESILIENT_CLASS) +# if __has_attribute(objc_class_stub) +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub)) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME) +# else +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME) +# endif +#endif +#if !defined(SWIFT_PROTOCOL) +# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_EXTENSION) +# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) +#endif +#if !defined(OBJC_DESIGNATED_INITIALIZER) +# if __has_attribute(objc_designated_initializer) +# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +# else +# define OBJC_DESIGNATED_INITIALIZER +# endif +#endif +#if !defined(SWIFT_ENUM_ATTR) +# if __has_attribute(enum_extensibility) +# define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility))) +# else +# define SWIFT_ENUM_ATTR(_extensibility) +# endif +#endif +#if !defined(SWIFT_ENUM) +# define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# if __has_feature(generalized_swift_name) +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# else +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility) +# endif +#endif +#if !defined(SWIFT_UNAVAILABLE) +# define SWIFT_UNAVAILABLE __attribute__((unavailable)) +#endif +#if !defined(SWIFT_UNAVAILABLE_MSG) +# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg))) +#endif +#if !defined(SWIFT_AVAILABILITY) +# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__))) +#endif +#if !defined(SWIFT_WEAK_IMPORT) +# define SWIFT_WEAK_IMPORT __attribute__((weak_import)) +#endif +#if !defined(SWIFT_DEPRECATED) +# define SWIFT_DEPRECATED __attribute__((deprecated)) +#endif +#if !defined(SWIFT_DEPRECATED_MSG) +# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__))) +#endif +#if !defined(SWIFT_DEPRECATED_OBJC) +# if __has_feature(attribute_diagnose_if_objc) +# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning"))) +# else +# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) +# endif +#endif +#if defined(__OBJC__) +#if !defined(IBSegueAction) +# define IBSegueAction +#endif +#endif +#if !defined(SWIFT_EXTERN) +# if defined(__cplusplus) +# define SWIFT_EXTERN extern "C" +# else +# define SWIFT_EXTERN extern +# endif +#endif +#if !defined(SWIFT_CALL) +# define SWIFT_CALL __attribute__((swiftcall)) +#endif +#if !defined(SWIFT_INDIRECT_RESULT) +# define SWIFT_INDIRECT_RESULT __attribute__((swift_indirect_result)) +#endif +#if !defined(SWIFT_CONTEXT) +# define SWIFT_CONTEXT __attribute__((swift_context)) +#endif +#if !defined(SWIFT_ERROR_RESULT) +# define SWIFT_ERROR_RESULT __attribute__((swift_error_result)) +#endif +#if defined(__cplusplus) +# define SWIFT_NOEXCEPT noexcept +#else +# define SWIFT_NOEXCEPT +#endif +#if !defined(SWIFT_C_INLINE_THUNK) +# if __has_attribute(always_inline) +# if __has_attribute(nodebug) +# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) __attribute__((nodebug)) +# else +# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) +# endif +# else +# define SWIFT_C_INLINE_THUNK inline +# endif +#endif +#if defined(_WIN32) +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL __declspec(dllimport) +#endif +#else +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL +#endif +#endif +#if defined(__OBJC__) +#if __has_feature(objc_modules) +#if __has_warning("-Watimport-in-framework-header") +#pragma clang diagnostic ignored "-Watimport-in-framework-header" +#endif +#endif + +#endif +#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" +#pragma clang diagnostic ignored "-Wduplicate-method-arg" +#if __has_warning("-Wpragma-clang-attribute") +# pragma clang diagnostic ignored "-Wpragma-clang-attribute" +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wnullability" +#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension" + +#if __has_attribute(external_source_symbol) +# pragma push_macro("any") +# undef any +# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="FirebaseAnalytics",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) +# pragma pop_macro("any") +#endif + +#if defined(__OBJC__) + +#endif +#if __has_attribute(external_source_symbol) +# pragma clang attribute pop +#endif +#if defined(__cplusplus) +#endif +#pragma clang diagnostic pop +#endif + +#else +#error unsupported Swift architecture +#endif diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics-umbrella.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics-umbrella.h new file mode 100644 index 0000000..ad84fbb --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics-umbrella.h @@ -0,0 +1,24 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "FIRAnalytics+AppDelegate.h" +#import "FIRAnalytics+Consent.h" +#import "FIRAnalytics+OnDevice.h" +#import "FIRAnalytics.h" +#import "FirebaseAnalytics.h" +#import "FIREventNames.h" +#import "FIRParameterNames.h" +#import "FIRUserPropertyNames.h" + +FOUNDATION_EXPORT double FirebaseAnalyticsVersionNumber; +FOUNDATION_EXPORT const unsigned char FirebaseAnalyticsVersionString[]; + diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics.h new file mode 100644 index 0000000..351da20 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics.h @@ -0,0 +1,7 @@ +#import "FIRAnalytics+AppDelegate.h" +#import "FIRAnalytics+Consent.h" +#import "FIRAnalytics+OnDevice.h" +#import "FIRAnalytics.h" +#import "FIREventNames.h" +#import "FIRParameterNames.h" +#import "FIRUserPropertyNames.h" diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-ios-macabi.swiftsourceinfo b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-ios-macabi.swiftsourceinfo new file mode 100644 index 0000000..bea5135 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-ios-macabi.swiftsourceinfo differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/Project/x86_64-apple-ios-macabi.swiftsourceinfo b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/Project/x86_64-apple-ios-macabi.swiftsourceinfo new file mode 100644 index 0000000..9659207 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/Project/x86_64-apple-ios-macabi.swiftsourceinfo differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-macabi.abi.json b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-macabi.abi.json new file mode 100644 index 0000000..fde2b92 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-macabi.abi.json @@ -0,0 +1,239 @@ +{ + "ABIRoot": { + "kind": "Root", + "name": "TopLevel", + "printedName": "TopLevel", + "children": [ + { + "kind": "Import", + "name": "StoreKit", + "printedName": "StoreKit", + "declKind": "Import", + "moduleName": "FirebaseAnalytics" + }, + { + "kind": "Import", + "name": "SwiftUI", + "printedName": "SwiftUI", + "declKind": "Import", + "moduleName": "FirebaseAnalytics" + }, + { + "kind": "TypeDecl", + "name": "Analytics", + "printedName": "Analytics", + "children": [ + { + "kind": "Function", + "name": "logTransaction", + "printedName": "logTransaction(_:)", + "children": [ + { + "kind": "TypeNominal", + "name": "Void", + "printedName": "()" + }, + { + "kind": "TypeNominal", + "name": "Transaction", + "printedName": "StoreKit.Transaction", + "usr": "s:8StoreKit11TransactionV" + } + ], + "declKind": "Func", + "usr": "s:So12FIRAnalyticsC17FirebaseAnalyticsE14logTransactionyy8StoreKit0E0VFZ", + "mangledName": "$sSo12FIRAnalyticsC17FirebaseAnalyticsE14logTransactionyy8StoreKit0E0VFZ", + "moduleName": "FirebaseAnalytics", + "static": true, + "declAttributes": [ + "Final", + "AccessControl", + "RawDocComment" + ], + "isFromExtension": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Class", + "usr": "c:objc(cs)FIRAnalytics", + "moduleName": "FirebaseAnalytics", + "isOpen": true, + "objc_name": "FIRAnalytics", + "declAttributes": [ + "ObjC", + "Dynamic" + ], + "superclassUsr": "c:objc(cs)NSObject", + "isExternal": true, + "inheritsConvenienceInitializers": true, + "superclassNames": [ + "ObjectiveC.NSObject" + ], + "conformances": [ + { + "kind": "Conformance", + "name": "Equatable", + "printedName": "Equatable", + "usr": "s:SQ", + "mangledName": "$sSQ" + }, + { + "kind": "Conformance", + "name": "Hashable", + "printedName": "Hashable", + "usr": "s:SH", + "mangledName": "$sSH" + }, + { + "kind": "Conformance", + "name": "CVarArg", + "printedName": "CVarArg", + "usr": "s:s7CVarArgP", + "mangledName": "$ss7CVarArgP" + }, + { + "kind": "Conformance", + "name": "_KeyValueCodingAndObservingPublishing", + "printedName": "_KeyValueCodingAndObservingPublishing", + "usr": "s:10Foundation37_KeyValueCodingAndObservingPublishingP", + "mangledName": "$s10Foundation37_KeyValueCodingAndObservingPublishingP" + }, + { + "kind": "Conformance", + "name": "_KeyValueCodingAndObserving", + "printedName": "_KeyValueCodingAndObserving", + "usr": "s:10Foundation27_KeyValueCodingAndObservingP", + "mangledName": "$s10Foundation27_KeyValueCodingAndObservingP" + }, + { + "kind": "Conformance", + "name": "CustomStringConvertible", + "printedName": "CustomStringConvertible", + "usr": "s:s23CustomStringConvertibleP", + "mangledName": "$ss23CustomStringConvertibleP" + }, + { + "kind": "Conformance", + "name": "CustomDebugStringConvertible", + "printedName": "CustomDebugStringConvertible", + "usr": "s:s28CustomDebugStringConvertibleP", + "mangledName": "$ss28CustomDebugStringConvertibleP" + } + ] + }, + { + "kind": "TypeDecl", + "name": "View", + "printedName": "View", + "children": [ + { + "kind": "Function", + "name": "analyticsScreen", + "printedName": "analyticsScreen(name:class:extraParameters:)", + "children": [ + { + "kind": "TypeNominal", + "name": "ModifiedContent", + "printedName": "SwiftUI.ModifiedContent<τ_0_0, FirebaseAnalytics.LoggedAnalyticsModifier>", + "children": [ + { + "kind": "TypeNominal", + "name": "GenericTypeParam", + "printedName": "τ_0_0" + }, + { + "kind": "TypeNominal", + "name": "LoggedAnalyticsModifier", + "printedName": "FirebaseAnalytics.LoggedAnalyticsModifier", + "usr": "s:17FirebaseAnalytics06LoggedB8ModifierV" + } + ], + "usr": "s:7SwiftUI15ModifiedContentV" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "hasDefaultArg": true, + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "Dictionary", + "printedName": "[Swift.String : Any]", + "children": [ + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "ProtocolComposition", + "printedName": "Any" + } + ], + "hasDefaultArg": true, + "usr": "s:SD" + } + ], + "declKind": "Func", + "usr": "s:7SwiftUI4ViewP17FirebaseAnalyticsE15analyticsScreen4name5class15extraParametersQrSS_SSSDySSypGtF", + "mangledName": "$s7SwiftUI4ViewP17FirebaseAnalyticsE15analyticsScreen4name5class15extraParametersQrSS_SSSDySSypGtF", + "moduleName": "FirebaseAnalytics", + "genericSig": "<τ_0_0 where τ_0_0 : SwiftUI.View>", + "sugared_genericSig": "", + "declAttributes": [ + "AccessControl", + "RawDocComment" + ], + "isFromExtension": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Protocol", + "usr": "s:7SwiftUI4ViewP", + "mangledName": "$s7SwiftUI4ViewP", + "moduleName": "SwiftUI", + "genericSig": "<τ_0_0.Body : SwiftUI.View>", + "sugared_genericSig": "", + "intro_Macosx": "10.15", + "intro_iOS": "13.0", + "intro_tvOS": "13.0", + "intro_watchOS": "6.0", + "declAttributes": [ + "TypeEraser", + "Available", + "Available", + "Available", + "Available" + ], + "isExternal": true + } + ], + "json_format_version": 8 + }, + "ConstValues": [ + { + "filePath": "\/Volumes\/google\/src\/cloud\/pdchen\/firebaserelease\/google3\/googlemac\/iPhone\/Firebase\/Analytics\/Sources\/Swift\/Analytics+SwiftUI.swift", + "kind": "StringLiteral", + "offset": 2654, + "length": 6, + "value": "\"View\"" + }, + { + "filePath": "\/Volumes\/google\/src\/cloud\/pdchen\/firebaserelease\/google3\/googlemac\/iPhone\/Firebase\/Analytics\/Sources\/Swift\/Analytics+SwiftUI.swift", + "kind": "Dictionary", + "offset": 2701, + "length": 3, + "value": "[]" + } + ] +} \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-macabi.private.swiftinterface b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-macabi.private.swiftinterface new file mode 100644 index 0000000..167a18c --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-macabi.private.swiftinterface @@ -0,0 +1,22 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +// swift-module-flags: -target arm64-apple-ios13.1-macabi -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name FirebaseAnalytics +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import FirebaseAnalytics +import StoreKit +import Swift +import SwiftUI +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *) +@available(watchOS, unavailable) +extension FirebaseAnalytics.Analytics { + public static func logTransaction(_ transaction: StoreKit.Transaction) +} +@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *) +@available(watchOS, unavailable) +extension SwiftUI.View { + public func analyticsScreen(name: Swift.String, class: Swift.String = "View", extraParameters: [Swift.String : Any] = [:]) -> some SwiftUI.View + +} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-macabi.swiftdoc b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-macabi.swiftdoc new file mode 100644 index 0000000..8591fff Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-macabi.swiftdoc differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-macabi.swiftinterface b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-macabi.swiftinterface new file mode 100644 index 0000000..167a18c --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-macabi.swiftinterface @@ -0,0 +1,22 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +// swift-module-flags: -target arm64-apple-ios13.1-macabi -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name FirebaseAnalytics +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import FirebaseAnalytics +import StoreKit +import Swift +import SwiftUI +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *) +@available(watchOS, unavailable) +extension FirebaseAnalytics.Analytics { + public static func logTransaction(_ transaction: StoreKit.Transaction) +} +@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *) +@available(watchOS, unavailable) +extension SwiftUI.View { + public func analyticsScreen(name: Swift.String, class: Swift.String = "View", extraParameters: [Swift.String : Any] = [:]) -> some SwiftUI.View + +} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-macabi.abi.json b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-macabi.abi.json new file mode 100644 index 0000000..fde2b92 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-macabi.abi.json @@ -0,0 +1,239 @@ +{ + "ABIRoot": { + "kind": "Root", + "name": "TopLevel", + "printedName": "TopLevel", + "children": [ + { + "kind": "Import", + "name": "StoreKit", + "printedName": "StoreKit", + "declKind": "Import", + "moduleName": "FirebaseAnalytics" + }, + { + "kind": "Import", + "name": "SwiftUI", + "printedName": "SwiftUI", + "declKind": "Import", + "moduleName": "FirebaseAnalytics" + }, + { + "kind": "TypeDecl", + "name": "Analytics", + "printedName": "Analytics", + "children": [ + { + "kind": "Function", + "name": "logTransaction", + "printedName": "logTransaction(_:)", + "children": [ + { + "kind": "TypeNominal", + "name": "Void", + "printedName": "()" + }, + { + "kind": "TypeNominal", + "name": "Transaction", + "printedName": "StoreKit.Transaction", + "usr": "s:8StoreKit11TransactionV" + } + ], + "declKind": "Func", + "usr": "s:So12FIRAnalyticsC17FirebaseAnalyticsE14logTransactionyy8StoreKit0E0VFZ", + "mangledName": "$sSo12FIRAnalyticsC17FirebaseAnalyticsE14logTransactionyy8StoreKit0E0VFZ", + "moduleName": "FirebaseAnalytics", + "static": true, + "declAttributes": [ + "Final", + "AccessControl", + "RawDocComment" + ], + "isFromExtension": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Class", + "usr": "c:objc(cs)FIRAnalytics", + "moduleName": "FirebaseAnalytics", + "isOpen": true, + "objc_name": "FIRAnalytics", + "declAttributes": [ + "ObjC", + "Dynamic" + ], + "superclassUsr": "c:objc(cs)NSObject", + "isExternal": true, + "inheritsConvenienceInitializers": true, + "superclassNames": [ + "ObjectiveC.NSObject" + ], + "conformances": [ + { + "kind": "Conformance", + "name": "Equatable", + "printedName": "Equatable", + "usr": "s:SQ", + "mangledName": "$sSQ" + }, + { + "kind": "Conformance", + "name": "Hashable", + "printedName": "Hashable", + "usr": "s:SH", + "mangledName": "$sSH" + }, + { + "kind": "Conformance", + "name": "CVarArg", + "printedName": "CVarArg", + "usr": "s:s7CVarArgP", + "mangledName": "$ss7CVarArgP" + }, + { + "kind": "Conformance", + "name": "_KeyValueCodingAndObservingPublishing", + "printedName": "_KeyValueCodingAndObservingPublishing", + "usr": "s:10Foundation37_KeyValueCodingAndObservingPublishingP", + "mangledName": "$s10Foundation37_KeyValueCodingAndObservingPublishingP" + }, + { + "kind": "Conformance", + "name": "_KeyValueCodingAndObserving", + "printedName": "_KeyValueCodingAndObserving", + "usr": "s:10Foundation27_KeyValueCodingAndObservingP", + "mangledName": "$s10Foundation27_KeyValueCodingAndObservingP" + }, + { + "kind": "Conformance", + "name": "CustomStringConvertible", + "printedName": "CustomStringConvertible", + "usr": "s:s23CustomStringConvertibleP", + "mangledName": "$ss23CustomStringConvertibleP" + }, + { + "kind": "Conformance", + "name": "CustomDebugStringConvertible", + "printedName": "CustomDebugStringConvertible", + "usr": "s:s28CustomDebugStringConvertibleP", + "mangledName": "$ss28CustomDebugStringConvertibleP" + } + ] + }, + { + "kind": "TypeDecl", + "name": "View", + "printedName": "View", + "children": [ + { + "kind": "Function", + "name": "analyticsScreen", + "printedName": "analyticsScreen(name:class:extraParameters:)", + "children": [ + { + "kind": "TypeNominal", + "name": "ModifiedContent", + "printedName": "SwiftUI.ModifiedContent<τ_0_0, FirebaseAnalytics.LoggedAnalyticsModifier>", + "children": [ + { + "kind": "TypeNominal", + "name": "GenericTypeParam", + "printedName": "τ_0_0" + }, + { + "kind": "TypeNominal", + "name": "LoggedAnalyticsModifier", + "printedName": "FirebaseAnalytics.LoggedAnalyticsModifier", + "usr": "s:17FirebaseAnalytics06LoggedB8ModifierV" + } + ], + "usr": "s:7SwiftUI15ModifiedContentV" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "hasDefaultArg": true, + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "Dictionary", + "printedName": "[Swift.String : Any]", + "children": [ + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "ProtocolComposition", + "printedName": "Any" + } + ], + "hasDefaultArg": true, + "usr": "s:SD" + } + ], + "declKind": "Func", + "usr": "s:7SwiftUI4ViewP17FirebaseAnalyticsE15analyticsScreen4name5class15extraParametersQrSS_SSSDySSypGtF", + "mangledName": "$s7SwiftUI4ViewP17FirebaseAnalyticsE15analyticsScreen4name5class15extraParametersQrSS_SSSDySSypGtF", + "moduleName": "FirebaseAnalytics", + "genericSig": "<τ_0_0 where τ_0_0 : SwiftUI.View>", + "sugared_genericSig": "", + "declAttributes": [ + "AccessControl", + "RawDocComment" + ], + "isFromExtension": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Protocol", + "usr": "s:7SwiftUI4ViewP", + "mangledName": "$s7SwiftUI4ViewP", + "moduleName": "SwiftUI", + "genericSig": "<τ_0_0.Body : SwiftUI.View>", + "sugared_genericSig": "", + "intro_Macosx": "10.15", + "intro_iOS": "13.0", + "intro_tvOS": "13.0", + "intro_watchOS": "6.0", + "declAttributes": [ + "TypeEraser", + "Available", + "Available", + "Available", + "Available" + ], + "isExternal": true + } + ], + "json_format_version": 8 + }, + "ConstValues": [ + { + "filePath": "\/Volumes\/google\/src\/cloud\/pdchen\/firebaserelease\/google3\/googlemac\/iPhone\/Firebase\/Analytics\/Sources\/Swift\/Analytics+SwiftUI.swift", + "kind": "StringLiteral", + "offset": 2654, + "length": 6, + "value": "\"View\"" + }, + { + "filePath": "\/Volumes\/google\/src\/cloud\/pdchen\/firebaserelease\/google3\/googlemac\/iPhone\/Firebase\/Analytics\/Sources\/Swift\/Analytics+SwiftUI.swift", + "kind": "Dictionary", + "offset": 2701, + "length": 3, + "value": "[]" + } + ] +} \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-macabi.private.swiftinterface b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-macabi.private.swiftinterface new file mode 100644 index 0000000..6dbbf72 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-macabi.private.swiftinterface @@ -0,0 +1,22 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +// swift-module-flags: -target x86_64-apple-ios13.1-macabi -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name FirebaseAnalytics +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import FirebaseAnalytics +import StoreKit +import Swift +import SwiftUI +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *) +@available(watchOS, unavailable) +extension FirebaseAnalytics.Analytics { + public static func logTransaction(_ transaction: StoreKit.Transaction) +} +@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *) +@available(watchOS, unavailable) +extension SwiftUI.View { + public func analyticsScreen(name: Swift.String, class: Swift.String = "View", extraParameters: [Swift.String : Any] = [:]) -> some SwiftUI.View + +} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-macabi.swiftdoc b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-macabi.swiftdoc new file mode 100644 index 0000000..7cfa677 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-macabi.swiftdoc differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-macabi.swiftinterface b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-macabi.swiftinterface new file mode 100644 index 0000000..6dbbf72 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-macabi.swiftinterface @@ -0,0 +1,22 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +// swift-module-flags: -target x86_64-apple-ios13.1-macabi -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name FirebaseAnalytics +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import FirebaseAnalytics +import StoreKit +import Swift +import SwiftUI +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *) +@available(watchOS, unavailable) +extension FirebaseAnalytics.Analytics { + public static func logTransaction(_ transaction: StoreKit.Transaction) +} +@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *) +@available(watchOS, unavailable) +extension SwiftUI.View { + public func analyticsScreen(name: Swift.String, class: Swift.String = "View", extraParameters: [Swift.String : Any] = [:]) -> some SwiftUI.View + +} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/module.modulemap b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/module.modulemap new file mode 100644 index 0000000..fa10817 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Modules/module.modulemap @@ -0,0 +1,16 @@ +framework module FirebaseAnalytics { +umbrella header "FirebaseAnalytics-umbrella.h" +export * +module * { export * } + link framework "Foundation" + link framework "Security" + link framework "SystemConfiguration" + link framework "UIKit" + link "c++" + link "sqlite3" + link "z" +} +module FirebaseAnalytics.Swift { + header "FirebaseAnalytics-Swift.h" + requires objc +} \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Resources/Info.plist b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Resources/Info.plist new file mode 100644 index 0000000..7f37251 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/A/Resources/Info.plist @@ -0,0 +1,54 @@ + + + + + BuildMachineOSBuild + 23F79 + CFBundleDevelopmentRegion + en + CFBundleExecutable + FirebaseAnalytics + CFBundleIdentifier + org.cocoapods.FirebaseAnalytics + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + FirebaseAnalytics + CFBundlePackageType + FMWK + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 1 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + + DTPlatformName + macosx + DTPlatformVersion + 14.2 + DTSDKBuild + 23C53 + DTSDKName + macosx14.2 + DTXcode + 1520 + DTXcodeBuild + 15C500b + LSMinimumSystemVersion + 10.15 + MinimumOSVersion + 100.0 + UIDeviceFamily + + 2 + + + diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/Current b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/Current new file mode 120000 index 0000000..8c7e5a6 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst/FirebaseAnalytics.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/FirebaseAnalytics b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/FirebaseAnalytics new file mode 100644 index 0000000..98f81db Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/FirebaseAnalytics differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h new file mode 100644 index 0000000..cb1e407 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h @@ -0,0 +1,80 @@ +#import + +#import "FIRAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +/// Provides App Delegate handlers to be used in your App Delegate. +/// +/// To save time integrating Firebase Analytics in an application, Firebase Analytics does not +/// require delegation implementation from the AppDelegate if neither SwiftUI nor UIScene lifecycle +/// is adopted. Instead this is automatically done by Firebase Analytics. Should you choose instead +/// to delegate manually, you can turn off the App Delegate Proxy by adding +/// FirebaseAppDelegateProxyEnabled into your app's Info.plist and setting it to boolean `NO`, and +/// adding the methods in this category to corresponding delegation handlers. +/// +/// To handle Universal Links, you must return `true` in +/// `UIApplicationDelegate.application(_:didFinishLaunchingWithOptions:)`. +@interface FIRAnalytics (AppDelegate) + +/// Handles events related to a URL session that are waiting to be processed. +/// +/// 1. If SwiftUI lifecycle is adopted, call this method from +/// `UIApplicationDelegate.application(_:handleEventsForBackgroundURLSession:completionHandler:)` +/// in your app delegate. +/// +/// 2. If SwiftUI lifecycle is not adopted, Firebase Analytics does not require delegation +/// implementation from the AppDelegate. If you choose instead to delegate manually, you can set +/// FirebaseAppDelegateProxyEnabled to boolean `NO` in your app's Info.plist and call this method +/// from +/// `UIApplicationDelegate.application(_:handleEventsForBackgroundURLSession:completionHandler:)` +/// in your app delegate. +/// +/// @param identifier The identifier of the URL session requiring attention. +/// @param completionHandler The completion handler to call when you finish processing the events. +/// Calling this completion handler lets the system know that your app's user interface is +/// updated and a new snapshot can be taken. ++ (void)handleEventsForBackgroundURLSession:(NSString *)identifier + completionHandler:(nullable void (^)(void))completionHandler; + +/// Handles the event when the app is launched by a URL (custom URL scheme or universal link). +/// +/// 1. If SwiftUI lifecycle is adopted, use `onOpenURL(perform:)` to register a handler and call +/// this method in the handler. +/// +/// 2. If UIScene lifecycle is adopted, call this method from +/// `UISceneDelegate.scene(_:willConnectTo:options:)` and +/// `UISceneDelegate.scene(_:openURLContexts:)` when the URL contexts are available. +/// +/// 3. If neither SwiftUI nor UIScene lifecycle is adopted, Firebase Analytics does not require +/// delegation implementation from the AppDelegate. If you choose instead to delegate manually, you +/// can set FirebaseAppDelegateProxyEnabled to boolean `NO` in your app's Info.plist and call this +/// method from `UIApplicationDelegate.application(_:open:options:)` in your app delegate. +/// +/// @param url The URL resource to open. This resource can be a network resource or a file. ++ (void)handleOpenURL:(NSURL *)url; + +/// Handles the event when the app receives data associated with user activity that includes a +/// Universal Link. +/// +/// 1. If SwiftUI lifecycle is adopted, use `onOpenURL(perform:)` to register a handler and call +/// `Analytics.handleOpen(_:)` instead in the handler. +/// +/// 2. If UIScene lifecycle is adopted, call this method from +/// `UISceneDelegate.scene(_:willConnectTo:options:)` and `UISceneDelegate.scene(_:continue:)` when +/// NSUserActivity is available. See the [Apple +/// doc](https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app) for +/// more details. +/// +/// 3. If neither SwiftUI nor UIScene lifecycle is adopted, Firebase Analytics does not require +/// delegation implementation from the AppDelegate. If you choose instead to delegate manually, you +/// can set FirebaseAppDelegateProxyEnabled to boolean `NO` in your app's Info.plist and call this +/// method from `UIApplication.application(_:continue:restorationHandler:)` in your app delegate. +/// +/// @param userActivity The activity object containing the data associated with the task the user +/// was performing. ++ (void)handleUserActivity:(id)userActivity; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h new file mode 100644 index 0000000..7758390 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h @@ -0,0 +1,51 @@ +#import + +#import "FIRAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +/// The type of consent to set. Supported consent types are `ConsentType.adStorage`, +/// `ConsentType.analyticsStorage`, `ConsentType.adUserData`, and `ConsentType.adPersonalization`. +/// Omitting a type retains its previous status. +typedef NSString *FIRConsentType NS_TYPED_ENUM NS_SWIFT_NAME(ConsentType); + +/// Enables storage (such as device identifiers) related to advertising. +extern FIRConsentType const FIRConsentTypeAdStorage; + +/// Enables storage (such as app identifiers) related to analytics, e.g. visit duration. +extern FIRConsentType const FIRConsentTypeAnalyticsStorage; + +/// Sets consent for sending user data to Google for advertising purposes. +extern FIRConsentType const FIRConsentTypeAdUserData; + +/// Sets consent for personalized advertising. +extern FIRConsentType const FIRConsentTypeAdPersonalization; + +/// The status value of the consent type. Supported statuses are `ConsentStatus.granted` and +/// `ConsentStatus.denied`. +typedef NSString *FIRConsentStatus NS_TYPED_ENUM NS_SWIFT_NAME(ConsentStatus); + +/// Consent status indicating consent is denied. For an overview of which data is sent when consent +/// is denied, see [SDK behavior with consent +/// mode](https://developers.google.com/tag-platform/security/concepts/consent-mode#tag-behavior). +extern FIRConsentStatus const FIRConsentStatusDenied; + +/// Consent status indicating consent is granted. +extern FIRConsentStatus const FIRConsentStatusGranted; + +/// Sets the applicable end user consent state. +@interface FIRAnalytics (Consent) + +/// Sets the applicable end user consent state (e.g. for device identifiers) for this app on this +/// device. Use the consent settings to specify individual consent type values. Settings are +/// persisted across app sessions. By default consent types are set to `ConsentStatus.granted`. +/// +/// @param consentSettings A Dictionary of consent types. Supported consent type keys are +/// `ConsentType.adStorage`, `ConsentType.analyticsStorage`, `ConsentType.adUserData`, and +/// `ConsentType.adPersonalization`. Valid values are `ConsentStatus.granted` and +/// `ConsentStatus.denied`. ++ (void)setConsent:(NSDictionary *)consentSettings; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+OnDevice.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+OnDevice.h new file mode 100644 index 0000000..0bfec88 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+OnDevice.h @@ -0,0 +1,44 @@ +#import + +#import "FIRAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +API_UNAVAILABLE(macCatalyst, macos, tvos, watchos) +@interface FIRAnalytics (OnDevice) + +/// Initiates on-device conversion measurement given a user email address. Requires dependency +/// GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a no-op. +/// @param emailAddress User email address. Include a domain name for all email addresses +/// (e.g. gmail.com or hotmail.co.jp). ++ (void)initiateOnDeviceConversionMeasurementWithEmailAddress:(NSString *)emailAddress + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(emailAddress:)); + +/// Initiates on-device conversion measurement given a phone number in E.164 format. Requires +/// dependency GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a no-op. +/// @param phoneNumber User phone number. Must be in E.164 format, which means it must be +/// limited to a maximum of 15 digits and must include a plus sign (+) prefix and country code +/// with no dashes, parentheses, or spaces. ++ (void)initiateOnDeviceConversionMeasurementWithPhoneNumber:(NSString *)phoneNumber + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(phoneNumber:)); + +/// Initiates on-device conversion measurement given a sha256-hashed user email address. Requires +/// dependency GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a no-op. +/// @param hashedEmailAddress User email address as a UTF8-encoded string normalized and hashed +/// according to the instructions at +/// https://firebase.google.com/docs/tutorials/ads-ios-on-device-measurement/step-3. ++ (void)initiateOnDeviceConversionMeasurementWithHashedEmailAddress:(NSData *)hashedEmailAddress + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(hashedEmailAddress:)); + +/// Initiates on-device conversion measurement given a sha256-hashed phone number in E.164 format. +/// Requires dependency GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a +/// no-op. +/// @param hashedPhoneNumber UTF8-encoded user phone number in E.164 format and then hashed +/// according to the instructions at +/// https://firebase.google.com/docs/tutorials/ads-ios-on-device-measurement/step-3. ++ (void)initiateOnDeviceConversionMeasurementWithHashedPhoneNumber:(NSData *)hashedPhoneNumber + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(hashedPhoneNumber:)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics.h new file mode 100644 index 0000000..e58d7dd --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics.h @@ -0,0 +1,155 @@ +#import + +#import "FIREventNames.h" +#import "FIRParameterNames.h" +#import "FIRUserPropertyNames.h" + +NS_ASSUME_NONNULL_BEGIN + +/// The top level Firebase Analytics singleton that provides methods for logging events and setting +/// user properties. See the developer guides for general +/// information on using Firebase Analytics in your apps. +/// +/// @note The Analytics SDK uses SQLite to persist events and other app-specific data. Calling +/// certain thread-unsafe global SQLite methods like `sqlite3_shutdown()` can result in +/// unexpected crashes at runtime. +NS_SWIFT_NAME(Analytics) +@interface FIRAnalytics : NSObject + +/// Logs an app event. The event can have up to 25 parameters. Events with the same name must have +/// the same parameters. Up to 500 event names are supported. Using predefined events and/or +/// parameters is recommended for optimal reporting. +/// +/// The following event names are reserved and cannot be used: +///
    +///
  • ad_activeview
  • +///
  • ad_click
  • +///
  • ad_exposure
  • +///
  • ad_query
  • +///
  • ad_reward
  • +///
  • adunit_exposure
  • +///
  • app_clear_data
  • +///
  • app_exception
  • +///
  • app_remove
  • +///
  • app_store_refund
  • +///
  • app_store_subscription_cancel
  • +///
  • app_store_subscription_convert
  • +///
  • app_store_subscription_renew
  • +///
  • app_update
  • +///
  • app_upgrade
  • +///
  • dynamic_link_app_open
  • +///
  • dynamic_link_app_update
  • +///
  • dynamic_link_first_open
  • +///
  • error
  • +///
  • firebase_campaign
  • +///
  • first_open
  • +///
  • first_visit
  • +///
  • in_app_purchase
  • +///
  • notification_dismiss
  • +///
  • notification_foreground
  • +///
  • notification_open
  • +///
  • notification_receive
  • +///
  • os_update
  • +///
  • session_start
  • +///
  • session_start_with_rollout
  • +///
  • user_engagement
  • +///
+/// +/// @param name The name of the event. Should contain 1 to 40 alphanumeric characters or +/// underscores. The name must start with an alphabetic character. Some event names are +/// reserved. See FIREventNames.h for the list of reserved event names. The "firebase_", +/// "google_", and "ga_" prefixes are reserved and should not be used. Note that event names are +/// case-sensitive and that logging two events whose names differ only in case will result in +/// two distinct events. To manually log screen view events, use the `screen_view` event name. +/// @param parameters The dictionary of event parameters. Passing `nil` indicates that the event has +/// no parameters. Parameter names can be up to 40 characters long and must start with an +/// alphabetic character and contain only alphanumeric characters and underscores. Only String, +/// Int, and Double parameter types are supported. String parameter values can be up to 100 +/// characters long for standard Google Analytics properties, and up to 500 characters long for +/// Google Analytics 360 properties. The "firebase_", "google_", and "ga_" prefixes are reserved +/// and should not be used for parameter names. ++ (void)logEventWithName:(NSString *)name + parameters:(nullable NSDictionary *)parameters + NS_SWIFT_NAME(logEvent(_:parameters:)); + +/// Sets a user property to a given value. Up to 25 user property names are supported. Once set, +/// user property values persist throughout the app lifecycle and across sessions. +/// +/// The following user property names are reserved and cannot be used: +///
    +///
  • first_open_time
  • +///
  • last_deep_link_referrer
  • +///
  • user_id
  • +///
+/// +/// @param value The value of the user property. Values can be up to 36 characters long. Setting the +/// value to `nil` removes the user property. +/// @param name The name of the user property to set. Should contain 1 to 24 alphanumeric characters +/// or underscores and must start with an alphabetic character. The "firebase_", "google_", and +/// "ga_" prefixes are reserved and should not be used for user property names. ++ (void)setUserPropertyString:(nullable NSString *)value forName:(NSString *)name + NS_SWIFT_NAME(setUserProperty(_:forName:)); + +/// Sets the user ID property. This feature must be used in accordance with +/// Google's Privacy Policy +/// +/// @param userID The user ID to ascribe to the user of this app on this device, which must be +/// non-empty and no more than 256 characters long. Setting userID to `nil` removes the user ID. ++ (void)setUserID:(nullable NSString *)userID; + +/// Sets whether analytics collection is enabled for this app on this device. This setting is +/// persisted across app sessions. By default it is enabled. +/// +/// @param analyticsCollectionEnabled A flag that enables or disables Analytics collection. ++ (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled; + +/// Sets the interval of inactivity in seconds that terminates the current session. The default +/// value is 1800 seconds (30 minutes). +/// +/// @param sessionTimeoutInterval The custom time of inactivity in seconds before the current +/// session terminates. ++ (void)setSessionTimeoutInterval:(NSTimeInterval)sessionTimeoutInterval; + +/// Asynchronously retrieves the identifier of the current app session. +/// +/// The session ID retrieval could fail due to Analytics collection disabled, app session expired, +/// etc. +/// +/// @param completion The completion handler to call when the session ID retrieval is complete. This +/// handler is executed on a system-defined global concurrent queue. +/// This completion handler takes the following parameters: +/// sessionID The identifier of the current app session. The value is undefined if the +/// request failed. +/// error An error object that indicates why the request failed, or `nil` if the request +/// was successful. ++ (void)sessionIDWithCompletion:(void (^)(int64_t sessionID, NSError *_Nullable error))completion; + +/// Returns the unique ID for this instance of the application or `nil` if +/// `ConsentType.analyticsStorage` has been set to `ConsentStatus.denied`. +/// +/// @see `FIRAnalytics+Consent.h` ++ (nullable NSString *)appInstanceID; + +/// Clears all analytics data for this instance from the device and resets the app instance ID. ++ (void)resetAnalyticsData; + +/// Adds parameters that will be set on every event logged from the SDK, including automatic ones. +/// The values passed in the parameters dictionary will be added to the dictionary of default event +/// parameters. These parameters persist across app runs. They are of lower precedence than event +/// parameters, so if an event parameter and a parameter set using this API have the same name, the +/// value of the event parameter will be used. The same limitations on event parameters apply to +/// default event parameters. +/// +/// @param parameters Parameters to be added to the dictionary of parameters added to every event. +/// They will be added to the dictionary of default event parameters, replacing any existing +/// parameter with the same name. Valid parameters are String, Int, and Double. Setting a key's +/// value to `NSNull()` will clear that parameter. Passing in a `nil` dictionary will clear all +/// parameters. ++ (void)setDefaultEventParameters:(nullable NSDictionary *)parameters; + +/// Unavailable. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIREventNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIREventNames.h new file mode 100644 index 0000000..1e69a44 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIREventNames.h @@ -0,0 +1,418 @@ +/// @file FIREventNames.h +/// +/// Predefined event names. +/// +/// An Event is an important occurrence in your app that you want to measure. You can report up to +/// 500 different types of Events per app and you can associate up to 25 unique parameters with each +/// Event type. Some common events are suggested below, but you may also choose to specify custom +/// Event types that are associated with your specific app. Each event type is identified by a +/// unique name. Event names can be up to 40 characters long, may only contain alphanumeric +/// characters and underscores ("_"), and must start with an alphabetic character. The "firebase_", +/// "google_", and "ga_" prefixes are reserved and should not be used. + +#import + +/// Ad Impression event. This event signifies when a user sees an ad impression. Note: If you supply +/// the @c AnalyticsParameterValue parameter, you must also supply the @c AnalyticsParameterCurrency +/// parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterAdPlatform (String) (optional)
  • +///
  • @c AnalyticsParameterAdFormat (String) (optional)
  • +///
  • @c AnalyticsParameterAdSource (String) (optional)
  • +///
  • @c AnalyticsParameterAdUnitName (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAdImpression NS_SWIFT_NAME(AnalyticsEventAdImpression) = + @"ad_impression"; + +/// Add Payment Info event. This event signifies that a user has submitted their payment +/// information. Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply +/// the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterPaymentType (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddPaymentInfo NS_SWIFT_NAME(AnalyticsEventAddPaymentInfo) = + @"add_payment_info"; + +/// Add Shipping Info event. This event signifies that a user has submitted their shipping +/// information. Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply +/// the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterShippingTier (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddShippingInfo NS_SWIFT_NAME(AnalyticsEventAddShippingInfo) = + @"add_shipping_info"; + +/// E-Commerce Add To Cart event. This event signifies that an item(s) was added to a cart for +/// purchase. Add this event to a funnel with @c AnalyticsEventPurchase to gauge the effectiveness +/// of your checkout process. Note: If you supply the @c AnalyticsParameterValue parameter, you must +/// also supply the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed +/// accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddToCart NS_SWIFT_NAME(AnalyticsEventAddToCart) = @"add_to_cart"; + +/// E-Commerce Add To Wishlist event. This event signifies that an item was added to a wishlist. Use +/// this event to identify popular gift items. Note: If you supply the @c AnalyticsParameterValue +/// parameter, you must also supply the @c AnalyticsParameterCurrency parameter so that revenue +/// metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddToWishlist NS_SWIFT_NAME(AnalyticsEventAddToWishlist) = + @"add_to_wishlist"; + +/// App Open event. By logging this event when an App becomes active, developers can understand how +/// often users leave and return during the course of a Session. Although Sessions are automatically +/// reported, this event can provide further clarification around the continuous engagement of +/// app-users. +static NSString *const kFIREventAppOpen NS_SWIFT_NAME(AnalyticsEventAppOpen) = @"app_open"; + +/// E-Commerce Begin Checkout event. This event signifies that a user has begun the process of +/// checking out. Add this event to a funnel with your @c AnalyticsEventPurchase event to gauge the +/// effectiveness of your checkout process. Note: If you supply the @c AnalyticsParameterValue +/// parameter, you must also supply the @c AnalyticsParameterCurrency parameter so that revenue +/// metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventBeginCheckout NS_SWIFT_NAME(AnalyticsEventBeginCheckout) = + @"begin_checkout"; + +/// Campaign Detail event. Log this event to supply the referral details of a re-engagement +/// campaign. Note: you must supply at least one of the required parameters +/// AnalyticsParameterSource, AnalyticsParameterMedium or AnalyticsParameterCampaign. Params: +/// +///
    +///
  • @c AnalyticsParameterSource (String)
  • +///
  • @c AnalyticsParameterMedium (String)
  • +///
  • @c AnalyticsParameterCampaign (String)
  • +///
  • @c AnalyticsParameterTerm (String) (optional)
  • +///
  • @c AnalyticsParameterContent (String) (optional)
  • +///
  • @c AnalyticsParameterAdNetworkClickID (String) (optional)
  • +///
  • @c AnalyticsParameterCP1 (String) (optional)
  • +///
  • @c AnalyticsParameterCampaignID (String) (optional)
  • +///
  • @c AnalyticsParameterCreativeFormat (String) (optional)
  • +///
  • @c AnalyticsParameterMarketingTactic (String) (optional)
  • +///
  • @c AnalyticsParameterSourcePlatform (String) (optional)
  • +///
+static NSString *const kFIREventCampaignDetails NS_SWIFT_NAME(AnalyticsEventCampaignDetails) = + @"campaign_details"; + +/// Earn Virtual Currency event. This event tracks the awarding of virtual currency in your app. Log +/// this along with @c AnalyticsEventSpendVirtualCurrency to better understand your virtual economy. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterVirtualCurrencyName (String)
  • +///
  • @c AnalyticsParameterValue (Int or Double)
  • +///
+static NSString *const kFIREventEarnVirtualCurrency + NS_SWIFT_NAME(AnalyticsEventEarnVirtualCurrency) = @"earn_virtual_currency"; + +/// Generate Lead event. Log this event when a lead has been generated in the app to understand the +/// efficacy of your install and re-engagement campaigns. Note: If you supply the +/// @c AnalyticsParameterValue parameter, you must also supply the @c AnalyticsParameterCurrency +/// parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventGenerateLead NS_SWIFT_NAME(AnalyticsEventGenerateLead) = + @"generate_lead"; + +/// Join Group event. Log this event when a user joins a group such as a guild, team or family. Use +/// this event to analyze how popular certain groups or social features are in your app. Params: +/// +///
    +///
  • @c AnalyticsParameterGroupID (String)
  • +///
+static NSString *const kFIREventJoinGroup NS_SWIFT_NAME(AnalyticsEventJoinGroup) = @"join_group"; + +/// Level End event. Log this event when the user finishes a level. Params: +/// +///
    +///
  • @c AnalyticsParameterLevelName (String)
  • +///
  • @c AnalyticsParameterSuccess (String)
  • +///
+static NSString *const kFIREventLevelEnd NS_SWIFT_NAME(AnalyticsEventLevelEnd) = @"level_end"; + +/// Level Start event. Log this event when the user starts a new level. Params: +/// +///
    +///
  • @c AnalyticsParameterLevelName (String)
  • +///
+static NSString *const kFIREventLevelStart NS_SWIFT_NAME(AnalyticsEventLevelStart) = @"level_start"; + +/// Level Up event. This event signifies that a player has leveled up in your gaming app. It can +/// help you gauge the level distribution of your userbase and help you identify certain levels that +/// are difficult to pass. Params: +/// +///
    +///
  • @c AnalyticsParameterLevel (Int)
  • +///
  • @c AnalyticsParameterCharacter (String) (optional)
  • +///
+static NSString *const kFIREventLevelUp NS_SWIFT_NAME(AnalyticsEventLevelUp) = @"level_up"; + +/// Login event. Apps with a login feature can report this event to signify that a user has logged +/// in. +static NSString *const kFIREventLogin NS_SWIFT_NAME(AnalyticsEventLogin) = @"login"; + +/// Post Score event. Log this event when the user posts a score in your gaming app. This event can +/// help you understand how users are actually performing in your game and it can help you correlate +/// high scores with certain audiences or behaviors. Params: +/// +///
    +///
  • @c AnalyticsParameterScore (Int)
  • +///
  • @c AnalyticsParameterLevel (Int) (optional)
  • +///
  • @c AnalyticsParameterCharacter (String) (optional)
  • +///
+static NSString *const kFIREventPostScore NS_SWIFT_NAME(AnalyticsEventPostScore) = @"post_score"; + +/// E-Commerce Purchase event. This event signifies that an item(s) was purchased by a user. Note: +/// This is different from the in-app purchase event, which is reported automatically for App +/// Store-based apps. Note: If you supply the @c AnalyticsParameterValue parameter, you must also +/// supply the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed +/// accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterAffiliation (String) (optional)
  • +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterEndDate (String) (optional)
  • +///
  • @c AnalyticsParameterItemID (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterShipping (Double) (optional)
  • +///
  • @c AnalyticsParameterStartDate (String) (optional)
  • +///
  • @c AnalyticsParameterTax (Double) (optional)
  • +///
  • @c AnalyticsParameterTransactionID (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventPurchase NS_SWIFT_NAME(AnalyticsEventPurchase) = @"purchase"; + +/// E-Commerce Refund event. This event signifies that a refund was issued. Note: If you supply the +/// @c AnalyticsParameterValue parameter, you must also supply the @c AnalyticsParameterCurrency +/// parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterAffiliation (String) (optional)
  • +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterShipping (Double) (optional)
  • +///
  • @c AnalyticsParameterTax (Double) (optional)
  • +///
  • @c AnalyticsParameterTransactionID (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventRefund NS_SWIFT_NAME(AnalyticsEventRefund) = @"refund"; + +/// E-Commerce Remove from Cart event. This event signifies that an item(s) was removed from a cart. +/// Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply the @c +/// AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventRemoveFromCart NS_SWIFT_NAME(AnalyticsEventRemoveFromCart) = + @"remove_from_cart"; + +/// Screen View event. This event signifies a screen view. Use this when a screen transition occurs. +/// This event can be logged irrespective of whether automatic screen tracking is enabled. Params: +/// +///
    +///
  • @c AnalyticsParameterScreenClass (String) (optional)
  • +///
  • @c AnalyticsParameterScreenName (String) (optional)
  • +///
+static NSString *const kFIREventScreenView NS_SWIFT_NAME(AnalyticsEventScreenView) = @"screen_view"; + +/// Search event. Apps that support search features can use this event to contextualize search +/// operations by supplying the appropriate, corresponding parameters. This event can help you +/// identify the most popular content in your app. Params: +/// +///
    +///
  • @c AnalyticsParameterSearchTerm (String)
  • +///
  • @c AnalyticsParameterStartDate (String) (optional)
  • +///
  • @c AnalyticsParameterEndDate (String) (optional)
  • +///
  • @c AnalyticsParameterNumberOfNights (Int) (optional) for hotel bookings
  • +///
  • @c AnalyticsParameterNumberOfRooms (Int) (optional) for hotel bookings
  • +///
  • @c AnalyticsParameterNumberOfPassengers (Int) (optional) for travel bookings
  • +///
  • @c AnalyticsParameterOrigin (String) (optional)
  • +///
  • @c AnalyticsParameterDestination (String) (optional)
  • +///
  • @c AnalyticsParameterTravelClass (String) (optional) for travel bookings
  • +///
+static NSString *const kFIREventSearch NS_SWIFT_NAME(AnalyticsEventSearch) = @"search"; + +/// Select Content event. This general purpose event signifies that a user has selected some content +/// of a certain type in an app. The content can be any object in your app. This event can help you +/// identify popular content and categories of content in your app. Params: +/// +///
    +///
  • @c AnalyticsParameterContentType (String)
  • +///
  • @c AnalyticsParameterItemID (String)
  • +///
+static NSString *const kFIREventSelectContent NS_SWIFT_NAME(AnalyticsEventSelectContent) = + @"select_content"; + +/// Select Item event. This event signifies that an item was selected by a user from a list. Use the +/// appropriate parameters to contextualize the event. Use this event to discover the most popular +/// items selected. Params: +/// +///
    +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterItemListID (String) (optional)
  • +///
  • @c AnalyticsParameterItemListName (String) (optional)
  • +///
+static NSString *const kFIREventSelectItem NS_SWIFT_NAME(AnalyticsEventSelectItem) = @"select_item"; + +/// Select promotion event. This event signifies that a user has selected a promotion offer. Use the +/// appropriate parameters to contextualize the event, such as the item(s) for which the promotion +/// applies. Params: +/// +///
    +///
  • @c AnalyticsParameterCreativeName (String) (optional)
  • +///
  • @c AnalyticsParameterCreativeSlot (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterLocationID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionName (String) (optional)
  • +///
+static NSString *const kFIREventSelectPromotion NS_SWIFT_NAME(AnalyticsEventSelectPromotion) = + @"select_promotion"; + +/// Share event. Apps with social features can log the Share event to identify the most viral +/// content. Params: +/// +///
    +///
  • @c AnalyticsParameterContentType (String)
  • +///
  • @c AnalyticsParameterItemID (String)
  • +///
+static NSString *const kFIREventShare NS_SWIFT_NAME(AnalyticsEventShare) = @"share"; + +/// Sign Up event. This event indicates that a user has signed up for an account in your app. The +/// parameter signifies the method by which the user signed up. Use this event to understand the +/// different behaviors between logged in and logged out users. Params: +/// +///
    +///
  • @c AnalyticsParameterMethod (String)
  • +///
+static NSString *const kFIREventSignUp NS_SWIFT_NAME(AnalyticsEventSignUp) = @"sign_up"; + +/// Spend Virtual Currency event. This event tracks the sale of virtual goods in your app and can +/// help you identify which virtual goods are the most popular objects of purchase. Params: +/// +///
    +///
  • @c AnalyticsParameterItemName (String)
  • +///
  • @c AnalyticsParameterVirtualCurrencyName (String)
  • +///
  • @c AnalyticsParameterValue (Int or Double)
  • +///
+static NSString *const kFIREventSpendVirtualCurrency + NS_SWIFT_NAME(AnalyticsEventSpendVirtualCurrency) = @"spend_virtual_currency"; + +/// Tutorial Begin event. This event signifies the start of the on-boarding process in your app. Use +/// this in a funnel with @c AnalyticsEventTutorialComplete to understand how many users complete +/// this process and move on to the full app experience. +static NSString *const kFIREventTutorialBegin NS_SWIFT_NAME(AnalyticsEventTutorialBegin) = + @"tutorial_begin"; + +/// Tutorial End event. Use this event to signify the user's completion of your app's on-boarding +/// process. Add this to a funnel with @c AnalyticsEventTutorialBegin to gauge the completion rate +/// of your on-boarding process. +static NSString *const kFIREventTutorialComplete NS_SWIFT_NAME(AnalyticsEventTutorialComplete) = + @"tutorial_complete"; + +/// Unlock Achievement event. Log this event when the user has unlocked an achievement in your +/// game. Since achievements generally represent the breadth of a gaming experience, this event can +/// help you understand how many users are experiencing all that your game has to offer. Params: +/// +///
    +///
  • @c AnalyticsParameterAchievementID (String)
  • +///
+static NSString *const kFIREventUnlockAchievement NS_SWIFT_NAME(AnalyticsEventUnlockAchievement) = + @"unlock_achievement"; + +/// E-commerce View Cart event. This event signifies that a user has viewed their cart. Use this to +/// analyze your purchase funnel. Note: If you supply the @c AnalyticsParameterValue parameter, you +/// must also supply the @c AnalyticsParameterCurrency parameter so that revenue metrics can be +/// computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventViewCart NS_SWIFT_NAME(AnalyticsEventViewCart) = @"view_cart"; + +/// View Item event. This event signifies that a user has viewed an item. Use the appropriate +/// parameters to contextualize the event. Use this event to discover the most popular items viewed +/// in your app. Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply +/// the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventViewItem NS_SWIFT_NAME(AnalyticsEventViewItem) = @"view_item"; + +/// View Item List event. Log this event when a user sees a list of items or offerings. Params: +/// +///
    +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterItemListID (String) (optional)
  • +///
  • @c AnalyticsParameterItemListName (String) (optional)
  • +///
+static NSString *const kFIREventViewItemList NS_SWIFT_NAME(AnalyticsEventViewItemList) = + @"view_item_list"; + +/// View Promotion event. This event signifies that a promotion was shown to a user. Add this event +/// to a funnel with the @c AnalyticsEventAddToCart and @c AnalyticsEventPurchase to gauge your +/// conversion process. Params: +/// +///
    +///
  • @c AnalyticsParameterCreativeName (String) (optional)
  • +///
  • @c AnalyticsParameterCreativeSlot (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterLocationID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionName (String) (optional)
  • +///
+static NSString *const kFIREventViewPromotion NS_SWIFT_NAME(AnalyticsEventViewPromotion) = + @"view_promotion"; + +/// View Search Results event. Log this event when the user has been presented with the results of a +/// search. Params: +/// +///
    +///
  • @c AnalyticsParameterSearchTerm (String)
  • +///
+static NSString *const kFIREventViewSearchResults NS_SWIFT_NAME(AnalyticsEventViewSearchResults) = + @"view_search_results"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRParameterNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRParameterNames.h new file mode 100644 index 0000000..58a5a21 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRParameterNames.h @@ -0,0 +1,722 @@ +/// @file FIRParameterNames.h +/// +/// Predefined event parameter names. +/// +/// Params supply information that contextualize Events. You can associate up to 25 unique Params +/// with each Event type. Some Params are suggested below for certain common Events, but you are +/// not limited to these. You may supply extra Params for suggested Events or custom Params for +/// Custom events. Param names can be up to 40 characters long, may only contain alphanumeric +/// characters and underscores ("_"), and must start with an alphabetic character. Param values can +/// be up to 100 characters long for standard Google Analytics properties and up to 500 characters +/// long for Google Analytics 360 properties. The "firebase_", "google_", and "ga_" prefixes are +/// reserved and should not be used. + +#import + +/// Game achievement ID (String). +///
+///     let params = [
+///       AnalyticsParameterAchievementID : "10_matches_won",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAchievementID NS_SWIFT_NAME(AnalyticsParameterAchievementID) = + @"achievement_id"; + +/// The ad format (e.g. Banner, Interstitial, Rewarded, Native, Rewarded Interstitial, Instream). +/// (String). +///
+///     let params = [
+///       AnalyticsParameterAdFormat : "Banner",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdFormat NS_SWIFT_NAME(AnalyticsParameterAdFormat) = + @"ad_format"; + +/// Ad Network Click ID (String). Used for network-specific click IDs which vary in format. +///
+///     let params = [
+///       AnalyticsParameterAdNetworkClickID : "1234567",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdNetworkClickID + NS_SWIFT_NAME(AnalyticsParameterAdNetworkClickID) = @"aclid"; + +/// The ad platform (e.g. MoPub, IronSource) (String). +///
+///     let params = [
+///       AnalyticsParameterAdPlatform : "MoPub",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdPlatform NS_SWIFT_NAME(AnalyticsParameterAdPlatform) = + @"ad_platform"; + +/// The ad source (e.g. AdColony) (String). +///
+///     let params = [
+///       AnalyticsParameterAdSource : "AdColony",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdSource NS_SWIFT_NAME(AnalyticsParameterAdSource) = + @"ad_source"; + +/// The ad unit name (e.g. Banner_03) (String). +///
+///     let params = [
+///       AnalyticsParameterAdUnitName : "Banner_03",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdUnitName NS_SWIFT_NAME(AnalyticsParameterAdUnitName) = + @"ad_unit_name"; + +/// A product affiliation to designate a supplying company or brick and mortar store location +/// (String).
+///     let params = [
+///       AnalyticsParameterAffiliation : "Google Store",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAffiliation NS_SWIFT_NAME(AnalyticsParameterAffiliation) = + @"affiliation"; + +/// Campaign custom parameter (String). Used as a method of capturing custom data in a campaign. +/// Use varies by network. +///
+///     let params = [
+///       AnalyticsParameterCP1 : "custom_data",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCP1 NS_SWIFT_NAME(AnalyticsParameterCP1) = @"cp1"; + +/// The individual campaign name, slogan, promo code, etc. Some networks have pre-defined macro to +/// capture campaign information, otherwise can be populated by developer. Highly Recommended +/// (String). +///
+///     let params = [
+///       AnalyticsParameterCampaign : "winter_promotion",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCampaign NS_SWIFT_NAME(AnalyticsParameterCampaign) = + @"campaign"; + +/// Campaign ID (String). Used for keyword analysis to identify a specific product promotion or +/// strategic campaign. This is a required key for GA4 data import. +///
+///     let params = [
+///       AnalyticsParameterCampaignID : "7877652710",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCampaignID NS_SWIFT_NAME(AnalyticsParameterCampaignID) = + @"campaign_id"; + +/// Character used in game (String). +///
+///     let params = [
+///       AnalyticsParameterCharacter : "beat_boss",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCharacter NS_SWIFT_NAME(AnalyticsParameterCharacter) = + @"character"; + +/// Campaign content (String). +static NSString *const kFIRParameterContent NS_SWIFT_NAME(AnalyticsParameterContent) = @"content"; + +/// Type of content selected (String). +///
+///     let params = [
+///       AnalyticsParameterContentType : "news article",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterContentType NS_SWIFT_NAME(AnalyticsParameterContentType) = + @"content_type"; + +/// Coupon code used for a purchase (String). +///
+///     let params = [
+///       AnalyticsParameterCoupon : "SUMMER_FUN",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCoupon NS_SWIFT_NAME(AnalyticsParameterCoupon) = @"coupon"; + +/// Creative Format (String). Used to identify the high-level classification of the type of ad +/// served by a specific campaign. +///
+///     let params = [
+///       AnalyticsParameterCreativeFormat : "display",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCreativeFormat NS_SWIFT_NAME(AnalyticsParameterCreativeFormat) = + @"creative_format"; + +/// The name of a creative used in a promotional spot (String). +///
+///     let params = [
+///       AnalyticsParameterCreativeName : "Summer Sale",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCreativeName NS_SWIFT_NAME(AnalyticsParameterCreativeName) = + @"creative_name"; + +/// The name of a creative slot (String). +///
+///     let params = [
+///       AnalyticsParameterCreativeSlot : "summer_banner2",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCreativeSlot NS_SWIFT_NAME(AnalyticsParameterCreativeSlot) = + @"creative_slot"; + +/// Currency of the purchase or items associated with the event, in 3-letter +/// ISO_4217 format (String). +///
+///     let params = [
+///       AnalyticsParameterCurrency : "USD",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCurrency NS_SWIFT_NAME(AnalyticsParameterCurrency) = + @"currency"; + +/// Flight or Travel destination (String). +///
+///     let params = [
+///       AnalyticsParameterDestination : "Mountain View, CA",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterDestination NS_SWIFT_NAME(AnalyticsParameterDestination) = + @"destination"; + +/// Monetary value of discount associated with a purchase (Double). +///
+///     let params = [
+///       AnalyticsParameterDiscount : 2.0,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $2.00 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterDiscount NS_SWIFT_NAME(AnalyticsParameterDiscount) = + @"discount"; + +/// The arrival date, check-out date or rental end date for the item. This should be in +/// YYYY-MM-DD format (String). +///
+///     let params = [
+///       AnalyticsParameterEndDate : "2015-09-14",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterEndDate NS_SWIFT_NAME(AnalyticsParameterEndDate) = @"end_date"; + +/// Indicates that the associated event should either extend the current session or start a new +/// session if no session was active when the event was logged. Specify 1 to extend the current +/// session or to start a new session; any other value will not extend or start a session. +///
+///     let params = [
+///       AnalyticsParameterExtendSession : 1,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterExtendSession NS_SWIFT_NAME(AnalyticsParameterExtendSession) = + @"extend_session"; + +/// Flight number for travel events (String). +///
+///     let params = [
+///       AnalyticsParameterFlightNumber : "ZZ800",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterFlightNumber NS_SWIFT_NAME(AnalyticsParameterFlightNumber) = + @"flight_number"; + +/// Group/clan/guild ID (String). +///
+///     let params = [
+///       AnalyticsParameterGroupID : "g1",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterGroupID NS_SWIFT_NAME(AnalyticsParameterGroupID) = @"group_id"; + +/// The index of the item in a list (Int). +///
+///     let params = [
+///       AnalyticsParameterIndex : 5,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterIndex NS_SWIFT_NAME(AnalyticsParameterIndex) = @"index"; + +/// Item brand (String). +///
+///     let params = [
+///       AnalyticsParameterItemBrand : "Google",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemBrand NS_SWIFT_NAME(AnalyticsParameterItemBrand) = + @"item_brand"; + +/// Item category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory NS_SWIFT_NAME(AnalyticsParameterItemCategory) = + @"item_category"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory2 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory2 NS_SWIFT_NAME(AnalyticsParameterItemCategory2) = + @"item_category2"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory3 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory3 NS_SWIFT_NAME(AnalyticsParameterItemCategory3) = + @"item_category3"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory4 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory4 NS_SWIFT_NAME(AnalyticsParameterItemCategory4) = + @"item_category4"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory5 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory5 NS_SWIFT_NAME(AnalyticsParameterItemCategory5) = + @"item_category5"; + +/// Item ID (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemID : "SKU_12345",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemID NS_SWIFT_NAME(AnalyticsParameterItemID) = @"item_id"; + +/// The ID of the list in which the item was presented to the user (String). +///
+///     let params = [
+///       AnalyticsParameterItemListID : "ABC123",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemListID NS_SWIFT_NAME(AnalyticsParameterItemListID) = + @"item_list_id"; + +/// The name of the list in which the item was presented to the user (String). +///
+///     let params = [
+///       AnalyticsParameterItemListName : "Related products",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemListName NS_SWIFT_NAME(AnalyticsParameterItemListName) = + @"item_list_name"; + +/// Item Name (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemName : "jeggings",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemName NS_SWIFT_NAME(AnalyticsParameterItemName) = + @"item_name"; + +/// Item variant (String). +///
+///     let params = [
+///       AnalyticsParameterItemVariant : "Black",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemVariant NS_SWIFT_NAME(AnalyticsParameterItemVariant) = + @"item_variant"; + +/// The list of items involved in the transaction expressed as `[[String: Any]]`. +///
+///     let params = [
+///       AnalyticsParameterItems : [
+///         [AnalyticsParameterItemName : "jeggings", AnalyticsParameterItemCategory : "pants"],
+///         [AnalyticsParameterItemName : "boots", AnalyticsParameterItemCategory : "shoes"],
+///       ],
+///     ]
+/// 
+static NSString *const kFIRParameterItems NS_SWIFT_NAME(AnalyticsParameterItems) = @"items"; + +/// Level in game (Int). +///
+///     let params = [
+///       AnalyticsParameterLevel : 42,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLevel NS_SWIFT_NAME(AnalyticsParameterLevel) = @"level"; + +/// The name of a level in a game (String). +///
+///     let params = [
+///       AnalyticsParameterLevelName : "room_1",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLevelName NS_SWIFT_NAME(AnalyticsParameterLevelName) = + @"level_name"; + +/// Location (String). The Google Place ID +/// that corresponds to the associated event. Alternatively, you can supply your own custom +/// Location ID. +///
+///     let params = [
+///       AnalyticsParameterLocation : "ChIJiyj437sx3YAR9kUWC8QkLzQ",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLocation NS_SWIFT_NAME(AnalyticsParameterLocation) = + @"location"; + +/// The location associated with the event. Preferred to be the Google +/// Place ID that corresponds to the +/// associated item but could be overridden to a custom location ID string.(String). +///
+///     let params = [
+///       AnalyticsParameterLocationID : "ChIJiyj437sx3YAR9kUWC8QkLzQ",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLocationID NS_SWIFT_NAME(AnalyticsParameterLocationID) = + @"location_id"; + +/// Marketing Tactic (String). Used to identify the targeting criteria applied to a specific +/// campaign. +///
+///     let params = [
+///       AnalyticsParameterMarketingTactic : "Remarketing",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterMarketingTactic + NS_SWIFT_NAME(AnalyticsParameterMarketingTactic) = @"marketing_tactic"; + +/// The advertising or marketing medium, for example: cpc, banner, email, push. Highly recommended +/// (String). +///
+///     let params = [
+///       AnalyticsParameterMedium : "email",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterMedium NS_SWIFT_NAME(AnalyticsParameterMedium) = @"medium"; + +/// A particular approach used in an operation; for example, "facebook" or "email" in the context +/// of a sign_up or login event. (String). +///
+///     let params = [
+///       AnalyticsParameterMethod : "google",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterMethod NS_SWIFT_NAME(AnalyticsParameterMethod) = @"method"; + +/// Number of nights staying at hotel (Int). +///
+///     let params = [
+///       AnalyticsParameterNumberOfNights : 3,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterNumberOfNights + NS_SWIFT_NAME(AnalyticsParameterNumberOfNights) = @"number_of_nights"; + +/// Number of passengers traveling (Int). +///
+///     let params = [
+///       AnalyticsParameterNumberOfPassengers : 11,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterNumberOfPassengers + NS_SWIFT_NAME(AnalyticsParameterNumberOfPassengers) = @"number_of_passengers"; + +/// Number of rooms for travel events (Int). +///
+///     let params = [
+///       AnalyticsParameterNumberOfRooms : 2,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterNumberOfRooms NS_SWIFT_NAME(AnalyticsParameterNumberOfRooms) = + @"number_of_rooms"; + +/// Flight or Travel origin (String). +///
+///     let params = [
+///       AnalyticsParameterOrigin : "Mountain View, CA",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterOrigin NS_SWIFT_NAME(AnalyticsParameterOrigin) = @"origin"; + +/// The chosen method of payment (String). +///
+///     let params = [
+///       AnalyticsParameterPaymentType : "Visa",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPaymentType NS_SWIFT_NAME(AnalyticsParameterPaymentType) = + @"payment_type"; + +/// Purchase price (Double). +///
+///     let params = [
+///       AnalyticsParameterPrice : 1.0,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $1.00 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPrice NS_SWIFT_NAME(AnalyticsParameterPrice) = @"price"; + +/// The ID of a product promotion (String). +///
+///     let params = [
+///       AnalyticsParameterPromotionID : "ABC123",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPromotionID NS_SWIFT_NAME(AnalyticsParameterPromotionID) = + @"promotion_id"; + +/// The name of a product promotion (String). +///
+///     let params = [
+///       AnalyticsParameterPromotionName : "Summer Sale",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPromotionName NS_SWIFT_NAME(AnalyticsParameterPromotionName) = + @"promotion_name"; + +/// Purchase quantity (Int). +///
+///     let params = [
+///       AnalyticsParameterQuantity : 1,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterQuantity NS_SWIFT_NAME(AnalyticsParameterQuantity) = + @"quantity"; + +/// Score in game (Int). +///
+///     let params = [
+///       AnalyticsParameterScore : 4200,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterScore NS_SWIFT_NAME(AnalyticsParameterScore) = @"score"; + +/// Current screen class, such as the class name of the UIViewController, logged with screen_view +/// event and added to every event (String). +///
+///     let params = [
+///       AnalyticsParameterScreenClass : "LoginViewController",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterScreenClass NS_SWIFT_NAME(AnalyticsParameterScreenClass) = + @"screen_class"; + +/// Current screen name, such as the name of the UIViewController, logged with screen_view event and +/// added to every event (String). +///
+///     let params = [
+///       AnalyticsParameterScreenName : "LoginView",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterScreenName NS_SWIFT_NAME(AnalyticsParameterScreenName) = + @"screen_name"; + +/// The search string/keywords used (String). +///
+///     let params = [
+///       AnalyticsParameterSearchTerm : "periodic table",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSearchTerm NS_SWIFT_NAME(AnalyticsParameterSearchTerm) = + @"search_term"; + +/// Shipping cost associated with a transaction (Double). +///
+///     let params = [
+///       AnalyticsParameterShipping : 5.99,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $5.99 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterShipping NS_SWIFT_NAME(AnalyticsParameterShipping) = + @"shipping"; + +/// The shipping tier (e.g. Ground, Air, Next-day) selected for delivery of the purchased item +/// (String). +///
+///     let params = [
+///       AnalyticsParameterShippingTier : "Ground",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterShippingTier NS_SWIFT_NAME(AnalyticsParameterShippingTier) = + @"shipping_tier"; + +/// The origin of your traffic, such as an Ad network (for example, google) or partner (urban +/// airship). Identify the advertiser, site, publication, etc. that is sending traffic to your +/// property. Highly recommended (String). +///
+///     let params = [
+///       AnalyticsParameterSource : "InMobi",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSource NS_SWIFT_NAME(AnalyticsParameterSource) = @"source"; + +/// Source Platform (String). Used to identify the platform responsible for directing traffic to a +/// given Analytics property (e.g., a buying platform where budgets, targeting criteria, etc. are +/// set, a platform for managing organic traffic data, etc.). +///
+///     let params = [
+///       AnalyticsParameterSourcePlatform : "sa360",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSourcePlatform NS_SWIFT_NAME(AnalyticsParameterSourcePlatform) = + @"source_platform"; + +/// The departure date, check-in date or rental start date for the item. This should be in +/// YYYY-MM-DD format (String). +///
+///     let params = [
+///       AnalyticsParameterStartDate : "2015-09-14",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterStartDate NS_SWIFT_NAME(AnalyticsParameterStartDate) = + @"start_date"; + +/// The result of an operation. Specify 1 to indicate success and 0 to indicate failure (Int). +///
+///     let params = [
+///       AnalyticsParameterSuccess : 1,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSuccess NS_SWIFT_NAME(AnalyticsParameterSuccess) = @"success"; + +/// Tax cost associated with a transaction (Double). +///
+///     let params = [
+///       AnalyticsParameterTax : 2.43,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $2.43 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTax NS_SWIFT_NAME(AnalyticsParameterTax) = @"tax"; + +/// If you're manually tagging keyword campaigns, you should use utm_term to specify the keyword +/// (String). +///
+///     let params = [
+///       AnalyticsParameterTerm : "game",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTerm NS_SWIFT_NAME(AnalyticsParameterTerm) = @"term"; + +/// The unique identifier of a transaction (String). +///
+///     let params = [
+///       AnalyticsParameterTransactionID : "T12345",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTransactionID NS_SWIFT_NAME(AnalyticsParameterTransactionID) = + @"transaction_id"; + +/// Travel class (String). +///
+///     let params = [
+///       AnalyticsParameterTravelClass : "business",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTravelClass NS_SWIFT_NAME(AnalyticsParameterTravelClass) = + @"travel_class"; + +/// A context-specific numeric value which is accumulated automatically for each event type. This is +/// a general purpose parameter that is useful for accumulating a key metric that pertains to an +/// event. Examples include revenue, distance, time and points. Value should be specified as Int or +/// Double. +/// Notes: Values for pre-defined currency-related events (such as @c AnalyticsEventAddToCart) +/// should be supplied using Double and must be accompanied by a @c AnalyticsParameterCurrency +/// parameter. The valid range of accumulated values is +/// [-9,223,372,036,854.77, 9,223,372,036,854.77]. Supplying a non-numeric value, omitting the +/// corresponding @c AnalyticsParameterCurrency parameter, or supplying an invalid +/// currency code for conversion events will cause that +/// conversion to be omitted from reporting. +///
+///     let params = [
+///       AnalyticsParameterValue : 3.99,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $3.99 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterValue NS_SWIFT_NAME(AnalyticsParameterValue) = @"value"; + +/// Name of virtual currency type (String). +///
+///     let params = [
+///       AnalyticsParameterVirtualCurrencyName : "virtual_currency_name",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterVirtualCurrencyName + NS_SWIFT_NAME(AnalyticsParameterVirtualCurrencyName) = @"virtual_currency_name"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h new file mode 100644 index 0000000..2442d8a --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h @@ -0,0 +1,28 @@ +/// @file FIRUserPropertyNames.h +/// +/// Predefined user property names. +/// +/// A UserProperty is an attribute that describes the app-user. By supplying UserProperties, you can +/// later analyze different behaviors of various segments of your userbase. You may supply up to 25 +/// unique UserProperties per app, and you can use the name and value of your choosing for each one. +/// UserProperty names can be up to 24 characters long, may only contain alphanumeric characters and +/// underscores ("_"), and must start with an alphabetic character. UserProperty values can be up to +/// 36 characters long. The "firebase_", "google_", and "ga_" prefixes are reserved and should not +/// be used. + +#import + +/// Indicates whether events logged by Google Analytics can be used to personalize ads for the user. +/// Set to "YES" to enable, or "NO" to disable. Default is enabled. See the +/// documentation for +/// more details and information about related settings. +/// +///
+///     Analytics.setUserProperty("NO", forName: AnalyticsUserPropertyAllowAdPersonalizationSignals)
+/// 
+static NSString *const kFIRUserPropertyAllowAdPersonalizationSignals + NS_SWIFT_NAME(AnalyticsUserPropertyAllowAdPersonalizationSignals) = @"allow_personalized_ads"; + +/// The method used to sign in. For example, "google", "facebook" or "twitter". +static NSString *const kFIRUserPropertySignUpMethod + NS_SWIFT_NAME(AnalyticsUserPropertySignUpMethod) = @"sign_up_method"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-Swift.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-Swift.h new file mode 100644 index 0000000..3dbf01a --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-Swift.h @@ -0,0 +1,620 @@ +#if 0 +#elif defined(__arm64__) && __arm64__ +// Generated by Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +#ifndef FIREBASEANALYTICS_SWIFT_H +#define FIREBASEANALYTICS_SWIFT_H +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgcc-compat" + +#if !defined(__has_include) +# define __has_include(x) 0 +#endif +#if !defined(__has_attribute) +# define __has_attribute(x) 0 +#endif +#if !defined(__has_feature) +# define __has_feature(x) 0 +#endif +#if !defined(__has_warning) +# define __has_warning(x) 0 +#endif + +#if __has_include() +# include +#endif + +#pragma clang diagnostic ignored "-Wauto-import" +#if defined(__OBJC__) +#include +#endif +#if defined(__cplusplus) +#include +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#endif +#if defined(__cplusplus) +#if defined(__arm64e__) && __has_include() +# include +#else +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreserved-macro-identifier" +# ifndef __ptrauth_swift_value_witness_function_pointer +# define __ptrauth_swift_value_witness_function_pointer(x) +# endif +# ifndef __ptrauth_swift_class_method_pointer +# define __ptrauth_swift_class_method_pointer(x) +# endif +#pragma clang diagnostic pop +#endif +#endif + +#if !defined(SWIFT_TYPEDEFS) +# define SWIFT_TYPEDEFS 1 +# if __has_include() +# include +# elif !defined(__cplusplus) +typedef uint_least16_t char16_t; +typedef uint_least32_t char32_t; +# endif +typedef float swift_float2 __attribute__((__ext_vector_type__(2))); +typedef float swift_float3 __attribute__((__ext_vector_type__(3))); +typedef float swift_float4 __attribute__((__ext_vector_type__(4))); +typedef double swift_double2 __attribute__((__ext_vector_type__(2))); +typedef double swift_double3 __attribute__((__ext_vector_type__(3))); +typedef double swift_double4 __attribute__((__ext_vector_type__(4))); +typedef int swift_int2 __attribute__((__ext_vector_type__(2))); +typedef int swift_int3 __attribute__((__ext_vector_type__(3))); +typedef int swift_int4 __attribute__((__ext_vector_type__(4))); +typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2))); +typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3))); +typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); +#endif + +#if !defined(SWIFT_PASTE) +# define SWIFT_PASTE_HELPER(x, y) x##y +# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) +#endif +#if !defined(SWIFT_METATYPE) +# define SWIFT_METATYPE(X) Class +#endif +#if !defined(SWIFT_CLASS_PROPERTY) +# if __has_feature(objc_class_property) +# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__ +# else +# define SWIFT_CLASS_PROPERTY(...) +# endif +#endif +#if !defined(SWIFT_RUNTIME_NAME) +# if __has_attribute(objc_runtime_name) +# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) +# else +# define SWIFT_RUNTIME_NAME(X) +# endif +#endif +#if !defined(SWIFT_COMPILE_NAME) +# if __has_attribute(swift_name) +# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) +# else +# define SWIFT_COMPILE_NAME(X) +# endif +#endif +#if !defined(SWIFT_METHOD_FAMILY) +# if __has_attribute(objc_method_family) +# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X))) +# else +# define SWIFT_METHOD_FAMILY(X) +# endif +#endif +#if !defined(SWIFT_NOESCAPE) +# if __has_attribute(noescape) +# define SWIFT_NOESCAPE __attribute__((noescape)) +# else +# define SWIFT_NOESCAPE +# endif +#endif +#if !defined(SWIFT_RELEASES_ARGUMENT) +# if __has_attribute(ns_consumed) +# define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed)) +# else +# define SWIFT_RELEASES_ARGUMENT +# endif +#endif +#if !defined(SWIFT_WARN_UNUSED_RESULT) +# if __has_attribute(warn_unused_result) +# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +# else +# define SWIFT_WARN_UNUSED_RESULT +# endif +#endif +#if !defined(SWIFT_NORETURN) +# if __has_attribute(noreturn) +# define SWIFT_NORETURN __attribute__((noreturn)) +# else +# define SWIFT_NORETURN +# endif +#endif +#if !defined(SWIFT_CLASS_EXTRA) +# define SWIFT_CLASS_EXTRA +#endif +#if !defined(SWIFT_PROTOCOL_EXTRA) +# define SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_ENUM_EXTRA) +# define SWIFT_ENUM_EXTRA +#endif +#if !defined(SWIFT_CLASS) +# if __has_attribute(objc_subclassing_restricted) +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# else +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# endif +#endif +#if !defined(SWIFT_RESILIENT_CLASS) +# if __has_attribute(objc_class_stub) +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub)) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME) +# else +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME) +# endif +#endif +#if !defined(SWIFT_PROTOCOL) +# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_EXTENSION) +# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) +#endif +#if !defined(OBJC_DESIGNATED_INITIALIZER) +# if __has_attribute(objc_designated_initializer) +# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +# else +# define OBJC_DESIGNATED_INITIALIZER +# endif +#endif +#if !defined(SWIFT_ENUM_ATTR) +# if __has_attribute(enum_extensibility) +# define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility))) +# else +# define SWIFT_ENUM_ATTR(_extensibility) +# endif +#endif +#if !defined(SWIFT_ENUM) +# define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# if __has_feature(generalized_swift_name) +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# else +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility) +# endif +#endif +#if !defined(SWIFT_UNAVAILABLE) +# define SWIFT_UNAVAILABLE __attribute__((unavailable)) +#endif +#if !defined(SWIFT_UNAVAILABLE_MSG) +# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg))) +#endif +#if !defined(SWIFT_AVAILABILITY) +# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__))) +#endif +#if !defined(SWIFT_WEAK_IMPORT) +# define SWIFT_WEAK_IMPORT __attribute__((weak_import)) +#endif +#if !defined(SWIFT_DEPRECATED) +# define SWIFT_DEPRECATED __attribute__((deprecated)) +#endif +#if !defined(SWIFT_DEPRECATED_MSG) +# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__))) +#endif +#if !defined(SWIFT_DEPRECATED_OBJC) +# if __has_feature(attribute_diagnose_if_objc) +# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning"))) +# else +# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) +# endif +#endif +#if defined(__OBJC__) +#if !defined(IBSegueAction) +# define IBSegueAction +#endif +#endif +#if !defined(SWIFT_EXTERN) +# if defined(__cplusplus) +# define SWIFT_EXTERN extern "C" +# else +# define SWIFT_EXTERN extern +# endif +#endif +#if !defined(SWIFT_CALL) +# define SWIFT_CALL __attribute__((swiftcall)) +#endif +#if !defined(SWIFT_INDIRECT_RESULT) +# define SWIFT_INDIRECT_RESULT __attribute__((swift_indirect_result)) +#endif +#if !defined(SWIFT_CONTEXT) +# define SWIFT_CONTEXT __attribute__((swift_context)) +#endif +#if !defined(SWIFT_ERROR_RESULT) +# define SWIFT_ERROR_RESULT __attribute__((swift_error_result)) +#endif +#if defined(__cplusplus) +# define SWIFT_NOEXCEPT noexcept +#else +# define SWIFT_NOEXCEPT +#endif +#if !defined(SWIFT_C_INLINE_THUNK) +# if __has_attribute(always_inline) +# if __has_attribute(nodebug) +# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) __attribute__((nodebug)) +# else +# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) +# endif +# else +# define SWIFT_C_INLINE_THUNK inline +# endif +#endif +#if defined(_WIN32) +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL __declspec(dllimport) +#endif +#else +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL +#endif +#endif +#if defined(__OBJC__) +#if __has_feature(objc_modules) +#if __has_warning("-Watimport-in-framework-header") +#pragma clang diagnostic ignored "-Watimport-in-framework-header" +#endif +#endif + +#endif +#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" +#pragma clang diagnostic ignored "-Wduplicate-method-arg" +#if __has_warning("-Wpragma-clang-attribute") +# pragma clang diagnostic ignored "-Wpragma-clang-attribute" +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wnullability" +#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension" + +#if __has_attribute(external_source_symbol) +# pragma push_macro("any") +# undef any +# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="FirebaseAnalytics",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) +# pragma pop_macro("any") +#endif + +#if defined(__OBJC__) + +#endif +#if __has_attribute(external_source_symbol) +# pragma clang attribute pop +#endif +#if defined(__cplusplus) +#endif +#pragma clang diagnostic pop +#endif + +#elif defined(__x86_64__) && __x86_64__ +// Generated by Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +#ifndef FIREBASEANALYTICS_SWIFT_H +#define FIREBASEANALYTICS_SWIFT_H +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgcc-compat" + +#if !defined(__has_include) +# define __has_include(x) 0 +#endif +#if !defined(__has_attribute) +# define __has_attribute(x) 0 +#endif +#if !defined(__has_feature) +# define __has_feature(x) 0 +#endif +#if !defined(__has_warning) +# define __has_warning(x) 0 +#endif + +#if __has_include() +# include +#endif + +#pragma clang diagnostic ignored "-Wauto-import" +#if defined(__OBJC__) +#include +#endif +#if defined(__cplusplus) +#include +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#endif +#if defined(__cplusplus) +#if defined(__arm64e__) && __has_include() +# include +#else +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreserved-macro-identifier" +# ifndef __ptrauth_swift_value_witness_function_pointer +# define __ptrauth_swift_value_witness_function_pointer(x) +# endif +# ifndef __ptrauth_swift_class_method_pointer +# define __ptrauth_swift_class_method_pointer(x) +# endif +#pragma clang diagnostic pop +#endif +#endif + +#if !defined(SWIFT_TYPEDEFS) +# define SWIFT_TYPEDEFS 1 +# if __has_include() +# include +# elif !defined(__cplusplus) +typedef uint_least16_t char16_t; +typedef uint_least32_t char32_t; +# endif +typedef float swift_float2 __attribute__((__ext_vector_type__(2))); +typedef float swift_float3 __attribute__((__ext_vector_type__(3))); +typedef float swift_float4 __attribute__((__ext_vector_type__(4))); +typedef double swift_double2 __attribute__((__ext_vector_type__(2))); +typedef double swift_double3 __attribute__((__ext_vector_type__(3))); +typedef double swift_double4 __attribute__((__ext_vector_type__(4))); +typedef int swift_int2 __attribute__((__ext_vector_type__(2))); +typedef int swift_int3 __attribute__((__ext_vector_type__(3))); +typedef int swift_int4 __attribute__((__ext_vector_type__(4))); +typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2))); +typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3))); +typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); +#endif + +#if !defined(SWIFT_PASTE) +# define SWIFT_PASTE_HELPER(x, y) x##y +# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) +#endif +#if !defined(SWIFT_METATYPE) +# define SWIFT_METATYPE(X) Class +#endif +#if !defined(SWIFT_CLASS_PROPERTY) +# if __has_feature(objc_class_property) +# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__ +# else +# define SWIFT_CLASS_PROPERTY(...) +# endif +#endif +#if !defined(SWIFT_RUNTIME_NAME) +# if __has_attribute(objc_runtime_name) +# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) +# else +# define SWIFT_RUNTIME_NAME(X) +# endif +#endif +#if !defined(SWIFT_COMPILE_NAME) +# if __has_attribute(swift_name) +# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) +# else +# define SWIFT_COMPILE_NAME(X) +# endif +#endif +#if !defined(SWIFT_METHOD_FAMILY) +# if __has_attribute(objc_method_family) +# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X))) +# else +# define SWIFT_METHOD_FAMILY(X) +# endif +#endif +#if !defined(SWIFT_NOESCAPE) +# if __has_attribute(noescape) +# define SWIFT_NOESCAPE __attribute__((noescape)) +# else +# define SWIFT_NOESCAPE +# endif +#endif +#if !defined(SWIFT_RELEASES_ARGUMENT) +# if __has_attribute(ns_consumed) +# define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed)) +# else +# define SWIFT_RELEASES_ARGUMENT +# endif +#endif +#if !defined(SWIFT_WARN_UNUSED_RESULT) +# if __has_attribute(warn_unused_result) +# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +# else +# define SWIFT_WARN_UNUSED_RESULT +# endif +#endif +#if !defined(SWIFT_NORETURN) +# if __has_attribute(noreturn) +# define SWIFT_NORETURN __attribute__((noreturn)) +# else +# define SWIFT_NORETURN +# endif +#endif +#if !defined(SWIFT_CLASS_EXTRA) +# define SWIFT_CLASS_EXTRA +#endif +#if !defined(SWIFT_PROTOCOL_EXTRA) +# define SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_ENUM_EXTRA) +# define SWIFT_ENUM_EXTRA +#endif +#if !defined(SWIFT_CLASS) +# if __has_attribute(objc_subclassing_restricted) +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# else +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# endif +#endif +#if !defined(SWIFT_RESILIENT_CLASS) +# if __has_attribute(objc_class_stub) +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub)) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME) +# else +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME) +# endif +#endif +#if !defined(SWIFT_PROTOCOL) +# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_EXTENSION) +# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) +#endif +#if !defined(OBJC_DESIGNATED_INITIALIZER) +# if __has_attribute(objc_designated_initializer) +# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +# else +# define OBJC_DESIGNATED_INITIALIZER +# endif +#endif +#if !defined(SWIFT_ENUM_ATTR) +# if __has_attribute(enum_extensibility) +# define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility))) +# else +# define SWIFT_ENUM_ATTR(_extensibility) +# endif +#endif +#if !defined(SWIFT_ENUM) +# define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# if __has_feature(generalized_swift_name) +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# else +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility) +# endif +#endif +#if !defined(SWIFT_UNAVAILABLE) +# define SWIFT_UNAVAILABLE __attribute__((unavailable)) +#endif +#if !defined(SWIFT_UNAVAILABLE_MSG) +# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg))) +#endif +#if !defined(SWIFT_AVAILABILITY) +# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__))) +#endif +#if !defined(SWIFT_WEAK_IMPORT) +# define SWIFT_WEAK_IMPORT __attribute__((weak_import)) +#endif +#if !defined(SWIFT_DEPRECATED) +# define SWIFT_DEPRECATED __attribute__((deprecated)) +#endif +#if !defined(SWIFT_DEPRECATED_MSG) +# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__))) +#endif +#if !defined(SWIFT_DEPRECATED_OBJC) +# if __has_feature(attribute_diagnose_if_objc) +# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning"))) +# else +# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) +# endif +#endif +#if defined(__OBJC__) +#if !defined(IBSegueAction) +# define IBSegueAction +#endif +#endif +#if !defined(SWIFT_EXTERN) +# if defined(__cplusplus) +# define SWIFT_EXTERN extern "C" +# else +# define SWIFT_EXTERN extern +# endif +#endif +#if !defined(SWIFT_CALL) +# define SWIFT_CALL __attribute__((swiftcall)) +#endif +#if !defined(SWIFT_INDIRECT_RESULT) +# define SWIFT_INDIRECT_RESULT __attribute__((swift_indirect_result)) +#endif +#if !defined(SWIFT_CONTEXT) +# define SWIFT_CONTEXT __attribute__((swift_context)) +#endif +#if !defined(SWIFT_ERROR_RESULT) +# define SWIFT_ERROR_RESULT __attribute__((swift_error_result)) +#endif +#if defined(__cplusplus) +# define SWIFT_NOEXCEPT noexcept +#else +# define SWIFT_NOEXCEPT +#endif +#if !defined(SWIFT_C_INLINE_THUNK) +# if __has_attribute(always_inline) +# if __has_attribute(nodebug) +# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) __attribute__((nodebug)) +# else +# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) +# endif +# else +# define SWIFT_C_INLINE_THUNK inline +# endif +#endif +#if defined(_WIN32) +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL __declspec(dllimport) +#endif +#else +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL +#endif +#endif +#if defined(__OBJC__) +#if __has_feature(objc_modules) +#if __has_warning("-Watimport-in-framework-header") +#pragma clang diagnostic ignored "-Watimport-in-framework-header" +#endif +#endif + +#endif +#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" +#pragma clang diagnostic ignored "-Wduplicate-method-arg" +#if __has_warning("-Wpragma-clang-attribute") +# pragma clang diagnostic ignored "-Wpragma-clang-attribute" +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wnullability" +#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension" + +#if __has_attribute(external_source_symbol) +# pragma push_macro("any") +# undef any +# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="FirebaseAnalytics",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) +# pragma pop_macro("any") +#endif + +#if defined(__OBJC__) + +#endif +#if __has_attribute(external_source_symbol) +# pragma clang attribute pop +#endif +#if defined(__cplusplus) +#endif +#pragma clang diagnostic pop +#endif + +#else +#error unsupported Swift architecture +#endif diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-umbrella.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-umbrella.h new file mode 100644 index 0000000..ad84fbb --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-umbrella.h @@ -0,0 +1,24 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "FIRAnalytics+AppDelegate.h" +#import "FIRAnalytics+Consent.h" +#import "FIRAnalytics+OnDevice.h" +#import "FIRAnalytics.h" +#import "FirebaseAnalytics.h" +#import "FIREventNames.h" +#import "FIRParameterNames.h" +#import "FIRUserPropertyNames.h" + +FOUNDATION_EXPORT double FirebaseAnalyticsVersionNumber; +FOUNDATION_EXPORT const unsigned char FirebaseAnalyticsVersionString[]; + diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h new file mode 100644 index 0000000..351da20 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h @@ -0,0 +1,7 @@ +#import "FIRAnalytics+AppDelegate.h" +#import "FIRAnalytics+Consent.h" +#import "FIRAnalytics+OnDevice.h" +#import "FIRAnalytics.h" +#import "FIREventNames.h" +#import "FIRParameterNames.h" +#import "FIRUserPropertyNames.h" diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Info.plist b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Info.plist new file mode 100644 index 0000000..e2cb49e --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Info.plist @@ -0,0 +1,53 @@ + + + + + BuildMachineOSBuild + 23F79 + CFBundleDevelopmentRegion + en + CFBundleExecutable + FirebaseAnalytics + CFBundleIdentifier + org.cocoapods.FirebaseAnalytics + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + FirebaseAnalytics + CFBundlePackageType + FMWK + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + iPhoneSimulator + + CFBundleVersion + 1 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 21C52 + DTPlatformName + iphonesimulator + DTPlatformVersion + 17.2 + DTSDKBuild + 21C52 + DTSDKName + iphonesimulator17.2 + DTXcode + 1520 + DTXcodeBuild + 15C500b + MinimumOSVersion + 100.0 + UIDeviceFamily + + 1 + 2 + + + diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-ios-simulator.swiftsourceinfo b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-ios-simulator.swiftsourceinfo new file mode 100644 index 0000000..45c143b Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-ios-simulator.swiftsourceinfo differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/x86_64-apple-ios-simulator.swiftsourceinfo b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/x86_64-apple-ios-simulator.swiftsourceinfo new file mode 100644 index 0000000..da57c7c Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/x86_64-apple-ios-simulator.swiftsourceinfo differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-simulator.abi.json b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-simulator.abi.json new file mode 100644 index 0000000..fde2b92 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-simulator.abi.json @@ -0,0 +1,239 @@ +{ + "ABIRoot": { + "kind": "Root", + "name": "TopLevel", + "printedName": "TopLevel", + "children": [ + { + "kind": "Import", + "name": "StoreKit", + "printedName": "StoreKit", + "declKind": "Import", + "moduleName": "FirebaseAnalytics" + }, + { + "kind": "Import", + "name": "SwiftUI", + "printedName": "SwiftUI", + "declKind": "Import", + "moduleName": "FirebaseAnalytics" + }, + { + "kind": "TypeDecl", + "name": "Analytics", + "printedName": "Analytics", + "children": [ + { + "kind": "Function", + "name": "logTransaction", + "printedName": "logTransaction(_:)", + "children": [ + { + "kind": "TypeNominal", + "name": "Void", + "printedName": "()" + }, + { + "kind": "TypeNominal", + "name": "Transaction", + "printedName": "StoreKit.Transaction", + "usr": "s:8StoreKit11TransactionV" + } + ], + "declKind": "Func", + "usr": "s:So12FIRAnalyticsC17FirebaseAnalyticsE14logTransactionyy8StoreKit0E0VFZ", + "mangledName": "$sSo12FIRAnalyticsC17FirebaseAnalyticsE14logTransactionyy8StoreKit0E0VFZ", + "moduleName": "FirebaseAnalytics", + "static": true, + "declAttributes": [ + "Final", + "AccessControl", + "RawDocComment" + ], + "isFromExtension": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Class", + "usr": "c:objc(cs)FIRAnalytics", + "moduleName": "FirebaseAnalytics", + "isOpen": true, + "objc_name": "FIRAnalytics", + "declAttributes": [ + "ObjC", + "Dynamic" + ], + "superclassUsr": "c:objc(cs)NSObject", + "isExternal": true, + "inheritsConvenienceInitializers": true, + "superclassNames": [ + "ObjectiveC.NSObject" + ], + "conformances": [ + { + "kind": "Conformance", + "name": "Equatable", + "printedName": "Equatable", + "usr": "s:SQ", + "mangledName": "$sSQ" + }, + { + "kind": "Conformance", + "name": "Hashable", + "printedName": "Hashable", + "usr": "s:SH", + "mangledName": "$sSH" + }, + { + "kind": "Conformance", + "name": "CVarArg", + "printedName": "CVarArg", + "usr": "s:s7CVarArgP", + "mangledName": "$ss7CVarArgP" + }, + { + "kind": "Conformance", + "name": "_KeyValueCodingAndObservingPublishing", + "printedName": "_KeyValueCodingAndObservingPublishing", + "usr": "s:10Foundation37_KeyValueCodingAndObservingPublishingP", + "mangledName": "$s10Foundation37_KeyValueCodingAndObservingPublishingP" + }, + { + "kind": "Conformance", + "name": "_KeyValueCodingAndObserving", + "printedName": "_KeyValueCodingAndObserving", + "usr": "s:10Foundation27_KeyValueCodingAndObservingP", + "mangledName": "$s10Foundation27_KeyValueCodingAndObservingP" + }, + { + "kind": "Conformance", + "name": "CustomStringConvertible", + "printedName": "CustomStringConvertible", + "usr": "s:s23CustomStringConvertibleP", + "mangledName": "$ss23CustomStringConvertibleP" + }, + { + "kind": "Conformance", + "name": "CustomDebugStringConvertible", + "printedName": "CustomDebugStringConvertible", + "usr": "s:s28CustomDebugStringConvertibleP", + "mangledName": "$ss28CustomDebugStringConvertibleP" + } + ] + }, + { + "kind": "TypeDecl", + "name": "View", + "printedName": "View", + "children": [ + { + "kind": "Function", + "name": "analyticsScreen", + "printedName": "analyticsScreen(name:class:extraParameters:)", + "children": [ + { + "kind": "TypeNominal", + "name": "ModifiedContent", + "printedName": "SwiftUI.ModifiedContent<τ_0_0, FirebaseAnalytics.LoggedAnalyticsModifier>", + "children": [ + { + "kind": "TypeNominal", + "name": "GenericTypeParam", + "printedName": "τ_0_0" + }, + { + "kind": "TypeNominal", + "name": "LoggedAnalyticsModifier", + "printedName": "FirebaseAnalytics.LoggedAnalyticsModifier", + "usr": "s:17FirebaseAnalytics06LoggedB8ModifierV" + } + ], + "usr": "s:7SwiftUI15ModifiedContentV" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "hasDefaultArg": true, + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "Dictionary", + "printedName": "[Swift.String : Any]", + "children": [ + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "ProtocolComposition", + "printedName": "Any" + } + ], + "hasDefaultArg": true, + "usr": "s:SD" + } + ], + "declKind": "Func", + "usr": "s:7SwiftUI4ViewP17FirebaseAnalyticsE15analyticsScreen4name5class15extraParametersQrSS_SSSDySSypGtF", + "mangledName": "$s7SwiftUI4ViewP17FirebaseAnalyticsE15analyticsScreen4name5class15extraParametersQrSS_SSSDySSypGtF", + "moduleName": "FirebaseAnalytics", + "genericSig": "<τ_0_0 where τ_0_0 : SwiftUI.View>", + "sugared_genericSig": "", + "declAttributes": [ + "AccessControl", + "RawDocComment" + ], + "isFromExtension": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Protocol", + "usr": "s:7SwiftUI4ViewP", + "mangledName": "$s7SwiftUI4ViewP", + "moduleName": "SwiftUI", + "genericSig": "<τ_0_0.Body : SwiftUI.View>", + "sugared_genericSig": "", + "intro_Macosx": "10.15", + "intro_iOS": "13.0", + "intro_tvOS": "13.0", + "intro_watchOS": "6.0", + "declAttributes": [ + "TypeEraser", + "Available", + "Available", + "Available", + "Available" + ], + "isExternal": true + } + ], + "json_format_version": 8 + }, + "ConstValues": [ + { + "filePath": "\/Volumes\/google\/src\/cloud\/pdchen\/firebaserelease\/google3\/googlemac\/iPhone\/Firebase\/Analytics\/Sources\/Swift\/Analytics+SwiftUI.swift", + "kind": "StringLiteral", + "offset": 2654, + "length": 6, + "value": "\"View\"" + }, + { + "filePath": "\/Volumes\/google\/src\/cloud\/pdchen\/firebaserelease\/google3\/googlemac\/iPhone\/Firebase\/Analytics\/Sources\/Swift\/Analytics+SwiftUI.swift", + "kind": "Dictionary", + "offset": 2701, + "length": 3, + "value": "[]" + } + ] +} \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface new file mode 100644 index 0000000..2d0570e --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface @@ -0,0 +1,22 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +// swift-module-flags: -target arm64-apple-ios10.0-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name FirebaseAnalytics +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import FirebaseAnalytics +import StoreKit +import Swift +import SwiftUI +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *) +@available(watchOS, unavailable) +extension FirebaseAnalytics.Analytics { + public static func logTransaction(_ transaction: StoreKit.Transaction) +} +@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *) +@available(watchOS, unavailable) +extension SwiftUI.View { + public func analyticsScreen(name: Swift.String, class: Swift.String = "View", extraParameters: [Swift.String : Any] = [:]) -> some SwiftUI.View + +} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-simulator.swiftdoc b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-simulator.swiftdoc new file mode 100644 index 0000000..e7e0528 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-simulator.swiftdoc differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-simulator.swiftinterface b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-simulator.swiftinterface new file mode 100644 index 0000000..2d0570e --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-ios-simulator.swiftinterface @@ -0,0 +1,22 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +// swift-module-flags: -target arm64-apple-ios10.0-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name FirebaseAnalytics +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import FirebaseAnalytics +import StoreKit +import Swift +import SwiftUI +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *) +@available(watchOS, unavailable) +extension FirebaseAnalytics.Analytics { + public static func logTransaction(_ transaction: StoreKit.Transaction) +} +@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *) +@available(watchOS, unavailable) +extension SwiftUI.View { + public func analyticsScreen(name: Swift.String, class: Swift.String = "View", extraParameters: [Swift.String : Any] = [:]) -> some SwiftUI.View + +} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-simulator.abi.json b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-simulator.abi.json new file mode 100644 index 0000000..fde2b92 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-simulator.abi.json @@ -0,0 +1,239 @@ +{ + "ABIRoot": { + "kind": "Root", + "name": "TopLevel", + "printedName": "TopLevel", + "children": [ + { + "kind": "Import", + "name": "StoreKit", + "printedName": "StoreKit", + "declKind": "Import", + "moduleName": "FirebaseAnalytics" + }, + { + "kind": "Import", + "name": "SwiftUI", + "printedName": "SwiftUI", + "declKind": "Import", + "moduleName": "FirebaseAnalytics" + }, + { + "kind": "TypeDecl", + "name": "Analytics", + "printedName": "Analytics", + "children": [ + { + "kind": "Function", + "name": "logTransaction", + "printedName": "logTransaction(_:)", + "children": [ + { + "kind": "TypeNominal", + "name": "Void", + "printedName": "()" + }, + { + "kind": "TypeNominal", + "name": "Transaction", + "printedName": "StoreKit.Transaction", + "usr": "s:8StoreKit11TransactionV" + } + ], + "declKind": "Func", + "usr": "s:So12FIRAnalyticsC17FirebaseAnalyticsE14logTransactionyy8StoreKit0E0VFZ", + "mangledName": "$sSo12FIRAnalyticsC17FirebaseAnalyticsE14logTransactionyy8StoreKit0E0VFZ", + "moduleName": "FirebaseAnalytics", + "static": true, + "declAttributes": [ + "Final", + "AccessControl", + "RawDocComment" + ], + "isFromExtension": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Class", + "usr": "c:objc(cs)FIRAnalytics", + "moduleName": "FirebaseAnalytics", + "isOpen": true, + "objc_name": "FIRAnalytics", + "declAttributes": [ + "ObjC", + "Dynamic" + ], + "superclassUsr": "c:objc(cs)NSObject", + "isExternal": true, + "inheritsConvenienceInitializers": true, + "superclassNames": [ + "ObjectiveC.NSObject" + ], + "conformances": [ + { + "kind": "Conformance", + "name": "Equatable", + "printedName": "Equatable", + "usr": "s:SQ", + "mangledName": "$sSQ" + }, + { + "kind": "Conformance", + "name": "Hashable", + "printedName": "Hashable", + "usr": "s:SH", + "mangledName": "$sSH" + }, + { + "kind": "Conformance", + "name": "CVarArg", + "printedName": "CVarArg", + "usr": "s:s7CVarArgP", + "mangledName": "$ss7CVarArgP" + }, + { + "kind": "Conformance", + "name": "_KeyValueCodingAndObservingPublishing", + "printedName": "_KeyValueCodingAndObservingPublishing", + "usr": "s:10Foundation37_KeyValueCodingAndObservingPublishingP", + "mangledName": "$s10Foundation37_KeyValueCodingAndObservingPublishingP" + }, + { + "kind": "Conformance", + "name": "_KeyValueCodingAndObserving", + "printedName": "_KeyValueCodingAndObserving", + "usr": "s:10Foundation27_KeyValueCodingAndObservingP", + "mangledName": "$s10Foundation27_KeyValueCodingAndObservingP" + }, + { + "kind": "Conformance", + "name": "CustomStringConvertible", + "printedName": "CustomStringConvertible", + "usr": "s:s23CustomStringConvertibleP", + "mangledName": "$ss23CustomStringConvertibleP" + }, + { + "kind": "Conformance", + "name": "CustomDebugStringConvertible", + "printedName": "CustomDebugStringConvertible", + "usr": "s:s28CustomDebugStringConvertibleP", + "mangledName": "$ss28CustomDebugStringConvertibleP" + } + ] + }, + { + "kind": "TypeDecl", + "name": "View", + "printedName": "View", + "children": [ + { + "kind": "Function", + "name": "analyticsScreen", + "printedName": "analyticsScreen(name:class:extraParameters:)", + "children": [ + { + "kind": "TypeNominal", + "name": "ModifiedContent", + "printedName": "SwiftUI.ModifiedContent<τ_0_0, FirebaseAnalytics.LoggedAnalyticsModifier>", + "children": [ + { + "kind": "TypeNominal", + "name": "GenericTypeParam", + "printedName": "τ_0_0" + }, + { + "kind": "TypeNominal", + "name": "LoggedAnalyticsModifier", + "printedName": "FirebaseAnalytics.LoggedAnalyticsModifier", + "usr": "s:17FirebaseAnalytics06LoggedB8ModifierV" + } + ], + "usr": "s:7SwiftUI15ModifiedContentV" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "hasDefaultArg": true, + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "Dictionary", + "printedName": "[Swift.String : Any]", + "children": [ + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "ProtocolComposition", + "printedName": "Any" + } + ], + "hasDefaultArg": true, + "usr": "s:SD" + } + ], + "declKind": "Func", + "usr": "s:7SwiftUI4ViewP17FirebaseAnalyticsE15analyticsScreen4name5class15extraParametersQrSS_SSSDySSypGtF", + "mangledName": "$s7SwiftUI4ViewP17FirebaseAnalyticsE15analyticsScreen4name5class15extraParametersQrSS_SSSDySSypGtF", + "moduleName": "FirebaseAnalytics", + "genericSig": "<τ_0_0 where τ_0_0 : SwiftUI.View>", + "sugared_genericSig": "", + "declAttributes": [ + "AccessControl", + "RawDocComment" + ], + "isFromExtension": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Protocol", + "usr": "s:7SwiftUI4ViewP", + "mangledName": "$s7SwiftUI4ViewP", + "moduleName": "SwiftUI", + "genericSig": "<τ_0_0.Body : SwiftUI.View>", + "sugared_genericSig": "", + "intro_Macosx": "10.15", + "intro_iOS": "13.0", + "intro_tvOS": "13.0", + "intro_watchOS": "6.0", + "declAttributes": [ + "TypeEraser", + "Available", + "Available", + "Available", + "Available" + ], + "isExternal": true + } + ], + "json_format_version": 8 + }, + "ConstValues": [ + { + "filePath": "\/Volumes\/google\/src\/cloud\/pdchen\/firebaserelease\/google3\/googlemac\/iPhone\/Firebase\/Analytics\/Sources\/Swift\/Analytics+SwiftUI.swift", + "kind": "StringLiteral", + "offset": 2654, + "length": 6, + "value": "\"View\"" + }, + { + "filePath": "\/Volumes\/google\/src\/cloud\/pdchen\/firebaserelease\/google3\/googlemac\/iPhone\/Firebase\/Analytics\/Sources\/Swift\/Analytics+SwiftUI.swift", + "kind": "Dictionary", + "offset": 2701, + "length": 3, + "value": "[]" + } + ] +} \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface new file mode 100644 index 0000000..51e70ee --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface @@ -0,0 +1,22 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +// swift-module-flags: -target x86_64-apple-ios10.0-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name FirebaseAnalytics +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import FirebaseAnalytics +import StoreKit +import Swift +import SwiftUI +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *) +@available(watchOS, unavailable) +extension FirebaseAnalytics.Analytics { + public static func logTransaction(_ transaction: StoreKit.Transaction) +} +@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *) +@available(watchOS, unavailable) +extension SwiftUI.View { + public func analyticsScreen(name: Swift.String, class: Swift.String = "View", extraParameters: [Swift.String : Any] = [:]) -> some SwiftUI.View + +} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-simulator.swiftdoc b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-simulator.swiftdoc new file mode 100644 index 0000000..32b23ba Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-simulator.swiftdoc differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-simulator.swiftinterface b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-simulator.swiftinterface new file mode 100644 index 0000000..51e70ee --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-ios-simulator.swiftinterface @@ -0,0 +1,22 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +// swift-module-flags: -target x86_64-apple-ios10.0-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name FirebaseAnalytics +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import FirebaseAnalytics +import StoreKit +import Swift +import SwiftUI +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *) +@available(watchOS, unavailable) +extension FirebaseAnalytics.Analytics { + public static func logTransaction(_ transaction: StoreKit.Transaction) +} +@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *) +@available(watchOS, unavailable) +extension SwiftUI.View { + public func analyticsScreen(name: Swift.String, class: Swift.String = "View", extraParameters: [Swift.String : Any] = [:]) -> some SwiftUI.View + +} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/module.modulemap b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/module.modulemap new file mode 100644 index 0000000..fa10817 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/module.modulemap @@ -0,0 +1,16 @@ +framework module FirebaseAnalytics { +umbrella header "FirebaseAnalytics-umbrella.h" +export * +module * { export * } + link framework "Foundation" + link framework "Security" + link framework "SystemConfiguration" + link framework "UIKit" + link "c++" + link "sqlite3" + link "z" +} +module FirebaseAnalytics.Swift { + header "FirebaseAnalytics-Swift.h" + requires objc +} \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/FirebaseAnalytics b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/FirebaseAnalytics new file mode 120000 index 0000000..82502e9 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/FirebaseAnalytics @@ -0,0 +1 @@ +Versions/Current/FirebaseAnalytics \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Headers b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Headers new file mode 120000 index 0000000..a177d2a --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Modules b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Modules new file mode 120000 index 0000000..5736f31 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Modules @@ -0,0 +1 @@ +Versions/Current/Modules \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Resources b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Resources new file mode 120000 index 0000000..953ee36 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/FirebaseAnalytics b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/FirebaseAnalytics new file mode 100644 index 0000000..6a4b553 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/FirebaseAnalytics differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+AppDelegate.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+AppDelegate.h new file mode 100644 index 0000000..cb1e407 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+AppDelegate.h @@ -0,0 +1,80 @@ +#import + +#import "FIRAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +/// Provides App Delegate handlers to be used in your App Delegate. +/// +/// To save time integrating Firebase Analytics in an application, Firebase Analytics does not +/// require delegation implementation from the AppDelegate if neither SwiftUI nor UIScene lifecycle +/// is adopted. Instead this is automatically done by Firebase Analytics. Should you choose instead +/// to delegate manually, you can turn off the App Delegate Proxy by adding +/// FirebaseAppDelegateProxyEnabled into your app's Info.plist and setting it to boolean `NO`, and +/// adding the methods in this category to corresponding delegation handlers. +/// +/// To handle Universal Links, you must return `true` in +/// `UIApplicationDelegate.application(_:didFinishLaunchingWithOptions:)`. +@interface FIRAnalytics (AppDelegate) + +/// Handles events related to a URL session that are waiting to be processed. +/// +/// 1. If SwiftUI lifecycle is adopted, call this method from +/// `UIApplicationDelegate.application(_:handleEventsForBackgroundURLSession:completionHandler:)` +/// in your app delegate. +/// +/// 2. If SwiftUI lifecycle is not adopted, Firebase Analytics does not require delegation +/// implementation from the AppDelegate. If you choose instead to delegate manually, you can set +/// FirebaseAppDelegateProxyEnabled to boolean `NO` in your app's Info.plist and call this method +/// from +/// `UIApplicationDelegate.application(_:handleEventsForBackgroundURLSession:completionHandler:)` +/// in your app delegate. +/// +/// @param identifier The identifier of the URL session requiring attention. +/// @param completionHandler The completion handler to call when you finish processing the events. +/// Calling this completion handler lets the system know that your app's user interface is +/// updated and a new snapshot can be taken. ++ (void)handleEventsForBackgroundURLSession:(NSString *)identifier + completionHandler:(nullable void (^)(void))completionHandler; + +/// Handles the event when the app is launched by a URL (custom URL scheme or universal link). +/// +/// 1. If SwiftUI lifecycle is adopted, use `onOpenURL(perform:)` to register a handler and call +/// this method in the handler. +/// +/// 2. If UIScene lifecycle is adopted, call this method from +/// `UISceneDelegate.scene(_:willConnectTo:options:)` and +/// `UISceneDelegate.scene(_:openURLContexts:)` when the URL contexts are available. +/// +/// 3. If neither SwiftUI nor UIScene lifecycle is adopted, Firebase Analytics does not require +/// delegation implementation from the AppDelegate. If you choose instead to delegate manually, you +/// can set FirebaseAppDelegateProxyEnabled to boolean `NO` in your app's Info.plist and call this +/// method from `UIApplicationDelegate.application(_:open:options:)` in your app delegate. +/// +/// @param url The URL resource to open. This resource can be a network resource or a file. ++ (void)handleOpenURL:(NSURL *)url; + +/// Handles the event when the app receives data associated with user activity that includes a +/// Universal Link. +/// +/// 1. If SwiftUI lifecycle is adopted, use `onOpenURL(perform:)` to register a handler and call +/// `Analytics.handleOpen(_:)` instead in the handler. +/// +/// 2. If UIScene lifecycle is adopted, call this method from +/// `UISceneDelegate.scene(_:willConnectTo:options:)` and `UISceneDelegate.scene(_:continue:)` when +/// NSUserActivity is available. See the [Apple +/// doc](https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app) for +/// more details. +/// +/// 3. If neither SwiftUI nor UIScene lifecycle is adopted, Firebase Analytics does not require +/// delegation implementation from the AppDelegate. If you choose instead to delegate manually, you +/// can set FirebaseAppDelegateProxyEnabled to boolean `NO` in your app's Info.plist and call this +/// method from `UIApplication.application(_:continue:restorationHandler:)` in your app delegate. +/// +/// @param userActivity The activity object containing the data associated with the task the user +/// was performing. ++ (void)handleUserActivity:(id)userActivity; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+Consent.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+Consent.h new file mode 100644 index 0000000..7758390 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+Consent.h @@ -0,0 +1,51 @@ +#import + +#import "FIRAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +/// The type of consent to set. Supported consent types are `ConsentType.adStorage`, +/// `ConsentType.analyticsStorage`, `ConsentType.adUserData`, and `ConsentType.adPersonalization`. +/// Omitting a type retains its previous status. +typedef NSString *FIRConsentType NS_TYPED_ENUM NS_SWIFT_NAME(ConsentType); + +/// Enables storage (such as device identifiers) related to advertising. +extern FIRConsentType const FIRConsentTypeAdStorage; + +/// Enables storage (such as app identifiers) related to analytics, e.g. visit duration. +extern FIRConsentType const FIRConsentTypeAnalyticsStorage; + +/// Sets consent for sending user data to Google for advertising purposes. +extern FIRConsentType const FIRConsentTypeAdUserData; + +/// Sets consent for personalized advertising. +extern FIRConsentType const FIRConsentTypeAdPersonalization; + +/// The status value of the consent type. Supported statuses are `ConsentStatus.granted` and +/// `ConsentStatus.denied`. +typedef NSString *FIRConsentStatus NS_TYPED_ENUM NS_SWIFT_NAME(ConsentStatus); + +/// Consent status indicating consent is denied. For an overview of which data is sent when consent +/// is denied, see [SDK behavior with consent +/// mode](https://developers.google.com/tag-platform/security/concepts/consent-mode#tag-behavior). +extern FIRConsentStatus const FIRConsentStatusDenied; + +/// Consent status indicating consent is granted. +extern FIRConsentStatus const FIRConsentStatusGranted; + +/// Sets the applicable end user consent state. +@interface FIRAnalytics (Consent) + +/// Sets the applicable end user consent state (e.g. for device identifiers) for this app on this +/// device. Use the consent settings to specify individual consent type values. Settings are +/// persisted across app sessions. By default consent types are set to `ConsentStatus.granted`. +/// +/// @param consentSettings A Dictionary of consent types. Supported consent type keys are +/// `ConsentType.adStorage`, `ConsentType.analyticsStorage`, `ConsentType.adUserData`, and +/// `ConsentType.adPersonalization`. Valid values are `ConsentStatus.granted` and +/// `ConsentStatus.denied`. ++ (void)setConsent:(NSDictionary *)consentSettings; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+OnDevice.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+OnDevice.h new file mode 100644 index 0000000..0bfec88 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics+OnDevice.h @@ -0,0 +1,44 @@ +#import + +#import "FIRAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +API_UNAVAILABLE(macCatalyst, macos, tvos, watchos) +@interface FIRAnalytics (OnDevice) + +/// Initiates on-device conversion measurement given a user email address. Requires dependency +/// GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a no-op. +/// @param emailAddress User email address. Include a domain name for all email addresses +/// (e.g. gmail.com or hotmail.co.jp). ++ (void)initiateOnDeviceConversionMeasurementWithEmailAddress:(NSString *)emailAddress + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(emailAddress:)); + +/// Initiates on-device conversion measurement given a phone number in E.164 format. Requires +/// dependency GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a no-op. +/// @param phoneNumber User phone number. Must be in E.164 format, which means it must be +/// limited to a maximum of 15 digits and must include a plus sign (+) prefix and country code +/// with no dashes, parentheses, or spaces. ++ (void)initiateOnDeviceConversionMeasurementWithPhoneNumber:(NSString *)phoneNumber + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(phoneNumber:)); + +/// Initiates on-device conversion measurement given a sha256-hashed user email address. Requires +/// dependency GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a no-op. +/// @param hashedEmailAddress User email address as a UTF8-encoded string normalized and hashed +/// according to the instructions at +/// https://firebase.google.com/docs/tutorials/ads-ios-on-device-measurement/step-3. ++ (void)initiateOnDeviceConversionMeasurementWithHashedEmailAddress:(NSData *)hashedEmailAddress + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(hashedEmailAddress:)); + +/// Initiates on-device conversion measurement given a sha256-hashed phone number in E.164 format. +/// Requires dependency GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a +/// no-op. +/// @param hashedPhoneNumber UTF8-encoded user phone number in E.164 format and then hashed +/// according to the instructions at +/// https://firebase.google.com/docs/tutorials/ads-ios-on-device-measurement/step-3. ++ (void)initiateOnDeviceConversionMeasurementWithHashedPhoneNumber:(NSData *)hashedPhoneNumber + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(hashedPhoneNumber:)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics.h new file mode 100644 index 0000000..e58d7dd --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRAnalytics.h @@ -0,0 +1,155 @@ +#import + +#import "FIREventNames.h" +#import "FIRParameterNames.h" +#import "FIRUserPropertyNames.h" + +NS_ASSUME_NONNULL_BEGIN + +/// The top level Firebase Analytics singleton that provides methods for logging events and setting +/// user properties. See the developer guides for general +/// information on using Firebase Analytics in your apps. +/// +/// @note The Analytics SDK uses SQLite to persist events and other app-specific data. Calling +/// certain thread-unsafe global SQLite methods like `sqlite3_shutdown()` can result in +/// unexpected crashes at runtime. +NS_SWIFT_NAME(Analytics) +@interface FIRAnalytics : NSObject + +/// Logs an app event. The event can have up to 25 parameters. Events with the same name must have +/// the same parameters. Up to 500 event names are supported. Using predefined events and/or +/// parameters is recommended for optimal reporting. +/// +/// The following event names are reserved and cannot be used: +///
    +///
  • ad_activeview
  • +///
  • ad_click
  • +///
  • ad_exposure
  • +///
  • ad_query
  • +///
  • ad_reward
  • +///
  • adunit_exposure
  • +///
  • app_clear_data
  • +///
  • app_exception
  • +///
  • app_remove
  • +///
  • app_store_refund
  • +///
  • app_store_subscription_cancel
  • +///
  • app_store_subscription_convert
  • +///
  • app_store_subscription_renew
  • +///
  • app_update
  • +///
  • app_upgrade
  • +///
  • dynamic_link_app_open
  • +///
  • dynamic_link_app_update
  • +///
  • dynamic_link_first_open
  • +///
  • error
  • +///
  • firebase_campaign
  • +///
  • first_open
  • +///
  • first_visit
  • +///
  • in_app_purchase
  • +///
  • notification_dismiss
  • +///
  • notification_foreground
  • +///
  • notification_open
  • +///
  • notification_receive
  • +///
  • os_update
  • +///
  • session_start
  • +///
  • session_start_with_rollout
  • +///
  • user_engagement
  • +///
+/// +/// @param name The name of the event. Should contain 1 to 40 alphanumeric characters or +/// underscores. The name must start with an alphabetic character. Some event names are +/// reserved. See FIREventNames.h for the list of reserved event names. The "firebase_", +/// "google_", and "ga_" prefixes are reserved and should not be used. Note that event names are +/// case-sensitive and that logging two events whose names differ only in case will result in +/// two distinct events. To manually log screen view events, use the `screen_view` event name. +/// @param parameters The dictionary of event parameters. Passing `nil` indicates that the event has +/// no parameters. Parameter names can be up to 40 characters long and must start with an +/// alphabetic character and contain only alphanumeric characters and underscores. Only String, +/// Int, and Double parameter types are supported. String parameter values can be up to 100 +/// characters long for standard Google Analytics properties, and up to 500 characters long for +/// Google Analytics 360 properties. The "firebase_", "google_", and "ga_" prefixes are reserved +/// and should not be used for parameter names. ++ (void)logEventWithName:(NSString *)name + parameters:(nullable NSDictionary *)parameters + NS_SWIFT_NAME(logEvent(_:parameters:)); + +/// Sets a user property to a given value. Up to 25 user property names are supported. Once set, +/// user property values persist throughout the app lifecycle and across sessions. +/// +/// The following user property names are reserved and cannot be used: +///
    +///
  • first_open_time
  • +///
  • last_deep_link_referrer
  • +///
  • user_id
  • +///
+/// +/// @param value The value of the user property. Values can be up to 36 characters long. Setting the +/// value to `nil` removes the user property. +/// @param name The name of the user property to set. Should contain 1 to 24 alphanumeric characters +/// or underscores and must start with an alphabetic character. The "firebase_", "google_", and +/// "ga_" prefixes are reserved and should not be used for user property names. ++ (void)setUserPropertyString:(nullable NSString *)value forName:(NSString *)name + NS_SWIFT_NAME(setUserProperty(_:forName:)); + +/// Sets the user ID property. This feature must be used in accordance with +/// Google's Privacy Policy +/// +/// @param userID The user ID to ascribe to the user of this app on this device, which must be +/// non-empty and no more than 256 characters long. Setting userID to `nil` removes the user ID. ++ (void)setUserID:(nullable NSString *)userID; + +/// Sets whether analytics collection is enabled for this app on this device. This setting is +/// persisted across app sessions. By default it is enabled. +/// +/// @param analyticsCollectionEnabled A flag that enables or disables Analytics collection. ++ (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled; + +/// Sets the interval of inactivity in seconds that terminates the current session. The default +/// value is 1800 seconds (30 minutes). +/// +/// @param sessionTimeoutInterval The custom time of inactivity in seconds before the current +/// session terminates. ++ (void)setSessionTimeoutInterval:(NSTimeInterval)sessionTimeoutInterval; + +/// Asynchronously retrieves the identifier of the current app session. +/// +/// The session ID retrieval could fail due to Analytics collection disabled, app session expired, +/// etc. +/// +/// @param completion The completion handler to call when the session ID retrieval is complete. This +/// handler is executed on a system-defined global concurrent queue. +/// This completion handler takes the following parameters: +/// sessionID The identifier of the current app session. The value is undefined if the +/// request failed. +/// error An error object that indicates why the request failed, or `nil` if the request +/// was successful. ++ (void)sessionIDWithCompletion:(void (^)(int64_t sessionID, NSError *_Nullable error))completion; + +/// Returns the unique ID for this instance of the application or `nil` if +/// `ConsentType.analyticsStorage` has been set to `ConsentStatus.denied`. +/// +/// @see `FIRAnalytics+Consent.h` ++ (nullable NSString *)appInstanceID; + +/// Clears all analytics data for this instance from the device and resets the app instance ID. ++ (void)resetAnalyticsData; + +/// Adds parameters that will be set on every event logged from the SDK, including automatic ones. +/// The values passed in the parameters dictionary will be added to the dictionary of default event +/// parameters. These parameters persist across app runs. They are of lower precedence than event +/// parameters, so if an event parameter and a parameter set using this API have the same name, the +/// value of the event parameter will be used. The same limitations on event parameters apply to +/// default event parameters. +/// +/// @param parameters Parameters to be added to the dictionary of parameters added to every event. +/// They will be added to the dictionary of default event parameters, replacing any existing +/// parameter with the same name. Valid parameters are String, Int, and Double. Setting a key's +/// value to `NSNull()` will clear that parameter. Passing in a `nil` dictionary will clear all +/// parameters. ++ (void)setDefaultEventParameters:(nullable NSDictionary *)parameters; + +/// Unavailable. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIREventNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIREventNames.h new file mode 100644 index 0000000..1e69a44 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIREventNames.h @@ -0,0 +1,418 @@ +/// @file FIREventNames.h +/// +/// Predefined event names. +/// +/// An Event is an important occurrence in your app that you want to measure. You can report up to +/// 500 different types of Events per app and you can associate up to 25 unique parameters with each +/// Event type. Some common events are suggested below, but you may also choose to specify custom +/// Event types that are associated with your specific app. Each event type is identified by a +/// unique name. Event names can be up to 40 characters long, may only contain alphanumeric +/// characters and underscores ("_"), and must start with an alphabetic character. The "firebase_", +/// "google_", and "ga_" prefixes are reserved and should not be used. + +#import + +/// Ad Impression event. This event signifies when a user sees an ad impression. Note: If you supply +/// the @c AnalyticsParameterValue parameter, you must also supply the @c AnalyticsParameterCurrency +/// parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterAdPlatform (String) (optional)
  • +///
  • @c AnalyticsParameterAdFormat (String) (optional)
  • +///
  • @c AnalyticsParameterAdSource (String) (optional)
  • +///
  • @c AnalyticsParameterAdUnitName (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAdImpression NS_SWIFT_NAME(AnalyticsEventAdImpression) = + @"ad_impression"; + +/// Add Payment Info event. This event signifies that a user has submitted their payment +/// information. Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply +/// the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterPaymentType (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddPaymentInfo NS_SWIFT_NAME(AnalyticsEventAddPaymentInfo) = + @"add_payment_info"; + +/// Add Shipping Info event. This event signifies that a user has submitted their shipping +/// information. Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply +/// the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterShippingTier (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddShippingInfo NS_SWIFT_NAME(AnalyticsEventAddShippingInfo) = + @"add_shipping_info"; + +/// E-Commerce Add To Cart event. This event signifies that an item(s) was added to a cart for +/// purchase. Add this event to a funnel with @c AnalyticsEventPurchase to gauge the effectiveness +/// of your checkout process. Note: If you supply the @c AnalyticsParameterValue parameter, you must +/// also supply the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed +/// accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddToCart NS_SWIFT_NAME(AnalyticsEventAddToCart) = @"add_to_cart"; + +/// E-Commerce Add To Wishlist event. This event signifies that an item was added to a wishlist. Use +/// this event to identify popular gift items. Note: If you supply the @c AnalyticsParameterValue +/// parameter, you must also supply the @c AnalyticsParameterCurrency parameter so that revenue +/// metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddToWishlist NS_SWIFT_NAME(AnalyticsEventAddToWishlist) = + @"add_to_wishlist"; + +/// App Open event. By logging this event when an App becomes active, developers can understand how +/// often users leave and return during the course of a Session. Although Sessions are automatically +/// reported, this event can provide further clarification around the continuous engagement of +/// app-users. +static NSString *const kFIREventAppOpen NS_SWIFT_NAME(AnalyticsEventAppOpen) = @"app_open"; + +/// E-Commerce Begin Checkout event. This event signifies that a user has begun the process of +/// checking out. Add this event to a funnel with your @c AnalyticsEventPurchase event to gauge the +/// effectiveness of your checkout process. Note: If you supply the @c AnalyticsParameterValue +/// parameter, you must also supply the @c AnalyticsParameterCurrency parameter so that revenue +/// metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventBeginCheckout NS_SWIFT_NAME(AnalyticsEventBeginCheckout) = + @"begin_checkout"; + +/// Campaign Detail event. Log this event to supply the referral details of a re-engagement +/// campaign. Note: you must supply at least one of the required parameters +/// AnalyticsParameterSource, AnalyticsParameterMedium or AnalyticsParameterCampaign. Params: +/// +///
    +///
  • @c AnalyticsParameterSource (String)
  • +///
  • @c AnalyticsParameterMedium (String)
  • +///
  • @c AnalyticsParameterCampaign (String)
  • +///
  • @c AnalyticsParameterTerm (String) (optional)
  • +///
  • @c AnalyticsParameterContent (String) (optional)
  • +///
  • @c AnalyticsParameterAdNetworkClickID (String) (optional)
  • +///
  • @c AnalyticsParameterCP1 (String) (optional)
  • +///
  • @c AnalyticsParameterCampaignID (String) (optional)
  • +///
  • @c AnalyticsParameterCreativeFormat (String) (optional)
  • +///
  • @c AnalyticsParameterMarketingTactic (String) (optional)
  • +///
  • @c AnalyticsParameterSourcePlatform (String) (optional)
  • +///
+static NSString *const kFIREventCampaignDetails NS_SWIFT_NAME(AnalyticsEventCampaignDetails) = + @"campaign_details"; + +/// Earn Virtual Currency event. This event tracks the awarding of virtual currency in your app. Log +/// this along with @c AnalyticsEventSpendVirtualCurrency to better understand your virtual economy. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterVirtualCurrencyName (String)
  • +///
  • @c AnalyticsParameterValue (Int or Double)
  • +///
+static NSString *const kFIREventEarnVirtualCurrency + NS_SWIFT_NAME(AnalyticsEventEarnVirtualCurrency) = @"earn_virtual_currency"; + +/// Generate Lead event. Log this event when a lead has been generated in the app to understand the +/// efficacy of your install and re-engagement campaigns. Note: If you supply the +/// @c AnalyticsParameterValue parameter, you must also supply the @c AnalyticsParameterCurrency +/// parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventGenerateLead NS_SWIFT_NAME(AnalyticsEventGenerateLead) = + @"generate_lead"; + +/// Join Group event. Log this event when a user joins a group such as a guild, team or family. Use +/// this event to analyze how popular certain groups or social features are in your app. Params: +/// +///
    +///
  • @c AnalyticsParameterGroupID (String)
  • +///
+static NSString *const kFIREventJoinGroup NS_SWIFT_NAME(AnalyticsEventJoinGroup) = @"join_group"; + +/// Level End event. Log this event when the user finishes a level. Params: +/// +///
    +///
  • @c AnalyticsParameterLevelName (String)
  • +///
  • @c AnalyticsParameterSuccess (String)
  • +///
+static NSString *const kFIREventLevelEnd NS_SWIFT_NAME(AnalyticsEventLevelEnd) = @"level_end"; + +/// Level Start event. Log this event when the user starts a new level. Params: +/// +///
    +///
  • @c AnalyticsParameterLevelName (String)
  • +///
+static NSString *const kFIREventLevelStart NS_SWIFT_NAME(AnalyticsEventLevelStart) = @"level_start"; + +/// Level Up event. This event signifies that a player has leveled up in your gaming app. It can +/// help you gauge the level distribution of your userbase and help you identify certain levels that +/// are difficult to pass. Params: +/// +///
    +///
  • @c AnalyticsParameterLevel (Int)
  • +///
  • @c AnalyticsParameterCharacter (String) (optional)
  • +///
+static NSString *const kFIREventLevelUp NS_SWIFT_NAME(AnalyticsEventLevelUp) = @"level_up"; + +/// Login event. Apps with a login feature can report this event to signify that a user has logged +/// in. +static NSString *const kFIREventLogin NS_SWIFT_NAME(AnalyticsEventLogin) = @"login"; + +/// Post Score event. Log this event when the user posts a score in your gaming app. This event can +/// help you understand how users are actually performing in your game and it can help you correlate +/// high scores with certain audiences or behaviors. Params: +/// +///
    +///
  • @c AnalyticsParameterScore (Int)
  • +///
  • @c AnalyticsParameterLevel (Int) (optional)
  • +///
  • @c AnalyticsParameterCharacter (String) (optional)
  • +///
+static NSString *const kFIREventPostScore NS_SWIFT_NAME(AnalyticsEventPostScore) = @"post_score"; + +/// E-Commerce Purchase event. This event signifies that an item(s) was purchased by a user. Note: +/// This is different from the in-app purchase event, which is reported automatically for App +/// Store-based apps. Note: If you supply the @c AnalyticsParameterValue parameter, you must also +/// supply the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed +/// accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterAffiliation (String) (optional)
  • +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterEndDate (String) (optional)
  • +///
  • @c AnalyticsParameterItemID (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterShipping (Double) (optional)
  • +///
  • @c AnalyticsParameterStartDate (String) (optional)
  • +///
  • @c AnalyticsParameterTax (Double) (optional)
  • +///
  • @c AnalyticsParameterTransactionID (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventPurchase NS_SWIFT_NAME(AnalyticsEventPurchase) = @"purchase"; + +/// E-Commerce Refund event. This event signifies that a refund was issued. Note: If you supply the +/// @c AnalyticsParameterValue parameter, you must also supply the @c AnalyticsParameterCurrency +/// parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterAffiliation (String) (optional)
  • +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterShipping (Double) (optional)
  • +///
  • @c AnalyticsParameterTax (Double) (optional)
  • +///
  • @c AnalyticsParameterTransactionID (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventRefund NS_SWIFT_NAME(AnalyticsEventRefund) = @"refund"; + +/// E-Commerce Remove from Cart event. This event signifies that an item(s) was removed from a cart. +/// Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply the @c +/// AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventRemoveFromCart NS_SWIFT_NAME(AnalyticsEventRemoveFromCart) = + @"remove_from_cart"; + +/// Screen View event. This event signifies a screen view. Use this when a screen transition occurs. +/// This event can be logged irrespective of whether automatic screen tracking is enabled. Params: +/// +///
    +///
  • @c AnalyticsParameterScreenClass (String) (optional)
  • +///
  • @c AnalyticsParameterScreenName (String) (optional)
  • +///
+static NSString *const kFIREventScreenView NS_SWIFT_NAME(AnalyticsEventScreenView) = @"screen_view"; + +/// Search event. Apps that support search features can use this event to contextualize search +/// operations by supplying the appropriate, corresponding parameters. This event can help you +/// identify the most popular content in your app. Params: +/// +///
    +///
  • @c AnalyticsParameterSearchTerm (String)
  • +///
  • @c AnalyticsParameterStartDate (String) (optional)
  • +///
  • @c AnalyticsParameterEndDate (String) (optional)
  • +///
  • @c AnalyticsParameterNumberOfNights (Int) (optional) for hotel bookings
  • +///
  • @c AnalyticsParameterNumberOfRooms (Int) (optional) for hotel bookings
  • +///
  • @c AnalyticsParameterNumberOfPassengers (Int) (optional) for travel bookings
  • +///
  • @c AnalyticsParameterOrigin (String) (optional)
  • +///
  • @c AnalyticsParameterDestination (String) (optional)
  • +///
  • @c AnalyticsParameterTravelClass (String) (optional) for travel bookings
  • +///
+static NSString *const kFIREventSearch NS_SWIFT_NAME(AnalyticsEventSearch) = @"search"; + +/// Select Content event. This general purpose event signifies that a user has selected some content +/// of a certain type in an app. The content can be any object in your app. This event can help you +/// identify popular content and categories of content in your app. Params: +/// +///
    +///
  • @c AnalyticsParameterContentType (String)
  • +///
  • @c AnalyticsParameterItemID (String)
  • +///
+static NSString *const kFIREventSelectContent NS_SWIFT_NAME(AnalyticsEventSelectContent) = + @"select_content"; + +/// Select Item event. This event signifies that an item was selected by a user from a list. Use the +/// appropriate parameters to contextualize the event. Use this event to discover the most popular +/// items selected. Params: +/// +///
    +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterItemListID (String) (optional)
  • +///
  • @c AnalyticsParameterItemListName (String) (optional)
  • +///
+static NSString *const kFIREventSelectItem NS_SWIFT_NAME(AnalyticsEventSelectItem) = @"select_item"; + +/// Select promotion event. This event signifies that a user has selected a promotion offer. Use the +/// appropriate parameters to contextualize the event, such as the item(s) for which the promotion +/// applies. Params: +/// +///
    +///
  • @c AnalyticsParameterCreativeName (String) (optional)
  • +///
  • @c AnalyticsParameterCreativeSlot (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterLocationID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionName (String) (optional)
  • +///
+static NSString *const kFIREventSelectPromotion NS_SWIFT_NAME(AnalyticsEventSelectPromotion) = + @"select_promotion"; + +/// Share event. Apps with social features can log the Share event to identify the most viral +/// content. Params: +/// +///
    +///
  • @c AnalyticsParameterContentType (String)
  • +///
  • @c AnalyticsParameterItemID (String)
  • +///
+static NSString *const kFIREventShare NS_SWIFT_NAME(AnalyticsEventShare) = @"share"; + +/// Sign Up event. This event indicates that a user has signed up for an account in your app. The +/// parameter signifies the method by which the user signed up. Use this event to understand the +/// different behaviors between logged in and logged out users. Params: +/// +///
    +///
  • @c AnalyticsParameterMethod (String)
  • +///
+static NSString *const kFIREventSignUp NS_SWIFT_NAME(AnalyticsEventSignUp) = @"sign_up"; + +/// Spend Virtual Currency event. This event tracks the sale of virtual goods in your app and can +/// help you identify which virtual goods are the most popular objects of purchase. Params: +/// +///
    +///
  • @c AnalyticsParameterItemName (String)
  • +///
  • @c AnalyticsParameterVirtualCurrencyName (String)
  • +///
  • @c AnalyticsParameterValue (Int or Double)
  • +///
+static NSString *const kFIREventSpendVirtualCurrency + NS_SWIFT_NAME(AnalyticsEventSpendVirtualCurrency) = @"spend_virtual_currency"; + +/// Tutorial Begin event. This event signifies the start of the on-boarding process in your app. Use +/// this in a funnel with @c AnalyticsEventTutorialComplete to understand how many users complete +/// this process and move on to the full app experience. +static NSString *const kFIREventTutorialBegin NS_SWIFT_NAME(AnalyticsEventTutorialBegin) = + @"tutorial_begin"; + +/// Tutorial End event. Use this event to signify the user's completion of your app's on-boarding +/// process. Add this to a funnel with @c AnalyticsEventTutorialBegin to gauge the completion rate +/// of your on-boarding process. +static NSString *const kFIREventTutorialComplete NS_SWIFT_NAME(AnalyticsEventTutorialComplete) = + @"tutorial_complete"; + +/// Unlock Achievement event. Log this event when the user has unlocked an achievement in your +/// game. Since achievements generally represent the breadth of a gaming experience, this event can +/// help you understand how many users are experiencing all that your game has to offer. Params: +/// +///
    +///
  • @c AnalyticsParameterAchievementID (String)
  • +///
+static NSString *const kFIREventUnlockAchievement NS_SWIFT_NAME(AnalyticsEventUnlockAchievement) = + @"unlock_achievement"; + +/// E-commerce View Cart event. This event signifies that a user has viewed their cart. Use this to +/// analyze your purchase funnel. Note: If you supply the @c AnalyticsParameterValue parameter, you +/// must also supply the @c AnalyticsParameterCurrency parameter so that revenue metrics can be +/// computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventViewCart NS_SWIFT_NAME(AnalyticsEventViewCart) = @"view_cart"; + +/// View Item event. This event signifies that a user has viewed an item. Use the appropriate +/// parameters to contextualize the event. Use this event to discover the most popular items viewed +/// in your app. Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply +/// the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventViewItem NS_SWIFT_NAME(AnalyticsEventViewItem) = @"view_item"; + +/// View Item List event. Log this event when a user sees a list of items or offerings. Params: +/// +///
    +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterItemListID (String) (optional)
  • +///
  • @c AnalyticsParameterItemListName (String) (optional)
  • +///
+static NSString *const kFIREventViewItemList NS_SWIFT_NAME(AnalyticsEventViewItemList) = + @"view_item_list"; + +/// View Promotion event. This event signifies that a promotion was shown to a user. Add this event +/// to a funnel with the @c AnalyticsEventAddToCart and @c AnalyticsEventPurchase to gauge your +/// conversion process. Params: +/// +///
    +///
  • @c AnalyticsParameterCreativeName (String) (optional)
  • +///
  • @c AnalyticsParameterCreativeSlot (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterLocationID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionName (String) (optional)
  • +///
+static NSString *const kFIREventViewPromotion NS_SWIFT_NAME(AnalyticsEventViewPromotion) = + @"view_promotion"; + +/// View Search Results event. Log this event when the user has been presented with the results of a +/// search. Params: +/// +///
    +///
  • @c AnalyticsParameterSearchTerm (String)
  • +///
+static NSString *const kFIREventViewSearchResults NS_SWIFT_NAME(AnalyticsEventViewSearchResults) = + @"view_search_results"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRParameterNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRParameterNames.h new file mode 100644 index 0000000..58a5a21 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRParameterNames.h @@ -0,0 +1,722 @@ +/// @file FIRParameterNames.h +/// +/// Predefined event parameter names. +/// +/// Params supply information that contextualize Events. You can associate up to 25 unique Params +/// with each Event type. Some Params are suggested below for certain common Events, but you are +/// not limited to these. You may supply extra Params for suggested Events or custom Params for +/// Custom events. Param names can be up to 40 characters long, may only contain alphanumeric +/// characters and underscores ("_"), and must start with an alphabetic character. Param values can +/// be up to 100 characters long for standard Google Analytics properties and up to 500 characters +/// long for Google Analytics 360 properties. The "firebase_", "google_", and "ga_" prefixes are +/// reserved and should not be used. + +#import + +/// Game achievement ID (String). +///
+///     let params = [
+///       AnalyticsParameterAchievementID : "10_matches_won",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAchievementID NS_SWIFT_NAME(AnalyticsParameterAchievementID) = + @"achievement_id"; + +/// The ad format (e.g. Banner, Interstitial, Rewarded, Native, Rewarded Interstitial, Instream). +/// (String). +///
+///     let params = [
+///       AnalyticsParameterAdFormat : "Banner",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdFormat NS_SWIFT_NAME(AnalyticsParameterAdFormat) = + @"ad_format"; + +/// Ad Network Click ID (String). Used for network-specific click IDs which vary in format. +///
+///     let params = [
+///       AnalyticsParameterAdNetworkClickID : "1234567",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdNetworkClickID + NS_SWIFT_NAME(AnalyticsParameterAdNetworkClickID) = @"aclid"; + +/// The ad platform (e.g. MoPub, IronSource) (String). +///
+///     let params = [
+///       AnalyticsParameterAdPlatform : "MoPub",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdPlatform NS_SWIFT_NAME(AnalyticsParameterAdPlatform) = + @"ad_platform"; + +/// The ad source (e.g. AdColony) (String). +///
+///     let params = [
+///       AnalyticsParameterAdSource : "AdColony",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdSource NS_SWIFT_NAME(AnalyticsParameterAdSource) = + @"ad_source"; + +/// The ad unit name (e.g. Banner_03) (String). +///
+///     let params = [
+///       AnalyticsParameterAdUnitName : "Banner_03",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdUnitName NS_SWIFT_NAME(AnalyticsParameterAdUnitName) = + @"ad_unit_name"; + +/// A product affiliation to designate a supplying company or brick and mortar store location +/// (String).
+///     let params = [
+///       AnalyticsParameterAffiliation : "Google Store",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAffiliation NS_SWIFT_NAME(AnalyticsParameterAffiliation) = + @"affiliation"; + +/// Campaign custom parameter (String). Used as a method of capturing custom data in a campaign. +/// Use varies by network. +///
+///     let params = [
+///       AnalyticsParameterCP1 : "custom_data",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCP1 NS_SWIFT_NAME(AnalyticsParameterCP1) = @"cp1"; + +/// The individual campaign name, slogan, promo code, etc. Some networks have pre-defined macro to +/// capture campaign information, otherwise can be populated by developer. Highly Recommended +/// (String). +///
+///     let params = [
+///       AnalyticsParameterCampaign : "winter_promotion",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCampaign NS_SWIFT_NAME(AnalyticsParameterCampaign) = + @"campaign"; + +/// Campaign ID (String). Used for keyword analysis to identify a specific product promotion or +/// strategic campaign. This is a required key for GA4 data import. +///
+///     let params = [
+///       AnalyticsParameterCampaignID : "7877652710",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCampaignID NS_SWIFT_NAME(AnalyticsParameterCampaignID) = + @"campaign_id"; + +/// Character used in game (String). +///
+///     let params = [
+///       AnalyticsParameterCharacter : "beat_boss",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCharacter NS_SWIFT_NAME(AnalyticsParameterCharacter) = + @"character"; + +/// Campaign content (String). +static NSString *const kFIRParameterContent NS_SWIFT_NAME(AnalyticsParameterContent) = @"content"; + +/// Type of content selected (String). +///
+///     let params = [
+///       AnalyticsParameterContentType : "news article",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterContentType NS_SWIFT_NAME(AnalyticsParameterContentType) = + @"content_type"; + +/// Coupon code used for a purchase (String). +///
+///     let params = [
+///       AnalyticsParameterCoupon : "SUMMER_FUN",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCoupon NS_SWIFT_NAME(AnalyticsParameterCoupon) = @"coupon"; + +/// Creative Format (String). Used to identify the high-level classification of the type of ad +/// served by a specific campaign. +///
+///     let params = [
+///       AnalyticsParameterCreativeFormat : "display",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCreativeFormat NS_SWIFT_NAME(AnalyticsParameterCreativeFormat) = + @"creative_format"; + +/// The name of a creative used in a promotional spot (String). +///
+///     let params = [
+///       AnalyticsParameterCreativeName : "Summer Sale",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCreativeName NS_SWIFT_NAME(AnalyticsParameterCreativeName) = + @"creative_name"; + +/// The name of a creative slot (String). +///
+///     let params = [
+///       AnalyticsParameterCreativeSlot : "summer_banner2",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCreativeSlot NS_SWIFT_NAME(AnalyticsParameterCreativeSlot) = + @"creative_slot"; + +/// Currency of the purchase or items associated with the event, in 3-letter +/// ISO_4217 format (String). +///
+///     let params = [
+///       AnalyticsParameterCurrency : "USD",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCurrency NS_SWIFT_NAME(AnalyticsParameterCurrency) = + @"currency"; + +/// Flight or Travel destination (String). +///
+///     let params = [
+///       AnalyticsParameterDestination : "Mountain View, CA",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterDestination NS_SWIFT_NAME(AnalyticsParameterDestination) = + @"destination"; + +/// Monetary value of discount associated with a purchase (Double). +///
+///     let params = [
+///       AnalyticsParameterDiscount : 2.0,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $2.00 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterDiscount NS_SWIFT_NAME(AnalyticsParameterDiscount) = + @"discount"; + +/// The arrival date, check-out date or rental end date for the item. This should be in +/// YYYY-MM-DD format (String). +///
+///     let params = [
+///       AnalyticsParameterEndDate : "2015-09-14",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterEndDate NS_SWIFT_NAME(AnalyticsParameterEndDate) = @"end_date"; + +/// Indicates that the associated event should either extend the current session or start a new +/// session if no session was active when the event was logged. Specify 1 to extend the current +/// session or to start a new session; any other value will not extend or start a session. +///
+///     let params = [
+///       AnalyticsParameterExtendSession : 1,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterExtendSession NS_SWIFT_NAME(AnalyticsParameterExtendSession) = + @"extend_session"; + +/// Flight number for travel events (String). +///
+///     let params = [
+///       AnalyticsParameterFlightNumber : "ZZ800",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterFlightNumber NS_SWIFT_NAME(AnalyticsParameterFlightNumber) = + @"flight_number"; + +/// Group/clan/guild ID (String). +///
+///     let params = [
+///       AnalyticsParameterGroupID : "g1",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterGroupID NS_SWIFT_NAME(AnalyticsParameterGroupID) = @"group_id"; + +/// The index of the item in a list (Int). +///
+///     let params = [
+///       AnalyticsParameterIndex : 5,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterIndex NS_SWIFT_NAME(AnalyticsParameterIndex) = @"index"; + +/// Item brand (String). +///
+///     let params = [
+///       AnalyticsParameterItemBrand : "Google",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemBrand NS_SWIFT_NAME(AnalyticsParameterItemBrand) = + @"item_brand"; + +/// Item category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory NS_SWIFT_NAME(AnalyticsParameterItemCategory) = + @"item_category"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory2 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory2 NS_SWIFT_NAME(AnalyticsParameterItemCategory2) = + @"item_category2"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory3 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory3 NS_SWIFT_NAME(AnalyticsParameterItemCategory3) = + @"item_category3"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory4 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory4 NS_SWIFT_NAME(AnalyticsParameterItemCategory4) = + @"item_category4"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory5 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory5 NS_SWIFT_NAME(AnalyticsParameterItemCategory5) = + @"item_category5"; + +/// Item ID (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemID : "SKU_12345",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemID NS_SWIFT_NAME(AnalyticsParameterItemID) = @"item_id"; + +/// The ID of the list in which the item was presented to the user (String). +///
+///     let params = [
+///       AnalyticsParameterItemListID : "ABC123",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemListID NS_SWIFT_NAME(AnalyticsParameterItemListID) = + @"item_list_id"; + +/// The name of the list in which the item was presented to the user (String). +///
+///     let params = [
+///       AnalyticsParameterItemListName : "Related products",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemListName NS_SWIFT_NAME(AnalyticsParameterItemListName) = + @"item_list_name"; + +/// Item Name (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemName : "jeggings",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemName NS_SWIFT_NAME(AnalyticsParameterItemName) = + @"item_name"; + +/// Item variant (String). +///
+///     let params = [
+///       AnalyticsParameterItemVariant : "Black",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemVariant NS_SWIFT_NAME(AnalyticsParameterItemVariant) = + @"item_variant"; + +/// The list of items involved in the transaction expressed as `[[String: Any]]`. +///
+///     let params = [
+///       AnalyticsParameterItems : [
+///         [AnalyticsParameterItemName : "jeggings", AnalyticsParameterItemCategory : "pants"],
+///         [AnalyticsParameterItemName : "boots", AnalyticsParameterItemCategory : "shoes"],
+///       ],
+///     ]
+/// 
+static NSString *const kFIRParameterItems NS_SWIFT_NAME(AnalyticsParameterItems) = @"items"; + +/// Level in game (Int). +///
+///     let params = [
+///       AnalyticsParameterLevel : 42,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLevel NS_SWIFT_NAME(AnalyticsParameterLevel) = @"level"; + +/// The name of a level in a game (String). +///
+///     let params = [
+///       AnalyticsParameterLevelName : "room_1",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLevelName NS_SWIFT_NAME(AnalyticsParameterLevelName) = + @"level_name"; + +/// Location (String). The Google Place ID +/// that corresponds to the associated event. Alternatively, you can supply your own custom +/// Location ID. +///
+///     let params = [
+///       AnalyticsParameterLocation : "ChIJiyj437sx3YAR9kUWC8QkLzQ",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLocation NS_SWIFT_NAME(AnalyticsParameterLocation) = + @"location"; + +/// The location associated with the event. Preferred to be the Google +/// Place ID that corresponds to the +/// associated item but could be overridden to a custom location ID string.(String). +///
+///     let params = [
+///       AnalyticsParameterLocationID : "ChIJiyj437sx3YAR9kUWC8QkLzQ",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLocationID NS_SWIFT_NAME(AnalyticsParameterLocationID) = + @"location_id"; + +/// Marketing Tactic (String). Used to identify the targeting criteria applied to a specific +/// campaign. +///
+///     let params = [
+///       AnalyticsParameterMarketingTactic : "Remarketing",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterMarketingTactic + NS_SWIFT_NAME(AnalyticsParameterMarketingTactic) = @"marketing_tactic"; + +/// The advertising or marketing medium, for example: cpc, banner, email, push. Highly recommended +/// (String). +///
+///     let params = [
+///       AnalyticsParameterMedium : "email",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterMedium NS_SWIFT_NAME(AnalyticsParameterMedium) = @"medium"; + +/// A particular approach used in an operation; for example, "facebook" or "email" in the context +/// of a sign_up or login event. (String). +///
+///     let params = [
+///       AnalyticsParameterMethod : "google",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterMethod NS_SWIFT_NAME(AnalyticsParameterMethod) = @"method"; + +/// Number of nights staying at hotel (Int). +///
+///     let params = [
+///       AnalyticsParameterNumberOfNights : 3,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterNumberOfNights + NS_SWIFT_NAME(AnalyticsParameterNumberOfNights) = @"number_of_nights"; + +/// Number of passengers traveling (Int). +///
+///     let params = [
+///       AnalyticsParameterNumberOfPassengers : 11,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterNumberOfPassengers + NS_SWIFT_NAME(AnalyticsParameterNumberOfPassengers) = @"number_of_passengers"; + +/// Number of rooms for travel events (Int). +///
+///     let params = [
+///       AnalyticsParameterNumberOfRooms : 2,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterNumberOfRooms NS_SWIFT_NAME(AnalyticsParameterNumberOfRooms) = + @"number_of_rooms"; + +/// Flight or Travel origin (String). +///
+///     let params = [
+///       AnalyticsParameterOrigin : "Mountain View, CA",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterOrigin NS_SWIFT_NAME(AnalyticsParameterOrigin) = @"origin"; + +/// The chosen method of payment (String). +///
+///     let params = [
+///       AnalyticsParameterPaymentType : "Visa",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPaymentType NS_SWIFT_NAME(AnalyticsParameterPaymentType) = + @"payment_type"; + +/// Purchase price (Double). +///
+///     let params = [
+///       AnalyticsParameterPrice : 1.0,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $1.00 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPrice NS_SWIFT_NAME(AnalyticsParameterPrice) = @"price"; + +/// The ID of a product promotion (String). +///
+///     let params = [
+///       AnalyticsParameterPromotionID : "ABC123",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPromotionID NS_SWIFT_NAME(AnalyticsParameterPromotionID) = + @"promotion_id"; + +/// The name of a product promotion (String). +///
+///     let params = [
+///       AnalyticsParameterPromotionName : "Summer Sale",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPromotionName NS_SWIFT_NAME(AnalyticsParameterPromotionName) = + @"promotion_name"; + +/// Purchase quantity (Int). +///
+///     let params = [
+///       AnalyticsParameterQuantity : 1,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterQuantity NS_SWIFT_NAME(AnalyticsParameterQuantity) = + @"quantity"; + +/// Score in game (Int). +///
+///     let params = [
+///       AnalyticsParameterScore : 4200,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterScore NS_SWIFT_NAME(AnalyticsParameterScore) = @"score"; + +/// Current screen class, such as the class name of the UIViewController, logged with screen_view +/// event and added to every event (String). +///
+///     let params = [
+///       AnalyticsParameterScreenClass : "LoginViewController",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterScreenClass NS_SWIFT_NAME(AnalyticsParameterScreenClass) = + @"screen_class"; + +/// Current screen name, such as the name of the UIViewController, logged with screen_view event and +/// added to every event (String). +///
+///     let params = [
+///       AnalyticsParameterScreenName : "LoginView",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterScreenName NS_SWIFT_NAME(AnalyticsParameterScreenName) = + @"screen_name"; + +/// The search string/keywords used (String). +///
+///     let params = [
+///       AnalyticsParameterSearchTerm : "periodic table",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSearchTerm NS_SWIFT_NAME(AnalyticsParameterSearchTerm) = + @"search_term"; + +/// Shipping cost associated with a transaction (Double). +///
+///     let params = [
+///       AnalyticsParameterShipping : 5.99,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $5.99 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterShipping NS_SWIFT_NAME(AnalyticsParameterShipping) = + @"shipping"; + +/// The shipping tier (e.g. Ground, Air, Next-day) selected for delivery of the purchased item +/// (String). +///
+///     let params = [
+///       AnalyticsParameterShippingTier : "Ground",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterShippingTier NS_SWIFT_NAME(AnalyticsParameterShippingTier) = + @"shipping_tier"; + +/// The origin of your traffic, such as an Ad network (for example, google) or partner (urban +/// airship). Identify the advertiser, site, publication, etc. that is sending traffic to your +/// property. Highly recommended (String). +///
+///     let params = [
+///       AnalyticsParameterSource : "InMobi",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSource NS_SWIFT_NAME(AnalyticsParameterSource) = @"source"; + +/// Source Platform (String). Used to identify the platform responsible for directing traffic to a +/// given Analytics property (e.g., a buying platform where budgets, targeting criteria, etc. are +/// set, a platform for managing organic traffic data, etc.). +///
+///     let params = [
+///       AnalyticsParameterSourcePlatform : "sa360",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSourcePlatform NS_SWIFT_NAME(AnalyticsParameterSourcePlatform) = + @"source_platform"; + +/// The departure date, check-in date or rental start date for the item. This should be in +/// YYYY-MM-DD format (String). +///
+///     let params = [
+///       AnalyticsParameterStartDate : "2015-09-14",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterStartDate NS_SWIFT_NAME(AnalyticsParameterStartDate) = + @"start_date"; + +/// The result of an operation. Specify 1 to indicate success and 0 to indicate failure (Int). +///
+///     let params = [
+///       AnalyticsParameterSuccess : 1,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSuccess NS_SWIFT_NAME(AnalyticsParameterSuccess) = @"success"; + +/// Tax cost associated with a transaction (Double). +///
+///     let params = [
+///       AnalyticsParameterTax : 2.43,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $2.43 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTax NS_SWIFT_NAME(AnalyticsParameterTax) = @"tax"; + +/// If you're manually tagging keyword campaigns, you should use utm_term to specify the keyword +/// (String). +///
+///     let params = [
+///       AnalyticsParameterTerm : "game",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTerm NS_SWIFT_NAME(AnalyticsParameterTerm) = @"term"; + +/// The unique identifier of a transaction (String). +///
+///     let params = [
+///       AnalyticsParameterTransactionID : "T12345",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTransactionID NS_SWIFT_NAME(AnalyticsParameterTransactionID) = + @"transaction_id"; + +/// Travel class (String). +///
+///     let params = [
+///       AnalyticsParameterTravelClass : "business",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTravelClass NS_SWIFT_NAME(AnalyticsParameterTravelClass) = + @"travel_class"; + +/// A context-specific numeric value which is accumulated automatically for each event type. This is +/// a general purpose parameter that is useful for accumulating a key metric that pertains to an +/// event. Examples include revenue, distance, time and points. Value should be specified as Int or +/// Double. +/// Notes: Values for pre-defined currency-related events (such as @c AnalyticsEventAddToCart) +/// should be supplied using Double and must be accompanied by a @c AnalyticsParameterCurrency +/// parameter. The valid range of accumulated values is +/// [-9,223,372,036,854.77, 9,223,372,036,854.77]. Supplying a non-numeric value, omitting the +/// corresponding @c AnalyticsParameterCurrency parameter, or supplying an invalid +/// currency code for conversion events will cause that +/// conversion to be omitted from reporting. +///
+///     let params = [
+///       AnalyticsParameterValue : 3.99,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $3.99 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterValue NS_SWIFT_NAME(AnalyticsParameterValue) = @"value"; + +/// Name of virtual currency type (String). +///
+///     let params = [
+///       AnalyticsParameterVirtualCurrencyName : "virtual_currency_name",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterVirtualCurrencyName + NS_SWIFT_NAME(AnalyticsParameterVirtualCurrencyName) = @"virtual_currency_name"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRUserPropertyNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRUserPropertyNames.h new file mode 100644 index 0000000..2442d8a --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FIRUserPropertyNames.h @@ -0,0 +1,28 @@ +/// @file FIRUserPropertyNames.h +/// +/// Predefined user property names. +/// +/// A UserProperty is an attribute that describes the app-user. By supplying UserProperties, you can +/// later analyze different behaviors of various segments of your userbase. You may supply up to 25 +/// unique UserProperties per app, and you can use the name and value of your choosing for each one. +/// UserProperty names can be up to 24 characters long, may only contain alphanumeric characters and +/// underscores ("_"), and must start with an alphabetic character. UserProperty values can be up to +/// 36 characters long. The "firebase_", "google_", and "ga_" prefixes are reserved and should not +/// be used. + +#import + +/// Indicates whether events logged by Google Analytics can be used to personalize ads for the user. +/// Set to "YES" to enable, or "NO" to disable. Default is enabled. See the +/// documentation for +/// more details and information about related settings. +/// +///
+///     Analytics.setUserProperty("NO", forName: AnalyticsUserPropertyAllowAdPersonalizationSignals)
+/// 
+static NSString *const kFIRUserPropertyAllowAdPersonalizationSignals + NS_SWIFT_NAME(AnalyticsUserPropertyAllowAdPersonalizationSignals) = @"allow_personalized_ads"; + +/// The method used to sign in. For example, "google", "facebook" or "twitter". +static NSString *const kFIRUserPropertySignUpMethod + NS_SWIFT_NAME(AnalyticsUserPropertySignUpMethod) = @"sign_up_method"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics-Swift.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics-Swift.h new file mode 100644 index 0000000..3dbf01a --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics-Swift.h @@ -0,0 +1,620 @@ +#if 0 +#elif defined(__arm64__) && __arm64__ +// Generated by Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +#ifndef FIREBASEANALYTICS_SWIFT_H +#define FIREBASEANALYTICS_SWIFT_H +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgcc-compat" + +#if !defined(__has_include) +# define __has_include(x) 0 +#endif +#if !defined(__has_attribute) +# define __has_attribute(x) 0 +#endif +#if !defined(__has_feature) +# define __has_feature(x) 0 +#endif +#if !defined(__has_warning) +# define __has_warning(x) 0 +#endif + +#if __has_include() +# include +#endif + +#pragma clang diagnostic ignored "-Wauto-import" +#if defined(__OBJC__) +#include +#endif +#if defined(__cplusplus) +#include +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#endif +#if defined(__cplusplus) +#if defined(__arm64e__) && __has_include() +# include +#else +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreserved-macro-identifier" +# ifndef __ptrauth_swift_value_witness_function_pointer +# define __ptrauth_swift_value_witness_function_pointer(x) +# endif +# ifndef __ptrauth_swift_class_method_pointer +# define __ptrauth_swift_class_method_pointer(x) +# endif +#pragma clang diagnostic pop +#endif +#endif + +#if !defined(SWIFT_TYPEDEFS) +# define SWIFT_TYPEDEFS 1 +# if __has_include() +# include +# elif !defined(__cplusplus) +typedef uint_least16_t char16_t; +typedef uint_least32_t char32_t; +# endif +typedef float swift_float2 __attribute__((__ext_vector_type__(2))); +typedef float swift_float3 __attribute__((__ext_vector_type__(3))); +typedef float swift_float4 __attribute__((__ext_vector_type__(4))); +typedef double swift_double2 __attribute__((__ext_vector_type__(2))); +typedef double swift_double3 __attribute__((__ext_vector_type__(3))); +typedef double swift_double4 __attribute__((__ext_vector_type__(4))); +typedef int swift_int2 __attribute__((__ext_vector_type__(2))); +typedef int swift_int3 __attribute__((__ext_vector_type__(3))); +typedef int swift_int4 __attribute__((__ext_vector_type__(4))); +typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2))); +typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3))); +typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); +#endif + +#if !defined(SWIFT_PASTE) +# define SWIFT_PASTE_HELPER(x, y) x##y +# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) +#endif +#if !defined(SWIFT_METATYPE) +# define SWIFT_METATYPE(X) Class +#endif +#if !defined(SWIFT_CLASS_PROPERTY) +# if __has_feature(objc_class_property) +# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__ +# else +# define SWIFT_CLASS_PROPERTY(...) +# endif +#endif +#if !defined(SWIFT_RUNTIME_NAME) +# if __has_attribute(objc_runtime_name) +# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) +# else +# define SWIFT_RUNTIME_NAME(X) +# endif +#endif +#if !defined(SWIFT_COMPILE_NAME) +# if __has_attribute(swift_name) +# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) +# else +# define SWIFT_COMPILE_NAME(X) +# endif +#endif +#if !defined(SWIFT_METHOD_FAMILY) +# if __has_attribute(objc_method_family) +# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X))) +# else +# define SWIFT_METHOD_FAMILY(X) +# endif +#endif +#if !defined(SWIFT_NOESCAPE) +# if __has_attribute(noescape) +# define SWIFT_NOESCAPE __attribute__((noescape)) +# else +# define SWIFT_NOESCAPE +# endif +#endif +#if !defined(SWIFT_RELEASES_ARGUMENT) +# if __has_attribute(ns_consumed) +# define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed)) +# else +# define SWIFT_RELEASES_ARGUMENT +# endif +#endif +#if !defined(SWIFT_WARN_UNUSED_RESULT) +# if __has_attribute(warn_unused_result) +# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +# else +# define SWIFT_WARN_UNUSED_RESULT +# endif +#endif +#if !defined(SWIFT_NORETURN) +# if __has_attribute(noreturn) +# define SWIFT_NORETURN __attribute__((noreturn)) +# else +# define SWIFT_NORETURN +# endif +#endif +#if !defined(SWIFT_CLASS_EXTRA) +# define SWIFT_CLASS_EXTRA +#endif +#if !defined(SWIFT_PROTOCOL_EXTRA) +# define SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_ENUM_EXTRA) +# define SWIFT_ENUM_EXTRA +#endif +#if !defined(SWIFT_CLASS) +# if __has_attribute(objc_subclassing_restricted) +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# else +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# endif +#endif +#if !defined(SWIFT_RESILIENT_CLASS) +# if __has_attribute(objc_class_stub) +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub)) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME) +# else +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME) +# endif +#endif +#if !defined(SWIFT_PROTOCOL) +# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_EXTENSION) +# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) +#endif +#if !defined(OBJC_DESIGNATED_INITIALIZER) +# if __has_attribute(objc_designated_initializer) +# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +# else +# define OBJC_DESIGNATED_INITIALIZER +# endif +#endif +#if !defined(SWIFT_ENUM_ATTR) +# if __has_attribute(enum_extensibility) +# define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility))) +# else +# define SWIFT_ENUM_ATTR(_extensibility) +# endif +#endif +#if !defined(SWIFT_ENUM) +# define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# if __has_feature(generalized_swift_name) +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# else +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility) +# endif +#endif +#if !defined(SWIFT_UNAVAILABLE) +# define SWIFT_UNAVAILABLE __attribute__((unavailable)) +#endif +#if !defined(SWIFT_UNAVAILABLE_MSG) +# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg))) +#endif +#if !defined(SWIFT_AVAILABILITY) +# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__))) +#endif +#if !defined(SWIFT_WEAK_IMPORT) +# define SWIFT_WEAK_IMPORT __attribute__((weak_import)) +#endif +#if !defined(SWIFT_DEPRECATED) +# define SWIFT_DEPRECATED __attribute__((deprecated)) +#endif +#if !defined(SWIFT_DEPRECATED_MSG) +# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__))) +#endif +#if !defined(SWIFT_DEPRECATED_OBJC) +# if __has_feature(attribute_diagnose_if_objc) +# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning"))) +# else +# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) +# endif +#endif +#if defined(__OBJC__) +#if !defined(IBSegueAction) +# define IBSegueAction +#endif +#endif +#if !defined(SWIFT_EXTERN) +# if defined(__cplusplus) +# define SWIFT_EXTERN extern "C" +# else +# define SWIFT_EXTERN extern +# endif +#endif +#if !defined(SWIFT_CALL) +# define SWIFT_CALL __attribute__((swiftcall)) +#endif +#if !defined(SWIFT_INDIRECT_RESULT) +# define SWIFT_INDIRECT_RESULT __attribute__((swift_indirect_result)) +#endif +#if !defined(SWIFT_CONTEXT) +# define SWIFT_CONTEXT __attribute__((swift_context)) +#endif +#if !defined(SWIFT_ERROR_RESULT) +# define SWIFT_ERROR_RESULT __attribute__((swift_error_result)) +#endif +#if defined(__cplusplus) +# define SWIFT_NOEXCEPT noexcept +#else +# define SWIFT_NOEXCEPT +#endif +#if !defined(SWIFT_C_INLINE_THUNK) +# if __has_attribute(always_inline) +# if __has_attribute(nodebug) +# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) __attribute__((nodebug)) +# else +# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) +# endif +# else +# define SWIFT_C_INLINE_THUNK inline +# endif +#endif +#if defined(_WIN32) +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL __declspec(dllimport) +#endif +#else +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL +#endif +#endif +#if defined(__OBJC__) +#if __has_feature(objc_modules) +#if __has_warning("-Watimport-in-framework-header") +#pragma clang diagnostic ignored "-Watimport-in-framework-header" +#endif +#endif + +#endif +#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" +#pragma clang diagnostic ignored "-Wduplicate-method-arg" +#if __has_warning("-Wpragma-clang-attribute") +# pragma clang diagnostic ignored "-Wpragma-clang-attribute" +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wnullability" +#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension" + +#if __has_attribute(external_source_symbol) +# pragma push_macro("any") +# undef any +# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="FirebaseAnalytics",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) +# pragma pop_macro("any") +#endif + +#if defined(__OBJC__) + +#endif +#if __has_attribute(external_source_symbol) +# pragma clang attribute pop +#endif +#if defined(__cplusplus) +#endif +#pragma clang diagnostic pop +#endif + +#elif defined(__x86_64__) && __x86_64__ +// Generated by Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +#ifndef FIREBASEANALYTICS_SWIFT_H +#define FIREBASEANALYTICS_SWIFT_H +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgcc-compat" + +#if !defined(__has_include) +# define __has_include(x) 0 +#endif +#if !defined(__has_attribute) +# define __has_attribute(x) 0 +#endif +#if !defined(__has_feature) +# define __has_feature(x) 0 +#endif +#if !defined(__has_warning) +# define __has_warning(x) 0 +#endif + +#if __has_include() +# include +#endif + +#pragma clang diagnostic ignored "-Wauto-import" +#if defined(__OBJC__) +#include +#endif +#if defined(__cplusplus) +#include +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#endif +#if defined(__cplusplus) +#if defined(__arm64e__) && __has_include() +# include +#else +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreserved-macro-identifier" +# ifndef __ptrauth_swift_value_witness_function_pointer +# define __ptrauth_swift_value_witness_function_pointer(x) +# endif +# ifndef __ptrauth_swift_class_method_pointer +# define __ptrauth_swift_class_method_pointer(x) +# endif +#pragma clang diagnostic pop +#endif +#endif + +#if !defined(SWIFT_TYPEDEFS) +# define SWIFT_TYPEDEFS 1 +# if __has_include() +# include +# elif !defined(__cplusplus) +typedef uint_least16_t char16_t; +typedef uint_least32_t char32_t; +# endif +typedef float swift_float2 __attribute__((__ext_vector_type__(2))); +typedef float swift_float3 __attribute__((__ext_vector_type__(3))); +typedef float swift_float4 __attribute__((__ext_vector_type__(4))); +typedef double swift_double2 __attribute__((__ext_vector_type__(2))); +typedef double swift_double3 __attribute__((__ext_vector_type__(3))); +typedef double swift_double4 __attribute__((__ext_vector_type__(4))); +typedef int swift_int2 __attribute__((__ext_vector_type__(2))); +typedef int swift_int3 __attribute__((__ext_vector_type__(3))); +typedef int swift_int4 __attribute__((__ext_vector_type__(4))); +typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2))); +typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3))); +typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); +#endif + +#if !defined(SWIFT_PASTE) +# define SWIFT_PASTE_HELPER(x, y) x##y +# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) +#endif +#if !defined(SWIFT_METATYPE) +# define SWIFT_METATYPE(X) Class +#endif +#if !defined(SWIFT_CLASS_PROPERTY) +# if __has_feature(objc_class_property) +# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__ +# else +# define SWIFT_CLASS_PROPERTY(...) +# endif +#endif +#if !defined(SWIFT_RUNTIME_NAME) +# if __has_attribute(objc_runtime_name) +# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) +# else +# define SWIFT_RUNTIME_NAME(X) +# endif +#endif +#if !defined(SWIFT_COMPILE_NAME) +# if __has_attribute(swift_name) +# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) +# else +# define SWIFT_COMPILE_NAME(X) +# endif +#endif +#if !defined(SWIFT_METHOD_FAMILY) +# if __has_attribute(objc_method_family) +# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X))) +# else +# define SWIFT_METHOD_FAMILY(X) +# endif +#endif +#if !defined(SWIFT_NOESCAPE) +# if __has_attribute(noescape) +# define SWIFT_NOESCAPE __attribute__((noescape)) +# else +# define SWIFT_NOESCAPE +# endif +#endif +#if !defined(SWIFT_RELEASES_ARGUMENT) +# if __has_attribute(ns_consumed) +# define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed)) +# else +# define SWIFT_RELEASES_ARGUMENT +# endif +#endif +#if !defined(SWIFT_WARN_UNUSED_RESULT) +# if __has_attribute(warn_unused_result) +# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +# else +# define SWIFT_WARN_UNUSED_RESULT +# endif +#endif +#if !defined(SWIFT_NORETURN) +# if __has_attribute(noreturn) +# define SWIFT_NORETURN __attribute__((noreturn)) +# else +# define SWIFT_NORETURN +# endif +#endif +#if !defined(SWIFT_CLASS_EXTRA) +# define SWIFT_CLASS_EXTRA +#endif +#if !defined(SWIFT_PROTOCOL_EXTRA) +# define SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_ENUM_EXTRA) +# define SWIFT_ENUM_EXTRA +#endif +#if !defined(SWIFT_CLASS) +# if __has_attribute(objc_subclassing_restricted) +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# else +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# endif +#endif +#if !defined(SWIFT_RESILIENT_CLASS) +# if __has_attribute(objc_class_stub) +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub)) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME) +# else +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME) +# endif +#endif +#if !defined(SWIFT_PROTOCOL) +# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_EXTENSION) +# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) +#endif +#if !defined(OBJC_DESIGNATED_INITIALIZER) +# if __has_attribute(objc_designated_initializer) +# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +# else +# define OBJC_DESIGNATED_INITIALIZER +# endif +#endif +#if !defined(SWIFT_ENUM_ATTR) +# if __has_attribute(enum_extensibility) +# define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility))) +# else +# define SWIFT_ENUM_ATTR(_extensibility) +# endif +#endif +#if !defined(SWIFT_ENUM) +# define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# if __has_feature(generalized_swift_name) +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# else +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility) +# endif +#endif +#if !defined(SWIFT_UNAVAILABLE) +# define SWIFT_UNAVAILABLE __attribute__((unavailable)) +#endif +#if !defined(SWIFT_UNAVAILABLE_MSG) +# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg))) +#endif +#if !defined(SWIFT_AVAILABILITY) +# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__))) +#endif +#if !defined(SWIFT_WEAK_IMPORT) +# define SWIFT_WEAK_IMPORT __attribute__((weak_import)) +#endif +#if !defined(SWIFT_DEPRECATED) +# define SWIFT_DEPRECATED __attribute__((deprecated)) +#endif +#if !defined(SWIFT_DEPRECATED_MSG) +# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__))) +#endif +#if !defined(SWIFT_DEPRECATED_OBJC) +# if __has_feature(attribute_diagnose_if_objc) +# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning"))) +# else +# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) +# endif +#endif +#if defined(__OBJC__) +#if !defined(IBSegueAction) +# define IBSegueAction +#endif +#endif +#if !defined(SWIFT_EXTERN) +# if defined(__cplusplus) +# define SWIFT_EXTERN extern "C" +# else +# define SWIFT_EXTERN extern +# endif +#endif +#if !defined(SWIFT_CALL) +# define SWIFT_CALL __attribute__((swiftcall)) +#endif +#if !defined(SWIFT_INDIRECT_RESULT) +# define SWIFT_INDIRECT_RESULT __attribute__((swift_indirect_result)) +#endif +#if !defined(SWIFT_CONTEXT) +# define SWIFT_CONTEXT __attribute__((swift_context)) +#endif +#if !defined(SWIFT_ERROR_RESULT) +# define SWIFT_ERROR_RESULT __attribute__((swift_error_result)) +#endif +#if defined(__cplusplus) +# define SWIFT_NOEXCEPT noexcept +#else +# define SWIFT_NOEXCEPT +#endif +#if !defined(SWIFT_C_INLINE_THUNK) +# if __has_attribute(always_inline) +# if __has_attribute(nodebug) +# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) __attribute__((nodebug)) +# else +# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) +# endif +# else +# define SWIFT_C_INLINE_THUNK inline +# endif +#endif +#if defined(_WIN32) +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL __declspec(dllimport) +#endif +#else +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL +#endif +#endif +#if defined(__OBJC__) +#if __has_feature(objc_modules) +#if __has_warning("-Watimport-in-framework-header") +#pragma clang diagnostic ignored "-Watimport-in-framework-header" +#endif +#endif + +#endif +#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" +#pragma clang diagnostic ignored "-Wduplicate-method-arg" +#if __has_warning("-Wpragma-clang-attribute") +# pragma clang diagnostic ignored "-Wpragma-clang-attribute" +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wnullability" +#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension" + +#if __has_attribute(external_source_symbol) +# pragma push_macro("any") +# undef any +# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="FirebaseAnalytics",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) +# pragma pop_macro("any") +#endif + +#if defined(__OBJC__) + +#endif +#if __has_attribute(external_source_symbol) +# pragma clang attribute pop +#endif +#if defined(__cplusplus) +#endif +#pragma clang diagnostic pop +#endif + +#else +#error unsupported Swift architecture +#endif diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics-umbrella.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics-umbrella.h new file mode 100644 index 0000000..58342c6 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics-umbrella.h @@ -0,0 +1,24 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "FIRAnalytics+AppDelegate.h" +#import "FIRAnalytics+Consent.h" +#import "FIRAnalytics+OnDevice.h" +#import "FIRAnalytics.h" +#import "FirebaseAnalytics.h" +#import "FIREventNames.h" +#import "FIRParameterNames.h" +#import "FIRUserPropertyNames.h" + +FOUNDATION_EXPORT double FirebaseAnalyticsVersionNumber; +FOUNDATION_EXPORT const unsigned char FirebaseAnalyticsVersionString[]; + diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics.h new file mode 100644 index 0000000..351da20 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Headers/FirebaseAnalytics.h @@ -0,0 +1,7 @@ +#import "FIRAnalytics+AppDelegate.h" +#import "FIRAnalytics+Consent.h" +#import "FIRAnalytics+OnDevice.h" +#import "FIRAnalytics.h" +#import "FIREventNames.h" +#import "FIRParameterNames.h" +#import "FIRUserPropertyNames.h" diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-macos.swiftsourceinfo b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-macos.swiftsourceinfo new file mode 100644 index 0000000..db0eab2 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-macos.swiftsourceinfo differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/Project/x86_64-apple-macos.swiftsourceinfo b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/Project/x86_64-apple-macos.swiftsourceinfo new file mode 100644 index 0000000..dff38b7 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/Project/x86_64-apple-macos.swiftsourceinfo differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-macos.abi.json b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-macos.abi.json new file mode 100644 index 0000000..fde2b92 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-macos.abi.json @@ -0,0 +1,239 @@ +{ + "ABIRoot": { + "kind": "Root", + "name": "TopLevel", + "printedName": "TopLevel", + "children": [ + { + "kind": "Import", + "name": "StoreKit", + "printedName": "StoreKit", + "declKind": "Import", + "moduleName": "FirebaseAnalytics" + }, + { + "kind": "Import", + "name": "SwiftUI", + "printedName": "SwiftUI", + "declKind": "Import", + "moduleName": "FirebaseAnalytics" + }, + { + "kind": "TypeDecl", + "name": "Analytics", + "printedName": "Analytics", + "children": [ + { + "kind": "Function", + "name": "logTransaction", + "printedName": "logTransaction(_:)", + "children": [ + { + "kind": "TypeNominal", + "name": "Void", + "printedName": "()" + }, + { + "kind": "TypeNominal", + "name": "Transaction", + "printedName": "StoreKit.Transaction", + "usr": "s:8StoreKit11TransactionV" + } + ], + "declKind": "Func", + "usr": "s:So12FIRAnalyticsC17FirebaseAnalyticsE14logTransactionyy8StoreKit0E0VFZ", + "mangledName": "$sSo12FIRAnalyticsC17FirebaseAnalyticsE14logTransactionyy8StoreKit0E0VFZ", + "moduleName": "FirebaseAnalytics", + "static": true, + "declAttributes": [ + "Final", + "AccessControl", + "RawDocComment" + ], + "isFromExtension": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Class", + "usr": "c:objc(cs)FIRAnalytics", + "moduleName": "FirebaseAnalytics", + "isOpen": true, + "objc_name": "FIRAnalytics", + "declAttributes": [ + "ObjC", + "Dynamic" + ], + "superclassUsr": "c:objc(cs)NSObject", + "isExternal": true, + "inheritsConvenienceInitializers": true, + "superclassNames": [ + "ObjectiveC.NSObject" + ], + "conformances": [ + { + "kind": "Conformance", + "name": "Equatable", + "printedName": "Equatable", + "usr": "s:SQ", + "mangledName": "$sSQ" + }, + { + "kind": "Conformance", + "name": "Hashable", + "printedName": "Hashable", + "usr": "s:SH", + "mangledName": "$sSH" + }, + { + "kind": "Conformance", + "name": "CVarArg", + "printedName": "CVarArg", + "usr": "s:s7CVarArgP", + "mangledName": "$ss7CVarArgP" + }, + { + "kind": "Conformance", + "name": "_KeyValueCodingAndObservingPublishing", + "printedName": "_KeyValueCodingAndObservingPublishing", + "usr": "s:10Foundation37_KeyValueCodingAndObservingPublishingP", + "mangledName": "$s10Foundation37_KeyValueCodingAndObservingPublishingP" + }, + { + "kind": "Conformance", + "name": "_KeyValueCodingAndObserving", + "printedName": "_KeyValueCodingAndObserving", + "usr": "s:10Foundation27_KeyValueCodingAndObservingP", + "mangledName": "$s10Foundation27_KeyValueCodingAndObservingP" + }, + { + "kind": "Conformance", + "name": "CustomStringConvertible", + "printedName": "CustomStringConvertible", + "usr": "s:s23CustomStringConvertibleP", + "mangledName": "$ss23CustomStringConvertibleP" + }, + { + "kind": "Conformance", + "name": "CustomDebugStringConvertible", + "printedName": "CustomDebugStringConvertible", + "usr": "s:s28CustomDebugStringConvertibleP", + "mangledName": "$ss28CustomDebugStringConvertibleP" + } + ] + }, + { + "kind": "TypeDecl", + "name": "View", + "printedName": "View", + "children": [ + { + "kind": "Function", + "name": "analyticsScreen", + "printedName": "analyticsScreen(name:class:extraParameters:)", + "children": [ + { + "kind": "TypeNominal", + "name": "ModifiedContent", + "printedName": "SwiftUI.ModifiedContent<τ_0_0, FirebaseAnalytics.LoggedAnalyticsModifier>", + "children": [ + { + "kind": "TypeNominal", + "name": "GenericTypeParam", + "printedName": "τ_0_0" + }, + { + "kind": "TypeNominal", + "name": "LoggedAnalyticsModifier", + "printedName": "FirebaseAnalytics.LoggedAnalyticsModifier", + "usr": "s:17FirebaseAnalytics06LoggedB8ModifierV" + } + ], + "usr": "s:7SwiftUI15ModifiedContentV" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "hasDefaultArg": true, + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "Dictionary", + "printedName": "[Swift.String : Any]", + "children": [ + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "ProtocolComposition", + "printedName": "Any" + } + ], + "hasDefaultArg": true, + "usr": "s:SD" + } + ], + "declKind": "Func", + "usr": "s:7SwiftUI4ViewP17FirebaseAnalyticsE15analyticsScreen4name5class15extraParametersQrSS_SSSDySSypGtF", + "mangledName": "$s7SwiftUI4ViewP17FirebaseAnalyticsE15analyticsScreen4name5class15extraParametersQrSS_SSSDySSypGtF", + "moduleName": "FirebaseAnalytics", + "genericSig": "<τ_0_0 where τ_0_0 : SwiftUI.View>", + "sugared_genericSig": "", + "declAttributes": [ + "AccessControl", + "RawDocComment" + ], + "isFromExtension": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Protocol", + "usr": "s:7SwiftUI4ViewP", + "mangledName": "$s7SwiftUI4ViewP", + "moduleName": "SwiftUI", + "genericSig": "<τ_0_0.Body : SwiftUI.View>", + "sugared_genericSig": "", + "intro_Macosx": "10.15", + "intro_iOS": "13.0", + "intro_tvOS": "13.0", + "intro_watchOS": "6.0", + "declAttributes": [ + "TypeEraser", + "Available", + "Available", + "Available", + "Available" + ], + "isExternal": true + } + ], + "json_format_version": 8 + }, + "ConstValues": [ + { + "filePath": "\/Volumes\/google\/src\/cloud\/pdchen\/firebaserelease\/google3\/googlemac\/iPhone\/Firebase\/Analytics\/Sources\/Swift\/Analytics+SwiftUI.swift", + "kind": "StringLiteral", + "offset": 2654, + "length": 6, + "value": "\"View\"" + }, + { + "filePath": "\/Volumes\/google\/src\/cloud\/pdchen\/firebaserelease\/google3\/googlemac\/iPhone\/Firebase\/Analytics\/Sources\/Swift\/Analytics+SwiftUI.swift", + "kind": "Dictionary", + "offset": 2701, + "length": 3, + "value": "[]" + } + ] +} \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-macos.private.swiftinterface b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-macos.private.swiftinterface new file mode 100644 index 0000000..574b6d9 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-macos.private.swiftinterface @@ -0,0 +1,22 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +// swift-module-flags: -target arm64-apple-macos10.13 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name FirebaseAnalytics +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import FirebaseAnalytics +import StoreKit +import Swift +import SwiftUI +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *) +@available(watchOS, unavailable) +extension FirebaseAnalytics.Analytics { + public static func logTransaction(_ transaction: StoreKit.Transaction) +} +@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *) +@available(watchOS, unavailable) +extension SwiftUI.View { + public func analyticsScreen(name: Swift.String, class: Swift.String = "View", extraParameters: [Swift.String : Any] = [:]) -> some SwiftUI.View + +} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-macos.swiftdoc b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-macos.swiftdoc new file mode 100644 index 0000000..acac909 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-macos.swiftdoc differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-macos.swiftinterface b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-macos.swiftinterface new file mode 100644 index 0000000..574b6d9 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-macos.swiftinterface @@ -0,0 +1,22 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +// swift-module-flags: -target arm64-apple-macos10.13 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name FirebaseAnalytics +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import FirebaseAnalytics +import StoreKit +import Swift +import SwiftUI +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *) +@available(watchOS, unavailable) +extension FirebaseAnalytics.Analytics { + public static func logTransaction(_ transaction: StoreKit.Transaction) +} +@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *) +@available(watchOS, unavailable) +extension SwiftUI.View { + public func analyticsScreen(name: Swift.String, class: Swift.String = "View", extraParameters: [Swift.String : Any] = [:]) -> some SwiftUI.View + +} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-macos.abi.json b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-macos.abi.json new file mode 100644 index 0000000..fde2b92 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-macos.abi.json @@ -0,0 +1,239 @@ +{ + "ABIRoot": { + "kind": "Root", + "name": "TopLevel", + "printedName": "TopLevel", + "children": [ + { + "kind": "Import", + "name": "StoreKit", + "printedName": "StoreKit", + "declKind": "Import", + "moduleName": "FirebaseAnalytics" + }, + { + "kind": "Import", + "name": "SwiftUI", + "printedName": "SwiftUI", + "declKind": "Import", + "moduleName": "FirebaseAnalytics" + }, + { + "kind": "TypeDecl", + "name": "Analytics", + "printedName": "Analytics", + "children": [ + { + "kind": "Function", + "name": "logTransaction", + "printedName": "logTransaction(_:)", + "children": [ + { + "kind": "TypeNominal", + "name": "Void", + "printedName": "()" + }, + { + "kind": "TypeNominal", + "name": "Transaction", + "printedName": "StoreKit.Transaction", + "usr": "s:8StoreKit11TransactionV" + } + ], + "declKind": "Func", + "usr": "s:So12FIRAnalyticsC17FirebaseAnalyticsE14logTransactionyy8StoreKit0E0VFZ", + "mangledName": "$sSo12FIRAnalyticsC17FirebaseAnalyticsE14logTransactionyy8StoreKit0E0VFZ", + "moduleName": "FirebaseAnalytics", + "static": true, + "declAttributes": [ + "Final", + "AccessControl", + "RawDocComment" + ], + "isFromExtension": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Class", + "usr": "c:objc(cs)FIRAnalytics", + "moduleName": "FirebaseAnalytics", + "isOpen": true, + "objc_name": "FIRAnalytics", + "declAttributes": [ + "ObjC", + "Dynamic" + ], + "superclassUsr": "c:objc(cs)NSObject", + "isExternal": true, + "inheritsConvenienceInitializers": true, + "superclassNames": [ + "ObjectiveC.NSObject" + ], + "conformances": [ + { + "kind": "Conformance", + "name": "Equatable", + "printedName": "Equatable", + "usr": "s:SQ", + "mangledName": "$sSQ" + }, + { + "kind": "Conformance", + "name": "Hashable", + "printedName": "Hashable", + "usr": "s:SH", + "mangledName": "$sSH" + }, + { + "kind": "Conformance", + "name": "CVarArg", + "printedName": "CVarArg", + "usr": "s:s7CVarArgP", + "mangledName": "$ss7CVarArgP" + }, + { + "kind": "Conformance", + "name": "_KeyValueCodingAndObservingPublishing", + "printedName": "_KeyValueCodingAndObservingPublishing", + "usr": "s:10Foundation37_KeyValueCodingAndObservingPublishingP", + "mangledName": "$s10Foundation37_KeyValueCodingAndObservingPublishingP" + }, + { + "kind": "Conformance", + "name": "_KeyValueCodingAndObserving", + "printedName": "_KeyValueCodingAndObserving", + "usr": "s:10Foundation27_KeyValueCodingAndObservingP", + "mangledName": "$s10Foundation27_KeyValueCodingAndObservingP" + }, + { + "kind": "Conformance", + "name": "CustomStringConvertible", + "printedName": "CustomStringConvertible", + "usr": "s:s23CustomStringConvertibleP", + "mangledName": "$ss23CustomStringConvertibleP" + }, + { + "kind": "Conformance", + "name": "CustomDebugStringConvertible", + "printedName": "CustomDebugStringConvertible", + "usr": "s:s28CustomDebugStringConvertibleP", + "mangledName": "$ss28CustomDebugStringConvertibleP" + } + ] + }, + { + "kind": "TypeDecl", + "name": "View", + "printedName": "View", + "children": [ + { + "kind": "Function", + "name": "analyticsScreen", + "printedName": "analyticsScreen(name:class:extraParameters:)", + "children": [ + { + "kind": "TypeNominal", + "name": "ModifiedContent", + "printedName": "SwiftUI.ModifiedContent<τ_0_0, FirebaseAnalytics.LoggedAnalyticsModifier>", + "children": [ + { + "kind": "TypeNominal", + "name": "GenericTypeParam", + "printedName": "τ_0_0" + }, + { + "kind": "TypeNominal", + "name": "LoggedAnalyticsModifier", + "printedName": "FirebaseAnalytics.LoggedAnalyticsModifier", + "usr": "s:17FirebaseAnalytics06LoggedB8ModifierV" + } + ], + "usr": "s:7SwiftUI15ModifiedContentV" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "hasDefaultArg": true, + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "Dictionary", + "printedName": "[Swift.String : Any]", + "children": [ + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "ProtocolComposition", + "printedName": "Any" + } + ], + "hasDefaultArg": true, + "usr": "s:SD" + } + ], + "declKind": "Func", + "usr": "s:7SwiftUI4ViewP17FirebaseAnalyticsE15analyticsScreen4name5class15extraParametersQrSS_SSSDySSypGtF", + "mangledName": "$s7SwiftUI4ViewP17FirebaseAnalyticsE15analyticsScreen4name5class15extraParametersQrSS_SSSDySSypGtF", + "moduleName": "FirebaseAnalytics", + "genericSig": "<τ_0_0 where τ_0_0 : SwiftUI.View>", + "sugared_genericSig": "", + "declAttributes": [ + "AccessControl", + "RawDocComment" + ], + "isFromExtension": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Protocol", + "usr": "s:7SwiftUI4ViewP", + "mangledName": "$s7SwiftUI4ViewP", + "moduleName": "SwiftUI", + "genericSig": "<τ_0_0.Body : SwiftUI.View>", + "sugared_genericSig": "", + "intro_Macosx": "10.15", + "intro_iOS": "13.0", + "intro_tvOS": "13.0", + "intro_watchOS": "6.0", + "declAttributes": [ + "TypeEraser", + "Available", + "Available", + "Available", + "Available" + ], + "isExternal": true + } + ], + "json_format_version": 8 + }, + "ConstValues": [ + { + "filePath": "\/Volumes\/google\/src\/cloud\/pdchen\/firebaserelease\/google3\/googlemac\/iPhone\/Firebase\/Analytics\/Sources\/Swift\/Analytics+SwiftUI.swift", + "kind": "StringLiteral", + "offset": 2654, + "length": 6, + "value": "\"View\"" + }, + { + "filePath": "\/Volumes\/google\/src\/cloud\/pdchen\/firebaserelease\/google3\/googlemac\/iPhone\/Firebase\/Analytics\/Sources\/Swift\/Analytics+SwiftUI.swift", + "kind": "Dictionary", + "offset": 2701, + "length": 3, + "value": "[]" + } + ] +} \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-macos.private.swiftinterface b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-macos.private.swiftinterface new file mode 100644 index 0000000..ee4eb6a --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-macos.private.swiftinterface @@ -0,0 +1,22 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +// swift-module-flags: -target x86_64-apple-macos10.13 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name FirebaseAnalytics +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import FirebaseAnalytics +import StoreKit +import Swift +import SwiftUI +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *) +@available(watchOS, unavailable) +extension FirebaseAnalytics.Analytics { + public static func logTransaction(_ transaction: StoreKit.Transaction) +} +@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *) +@available(watchOS, unavailable) +extension SwiftUI.View { + public func analyticsScreen(name: Swift.String, class: Swift.String = "View", extraParameters: [Swift.String : Any] = [:]) -> some SwiftUI.View + +} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-macos.swiftdoc b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-macos.swiftdoc new file mode 100644 index 0000000..a1ba26d Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-macos.swiftdoc differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-macos.swiftinterface b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-macos.swiftinterface new file mode 100644 index 0000000..ee4eb6a --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-macos.swiftinterface @@ -0,0 +1,22 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +// swift-module-flags: -target x86_64-apple-macos10.13 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name FirebaseAnalytics +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import FirebaseAnalytics +import StoreKit +import Swift +import SwiftUI +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *) +@available(watchOS, unavailable) +extension FirebaseAnalytics.Analytics { + public static func logTransaction(_ transaction: StoreKit.Transaction) +} +@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *) +@available(watchOS, unavailable) +extension SwiftUI.View { + public func analyticsScreen(name: Swift.String, class: Swift.String = "View", extraParameters: [Swift.String : Any] = [:]) -> some SwiftUI.View + +} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/module.modulemap b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/module.modulemap new file mode 100644 index 0000000..927d5c0 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Modules/module.modulemap @@ -0,0 +1,16 @@ +framework module FirebaseAnalytics { +umbrella header "FirebaseAnalytics-umbrella.h" +export * +module * { export * } + link framework "AppKit" + link framework "Foundation" + link framework "Security" + link framework "SystemConfiguration" + link "c++" + link "sqlite3" + link "z" +} +module FirebaseAnalytics.Swift { + header "FirebaseAnalytics-Swift.h" + requires objc +} \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Resources/Info.plist b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Resources/Info.plist new file mode 100644 index 0000000..f509cdd --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/A/Resources/Info.plist @@ -0,0 +1,50 @@ + + + + + BuildMachineOSBuild + 23F79 + CFBundleDevelopmentRegion + en + CFBundleExecutable + FirebaseAnalytics + CFBundleIdentifier + org.cocoapods.FirebaseAnalytics + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + FirebaseAnalytics + CFBundlePackageType + FMWK + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 1 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + + DTPlatformName + macosx + DTPlatformVersion + 14.2 + DTSDKBuild + 23C53 + DTSDKName + macosx14.2 + DTXcode + 1520 + DTXcodeBuild + 15C500b + LSMinimumSystemVersion + 10.13 + MinimumOSVersion + 100.0 + + diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/Current b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/Current new file mode 120000 index 0000000..8c7e5a6 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/macos-arm64_x86_64/FirebaseAnalytics.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/FirebaseAnalytics b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/FirebaseAnalytics new file mode 100644 index 0000000..37f03b2 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/FirebaseAnalytics differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h new file mode 100644 index 0000000..cb1e407 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h @@ -0,0 +1,80 @@ +#import + +#import "FIRAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +/// Provides App Delegate handlers to be used in your App Delegate. +/// +/// To save time integrating Firebase Analytics in an application, Firebase Analytics does not +/// require delegation implementation from the AppDelegate if neither SwiftUI nor UIScene lifecycle +/// is adopted. Instead this is automatically done by Firebase Analytics. Should you choose instead +/// to delegate manually, you can turn off the App Delegate Proxy by adding +/// FirebaseAppDelegateProxyEnabled into your app's Info.plist and setting it to boolean `NO`, and +/// adding the methods in this category to corresponding delegation handlers. +/// +/// To handle Universal Links, you must return `true` in +/// `UIApplicationDelegate.application(_:didFinishLaunchingWithOptions:)`. +@interface FIRAnalytics (AppDelegate) + +/// Handles events related to a URL session that are waiting to be processed. +/// +/// 1. If SwiftUI lifecycle is adopted, call this method from +/// `UIApplicationDelegate.application(_:handleEventsForBackgroundURLSession:completionHandler:)` +/// in your app delegate. +/// +/// 2. If SwiftUI lifecycle is not adopted, Firebase Analytics does not require delegation +/// implementation from the AppDelegate. If you choose instead to delegate manually, you can set +/// FirebaseAppDelegateProxyEnabled to boolean `NO` in your app's Info.plist and call this method +/// from +/// `UIApplicationDelegate.application(_:handleEventsForBackgroundURLSession:completionHandler:)` +/// in your app delegate. +/// +/// @param identifier The identifier of the URL session requiring attention. +/// @param completionHandler The completion handler to call when you finish processing the events. +/// Calling this completion handler lets the system know that your app's user interface is +/// updated and a new snapshot can be taken. ++ (void)handleEventsForBackgroundURLSession:(NSString *)identifier + completionHandler:(nullable void (^)(void))completionHandler; + +/// Handles the event when the app is launched by a URL (custom URL scheme or universal link). +/// +/// 1. If SwiftUI lifecycle is adopted, use `onOpenURL(perform:)` to register a handler and call +/// this method in the handler. +/// +/// 2. If UIScene lifecycle is adopted, call this method from +/// `UISceneDelegate.scene(_:willConnectTo:options:)` and +/// `UISceneDelegate.scene(_:openURLContexts:)` when the URL contexts are available. +/// +/// 3. If neither SwiftUI nor UIScene lifecycle is adopted, Firebase Analytics does not require +/// delegation implementation from the AppDelegate. If you choose instead to delegate manually, you +/// can set FirebaseAppDelegateProxyEnabled to boolean `NO` in your app's Info.plist and call this +/// method from `UIApplicationDelegate.application(_:open:options:)` in your app delegate. +/// +/// @param url The URL resource to open. This resource can be a network resource or a file. ++ (void)handleOpenURL:(NSURL *)url; + +/// Handles the event when the app receives data associated with user activity that includes a +/// Universal Link. +/// +/// 1. If SwiftUI lifecycle is adopted, use `onOpenURL(perform:)` to register a handler and call +/// `Analytics.handleOpen(_:)` instead in the handler. +/// +/// 2. If UIScene lifecycle is adopted, call this method from +/// `UISceneDelegate.scene(_:willConnectTo:options:)` and `UISceneDelegate.scene(_:continue:)` when +/// NSUserActivity is available. See the [Apple +/// doc](https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app) for +/// more details. +/// +/// 3. If neither SwiftUI nor UIScene lifecycle is adopted, Firebase Analytics does not require +/// delegation implementation from the AppDelegate. If you choose instead to delegate manually, you +/// can set FirebaseAppDelegateProxyEnabled to boolean `NO` in your app's Info.plist and call this +/// method from `UIApplication.application(_:continue:restorationHandler:)` in your app delegate. +/// +/// @param userActivity The activity object containing the data associated with the task the user +/// was performing. ++ (void)handleUserActivity:(id)userActivity; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h new file mode 100644 index 0000000..7758390 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h @@ -0,0 +1,51 @@ +#import + +#import "FIRAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +/// The type of consent to set. Supported consent types are `ConsentType.adStorage`, +/// `ConsentType.analyticsStorage`, `ConsentType.adUserData`, and `ConsentType.adPersonalization`. +/// Omitting a type retains its previous status. +typedef NSString *FIRConsentType NS_TYPED_ENUM NS_SWIFT_NAME(ConsentType); + +/// Enables storage (such as device identifiers) related to advertising. +extern FIRConsentType const FIRConsentTypeAdStorage; + +/// Enables storage (such as app identifiers) related to analytics, e.g. visit duration. +extern FIRConsentType const FIRConsentTypeAnalyticsStorage; + +/// Sets consent for sending user data to Google for advertising purposes. +extern FIRConsentType const FIRConsentTypeAdUserData; + +/// Sets consent for personalized advertising. +extern FIRConsentType const FIRConsentTypeAdPersonalization; + +/// The status value of the consent type. Supported statuses are `ConsentStatus.granted` and +/// `ConsentStatus.denied`. +typedef NSString *FIRConsentStatus NS_TYPED_ENUM NS_SWIFT_NAME(ConsentStatus); + +/// Consent status indicating consent is denied. For an overview of which data is sent when consent +/// is denied, see [SDK behavior with consent +/// mode](https://developers.google.com/tag-platform/security/concepts/consent-mode#tag-behavior). +extern FIRConsentStatus const FIRConsentStatusDenied; + +/// Consent status indicating consent is granted. +extern FIRConsentStatus const FIRConsentStatusGranted; + +/// Sets the applicable end user consent state. +@interface FIRAnalytics (Consent) + +/// Sets the applicable end user consent state (e.g. for device identifiers) for this app on this +/// device. Use the consent settings to specify individual consent type values. Settings are +/// persisted across app sessions. By default consent types are set to `ConsentStatus.granted`. +/// +/// @param consentSettings A Dictionary of consent types. Supported consent type keys are +/// `ConsentType.adStorage`, `ConsentType.analyticsStorage`, `ConsentType.adUserData`, and +/// `ConsentType.adPersonalization`. Valid values are `ConsentStatus.granted` and +/// `ConsentStatus.denied`. ++ (void)setConsent:(NSDictionary *)consentSettings; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+OnDevice.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+OnDevice.h new file mode 100644 index 0000000..0bfec88 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics+OnDevice.h @@ -0,0 +1,44 @@ +#import + +#import "FIRAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +API_UNAVAILABLE(macCatalyst, macos, tvos, watchos) +@interface FIRAnalytics (OnDevice) + +/// Initiates on-device conversion measurement given a user email address. Requires dependency +/// GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a no-op. +/// @param emailAddress User email address. Include a domain name for all email addresses +/// (e.g. gmail.com or hotmail.co.jp). ++ (void)initiateOnDeviceConversionMeasurementWithEmailAddress:(NSString *)emailAddress + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(emailAddress:)); + +/// Initiates on-device conversion measurement given a phone number in E.164 format. Requires +/// dependency GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a no-op. +/// @param phoneNumber User phone number. Must be in E.164 format, which means it must be +/// limited to a maximum of 15 digits and must include a plus sign (+) prefix and country code +/// with no dashes, parentheses, or spaces. ++ (void)initiateOnDeviceConversionMeasurementWithPhoneNumber:(NSString *)phoneNumber + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(phoneNumber:)); + +/// Initiates on-device conversion measurement given a sha256-hashed user email address. Requires +/// dependency GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a no-op. +/// @param hashedEmailAddress User email address as a UTF8-encoded string normalized and hashed +/// according to the instructions at +/// https://firebase.google.com/docs/tutorials/ads-ios-on-device-measurement/step-3. ++ (void)initiateOnDeviceConversionMeasurementWithHashedEmailAddress:(NSData *)hashedEmailAddress + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(hashedEmailAddress:)); + +/// Initiates on-device conversion measurement given a sha256-hashed phone number in E.164 format. +/// Requires dependency GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a +/// no-op. +/// @param hashedPhoneNumber UTF8-encoded user phone number in E.164 format and then hashed +/// according to the instructions at +/// https://firebase.google.com/docs/tutorials/ads-ios-on-device-measurement/step-3. ++ (void)initiateOnDeviceConversionMeasurementWithHashedPhoneNumber:(NSData *)hashedPhoneNumber + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(hashedPhoneNumber:)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics.h new file mode 100644 index 0000000..e58d7dd --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIRAnalytics.h @@ -0,0 +1,155 @@ +#import + +#import "FIREventNames.h" +#import "FIRParameterNames.h" +#import "FIRUserPropertyNames.h" + +NS_ASSUME_NONNULL_BEGIN + +/// The top level Firebase Analytics singleton that provides methods for logging events and setting +/// user properties. See the developer guides for general +/// information on using Firebase Analytics in your apps. +/// +/// @note The Analytics SDK uses SQLite to persist events and other app-specific data. Calling +/// certain thread-unsafe global SQLite methods like `sqlite3_shutdown()` can result in +/// unexpected crashes at runtime. +NS_SWIFT_NAME(Analytics) +@interface FIRAnalytics : NSObject + +/// Logs an app event. The event can have up to 25 parameters. Events with the same name must have +/// the same parameters. Up to 500 event names are supported. Using predefined events and/or +/// parameters is recommended for optimal reporting. +/// +/// The following event names are reserved and cannot be used: +///
    +///
  • ad_activeview
  • +///
  • ad_click
  • +///
  • ad_exposure
  • +///
  • ad_query
  • +///
  • ad_reward
  • +///
  • adunit_exposure
  • +///
  • app_clear_data
  • +///
  • app_exception
  • +///
  • app_remove
  • +///
  • app_store_refund
  • +///
  • app_store_subscription_cancel
  • +///
  • app_store_subscription_convert
  • +///
  • app_store_subscription_renew
  • +///
  • app_update
  • +///
  • app_upgrade
  • +///
  • dynamic_link_app_open
  • +///
  • dynamic_link_app_update
  • +///
  • dynamic_link_first_open
  • +///
  • error
  • +///
  • firebase_campaign
  • +///
  • first_open
  • +///
  • first_visit
  • +///
  • in_app_purchase
  • +///
  • notification_dismiss
  • +///
  • notification_foreground
  • +///
  • notification_open
  • +///
  • notification_receive
  • +///
  • os_update
  • +///
  • session_start
  • +///
  • session_start_with_rollout
  • +///
  • user_engagement
  • +///
+/// +/// @param name The name of the event. Should contain 1 to 40 alphanumeric characters or +/// underscores. The name must start with an alphabetic character. Some event names are +/// reserved. See FIREventNames.h for the list of reserved event names. The "firebase_", +/// "google_", and "ga_" prefixes are reserved and should not be used. Note that event names are +/// case-sensitive and that logging two events whose names differ only in case will result in +/// two distinct events. To manually log screen view events, use the `screen_view` event name. +/// @param parameters The dictionary of event parameters. Passing `nil` indicates that the event has +/// no parameters. Parameter names can be up to 40 characters long and must start with an +/// alphabetic character and contain only alphanumeric characters and underscores. Only String, +/// Int, and Double parameter types are supported. String parameter values can be up to 100 +/// characters long for standard Google Analytics properties, and up to 500 characters long for +/// Google Analytics 360 properties. The "firebase_", "google_", and "ga_" prefixes are reserved +/// and should not be used for parameter names. ++ (void)logEventWithName:(NSString *)name + parameters:(nullable NSDictionary *)parameters + NS_SWIFT_NAME(logEvent(_:parameters:)); + +/// Sets a user property to a given value. Up to 25 user property names are supported. Once set, +/// user property values persist throughout the app lifecycle and across sessions. +/// +/// The following user property names are reserved and cannot be used: +///
    +///
  • first_open_time
  • +///
  • last_deep_link_referrer
  • +///
  • user_id
  • +///
+/// +/// @param value The value of the user property. Values can be up to 36 characters long. Setting the +/// value to `nil` removes the user property. +/// @param name The name of the user property to set. Should contain 1 to 24 alphanumeric characters +/// or underscores and must start with an alphabetic character. The "firebase_", "google_", and +/// "ga_" prefixes are reserved and should not be used for user property names. ++ (void)setUserPropertyString:(nullable NSString *)value forName:(NSString *)name + NS_SWIFT_NAME(setUserProperty(_:forName:)); + +/// Sets the user ID property. This feature must be used in accordance with +/// Google's Privacy Policy +/// +/// @param userID The user ID to ascribe to the user of this app on this device, which must be +/// non-empty and no more than 256 characters long. Setting userID to `nil` removes the user ID. ++ (void)setUserID:(nullable NSString *)userID; + +/// Sets whether analytics collection is enabled for this app on this device. This setting is +/// persisted across app sessions. By default it is enabled. +/// +/// @param analyticsCollectionEnabled A flag that enables or disables Analytics collection. ++ (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled; + +/// Sets the interval of inactivity in seconds that terminates the current session. The default +/// value is 1800 seconds (30 minutes). +/// +/// @param sessionTimeoutInterval The custom time of inactivity in seconds before the current +/// session terminates. ++ (void)setSessionTimeoutInterval:(NSTimeInterval)sessionTimeoutInterval; + +/// Asynchronously retrieves the identifier of the current app session. +/// +/// The session ID retrieval could fail due to Analytics collection disabled, app session expired, +/// etc. +/// +/// @param completion The completion handler to call when the session ID retrieval is complete. This +/// handler is executed on a system-defined global concurrent queue. +/// This completion handler takes the following parameters: +/// sessionID The identifier of the current app session. The value is undefined if the +/// request failed. +/// error An error object that indicates why the request failed, or `nil` if the request +/// was successful. ++ (void)sessionIDWithCompletion:(void (^)(int64_t sessionID, NSError *_Nullable error))completion; + +/// Returns the unique ID for this instance of the application or `nil` if +/// `ConsentType.analyticsStorage` has been set to `ConsentStatus.denied`. +/// +/// @see `FIRAnalytics+Consent.h` ++ (nullable NSString *)appInstanceID; + +/// Clears all analytics data for this instance from the device and resets the app instance ID. ++ (void)resetAnalyticsData; + +/// Adds parameters that will be set on every event logged from the SDK, including automatic ones. +/// The values passed in the parameters dictionary will be added to the dictionary of default event +/// parameters. These parameters persist across app runs. They are of lower precedence than event +/// parameters, so if an event parameter and a parameter set using this API have the same name, the +/// value of the event parameter will be used. The same limitations on event parameters apply to +/// default event parameters. +/// +/// @param parameters Parameters to be added to the dictionary of parameters added to every event. +/// They will be added to the dictionary of default event parameters, replacing any existing +/// parameter with the same name. Valid parameters are String, Int, and Double. Setting a key's +/// value to `NSNull()` will clear that parameter. Passing in a `nil` dictionary will clear all +/// parameters. ++ (void)setDefaultEventParameters:(nullable NSDictionary *)parameters; + +/// Unavailable. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIREventNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIREventNames.h new file mode 100644 index 0000000..1e69a44 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIREventNames.h @@ -0,0 +1,418 @@ +/// @file FIREventNames.h +/// +/// Predefined event names. +/// +/// An Event is an important occurrence in your app that you want to measure. You can report up to +/// 500 different types of Events per app and you can associate up to 25 unique parameters with each +/// Event type. Some common events are suggested below, but you may also choose to specify custom +/// Event types that are associated with your specific app. Each event type is identified by a +/// unique name. Event names can be up to 40 characters long, may only contain alphanumeric +/// characters and underscores ("_"), and must start with an alphabetic character. The "firebase_", +/// "google_", and "ga_" prefixes are reserved and should not be used. + +#import + +/// Ad Impression event. This event signifies when a user sees an ad impression. Note: If you supply +/// the @c AnalyticsParameterValue parameter, you must also supply the @c AnalyticsParameterCurrency +/// parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterAdPlatform (String) (optional)
  • +///
  • @c AnalyticsParameterAdFormat (String) (optional)
  • +///
  • @c AnalyticsParameterAdSource (String) (optional)
  • +///
  • @c AnalyticsParameterAdUnitName (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAdImpression NS_SWIFT_NAME(AnalyticsEventAdImpression) = + @"ad_impression"; + +/// Add Payment Info event. This event signifies that a user has submitted their payment +/// information. Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply +/// the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterPaymentType (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddPaymentInfo NS_SWIFT_NAME(AnalyticsEventAddPaymentInfo) = + @"add_payment_info"; + +/// Add Shipping Info event. This event signifies that a user has submitted their shipping +/// information. Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply +/// the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterShippingTier (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddShippingInfo NS_SWIFT_NAME(AnalyticsEventAddShippingInfo) = + @"add_shipping_info"; + +/// E-Commerce Add To Cart event. This event signifies that an item(s) was added to a cart for +/// purchase. Add this event to a funnel with @c AnalyticsEventPurchase to gauge the effectiveness +/// of your checkout process. Note: If you supply the @c AnalyticsParameterValue parameter, you must +/// also supply the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed +/// accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddToCart NS_SWIFT_NAME(AnalyticsEventAddToCart) = @"add_to_cart"; + +/// E-Commerce Add To Wishlist event. This event signifies that an item was added to a wishlist. Use +/// this event to identify popular gift items. Note: If you supply the @c AnalyticsParameterValue +/// parameter, you must also supply the @c AnalyticsParameterCurrency parameter so that revenue +/// metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddToWishlist NS_SWIFT_NAME(AnalyticsEventAddToWishlist) = + @"add_to_wishlist"; + +/// App Open event. By logging this event when an App becomes active, developers can understand how +/// often users leave and return during the course of a Session. Although Sessions are automatically +/// reported, this event can provide further clarification around the continuous engagement of +/// app-users. +static NSString *const kFIREventAppOpen NS_SWIFT_NAME(AnalyticsEventAppOpen) = @"app_open"; + +/// E-Commerce Begin Checkout event. This event signifies that a user has begun the process of +/// checking out. Add this event to a funnel with your @c AnalyticsEventPurchase event to gauge the +/// effectiveness of your checkout process. Note: If you supply the @c AnalyticsParameterValue +/// parameter, you must also supply the @c AnalyticsParameterCurrency parameter so that revenue +/// metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventBeginCheckout NS_SWIFT_NAME(AnalyticsEventBeginCheckout) = + @"begin_checkout"; + +/// Campaign Detail event. Log this event to supply the referral details of a re-engagement +/// campaign. Note: you must supply at least one of the required parameters +/// AnalyticsParameterSource, AnalyticsParameterMedium or AnalyticsParameterCampaign. Params: +/// +///
    +///
  • @c AnalyticsParameterSource (String)
  • +///
  • @c AnalyticsParameterMedium (String)
  • +///
  • @c AnalyticsParameterCampaign (String)
  • +///
  • @c AnalyticsParameterTerm (String) (optional)
  • +///
  • @c AnalyticsParameterContent (String) (optional)
  • +///
  • @c AnalyticsParameterAdNetworkClickID (String) (optional)
  • +///
  • @c AnalyticsParameterCP1 (String) (optional)
  • +///
  • @c AnalyticsParameterCampaignID (String) (optional)
  • +///
  • @c AnalyticsParameterCreativeFormat (String) (optional)
  • +///
  • @c AnalyticsParameterMarketingTactic (String) (optional)
  • +///
  • @c AnalyticsParameterSourcePlatform (String) (optional)
  • +///
+static NSString *const kFIREventCampaignDetails NS_SWIFT_NAME(AnalyticsEventCampaignDetails) = + @"campaign_details"; + +/// Earn Virtual Currency event. This event tracks the awarding of virtual currency in your app. Log +/// this along with @c AnalyticsEventSpendVirtualCurrency to better understand your virtual economy. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterVirtualCurrencyName (String)
  • +///
  • @c AnalyticsParameterValue (Int or Double)
  • +///
+static NSString *const kFIREventEarnVirtualCurrency + NS_SWIFT_NAME(AnalyticsEventEarnVirtualCurrency) = @"earn_virtual_currency"; + +/// Generate Lead event. Log this event when a lead has been generated in the app to understand the +/// efficacy of your install and re-engagement campaigns. Note: If you supply the +/// @c AnalyticsParameterValue parameter, you must also supply the @c AnalyticsParameterCurrency +/// parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventGenerateLead NS_SWIFT_NAME(AnalyticsEventGenerateLead) = + @"generate_lead"; + +/// Join Group event. Log this event when a user joins a group such as a guild, team or family. Use +/// this event to analyze how popular certain groups or social features are in your app. Params: +/// +///
    +///
  • @c AnalyticsParameterGroupID (String)
  • +///
+static NSString *const kFIREventJoinGroup NS_SWIFT_NAME(AnalyticsEventJoinGroup) = @"join_group"; + +/// Level End event. Log this event when the user finishes a level. Params: +/// +///
    +///
  • @c AnalyticsParameterLevelName (String)
  • +///
  • @c AnalyticsParameterSuccess (String)
  • +///
+static NSString *const kFIREventLevelEnd NS_SWIFT_NAME(AnalyticsEventLevelEnd) = @"level_end"; + +/// Level Start event. Log this event when the user starts a new level. Params: +/// +///
    +///
  • @c AnalyticsParameterLevelName (String)
  • +///
+static NSString *const kFIREventLevelStart NS_SWIFT_NAME(AnalyticsEventLevelStart) = @"level_start"; + +/// Level Up event. This event signifies that a player has leveled up in your gaming app. It can +/// help you gauge the level distribution of your userbase and help you identify certain levels that +/// are difficult to pass. Params: +/// +///
    +///
  • @c AnalyticsParameterLevel (Int)
  • +///
  • @c AnalyticsParameterCharacter (String) (optional)
  • +///
+static NSString *const kFIREventLevelUp NS_SWIFT_NAME(AnalyticsEventLevelUp) = @"level_up"; + +/// Login event. Apps with a login feature can report this event to signify that a user has logged +/// in. +static NSString *const kFIREventLogin NS_SWIFT_NAME(AnalyticsEventLogin) = @"login"; + +/// Post Score event. Log this event when the user posts a score in your gaming app. This event can +/// help you understand how users are actually performing in your game and it can help you correlate +/// high scores with certain audiences or behaviors. Params: +/// +///
    +///
  • @c AnalyticsParameterScore (Int)
  • +///
  • @c AnalyticsParameterLevel (Int) (optional)
  • +///
  • @c AnalyticsParameterCharacter (String) (optional)
  • +///
+static NSString *const kFIREventPostScore NS_SWIFT_NAME(AnalyticsEventPostScore) = @"post_score"; + +/// E-Commerce Purchase event. This event signifies that an item(s) was purchased by a user. Note: +/// This is different from the in-app purchase event, which is reported automatically for App +/// Store-based apps. Note: If you supply the @c AnalyticsParameterValue parameter, you must also +/// supply the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed +/// accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterAffiliation (String) (optional)
  • +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterEndDate (String) (optional)
  • +///
  • @c AnalyticsParameterItemID (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterShipping (Double) (optional)
  • +///
  • @c AnalyticsParameterStartDate (String) (optional)
  • +///
  • @c AnalyticsParameterTax (Double) (optional)
  • +///
  • @c AnalyticsParameterTransactionID (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventPurchase NS_SWIFT_NAME(AnalyticsEventPurchase) = @"purchase"; + +/// E-Commerce Refund event. This event signifies that a refund was issued. Note: If you supply the +/// @c AnalyticsParameterValue parameter, you must also supply the @c AnalyticsParameterCurrency +/// parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterAffiliation (String) (optional)
  • +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterShipping (Double) (optional)
  • +///
  • @c AnalyticsParameterTax (Double) (optional)
  • +///
  • @c AnalyticsParameterTransactionID (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventRefund NS_SWIFT_NAME(AnalyticsEventRefund) = @"refund"; + +/// E-Commerce Remove from Cart event. This event signifies that an item(s) was removed from a cart. +/// Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply the @c +/// AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventRemoveFromCart NS_SWIFT_NAME(AnalyticsEventRemoveFromCart) = + @"remove_from_cart"; + +/// Screen View event. This event signifies a screen view. Use this when a screen transition occurs. +/// This event can be logged irrespective of whether automatic screen tracking is enabled. Params: +/// +///
    +///
  • @c AnalyticsParameterScreenClass (String) (optional)
  • +///
  • @c AnalyticsParameterScreenName (String) (optional)
  • +///
+static NSString *const kFIREventScreenView NS_SWIFT_NAME(AnalyticsEventScreenView) = @"screen_view"; + +/// Search event. Apps that support search features can use this event to contextualize search +/// operations by supplying the appropriate, corresponding parameters. This event can help you +/// identify the most popular content in your app. Params: +/// +///
    +///
  • @c AnalyticsParameterSearchTerm (String)
  • +///
  • @c AnalyticsParameterStartDate (String) (optional)
  • +///
  • @c AnalyticsParameterEndDate (String) (optional)
  • +///
  • @c AnalyticsParameterNumberOfNights (Int) (optional) for hotel bookings
  • +///
  • @c AnalyticsParameterNumberOfRooms (Int) (optional) for hotel bookings
  • +///
  • @c AnalyticsParameterNumberOfPassengers (Int) (optional) for travel bookings
  • +///
  • @c AnalyticsParameterOrigin (String) (optional)
  • +///
  • @c AnalyticsParameterDestination (String) (optional)
  • +///
  • @c AnalyticsParameterTravelClass (String) (optional) for travel bookings
  • +///
+static NSString *const kFIREventSearch NS_SWIFT_NAME(AnalyticsEventSearch) = @"search"; + +/// Select Content event. This general purpose event signifies that a user has selected some content +/// of a certain type in an app. The content can be any object in your app. This event can help you +/// identify popular content and categories of content in your app. Params: +/// +///
    +///
  • @c AnalyticsParameterContentType (String)
  • +///
  • @c AnalyticsParameterItemID (String)
  • +///
+static NSString *const kFIREventSelectContent NS_SWIFT_NAME(AnalyticsEventSelectContent) = + @"select_content"; + +/// Select Item event. This event signifies that an item was selected by a user from a list. Use the +/// appropriate parameters to contextualize the event. Use this event to discover the most popular +/// items selected. Params: +/// +///
    +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterItemListID (String) (optional)
  • +///
  • @c AnalyticsParameterItemListName (String) (optional)
  • +///
+static NSString *const kFIREventSelectItem NS_SWIFT_NAME(AnalyticsEventSelectItem) = @"select_item"; + +/// Select promotion event. This event signifies that a user has selected a promotion offer. Use the +/// appropriate parameters to contextualize the event, such as the item(s) for which the promotion +/// applies. Params: +/// +///
    +///
  • @c AnalyticsParameterCreativeName (String) (optional)
  • +///
  • @c AnalyticsParameterCreativeSlot (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterLocationID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionName (String) (optional)
  • +///
+static NSString *const kFIREventSelectPromotion NS_SWIFT_NAME(AnalyticsEventSelectPromotion) = + @"select_promotion"; + +/// Share event. Apps with social features can log the Share event to identify the most viral +/// content. Params: +/// +///
    +///
  • @c AnalyticsParameterContentType (String)
  • +///
  • @c AnalyticsParameterItemID (String)
  • +///
+static NSString *const kFIREventShare NS_SWIFT_NAME(AnalyticsEventShare) = @"share"; + +/// Sign Up event. This event indicates that a user has signed up for an account in your app. The +/// parameter signifies the method by which the user signed up. Use this event to understand the +/// different behaviors between logged in and logged out users. Params: +/// +///
    +///
  • @c AnalyticsParameterMethod (String)
  • +///
+static NSString *const kFIREventSignUp NS_SWIFT_NAME(AnalyticsEventSignUp) = @"sign_up"; + +/// Spend Virtual Currency event. This event tracks the sale of virtual goods in your app and can +/// help you identify which virtual goods are the most popular objects of purchase. Params: +/// +///
    +///
  • @c AnalyticsParameterItemName (String)
  • +///
  • @c AnalyticsParameterVirtualCurrencyName (String)
  • +///
  • @c AnalyticsParameterValue (Int or Double)
  • +///
+static NSString *const kFIREventSpendVirtualCurrency + NS_SWIFT_NAME(AnalyticsEventSpendVirtualCurrency) = @"spend_virtual_currency"; + +/// Tutorial Begin event. This event signifies the start of the on-boarding process in your app. Use +/// this in a funnel with @c AnalyticsEventTutorialComplete to understand how many users complete +/// this process and move on to the full app experience. +static NSString *const kFIREventTutorialBegin NS_SWIFT_NAME(AnalyticsEventTutorialBegin) = + @"tutorial_begin"; + +/// Tutorial End event. Use this event to signify the user's completion of your app's on-boarding +/// process. Add this to a funnel with @c AnalyticsEventTutorialBegin to gauge the completion rate +/// of your on-boarding process. +static NSString *const kFIREventTutorialComplete NS_SWIFT_NAME(AnalyticsEventTutorialComplete) = + @"tutorial_complete"; + +/// Unlock Achievement event. Log this event when the user has unlocked an achievement in your +/// game. Since achievements generally represent the breadth of a gaming experience, this event can +/// help you understand how many users are experiencing all that your game has to offer. Params: +/// +///
    +///
  • @c AnalyticsParameterAchievementID (String)
  • +///
+static NSString *const kFIREventUnlockAchievement NS_SWIFT_NAME(AnalyticsEventUnlockAchievement) = + @"unlock_achievement"; + +/// E-commerce View Cart event. This event signifies that a user has viewed their cart. Use this to +/// analyze your purchase funnel. Note: If you supply the @c AnalyticsParameterValue parameter, you +/// must also supply the @c AnalyticsParameterCurrency parameter so that revenue metrics can be +/// computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventViewCart NS_SWIFT_NAME(AnalyticsEventViewCart) = @"view_cart"; + +/// View Item event. This event signifies that a user has viewed an item. Use the appropriate +/// parameters to contextualize the event. Use this event to discover the most popular items viewed +/// in your app. Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply +/// the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventViewItem NS_SWIFT_NAME(AnalyticsEventViewItem) = @"view_item"; + +/// View Item List event. Log this event when a user sees a list of items or offerings. Params: +/// +///
    +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterItemListID (String) (optional)
  • +///
  • @c AnalyticsParameterItemListName (String) (optional)
  • +///
+static NSString *const kFIREventViewItemList NS_SWIFT_NAME(AnalyticsEventViewItemList) = + @"view_item_list"; + +/// View Promotion event. This event signifies that a promotion was shown to a user. Add this event +/// to a funnel with the @c AnalyticsEventAddToCart and @c AnalyticsEventPurchase to gauge your +/// conversion process. Params: +/// +///
    +///
  • @c AnalyticsParameterCreativeName (String) (optional)
  • +///
  • @c AnalyticsParameterCreativeSlot (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterLocationID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionName (String) (optional)
  • +///
+static NSString *const kFIREventViewPromotion NS_SWIFT_NAME(AnalyticsEventViewPromotion) = + @"view_promotion"; + +/// View Search Results event. Log this event when the user has been presented with the results of a +/// search. Params: +/// +///
    +///
  • @c AnalyticsParameterSearchTerm (String)
  • +///
+static NSString *const kFIREventViewSearchResults NS_SWIFT_NAME(AnalyticsEventViewSearchResults) = + @"view_search_results"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIRParameterNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIRParameterNames.h new file mode 100644 index 0000000..58a5a21 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIRParameterNames.h @@ -0,0 +1,722 @@ +/// @file FIRParameterNames.h +/// +/// Predefined event parameter names. +/// +/// Params supply information that contextualize Events. You can associate up to 25 unique Params +/// with each Event type. Some Params are suggested below for certain common Events, but you are +/// not limited to these. You may supply extra Params for suggested Events or custom Params for +/// Custom events. Param names can be up to 40 characters long, may only contain alphanumeric +/// characters and underscores ("_"), and must start with an alphabetic character. Param values can +/// be up to 100 characters long for standard Google Analytics properties and up to 500 characters +/// long for Google Analytics 360 properties. The "firebase_", "google_", and "ga_" prefixes are +/// reserved and should not be used. + +#import + +/// Game achievement ID (String). +///
+///     let params = [
+///       AnalyticsParameterAchievementID : "10_matches_won",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAchievementID NS_SWIFT_NAME(AnalyticsParameterAchievementID) = + @"achievement_id"; + +/// The ad format (e.g. Banner, Interstitial, Rewarded, Native, Rewarded Interstitial, Instream). +/// (String). +///
+///     let params = [
+///       AnalyticsParameterAdFormat : "Banner",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdFormat NS_SWIFT_NAME(AnalyticsParameterAdFormat) = + @"ad_format"; + +/// Ad Network Click ID (String). Used for network-specific click IDs which vary in format. +///
+///     let params = [
+///       AnalyticsParameterAdNetworkClickID : "1234567",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdNetworkClickID + NS_SWIFT_NAME(AnalyticsParameterAdNetworkClickID) = @"aclid"; + +/// The ad platform (e.g. MoPub, IronSource) (String). +///
+///     let params = [
+///       AnalyticsParameterAdPlatform : "MoPub",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdPlatform NS_SWIFT_NAME(AnalyticsParameterAdPlatform) = + @"ad_platform"; + +/// The ad source (e.g. AdColony) (String). +///
+///     let params = [
+///       AnalyticsParameterAdSource : "AdColony",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdSource NS_SWIFT_NAME(AnalyticsParameterAdSource) = + @"ad_source"; + +/// The ad unit name (e.g. Banner_03) (String). +///
+///     let params = [
+///       AnalyticsParameterAdUnitName : "Banner_03",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdUnitName NS_SWIFT_NAME(AnalyticsParameterAdUnitName) = + @"ad_unit_name"; + +/// A product affiliation to designate a supplying company or brick and mortar store location +/// (String).
+///     let params = [
+///       AnalyticsParameterAffiliation : "Google Store",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAffiliation NS_SWIFT_NAME(AnalyticsParameterAffiliation) = + @"affiliation"; + +/// Campaign custom parameter (String). Used as a method of capturing custom data in a campaign. +/// Use varies by network. +///
+///     let params = [
+///       AnalyticsParameterCP1 : "custom_data",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCP1 NS_SWIFT_NAME(AnalyticsParameterCP1) = @"cp1"; + +/// The individual campaign name, slogan, promo code, etc. Some networks have pre-defined macro to +/// capture campaign information, otherwise can be populated by developer. Highly Recommended +/// (String). +///
+///     let params = [
+///       AnalyticsParameterCampaign : "winter_promotion",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCampaign NS_SWIFT_NAME(AnalyticsParameterCampaign) = + @"campaign"; + +/// Campaign ID (String). Used for keyword analysis to identify a specific product promotion or +/// strategic campaign. This is a required key for GA4 data import. +///
+///     let params = [
+///       AnalyticsParameterCampaignID : "7877652710",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCampaignID NS_SWIFT_NAME(AnalyticsParameterCampaignID) = + @"campaign_id"; + +/// Character used in game (String). +///
+///     let params = [
+///       AnalyticsParameterCharacter : "beat_boss",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCharacter NS_SWIFT_NAME(AnalyticsParameterCharacter) = + @"character"; + +/// Campaign content (String). +static NSString *const kFIRParameterContent NS_SWIFT_NAME(AnalyticsParameterContent) = @"content"; + +/// Type of content selected (String). +///
+///     let params = [
+///       AnalyticsParameterContentType : "news article",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterContentType NS_SWIFT_NAME(AnalyticsParameterContentType) = + @"content_type"; + +/// Coupon code used for a purchase (String). +///
+///     let params = [
+///       AnalyticsParameterCoupon : "SUMMER_FUN",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCoupon NS_SWIFT_NAME(AnalyticsParameterCoupon) = @"coupon"; + +/// Creative Format (String). Used to identify the high-level classification of the type of ad +/// served by a specific campaign. +///
+///     let params = [
+///       AnalyticsParameterCreativeFormat : "display",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCreativeFormat NS_SWIFT_NAME(AnalyticsParameterCreativeFormat) = + @"creative_format"; + +/// The name of a creative used in a promotional spot (String). +///
+///     let params = [
+///       AnalyticsParameterCreativeName : "Summer Sale",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCreativeName NS_SWIFT_NAME(AnalyticsParameterCreativeName) = + @"creative_name"; + +/// The name of a creative slot (String). +///
+///     let params = [
+///       AnalyticsParameterCreativeSlot : "summer_banner2",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCreativeSlot NS_SWIFT_NAME(AnalyticsParameterCreativeSlot) = + @"creative_slot"; + +/// Currency of the purchase or items associated with the event, in 3-letter +/// ISO_4217 format (String). +///
+///     let params = [
+///       AnalyticsParameterCurrency : "USD",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCurrency NS_SWIFT_NAME(AnalyticsParameterCurrency) = + @"currency"; + +/// Flight or Travel destination (String). +///
+///     let params = [
+///       AnalyticsParameterDestination : "Mountain View, CA",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterDestination NS_SWIFT_NAME(AnalyticsParameterDestination) = + @"destination"; + +/// Monetary value of discount associated with a purchase (Double). +///
+///     let params = [
+///       AnalyticsParameterDiscount : 2.0,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $2.00 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterDiscount NS_SWIFT_NAME(AnalyticsParameterDiscount) = + @"discount"; + +/// The arrival date, check-out date or rental end date for the item. This should be in +/// YYYY-MM-DD format (String). +///
+///     let params = [
+///       AnalyticsParameterEndDate : "2015-09-14",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterEndDate NS_SWIFT_NAME(AnalyticsParameterEndDate) = @"end_date"; + +/// Indicates that the associated event should either extend the current session or start a new +/// session if no session was active when the event was logged. Specify 1 to extend the current +/// session or to start a new session; any other value will not extend or start a session. +///
+///     let params = [
+///       AnalyticsParameterExtendSession : 1,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterExtendSession NS_SWIFT_NAME(AnalyticsParameterExtendSession) = + @"extend_session"; + +/// Flight number for travel events (String). +///
+///     let params = [
+///       AnalyticsParameterFlightNumber : "ZZ800",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterFlightNumber NS_SWIFT_NAME(AnalyticsParameterFlightNumber) = + @"flight_number"; + +/// Group/clan/guild ID (String). +///
+///     let params = [
+///       AnalyticsParameterGroupID : "g1",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterGroupID NS_SWIFT_NAME(AnalyticsParameterGroupID) = @"group_id"; + +/// The index of the item in a list (Int). +///
+///     let params = [
+///       AnalyticsParameterIndex : 5,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterIndex NS_SWIFT_NAME(AnalyticsParameterIndex) = @"index"; + +/// Item brand (String). +///
+///     let params = [
+///       AnalyticsParameterItemBrand : "Google",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemBrand NS_SWIFT_NAME(AnalyticsParameterItemBrand) = + @"item_brand"; + +/// Item category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory NS_SWIFT_NAME(AnalyticsParameterItemCategory) = + @"item_category"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory2 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory2 NS_SWIFT_NAME(AnalyticsParameterItemCategory2) = + @"item_category2"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory3 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory3 NS_SWIFT_NAME(AnalyticsParameterItemCategory3) = + @"item_category3"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory4 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory4 NS_SWIFT_NAME(AnalyticsParameterItemCategory4) = + @"item_category4"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory5 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory5 NS_SWIFT_NAME(AnalyticsParameterItemCategory5) = + @"item_category5"; + +/// Item ID (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemID : "SKU_12345",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemID NS_SWIFT_NAME(AnalyticsParameterItemID) = @"item_id"; + +/// The ID of the list in which the item was presented to the user (String). +///
+///     let params = [
+///       AnalyticsParameterItemListID : "ABC123",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemListID NS_SWIFT_NAME(AnalyticsParameterItemListID) = + @"item_list_id"; + +/// The name of the list in which the item was presented to the user (String). +///
+///     let params = [
+///       AnalyticsParameterItemListName : "Related products",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemListName NS_SWIFT_NAME(AnalyticsParameterItemListName) = + @"item_list_name"; + +/// Item Name (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemName : "jeggings",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemName NS_SWIFT_NAME(AnalyticsParameterItemName) = + @"item_name"; + +/// Item variant (String). +///
+///     let params = [
+///       AnalyticsParameterItemVariant : "Black",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemVariant NS_SWIFT_NAME(AnalyticsParameterItemVariant) = + @"item_variant"; + +/// The list of items involved in the transaction expressed as `[[String: Any]]`. +///
+///     let params = [
+///       AnalyticsParameterItems : [
+///         [AnalyticsParameterItemName : "jeggings", AnalyticsParameterItemCategory : "pants"],
+///         [AnalyticsParameterItemName : "boots", AnalyticsParameterItemCategory : "shoes"],
+///       ],
+///     ]
+/// 
+static NSString *const kFIRParameterItems NS_SWIFT_NAME(AnalyticsParameterItems) = @"items"; + +/// Level in game (Int). +///
+///     let params = [
+///       AnalyticsParameterLevel : 42,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLevel NS_SWIFT_NAME(AnalyticsParameterLevel) = @"level"; + +/// The name of a level in a game (String). +///
+///     let params = [
+///       AnalyticsParameterLevelName : "room_1",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLevelName NS_SWIFT_NAME(AnalyticsParameterLevelName) = + @"level_name"; + +/// Location (String). The Google Place ID +/// that corresponds to the associated event. Alternatively, you can supply your own custom +/// Location ID. +///
+///     let params = [
+///       AnalyticsParameterLocation : "ChIJiyj437sx3YAR9kUWC8QkLzQ",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLocation NS_SWIFT_NAME(AnalyticsParameterLocation) = + @"location"; + +/// The location associated with the event. Preferred to be the Google +/// Place ID that corresponds to the +/// associated item but could be overridden to a custom location ID string.(String). +///
+///     let params = [
+///       AnalyticsParameterLocationID : "ChIJiyj437sx3YAR9kUWC8QkLzQ",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLocationID NS_SWIFT_NAME(AnalyticsParameterLocationID) = + @"location_id"; + +/// Marketing Tactic (String). Used to identify the targeting criteria applied to a specific +/// campaign. +///
+///     let params = [
+///       AnalyticsParameterMarketingTactic : "Remarketing",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterMarketingTactic + NS_SWIFT_NAME(AnalyticsParameterMarketingTactic) = @"marketing_tactic"; + +/// The advertising or marketing medium, for example: cpc, banner, email, push. Highly recommended +/// (String). +///
+///     let params = [
+///       AnalyticsParameterMedium : "email",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterMedium NS_SWIFT_NAME(AnalyticsParameterMedium) = @"medium"; + +/// A particular approach used in an operation; for example, "facebook" or "email" in the context +/// of a sign_up or login event. (String). +///
+///     let params = [
+///       AnalyticsParameterMethod : "google",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterMethod NS_SWIFT_NAME(AnalyticsParameterMethod) = @"method"; + +/// Number of nights staying at hotel (Int). +///
+///     let params = [
+///       AnalyticsParameterNumberOfNights : 3,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterNumberOfNights + NS_SWIFT_NAME(AnalyticsParameterNumberOfNights) = @"number_of_nights"; + +/// Number of passengers traveling (Int). +///
+///     let params = [
+///       AnalyticsParameterNumberOfPassengers : 11,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterNumberOfPassengers + NS_SWIFT_NAME(AnalyticsParameterNumberOfPassengers) = @"number_of_passengers"; + +/// Number of rooms for travel events (Int). +///
+///     let params = [
+///       AnalyticsParameterNumberOfRooms : 2,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterNumberOfRooms NS_SWIFT_NAME(AnalyticsParameterNumberOfRooms) = + @"number_of_rooms"; + +/// Flight or Travel origin (String). +///
+///     let params = [
+///       AnalyticsParameterOrigin : "Mountain View, CA",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterOrigin NS_SWIFT_NAME(AnalyticsParameterOrigin) = @"origin"; + +/// The chosen method of payment (String). +///
+///     let params = [
+///       AnalyticsParameterPaymentType : "Visa",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPaymentType NS_SWIFT_NAME(AnalyticsParameterPaymentType) = + @"payment_type"; + +/// Purchase price (Double). +///
+///     let params = [
+///       AnalyticsParameterPrice : 1.0,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $1.00 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPrice NS_SWIFT_NAME(AnalyticsParameterPrice) = @"price"; + +/// The ID of a product promotion (String). +///
+///     let params = [
+///       AnalyticsParameterPromotionID : "ABC123",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPromotionID NS_SWIFT_NAME(AnalyticsParameterPromotionID) = + @"promotion_id"; + +/// The name of a product promotion (String). +///
+///     let params = [
+///       AnalyticsParameterPromotionName : "Summer Sale",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPromotionName NS_SWIFT_NAME(AnalyticsParameterPromotionName) = + @"promotion_name"; + +/// Purchase quantity (Int). +///
+///     let params = [
+///       AnalyticsParameterQuantity : 1,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterQuantity NS_SWIFT_NAME(AnalyticsParameterQuantity) = + @"quantity"; + +/// Score in game (Int). +///
+///     let params = [
+///       AnalyticsParameterScore : 4200,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterScore NS_SWIFT_NAME(AnalyticsParameterScore) = @"score"; + +/// Current screen class, such as the class name of the UIViewController, logged with screen_view +/// event and added to every event (String). +///
+///     let params = [
+///       AnalyticsParameterScreenClass : "LoginViewController",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterScreenClass NS_SWIFT_NAME(AnalyticsParameterScreenClass) = + @"screen_class"; + +/// Current screen name, such as the name of the UIViewController, logged with screen_view event and +/// added to every event (String). +///
+///     let params = [
+///       AnalyticsParameterScreenName : "LoginView",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterScreenName NS_SWIFT_NAME(AnalyticsParameterScreenName) = + @"screen_name"; + +/// The search string/keywords used (String). +///
+///     let params = [
+///       AnalyticsParameterSearchTerm : "periodic table",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSearchTerm NS_SWIFT_NAME(AnalyticsParameterSearchTerm) = + @"search_term"; + +/// Shipping cost associated with a transaction (Double). +///
+///     let params = [
+///       AnalyticsParameterShipping : 5.99,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $5.99 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterShipping NS_SWIFT_NAME(AnalyticsParameterShipping) = + @"shipping"; + +/// The shipping tier (e.g. Ground, Air, Next-day) selected for delivery of the purchased item +/// (String). +///
+///     let params = [
+///       AnalyticsParameterShippingTier : "Ground",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterShippingTier NS_SWIFT_NAME(AnalyticsParameterShippingTier) = + @"shipping_tier"; + +/// The origin of your traffic, such as an Ad network (for example, google) or partner (urban +/// airship). Identify the advertiser, site, publication, etc. that is sending traffic to your +/// property. Highly recommended (String). +///
+///     let params = [
+///       AnalyticsParameterSource : "InMobi",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSource NS_SWIFT_NAME(AnalyticsParameterSource) = @"source"; + +/// Source Platform (String). Used to identify the platform responsible for directing traffic to a +/// given Analytics property (e.g., a buying platform where budgets, targeting criteria, etc. are +/// set, a platform for managing organic traffic data, etc.). +///
+///     let params = [
+///       AnalyticsParameterSourcePlatform : "sa360",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSourcePlatform NS_SWIFT_NAME(AnalyticsParameterSourcePlatform) = + @"source_platform"; + +/// The departure date, check-in date or rental start date for the item. This should be in +/// YYYY-MM-DD format (String). +///
+///     let params = [
+///       AnalyticsParameterStartDate : "2015-09-14",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterStartDate NS_SWIFT_NAME(AnalyticsParameterStartDate) = + @"start_date"; + +/// The result of an operation. Specify 1 to indicate success and 0 to indicate failure (Int). +///
+///     let params = [
+///       AnalyticsParameterSuccess : 1,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSuccess NS_SWIFT_NAME(AnalyticsParameterSuccess) = @"success"; + +/// Tax cost associated with a transaction (Double). +///
+///     let params = [
+///       AnalyticsParameterTax : 2.43,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $2.43 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTax NS_SWIFT_NAME(AnalyticsParameterTax) = @"tax"; + +/// If you're manually tagging keyword campaigns, you should use utm_term to specify the keyword +/// (String). +///
+///     let params = [
+///       AnalyticsParameterTerm : "game",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTerm NS_SWIFT_NAME(AnalyticsParameterTerm) = @"term"; + +/// The unique identifier of a transaction (String). +///
+///     let params = [
+///       AnalyticsParameterTransactionID : "T12345",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTransactionID NS_SWIFT_NAME(AnalyticsParameterTransactionID) = + @"transaction_id"; + +/// Travel class (String). +///
+///     let params = [
+///       AnalyticsParameterTravelClass : "business",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTravelClass NS_SWIFT_NAME(AnalyticsParameterTravelClass) = + @"travel_class"; + +/// A context-specific numeric value which is accumulated automatically for each event type. This is +/// a general purpose parameter that is useful for accumulating a key metric that pertains to an +/// event. Examples include revenue, distance, time and points. Value should be specified as Int or +/// Double. +/// Notes: Values for pre-defined currency-related events (such as @c AnalyticsEventAddToCart) +/// should be supplied using Double and must be accompanied by a @c AnalyticsParameterCurrency +/// parameter. The valid range of accumulated values is +/// [-9,223,372,036,854.77, 9,223,372,036,854.77]. Supplying a non-numeric value, omitting the +/// corresponding @c AnalyticsParameterCurrency parameter, or supplying an invalid +/// currency code for conversion events will cause that +/// conversion to be omitted from reporting. +///
+///     let params = [
+///       AnalyticsParameterValue : 3.99,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $3.99 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterValue NS_SWIFT_NAME(AnalyticsParameterValue) = @"value"; + +/// Name of virtual currency type (String). +///
+///     let params = [
+///       AnalyticsParameterVirtualCurrencyName : "virtual_currency_name",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterVirtualCurrencyName + NS_SWIFT_NAME(AnalyticsParameterVirtualCurrencyName) = @"virtual_currency_name"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h new file mode 100644 index 0000000..2442d8a --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h @@ -0,0 +1,28 @@ +/// @file FIRUserPropertyNames.h +/// +/// Predefined user property names. +/// +/// A UserProperty is an attribute that describes the app-user. By supplying UserProperties, you can +/// later analyze different behaviors of various segments of your userbase. You may supply up to 25 +/// unique UserProperties per app, and you can use the name and value of your choosing for each one. +/// UserProperty names can be up to 24 characters long, may only contain alphanumeric characters and +/// underscores ("_"), and must start with an alphabetic character. UserProperty values can be up to +/// 36 characters long. The "firebase_", "google_", and "ga_" prefixes are reserved and should not +/// be used. + +#import + +/// Indicates whether events logged by Google Analytics can be used to personalize ads for the user. +/// Set to "YES" to enable, or "NO" to disable. Default is enabled. See the +/// documentation for +/// more details and information about related settings. +/// +///
+///     Analytics.setUserProperty("NO", forName: AnalyticsUserPropertyAllowAdPersonalizationSignals)
+/// 
+static NSString *const kFIRUserPropertyAllowAdPersonalizationSignals + NS_SWIFT_NAME(AnalyticsUserPropertyAllowAdPersonalizationSignals) = @"allow_personalized_ads"; + +/// The method used to sign in. For example, "google", "facebook" or "twitter". +static NSString *const kFIRUserPropertySignUpMethod + NS_SWIFT_NAME(AnalyticsUserPropertySignUpMethod) = @"sign_up_method"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-Swift.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-Swift.h new file mode 100644 index 0000000..127576f --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-Swift.h @@ -0,0 +1,312 @@ +#if 0 +#elif defined(__arm64__) && __arm64__ +// Generated by Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +#ifndef FIREBASEANALYTICS_SWIFT_H +#define FIREBASEANALYTICS_SWIFT_H +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgcc-compat" + +#if !defined(__has_include) +# define __has_include(x) 0 +#endif +#if !defined(__has_attribute) +# define __has_attribute(x) 0 +#endif +#if !defined(__has_feature) +# define __has_feature(x) 0 +#endif +#if !defined(__has_warning) +# define __has_warning(x) 0 +#endif + +#if __has_include() +# include +#endif + +#pragma clang diagnostic ignored "-Wauto-import" +#if defined(__OBJC__) +#include +#endif +#if defined(__cplusplus) +#include +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#endif +#if defined(__cplusplus) +#if defined(__arm64e__) && __has_include() +# include +#else +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreserved-macro-identifier" +# ifndef __ptrauth_swift_value_witness_function_pointer +# define __ptrauth_swift_value_witness_function_pointer(x) +# endif +# ifndef __ptrauth_swift_class_method_pointer +# define __ptrauth_swift_class_method_pointer(x) +# endif +#pragma clang diagnostic pop +#endif +#endif + +#if !defined(SWIFT_TYPEDEFS) +# define SWIFT_TYPEDEFS 1 +# if __has_include() +# include +# elif !defined(__cplusplus) +typedef uint_least16_t char16_t; +typedef uint_least32_t char32_t; +# endif +typedef float swift_float2 __attribute__((__ext_vector_type__(2))); +typedef float swift_float3 __attribute__((__ext_vector_type__(3))); +typedef float swift_float4 __attribute__((__ext_vector_type__(4))); +typedef double swift_double2 __attribute__((__ext_vector_type__(2))); +typedef double swift_double3 __attribute__((__ext_vector_type__(3))); +typedef double swift_double4 __attribute__((__ext_vector_type__(4))); +typedef int swift_int2 __attribute__((__ext_vector_type__(2))); +typedef int swift_int3 __attribute__((__ext_vector_type__(3))); +typedef int swift_int4 __attribute__((__ext_vector_type__(4))); +typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2))); +typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3))); +typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); +#endif + +#if !defined(SWIFT_PASTE) +# define SWIFT_PASTE_HELPER(x, y) x##y +# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) +#endif +#if !defined(SWIFT_METATYPE) +# define SWIFT_METATYPE(X) Class +#endif +#if !defined(SWIFT_CLASS_PROPERTY) +# if __has_feature(objc_class_property) +# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__ +# else +# define SWIFT_CLASS_PROPERTY(...) +# endif +#endif +#if !defined(SWIFT_RUNTIME_NAME) +# if __has_attribute(objc_runtime_name) +# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) +# else +# define SWIFT_RUNTIME_NAME(X) +# endif +#endif +#if !defined(SWIFT_COMPILE_NAME) +# if __has_attribute(swift_name) +# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) +# else +# define SWIFT_COMPILE_NAME(X) +# endif +#endif +#if !defined(SWIFT_METHOD_FAMILY) +# if __has_attribute(objc_method_family) +# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X))) +# else +# define SWIFT_METHOD_FAMILY(X) +# endif +#endif +#if !defined(SWIFT_NOESCAPE) +# if __has_attribute(noescape) +# define SWIFT_NOESCAPE __attribute__((noescape)) +# else +# define SWIFT_NOESCAPE +# endif +#endif +#if !defined(SWIFT_RELEASES_ARGUMENT) +# if __has_attribute(ns_consumed) +# define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed)) +# else +# define SWIFT_RELEASES_ARGUMENT +# endif +#endif +#if !defined(SWIFT_WARN_UNUSED_RESULT) +# if __has_attribute(warn_unused_result) +# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +# else +# define SWIFT_WARN_UNUSED_RESULT +# endif +#endif +#if !defined(SWIFT_NORETURN) +# if __has_attribute(noreturn) +# define SWIFT_NORETURN __attribute__((noreturn)) +# else +# define SWIFT_NORETURN +# endif +#endif +#if !defined(SWIFT_CLASS_EXTRA) +# define SWIFT_CLASS_EXTRA +#endif +#if !defined(SWIFT_PROTOCOL_EXTRA) +# define SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_ENUM_EXTRA) +# define SWIFT_ENUM_EXTRA +#endif +#if !defined(SWIFT_CLASS) +# if __has_attribute(objc_subclassing_restricted) +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# else +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# endif +#endif +#if !defined(SWIFT_RESILIENT_CLASS) +# if __has_attribute(objc_class_stub) +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub)) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME) +# else +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME) +# endif +#endif +#if !defined(SWIFT_PROTOCOL) +# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_EXTENSION) +# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) +#endif +#if !defined(OBJC_DESIGNATED_INITIALIZER) +# if __has_attribute(objc_designated_initializer) +# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +# else +# define OBJC_DESIGNATED_INITIALIZER +# endif +#endif +#if !defined(SWIFT_ENUM_ATTR) +# if __has_attribute(enum_extensibility) +# define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility))) +# else +# define SWIFT_ENUM_ATTR(_extensibility) +# endif +#endif +#if !defined(SWIFT_ENUM) +# define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# if __has_feature(generalized_swift_name) +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# else +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility) +# endif +#endif +#if !defined(SWIFT_UNAVAILABLE) +# define SWIFT_UNAVAILABLE __attribute__((unavailable)) +#endif +#if !defined(SWIFT_UNAVAILABLE_MSG) +# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg))) +#endif +#if !defined(SWIFT_AVAILABILITY) +# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__))) +#endif +#if !defined(SWIFT_WEAK_IMPORT) +# define SWIFT_WEAK_IMPORT __attribute__((weak_import)) +#endif +#if !defined(SWIFT_DEPRECATED) +# define SWIFT_DEPRECATED __attribute__((deprecated)) +#endif +#if !defined(SWIFT_DEPRECATED_MSG) +# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__))) +#endif +#if !defined(SWIFT_DEPRECATED_OBJC) +# if __has_feature(attribute_diagnose_if_objc) +# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning"))) +# else +# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) +# endif +#endif +#if defined(__OBJC__) +#if !defined(IBSegueAction) +# define IBSegueAction +#endif +#endif +#if !defined(SWIFT_EXTERN) +# if defined(__cplusplus) +# define SWIFT_EXTERN extern "C" +# else +# define SWIFT_EXTERN extern +# endif +#endif +#if !defined(SWIFT_CALL) +# define SWIFT_CALL __attribute__((swiftcall)) +#endif +#if !defined(SWIFT_INDIRECT_RESULT) +# define SWIFT_INDIRECT_RESULT __attribute__((swift_indirect_result)) +#endif +#if !defined(SWIFT_CONTEXT) +# define SWIFT_CONTEXT __attribute__((swift_context)) +#endif +#if !defined(SWIFT_ERROR_RESULT) +# define SWIFT_ERROR_RESULT __attribute__((swift_error_result)) +#endif +#if defined(__cplusplus) +# define SWIFT_NOEXCEPT noexcept +#else +# define SWIFT_NOEXCEPT +#endif +#if !defined(SWIFT_C_INLINE_THUNK) +# if __has_attribute(always_inline) +# if __has_attribute(nodebug) +# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) __attribute__((nodebug)) +# else +# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) +# endif +# else +# define SWIFT_C_INLINE_THUNK inline +# endif +#endif +#if defined(_WIN32) +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL __declspec(dllimport) +#endif +#else +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL +#endif +#endif +#if defined(__OBJC__) +#if __has_feature(objc_modules) +#if __has_warning("-Watimport-in-framework-header") +#pragma clang diagnostic ignored "-Watimport-in-framework-header" +#endif +#endif + +#endif +#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" +#pragma clang diagnostic ignored "-Wduplicate-method-arg" +#if __has_warning("-Wpragma-clang-attribute") +# pragma clang diagnostic ignored "-Wpragma-clang-attribute" +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wnullability" +#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension" + +#if __has_attribute(external_source_symbol) +# pragma push_macro("any") +# undef any +# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="FirebaseAnalytics",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) +# pragma pop_macro("any") +#endif + +#if defined(__OBJC__) + +#endif +#if __has_attribute(external_source_symbol) +# pragma clang attribute pop +#endif +#if defined(__cplusplus) +#endif +#pragma clang diagnostic pop +#endif + +#else +#error unsupported Swift architecture +#endif diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-umbrella.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-umbrella.h new file mode 100644 index 0000000..ad84fbb --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-umbrella.h @@ -0,0 +1,24 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "FIRAnalytics+AppDelegate.h" +#import "FIRAnalytics+Consent.h" +#import "FIRAnalytics+OnDevice.h" +#import "FIRAnalytics.h" +#import "FirebaseAnalytics.h" +#import "FIREventNames.h" +#import "FIRParameterNames.h" +#import "FIRUserPropertyNames.h" + +FOUNDATION_EXPORT double FirebaseAnalyticsVersionNumber; +FOUNDATION_EXPORT const unsigned char FirebaseAnalyticsVersionString[]; + diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h new file mode 100644 index 0000000..351da20 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h @@ -0,0 +1,7 @@ +#import "FIRAnalytics+AppDelegate.h" +#import "FIRAnalytics+Consent.h" +#import "FIRAnalytics+OnDevice.h" +#import "FIRAnalytics.h" +#import "FIREventNames.h" +#import "FIRParameterNames.h" +#import "FIRUserPropertyNames.h" diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Info.plist b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Info.plist new file mode 100644 index 0000000..bee8438 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Info.plist @@ -0,0 +1,52 @@ + + + + + BuildMachineOSBuild + 23F79 + CFBundleDevelopmentRegion + en + CFBundleExecutable + FirebaseAnalytics + CFBundleIdentifier + org.cocoapods.FirebaseAnalytics + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + FirebaseAnalytics + CFBundlePackageType + FMWK + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + AppleTVOS + + CFBundleVersion + 1 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 21K354 + DTPlatformName + appletvos + DTPlatformVersion + 17.2 + DTSDKBuild + 21K354 + DTSDKName + appletvos17.2 + DTXcode + 1520 + DTXcodeBuild + 15C500b + MinimumOSVersion + 100.0 + UIDeviceFamily + + 3 + + + diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-tvos.swiftsourceinfo b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-tvos.swiftsourceinfo new file mode 100644 index 0000000..aa4771e Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-tvos.swiftsourceinfo differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos.abi.json b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos.abi.json new file mode 100644 index 0000000..fde2b92 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos.abi.json @@ -0,0 +1,239 @@ +{ + "ABIRoot": { + "kind": "Root", + "name": "TopLevel", + "printedName": "TopLevel", + "children": [ + { + "kind": "Import", + "name": "StoreKit", + "printedName": "StoreKit", + "declKind": "Import", + "moduleName": "FirebaseAnalytics" + }, + { + "kind": "Import", + "name": "SwiftUI", + "printedName": "SwiftUI", + "declKind": "Import", + "moduleName": "FirebaseAnalytics" + }, + { + "kind": "TypeDecl", + "name": "Analytics", + "printedName": "Analytics", + "children": [ + { + "kind": "Function", + "name": "logTransaction", + "printedName": "logTransaction(_:)", + "children": [ + { + "kind": "TypeNominal", + "name": "Void", + "printedName": "()" + }, + { + "kind": "TypeNominal", + "name": "Transaction", + "printedName": "StoreKit.Transaction", + "usr": "s:8StoreKit11TransactionV" + } + ], + "declKind": "Func", + "usr": "s:So12FIRAnalyticsC17FirebaseAnalyticsE14logTransactionyy8StoreKit0E0VFZ", + "mangledName": "$sSo12FIRAnalyticsC17FirebaseAnalyticsE14logTransactionyy8StoreKit0E0VFZ", + "moduleName": "FirebaseAnalytics", + "static": true, + "declAttributes": [ + "Final", + "AccessControl", + "RawDocComment" + ], + "isFromExtension": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Class", + "usr": "c:objc(cs)FIRAnalytics", + "moduleName": "FirebaseAnalytics", + "isOpen": true, + "objc_name": "FIRAnalytics", + "declAttributes": [ + "ObjC", + "Dynamic" + ], + "superclassUsr": "c:objc(cs)NSObject", + "isExternal": true, + "inheritsConvenienceInitializers": true, + "superclassNames": [ + "ObjectiveC.NSObject" + ], + "conformances": [ + { + "kind": "Conformance", + "name": "Equatable", + "printedName": "Equatable", + "usr": "s:SQ", + "mangledName": "$sSQ" + }, + { + "kind": "Conformance", + "name": "Hashable", + "printedName": "Hashable", + "usr": "s:SH", + "mangledName": "$sSH" + }, + { + "kind": "Conformance", + "name": "CVarArg", + "printedName": "CVarArg", + "usr": "s:s7CVarArgP", + "mangledName": "$ss7CVarArgP" + }, + { + "kind": "Conformance", + "name": "_KeyValueCodingAndObservingPublishing", + "printedName": "_KeyValueCodingAndObservingPublishing", + "usr": "s:10Foundation37_KeyValueCodingAndObservingPublishingP", + "mangledName": "$s10Foundation37_KeyValueCodingAndObservingPublishingP" + }, + { + "kind": "Conformance", + "name": "_KeyValueCodingAndObserving", + "printedName": "_KeyValueCodingAndObserving", + "usr": "s:10Foundation27_KeyValueCodingAndObservingP", + "mangledName": "$s10Foundation27_KeyValueCodingAndObservingP" + }, + { + "kind": "Conformance", + "name": "CustomStringConvertible", + "printedName": "CustomStringConvertible", + "usr": "s:s23CustomStringConvertibleP", + "mangledName": "$ss23CustomStringConvertibleP" + }, + { + "kind": "Conformance", + "name": "CustomDebugStringConvertible", + "printedName": "CustomDebugStringConvertible", + "usr": "s:s28CustomDebugStringConvertibleP", + "mangledName": "$ss28CustomDebugStringConvertibleP" + } + ] + }, + { + "kind": "TypeDecl", + "name": "View", + "printedName": "View", + "children": [ + { + "kind": "Function", + "name": "analyticsScreen", + "printedName": "analyticsScreen(name:class:extraParameters:)", + "children": [ + { + "kind": "TypeNominal", + "name": "ModifiedContent", + "printedName": "SwiftUI.ModifiedContent<τ_0_0, FirebaseAnalytics.LoggedAnalyticsModifier>", + "children": [ + { + "kind": "TypeNominal", + "name": "GenericTypeParam", + "printedName": "τ_0_0" + }, + { + "kind": "TypeNominal", + "name": "LoggedAnalyticsModifier", + "printedName": "FirebaseAnalytics.LoggedAnalyticsModifier", + "usr": "s:17FirebaseAnalytics06LoggedB8ModifierV" + } + ], + "usr": "s:7SwiftUI15ModifiedContentV" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "hasDefaultArg": true, + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "Dictionary", + "printedName": "[Swift.String : Any]", + "children": [ + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "ProtocolComposition", + "printedName": "Any" + } + ], + "hasDefaultArg": true, + "usr": "s:SD" + } + ], + "declKind": "Func", + "usr": "s:7SwiftUI4ViewP17FirebaseAnalyticsE15analyticsScreen4name5class15extraParametersQrSS_SSSDySSypGtF", + "mangledName": "$s7SwiftUI4ViewP17FirebaseAnalyticsE15analyticsScreen4name5class15extraParametersQrSS_SSSDySSypGtF", + "moduleName": "FirebaseAnalytics", + "genericSig": "<τ_0_0 where τ_0_0 : SwiftUI.View>", + "sugared_genericSig": "", + "declAttributes": [ + "AccessControl", + "RawDocComment" + ], + "isFromExtension": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Protocol", + "usr": "s:7SwiftUI4ViewP", + "mangledName": "$s7SwiftUI4ViewP", + "moduleName": "SwiftUI", + "genericSig": "<τ_0_0.Body : SwiftUI.View>", + "sugared_genericSig": "", + "intro_Macosx": "10.15", + "intro_iOS": "13.0", + "intro_tvOS": "13.0", + "intro_watchOS": "6.0", + "declAttributes": [ + "TypeEraser", + "Available", + "Available", + "Available", + "Available" + ], + "isExternal": true + } + ], + "json_format_version": 8 + }, + "ConstValues": [ + { + "filePath": "\/Volumes\/google\/src\/cloud\/pdchen\/firebaserelease\/google3\/googlemac\/iPhone\/Firebase\/Analytics\/Sources\/Swift\/Analytics+SwiftUI.swift", + "kind": "StringLiteral", + "offset": 2654, + "length": 6, + "value": "\"View\"" + }, + { + "filePath": "\/Volumes\/google\/src\/cloud\/pdchen\/firebaserelease\/google3\/googlemac\/iPhone\/Firebase\/Analytics\/Sources\/Swift\/Analytics+SwiftUI.swift", + "kind": "Dictionary", + "offset": 2701, + "length": 3, + "value": "[]" + } + ] +} \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos.private.swiftinterface b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos.private.swiftinterface new file mode 100644 index 0000000..adbbb93 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos.private.swiftinterface @@ -0,0 +1,22 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +// swift-module-flags: -target arm64-apple-tvos12.0 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name FirebaseAnalytics +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import FirebaseAnalytics +import StoreKit +import Swift +import SwiftUI +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *) +@available(watchOS, unavailable) +extension FirebaseAnalytics.Analytics { + public static func logTransaction(_ transaction: StoreKit.Transaction) +} +@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *) +@available(watchOS, unavailable) +extension SwiftUI.View { + public func analyticsScreen(name: Swift.String, class: Swift.String = "View", extraParameters: [Swift.String : Any] = [:]) -> some SwiftUI.View + +} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos.swiftdoc b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos.swiftdoc new file mode 100644 index 0000000..dd3b292 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos.swiftdoc differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos.swiftinterface b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos.swiftinterface new file mode 100644 index 0000000..adbbb93 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos.swiftinterface @@ -0,0 +1,22 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +// swift-module-flags: -target arm64-apple-tvos12.0 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name FirebaseAnalytics +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import FirebaseAnalytics +import StoreKit +import Swift +import SwiftUI +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *) +@available(watchOS, unavailable) +extension FirebaseAnalytics.Analytics { + public static func logTransaction(_ transaction: StoreKit.Transaction) +} +@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *) +@available(watchOS, unavailable) +extension SwiftUI.View { + public func analyticsScreen(name: Swift.String, class: Swift.String = "View", extraParameters: [Swift.String : Any] = [:]) -> some SwiftUI.View + +} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Modules/module.modulemap b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Modules/module.modulemap new file mode 100644 index 0000000..fa10817 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64/FirebaseAnalytics.framework/Modules/module.modulemap @@ -0,0 +1,16 @@ +framework module FirebaseAnalytics { +umbrella header "FirebaseAnalytics-umbrella.h" +export * +module * { export * } + link framework "Foundation" + link framework "Security" + link framework "SystemConfiguration" + link framework "UIKit" + link "c++" + link "sqlite3" + link "z" +} +module FirebaseAnalytics.Swift { + header "FirebaseAnalytics-Swift.h" + requires objc +} \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/FirebaseAnalytics b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/FirebaseAnalytics new file mode 100644 index 0000000..b3b1aa6 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/FirebaseAnalytics differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h new file mode 100644 index 0000000..cb1e407 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h @@ -0,0 +1,80 @@ +#import + +#import "FIRAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +/// Provides App Delegate handlers to be used in your App Delegate. +/// +/// To save time integrating Firebase Analytics in an application, Firebase Analytics does not +/// require delegation implementation from the AppDelegate if neither SwiftUI nor UIScene lifecycle +/// is adopted. Instead this is automatically done by Firebase Analytics. Should you choose instead +/// to delegate manually, you can turn off the App Delegate Proxy by adding +/// FirebaseAppDelegateProxyEnabled into your app's Info.plist and setting it to boolean `NO`, and +/// adding the methods in this category to corresponding delegation handlers. +/// +/// To handle Universal Links, you must return `true` in +/// `UIApplicationDelegate.application(_:didFinishLaunchingWithOptions:)`. +@interface FIRAnalytics (AppDelegate) + +/// Handles events related to a URL session that are waiting to be processed. +/// +/// 1. If SwiftUI lifecycle is adopted, call this method from +/// `UIApplicationDelegate.application(_:handleEventsForBackgroundURLSession:completionHandler:)` +/// in your app delegate. +/// +/// 2. If SwiftUI lifecycle is not adopted, Firebase Analytics does not require delegation +/// implementation from the AppDelegate. If you choose instead to delegate manually, you can set +/// FirebaseAppDelegateProxyEnabled to boolean `NO` in your app's Info.plist and call this method +/// from +/// `UIApplicationDelegate.application(_:handleEventsForBackgroundURLSession:completionHandler:)` +/// in your app delegate. +/// +/// @param identifier The identifier of the URL session requiring attention. +/// @param completionHandler The completion handler to call when you finish processing the events. +/// Calling this completion handler lets the system know that your app's user interface is +/// updated and a new snapshot can be taken. ++ (void)handleEventsForBackgroundURLSession:(NSString *)identifier + completionHandler:(nullable void (^)(void))completionHandler; + +/// Handles the event when the app is launched by a URL (custom URL scheme or universal link). +/// +/// 1. If SwiftUI lifecycle is adopted, use `onOpenURL(perform:)` to register a handler and call +/// this method in the handler. +/// +/// 2. If UIScene lifecycle is adopted, call this method from +/// `UISceneDelegate.scene(_:willConnectTo:options:)` and +/// `UISceneDelegate.scene(_:openURLContexts:)` when the URL contexts are available. +/// +/// 3. If neither SwiftUI nor UIScene lifecycle is adopted, Firebase Analytics does not require +/// delegation implementation from the AppDelegate. If you choose instead to delegate manually, you +/// can set FirebaseAppDelegateProxyEnabled to boolean `NO` in your app's Info.plist and call this +/// method from `UIApplicationDelegate.application(_:open:options:)` in your app delegate. +/// +/// @param url The URL resource to open. This resource can be a network resource or a file. ++ (void)handleOpenURL:(NSURL *)url; + +/// Handles the event when the app receives data associated with user activity that includes a +/// Universal Link. +/// +/// 1. If SwiftUI lifecycle is adopted, use `onOpenURL(perform:)` to register a handler and call +/// `Analytics.handleOpen(_:)` instead in the handler. +/// +/// 2. If UIScene lifecycle is adopted, call this method from +/// `UISceneDelegate.scene(_:willConnectTo:options:)` and `UISceneDelegate.scene(_:continue:)` when +/// NSUserActivity is available. See the [Apple +/// doc](https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app) for +/// more details. +/// +/// 3. If neither SwiftUI nor UIScene lifecycle is adopted, Firebase Analytics does not require +/// delegation implementation from the AppDelegate. If you choose instead to delegate manually, you +/// can set FirebaseAppDelegateProxyEnabled to boolean `NO` in your app's Info.plist and call this +/// method from `UIApplication.application(_:continue:restorationHandler:)` in your app delegate. +/// +/// @param userActivity The activity object containing the data associated with the task the user +/// was performing. ++ (void)handleUserActivity:(id)userActivity; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h new file mode 100644 index 0000000..7758390 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+Consent.h @@ -0,0 +1,51 @@ +#import + +#import "FIRAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +/// The type of consent to set. Supported consent types are `ConsentType.adStorage`, +/// `ConsentType.analyticsStorage`, `ConsentType.adUserData`, and `ConsentType.adPersonalization`. +/// Omitting a type retains its previous status. +typedef NSString *FIRConsentType NS_TYPED_ENUM NS_SWIFT_NAME(ConsentType); + +/// Enables storage (such as device identifiers) related to advertising. +extern FIRConsentType const FIRConsentTypeAdStorage; + +/// Enables storage (such as app identifiers) related to analytics, e.g. visit duration. +extern FIRConsentType const FIRConsentTypeAnalyticsStorage; + +/// Sets consent for sending user data to Google for advertising purposes. +extern FIRConsentType const FIRConsentTypeAdUserData; + +/// Sets consent for personalized advertising. +extern FIRConsentType const FIRConsentTypeAdPersonalization; + +/// The status value of the consent type. Supported statuses are `ConsentStatus.granted` and +/// `ConsentStatus.denied`. +typedef NSString *FIRConsentStatus NS_TYPED_ENUM NS_SWIFT_NAME(ConsentStatus); + +/// Consent status indicating consent is denied. For an overview of which data is sent when consent +/// is denied, see [SDK behavior with consent +/// mode](https://developers.google.com/tag-platform/security/concepts/consent-mode#tag-behavior). +extern FIRConsentStatus const FIRConsentStatusDenied; + +/// Consent status indicating consent is granted. +extern FIRConsentStatus const FIRConsentStatusGranted; + +/// Sets the applicable end user consent state. +@interface FIRAnalytics (Consent) + +/// Sets the applicable end user consent state (e.g. for device identifiers) for this app on this +/// device. Use the consent settings to specify individual consent type values. Settings are +/// persisted across app sessions. By default consent types are set to `ConsentStatus.granted`. +/// +/// @param consentSettings A Dictionary of consent types. Supported consent type keys are +/// `ConsentType.adStorage`, `ConsentType.analyticsStorage`, `ConsentType.adUserData`, and +/// `ConsentType.adPersonalization`. Valid values are `ConsentStatus.granted` and +/// `ConsentStatus.denied`. ++ (void)setConsent:(NSDictionary *)consentSettings; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+OnDevice.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+OnDevice.h new file mode 100644 index 0000000..0bfec88 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics+OnDevice.h @@ -0,0 +1,44 @@ +#import + +#import "FIRAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +API_UNAVAILABLE(macCatalyst, macos, tvos, watchos) +@interface FIRAnalytics (OnDevice) + +/// Initiates on-device conversion measurement given a user email address. Requires dependency +/// GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a no-op. +/// @param emailAddress User email address. Include a domain name for all email addresses +/// (e.g. gmail.com or hotmail.co.jp). ++ (void)initiateOnDeviceConversionMeasurementWithEmailAddress:(NSString *)emailAddress + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(emailAddress:)); + +/// Initiates on-device conversion measurement given a phone number in E.164 format. Requires +/// dependency GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a no-op. +/// @param phoneNumber User phone number. Must be in E.164 format, which means it must be +/// limited to a maximum of 15 digits and must include a plus sign (+) prefix and country code +/// with no dashes, parentheses, or spaces. ++ (void)initiateOnDeviceConversionMeasurementWithPhoneNumber:(NSString *)phoneNumber + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(phoneNumber:)); + +/// Initiates on-device conversion measurement given a sha256-hashed user email address. Requires +/// dependency GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a no-op. +/// @param hashedEmailAddress User email address as a UTF8-encoded string normalized and hashed +/// according to the instructions at +/// https://firebase.google.com/docs/tutorials/ads-ios-on-device-measurement/step-3. ++ (void)initiateOnDeviceConversionMeasurementWithHashedEmailAddress:(NSData *)hashedEmailAddress + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(hashedEmailAddress:)); + +/// Initiates on-device conversion measurement given a sha256-hashed phone number in E.164 format. +/// Requires dependency GoogleAppMeasurementOnDeviceConversion to be linked in, otherwise it is a +/// no-op. +/// @param hashedPhoneNumber UTF8-encoded user phone number in E.164 format and then hashed +/// according to the instructions at +/// https://firebase.google.com/docs/tutorials/ads-ios-on-device-measurement/step-3. ++ (void)initiateOnDeviceConversionMeasurementWithHashedPhoneNumber:(NSData *)hashedPhoneNumber + NS_SWIFT_NAME(initiateOnDeviceConversionMeasurement(hashedPhoneNumber:)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics.h new file mode 100644 index 0000000..e58d7dd --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRAnalytics.h @@ -0,0 +1,155 @@ +#import + +#import "FIREventNames.h" +#import "FIRParameterNames.h" +#import "FIRUserPropertyNames.h" + +NS_ASSUME_NONNULL_BEGIN + +/// The top level Firebase Analytics singleton that provides methods for logging events and setting +/// user properties. See the developer guides for general +/// information on using Firebase Analytics in your apps. +/// +/// @note The Analytics SDK uses SQLite to persist events and other app-specific data. Calling +/// certain thread-unsafe global SQLite methods like `sqlite3_shutdown()` can result in +/// unexpected crashes at runtime. +NS_SWIFT_NAME(Analytics) +@interface FIRAnalytics : NSObject + +/// Logs an app event. The event can have up to 25 parameters. Events with the same name must have +/// the same parameters. Up to 500 event names are supported. Using predefined events and/or +/// parameters is recommended for optimal reporting. +/// +/// The following event names are reserved and cannot be used: +///
    +///
  • ad_activeview
  • +///
  • ad_click
  • +///
  • ad_exposure
  • +///
  • ad_query
  • +///
  • ad_reward
  • +///
  • adunit_exposure
  • +///
  • app_clear_data
  • +///
  • app_exception
  • +///
  • app_remove
  • +///
  • app_store_refund
  • +///
  • app_store_subscription_cancel
  • +///
  • app_store_subscription_convert
  • +///
  • app_store_subscription_renew
  • +///
  • app_update
  • +///
  • app_upgrade
  • +///
  • dynamic_link_app_open
  • +///
  • dynamic_link_app_update
  • +///
  • dynamic_link_first_open
  • +///
  • error
  • +///
  • firebase_campaign
  • +///
  • first_open
  • +///
  • first_visit
  • +///
  • in_app_purchase
  • +///
  • notification_dismiss
  • +///
  • notification_foreground
  • +///
  • notification_open
  • +///
  • notification_receive
  • +///
  • os_update
  • +///
  • session_start
  • +///
  • session_start_with_rollout
  • +///
  • user_engagement
  • +///
+/// +/// @param name The name of the event. Should contain 1 to 40 alphanumeric characters or +/// underscores. The name must start with an alphabetic character. Some event names are +/// reserved. See FIREventNames.h for the list of reserved event names. The "firebase_", +/// "google_", and "ga_" prefixes are reserved and should not be used. Note that event names are +/// case-sensitive and that logging two events whose names differ only in case will result in +/// two distinct events. To manually log screen view events, use the `screen_view` event name. +/// @param parameters The dictionary of event parameters. Passing `nil` indicates that the event has +/// no parameters. Parameter names can be up to 40 characters long and must start with an +/// alphabetic character and contain only alphanumeric characters and underscores. Only String, +/// Int, and Double parameter types are supported. String parameter values can be up to 100 +/// characters long for standard Google Analytics properties, and up to 500 characters long for +/// Google Analytics 360 properties. The "firebase_", "google_", and "ga_" prefixes are reserved +/// and should not be used for parameter names. ++ (void)logEventWithName:(NSString *)name + parameters:(nullable NSDictionary *)parameters + NS_SWIFT_NAME(logEvent(_:parameters:)); + +/// Sets a user property to a given value. Up to 25 user property names are supported. Once set, +/// user property values persist throughout the app lifecycle and across sessions. +/// +/// The following user property names are reserved and cannot be used: +///
    +///
  • first_open_time
  • +///
  • last_deep_link_referrer
  • +///
  • user_id
  • +///
+/// +/// @param value The value of the user property. Values can be up to 36 characters long. Setting the +/// value to `nil` removes the user property. +/// @param name The name of the user property to set. Should contain 1 to 24 alphanumeric characters +/// or underscores and must start with an alphabetic character. The "firebase_", "google_", and +/// "ga_" prefixes are reserved and should not be used for user property names. ++ (void)setUserPropertyString:(nullable NSString *)value forName:(NSString *)name + NS_SWIFT_NAME(setUserProperty(_:forName:)); + +/// Sets the user ID property. This feature must be used in accordance with +/// Google's Privacy Policy +/// +/// @param userID The user ID to ascribe to the user of this app on this device, which must be +/// non-empty and no more than 256 characters long. Setting userID to `nil` removes the user ID. ++ (void)setUserID:(nullable NSString *)userID; + +/// Sets whether analytics collection is enabled for this app on this device. This setting is +/// persisted across app sessions. By default it is enabled. +/// +/// @param analyticsCollectionEnabled A flag that enables or disables Analytics collection. ++ (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled; + +/// Sets the interval of inactivity in seconds that terminates the current session. The default +/// value is 1800 seconds (30 minutes). +/// +/// @param sessionTimeoutInterval The custom time of inactivity in seconds before the current +/// session terminates. ++ (void)setSessionTimeoutInterval:(NSTimeInterval)sessionTimeoutInterval; + +/// Asynchronously retrieves the identifier of the current app session. +/// +/// The session ID retrieval could fail due to Analytics collection disabled, app session expired, +/// etc. +/// +/// @param completion The completion handler to call when the session ID retrieval is complete. This +/// handler is executed on a system-defined global concurrent queue. +/// This completion handler takes the following parameters: +/// sessionID The identifier of the current app session. The value is undefined if the +/// request failed. +/// error An error object that indicates why the request failed, or `nil` if the request +/// was successful. ++ (void)sessionIDWithCompletion:(void (^)(int64_t sessionID, NSError *_Nullable error))completion; + +/// Returns the unique ID for this instance of the application or `nil` if +/// `ConsentType.analyticsStorage` has been set to `ConsentStatus.denied`. +/// +/// @see `FIRAnalytics+Consent.h` ++ (nullable NSString *)appInstanceID; + +/// Clears all analytics data for this instance from the device and resets the app instance ID. ++ (void)resetAnalyticsData; + +/// Adds parameters that will be set on every event logged from the SDK, including automatic ones. +/// The values passed in the parameters dictionary will be added to the dictionary of default event +/// parameters. These parameters persist across app runs. They are of lower precedence than event +/// parameters, so if an event parameter and a parameter set using this API have the same name, the +/// value of the event parameter will be used. The same limitations on event parameters apply to +/// default event parameters. +/// +/// @param parameters Parameters to be added to the dictionary of parameters added to every event. +/// They will be added to the dictionary of default event parameters, replacing any existing +/// parameter with the same name. Valid parameters are String, Int, and Double. Setting a key's +/// value to `NSNull()` will clear that parameter. Passing in a `nil` dictionary will clear all +/// parameters. ++ (void)setDefaultEventParameters:(nullable NSDictionary *)parameters; + +/// Unavailable. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIREventNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIREventNames.h new file mode 100644 index 0000000..1e69a44 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIREventNames.h @@ -0,0 +1,418 @@ +/// @file FIREventNames.h +/// +/// Predefined event names. +/// +/// An Event is an important occurrence in your app that you want to measure. You can report up to +/// 500 different types of Events per app and you can associate up to 25 unique parameters with each +/// Event type. Some common events are suggested below, but you may also choose to specify custom +/// Event types that are associated with your specific app. Each event type is identified by a +/// unique name. Event names can be up to 40 characters long, may only contain alphanumeric +/// characters and underscores ("_"), and must start with an alphabetic character. The "firebase_", +/// "google_", and "ga_" prefixes are reserved and should not be used. + +#import + +/// Ad Impression event. This event signifies when a user sees an ad impression. Note: If you supply +/// the @c AnalyticsParameterValue parameter, you must also supply the @c AnalyticsParameterCurrency +/// parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterAdPlatform (String) (optional)
  • +///
  • @c AnalyticsParameterAdFormat (String) (optional)
  • +///
  • @c AnalyticsParameterAdSource (String) (optional)
  • +///
  • @c AnalyticsParameterAdUnitName (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAdImpression NS_SWIFT_NAME(AnalyticsEventAdImpression) = + @"ad_impression"; + +/// Add Payment Info event. This event signifies that a user has submitted their payment +/// information. Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply +/// the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterPaymentType (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddPaymentInfo NS_SWIFT_NAME(AnalyticsEventAddPaymentInfo) = + @"add_payment_info"; + +/// Add Shipping Info event. This event signifies that a user has submitted their shipping +/// information. Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply +/// the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterShippingTier (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddShippingInfo NS_SWIFT_NAME(AnalyticsEventAddShippingInfo) = + @"add_shipping_info"; + +/// E-Commerce Add To Cart event. This event signifies that an item(s) was added to a cart for +/// purchase. Add this event to a funnel with @c AnalyticsEventPurchase to gauge the effectiveness +/// of your checkout process. Note: If you supply the @c AnalyticsParameterValue parameter, you must +/// also supply the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed +/// accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddToCart NS_SWIFT_NAME(AnalyticsEventAddToCart) = @"add_to_cart"; + +/// E-Commerce Add To Wishlist event. This event signifies that an item was added to a wishlist. Use +/// this event to identify popular gift items. Note: If you supply the @c AnalyticsParameterValue +/// parameter, you must also supply the @c AnalyticsParameterCurrency parameter so that revenue +/// metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventAddToWishlist NS_SWIFT_NAME(AnalyticsEventAddToWishlist) = + @"add_to_wishlist"; + +/// App Open event. By logging this event when an App becomes active, developers can understand how +/// often users leave and return during the course of a Session. Although Sessions are automatically +/// reported, this event can provide further clarification around the continuous engagement of +/// app-users. +static NSString *const kFIREventAppOpen NS_SWIFT_NAME(AnalyticsEventAppOpen) = @"app_open"; + +/// E-Commerce Begin Checkout event. This event signifies that a user has begun the process of +/// checking out. Add this event to a funnel with your @c AnalyticsEventPurchase event to gauge the +/// effectiveness of your checkout process. Note: If you supply the @c AnalyticsParameterValue +/// parameter, you must also supply the @c AnalyticsParameterCurrency parameter so that revenue +/// metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventBeginCheckout NS_SWIFT_NAME(AnalyticsEventBeginCheckout) = + @"begin_checkout"; + +/// Campaign Detail event. Log this event to supply the referral details of a re-engagement +/// campaign. Note: you must supply at least one of the required parameters +/// AnalyticsParameterSource, AnalyticsParameterMedium or AnalyticsParameterCampaign. Params: +/// +///
    +///
  • @c AnalyticsParameterSource (String)
  • +///
  • @c AnalyticsParameterMedium (String)
  • +///
  • @c AnalyticsParameterCampaign (String)
  • +///
  • @c AnalyticsParameterTerm (String) (optional)
  • +///
  • @c AnalyticsParameterContent (String) (optional)
  • +///
  • @c AnalyticsParameterAdNetworkClickID (String) (optional)
  • +///
  • @c AnalyticsParameterCP1 (String) (optional)
  • +///
  • @c AnalyticsParameterCampaignID (String) (optional)
  • +///
  • @c AnalyticsParameterCreativeFormat (String) (optional)
  • +///
  • @c AnalyticsParameterMarketingTactic (String) (optional)
  • +///
  • @c AnalyticsParameterSourcePlatform (String) (optional)
  • +///
+static NSString *const kFIREventCampaignDetails NS_SWIFT_NAME(AnalyticsEventCampaignDetails) = + @"campaign_details"; + +/// Earn Virtual Currency event. This event tracks the awarding of virtual currency in your app. Log +/// this along with @c AnalyticsEventSpendVirtualCurrency to better understand your virtual economy. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterVirtualCurrencyName (String)
  • +///
  • @c AnalyticsParameterValue (Int or Double)
  • +///
+static NSString *const kFIREventEarnVirtualCurrency + NS_SWIFT_NAME(AnalyticsEventEarnVirtualCurrency) = @"earn_virtual_currency"; + +/// Generate Lead event. Log this event when a lead has been generated in the app to understand the +/// efficacy of your install and re-engagement campaigns. Note: If you supply the +/// @c AnalyticsParameterValue parameter, you must also supply the @c AnalyticsParameterCurrency +/// parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventGenerateLead NS_SWIFT_NAME(AnalyticsEventGenerateLead) = + @"generate_lead"; + +/// Join Group event. Log this event when a user joins a group such as a guild, team or family. Use +/// this event to analyze how popular certain groups or social features are in your app. Params: +/// +///
    +///
  • @c AnalyticsParameterGroupID (String)
  • +///
+static NSString *const kFIREventJoinGroup NS_SWIFT_NAME(AnalyticsEventJoinGroup) = @"join_group"; + +/// Level End event. Log this event when the user finishes a level. Params: +/// +///
    +///
  • @c AnalyticsParameterLevelName (String)
  • +///
  • @c AnalyticsParameterSuccess (String)
  • +///
+static NSString *const kFIREventLevelEnd NS_SWIFT_NAME(AnalyticsEventLevelEnd) = @"level_end"; + +/// Level Start event. Log this event when the user starts a new level. Params: +/// +///
    +///
  • @c AnalyticsParameterLevelName (String)
  • +///
+static NSString *const kFIREventLevelStart NS_SWIFT_NAME(AnalyticsEventLevelStart) = @"level_start"; + +/// Level Up event. This event signifies that a player has leveled up in your gaming app. It can +/// help you gauge the level distribution of your userbase and help you identify certain levels that +/// are difficult to pass. Params: +/// +///
    +///
  • @c AnalyticsParameterLevel (Int)
  • +///
  • @c AnalyticsParameterCharacter (String) (optional)
  • +///
+static NSString *const kFIREventLevelUp NS_SWIFT_NAME(AnalyticsEventLevelUp) = @"level_up"; + +/// Login event. Apps with a login feature can report this event to signify that a user has logged +/// in. +static NSString *const kFIREventLogin NS_SWIFT_NAME(AnalyticsEventLogin) = @"login"; + +/// Post Score event. Log this event when the user posts a score in your gaming app. This event can +/// help you understand how users are actually performing in your game and it can help you correlate +/// high scores with certain audiences or behaviors. Params: +/// +///
    +///
  • @c AnalyticsParameterScore (Int)
  • +///
  • @c AnalyticsParameterLevel (Int) (optional)
  • +///
  • @c AnalyticsParameterCharacter (String) (optional)
  • +///
+static NSString *const kFIREventPostScore NS_SWIFT_NAME(AnalyticsEventPostScore) = @"post_score"; + +/// E-Commerce Purchase event. This event signifies that an item(s) was purchased by a user. Note: +/// This is different from the in-app purchase event, which is reported automatically for App +/// Store-based apps. Note: If you supply the @c AnalyticsParameterValue parameter, you must also +/// supply the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed +/// accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterAffiliation (String) (optional)
  • +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterEndDate (String) (optional)
  • +///
  • @c AnalyticsParameterItemID (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterShipping (Double) (optional)
  • +///
  • @c AnalyticsParameterStartDate (String) (optional)
  • +///
  • @c AnalyticsParameterTax (Double) (optional)
  • +///
  • @c AnalyticsParameterTransactionID (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventPurchase NS_SWIFT_NAME(AnalyticsEventPurchase) = @"purchase"; + +/// E-Commerce Refund event. This event signifies that a refund was issued. Note: If you supply the +/// @c AnalyticsParameterValue parameter, you must also supply the @c AnalyticsParameterCurrency +/// parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterAffiliation (String) (optional)
  • +///
  • @c AnalyticsParameterCoupon (String) (optional)
  • +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterShipping (Double) (optional)
  • +///
  • @c AnalyticsParameterTax (Double) (optional)
  • +///
  • @c AnalyticsParameterTransactionID (String) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventRefund NS_SWIFT_NAME(AnalyticsEventRefund) = @"refund"; + +/// E-Commerce Remove from Cart event. This event signifies that an item(s) was removed from a cart. +/// Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply the @c +/// AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventRemoveFromCart NS_SWIFT_NAME(AnalyticsEventRemoveFromCart) = + @"remove_from_cart"; + +/// Screen View event. This event signifies a screen view. Use this when a screen transition occurs. +/// This event can be logged irrespective of whether automatic screen tracking is enabled. Params: +/// +///
    +///
  • @c AnalyticsParameterScreenClass (String) (optional)
  • +///
  • @c AnalyticsParameterScreenName (String) (optional)
  • +///
+static NSString *const kFIREventScreenView NS_SWIFT_NAME(AnalyticsEventScreenView) = @"screen_view"; + +/// Search event. Apps that support search features can use this event to contextualize search +/// operations by supplying the appropriate, corresponding parameters. This event can help you +/// identify the most popular content in your app. Params: +/// +///
    +///
  • @c AnalyticsParameterSearchTerm (String)
  • +///
  • @c AnalyticsParameterStartDate (String) (optional)
  • +///
  • @c AnalyticsParameterEndDate (String) (optional)
  • +///
  • @c AnalyticsParameterNumberOfNights (Int) (optional) for hotel bookings
  • +///
  • @c AnalyticsParameterNumberOfRooms (Int) (optional) for hotel bookings
  • +///
  • @c AnalyticsParameterNumberOfPassengers (Int) (optional) for travel bookings
  • +///
  • @c AnalyticsParameterOrigin (String) (optional)
  • +///
  • @c AnalyticsParameterDestination (String) (optional)
  • +///
  • @c AnalyticsParameterTravelClass (String) (optional) for travel bookings
  • +///
+static NSString *const kFIREventSearch NS_SWIFT_NAME(AnalyticsEventSearch) = @"search"; + +/// Select Content event. This general purpose event signifies that a user has selected some content +/// of a certain type in an app. The content can be any object in your app. This event can help you +/// identify popular content and categories of content in your app. Params: +/// +///
    +///
  • @c AnalyticsParameterContentType (String)
  • +///
  • @c AnalyticsParameterItemID (String)
  • +///
+static NSString *const kFIREventSelectContent NS_SWIFT_NAME(AnalyticsEventSelectContent) = + @"select_content"; + +/// Select Item event. This event signifies that an item was selected by a user from a list. Use the +/// appropriate parameters to contextualize the event. Use this event to discover the most popular +/// items selected. Params: +/// +///
    +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterItemListID (String) (optional)
  • +///
  • @c AnalyticsParameterItemListName (String) (optional)
  • +///
+static NSString *const kFIREventSelectItem NS_SWIFT_NAME(AnalyticsEventSelectItem) = @"select_item"; + +/// Select promotion event. This event signifies that a user has selected a promotion offer. Use the +/// appropriate parameters to contextualize the event, such as the item(s) for which the promotion +/// applies. Params: +/// +///
    +///
  • @c AnalyticsParameterCreativeName (String) (optional)
  • +///
  • @c AnalyticsParameterCreativeSlot (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterLocationID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionName (String) (optional)
  • +///
+static NSString *const kFIREventSelectPromotion NS_SWIFT_NAME(AnalyticsEventSelectPromotion) = + @"select_promotion"; + +/// Share event. Apps with social features can log the Share event to identify the most viral +/// content. Params: +/// +///
    +///
  • @c AnalyticsParameterContentType (String)
  • +///
  • @c AnalyticsParameterItemID (String)
  • +///
+static NSString *const kFIREventShare NS_SWIFT_NAME(AnalyticsEventShare) = @"share"; + +/// Sign Up event. This event indicates that a user has signed up for an account in your app. The +/// parameter signifies the method by which the user signed up. Use this event to understand the +/// different behaviors between logged in and logged out users. Params: +/// +///
    +///
  • @c AnalyticsParameterMethod (String)
  • +///
+static NSString *const kFIREventSignUp NS_SWIFT_NAME(AnalyticsEventSignUp) = @"sign_up"; + +/// Spend Virtual Currency event. This event tracks the sale of virtual goods in your app and can +/// help you identify which virtual goods are the most popular objects of purchase. Params: +/// +///
    +///
  • @c AnalyticsParameterItemName (String)
  • +///
  • @c AnalyticsParameterVirtualCurrencyName (String)
  • +///
  • @c AnalyticsParameterValue (Int or Double)
  • +///
+static NSString *const kFIREventSpendVirtualCurrency + NS_SWIFT_NAME(AnalyticsEventSpendVirtualCurrency) = @"spend_virtual_currency"; + +/// Tutorial Begin event. This event signifies the start of the on-boarding process in your app. Use +/// this in a funnel with @c AnalyticsEventTutorialComplete to understand how many users complete +/// this process and move on to the full app experience. +static NSString *const kFIREventTutorialBegin NS_SWIFT_NAME(AnalyticsEventTutorialBegin) = + @"tutorial_begin"; + +/// Tutorial End event. Use this event to signify the user's completion of your app's on-boarding +/// process. Add this to a funnel with @c AnalyticsEventTutorialBegin to gauge the completion rate +/// of your on-boarding process. +static NSString *const kFIREventTutorialComplete NS_SWIFT_NAME(AnalyticsEventTutorialComplete) = + @"tutorial_complete"; + +/// Unlock Achievement event. Log this event when the user has unlocked an achievement in your +/// game. Since achievements generally represent the breadth of a gaming experience, this event can +/// help you understand how many users are experiencing all that your game has to offer. Params: +/// +///
    +///
  • @c AnalyticsParameterAchievementID (String)
  • +///
+static NSString *const kFIREventUnlockAchievement NS_SWIFT_NAME(AnalyticsEventUnlockAchievement) = + @"unlock_achievement"; + +/// E-commerce View Cart event. This event signifies that a user has viewed their cart. Use this to +/// analyze your purchase funnel. Note: If you supply the @c AnalyticsParameterValue parameter, you +/// must also supply the @c AnalyticsParameterCurrency parameter so that revenue metrics can be +/// computed accurately. Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventViewCart NS_SWIFT_NAME(AnalyticsEventViewCart) = @"view_cart"; + +/// View Item event. This event signifies that a user has viewed an item. Use the appropriate +/// parameters to contextualize the event. Use this event to discover the most popular items viewed +/// in your app. Note: If you supply the @c AnalyticsParameterValue parameter, you must also supply +/// the @c AnalyticsParameterCurrency parameter so that revenue metrics can be computed accurately. +/// Params: +/// +///
    +///
  • @c AnalyticsParameterCurrency (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterValue (Double) (optional)
  • +///
+static NSString *const kFIREventViewItem NS_SWIFT_NAME(AnalyticsEventViewItem) = @"view_item"; + +/// View Item List event. Log this event when a user sees a list of items or offerings. Params: +/// +///
    +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterItemListID (String) (optional)
  • +///
  • @c AnalyticsParameterItemListName (String) (optional)
  • +///
+static NSString *const kFIREventViewItemList NS_SWIFT_NAME(AnalyticsEventViewItemList) = + @"view_item_list"; + +/// View Promotion event. This event signifies that a promotion was shown to a user. Add this event +/// to a funnel with the @c AnalyticsEventAddToCart and @c AnalyticsEventPurchase to gauge your +/// conversion process. Params: +/// +///
    +///
  • @c AnalyticsParameterCreativeName (String) (optional)
  • +///
  • @c AnalyticsParameterCreativeSlot (String) (optional)
  • +///
  • @c AnalyticsParameterItems ([[String: Any]]) (optional)
  • +///
  • @c AnalyticsParameterLocationID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionID (String) (optional)
  • +///
  • @c AnalyticsParameterPromotionName (String) (optional)
  • +///
+static NSString *const kFIREventViewPromotion NS_SWIFT_NAME(AnalyticsEventViewPromotion) = + @"view_promotion"; + +/// View Search Results event. Log this event when the user has been presented with the results of a +/// search. Params: +/// +///
    +///
  • @c AnalyticsParameterSearchTerm (String)
  • +///
+static NSString *const kFIREventViewSearchResults NS_SWIFT_NAME(AnalyticsEventViewSearchResults) = + @"view_search_results"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRParameterNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRParameterNames.h new file mode 100644 index 0000000..58a5a21 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRParameterNames.h @@ -0,0 +1,722 @@ +/// @file FIRParameterNames.h +/// +/// Predefined event parameter names. +/// +/// Params supply information that contextualize Events. You can associate up to 25 unique Params +/// with each Event type. Some Params are suggested below for certain common Events, but you are +/// not limited to these. You may supply extra Params for suggested Events or custom Params for +/// Custom events. Param names can be up to 40 characters long, may only contain alphanumeric +/// characters and underscores ("_"), and must start with an alphabetic character. Param values can +/// be up to 100 characters long for standard Google Analytics properties and up to 500 characters +/// long for Google Analytics 360 properties. The "firebase_", "google_", and "ga_" prefixes are +/// reserved and should not be used. + +#import + +/// Game achievement ID (String). +///
+///     let params = [
+///       AnalyticsParameterAchievementID : "10_matches_won",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAchievementID NS_SWIFT_NAME(AnalyticsParameterAchievementID) = + @"achievement_id"; + +/// The ad format (e.g. Banner, Interstitial, Rewarded, Native, Rewarded Interstitial, Instream). +/// (String). +///
+///     let params = [
+///       AnalyticsParameterAdFormat : "Banner",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdFormat NS_SWIFT_NAME(AnalyticsParameterAdFormat) = + @"ad_format"; + +/// Ad Network Click ID (String). Used for network-specific click IDs which vary in format. +///
+///     let params = [
+///       AnalyticsParameterAdNetworkClickID : "1234567",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdNetworkClickID + NS_SWIFT_NAME(AnalyticsParameterAdNetworkClickID) = @"aclid"; + +/// The ad platform (e.g. MoPub, IronSource) (String). +///
+///     let params = [
+///       AnalyticsParameterAdPlatform : "MoPub",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdPlatform NS_SWIFT_NAME(AnalyticsParameterAdPlatform) = + @"ad_platform"; + +/// The ad source (e.g. AdColony) (String). +///
+///     let params = [
+///       AnalyticsParameterAdSource : "AdColony",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdSource NS_SWIFT_NAME(AnalyticsParameterAdSource) = + @"ad_source"; + +/// The ad unit name (e.g. Banner_03) (String). +///
+///     let params = [
+///       AnalyticsParameterAdUnitName : "Banner_03",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAdUnitName NS_SWIFT_NAME(AnalyticsParameterAdUnitName) = + @"ad_unit_name"; + +/// A product affiliation to designate a supplying company or brick and mortar store location +/// (String).
+///     let params = [
+///       AnalyticsParameterAffiliation : "Google Store",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterAffiliation NS_SWIFT_NAME(AnalyticsParameterAffiliation) = + @"affiliation"; + +/// Campaign custom parameter (String). Used as a method of capturing custom data in a campaign. +/// Use varies by network. +///
+///     let params = [
+///       AnalyticsParameterCP1 : "custom_data",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCP1 NS_SWIFT_NAME(AnalyticsParameterCP1) = @"cp1"; + +/// The individual campaign name, slogan, promo code, etc. Some networks have pre-defined macro to +/// capture campaign information, otherwise can be populated by developer. Highly Recommended +/// (String). +///
+///     let params = [
+///       AnalyticsParameterCampaign : "winter_promotion",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCampaign NS_SWIFT_NAME(AnalyticsParameterCampaign) = + @"campaign"; + +/// Campaign ID (String). Used for keyword analysis to identify a specific product promotion or +/// strategic campaign. This is a required key for GA4 data import. +///
+///     let params = [
+///       AnalyticsParameterCampaignID : "7877652710",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCampaignID NS_SWIFT_NAME(AnalyticsParameterCampaignID) = + @"campaign_id"; + +/// Character used in game (String). +///
+///     let params = [
+///       AnalyticsParameterCharacter : "beat_boss",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCharacter NS_SWIFT_NAME(AnalyticsParameterCharacter) = + @"character"; + +/// Campaign content (String). +static NSString *const kFIRParameterContent NS_SWIFT_NAME(AnalyticsParameterContent) = @"content"; + +/// Type of content selected (String). +///
+///     let params = [
+///       AnalyticsParameterContentType : "news article",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterContentType NS_SWIFT_NAME(AnalyticsParameterContentType) = + @"content_type"; + +/// Coupon code used for a purchase (String). +///
+///     let params = [
+///       AnalyticsParameterCoupon : "SUMMER_FUN",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCoupon NS_SWIFT_NAME(AnalyticsParameterCoupon) = @"coupon"; + +/// Creative Format (String). Used to identify the high-level classification of the type of ad +/// served by a specific campaign. +///
+///     let params = [
+///       AnalyticsParameterCreativeFormat : "display",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCreativeFormat NS_SWIFT_NAME(AnalyticsParameterCreativeFormat) = + @"creative_format"; + +/// The name of a creative used in a promotional spot (String). +///
+///     let params = [
+///       AnalyticsParameterCreativeName : "Summer Sale",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCreativeName NS_SWIFT_NAME(AnalyticsParameterCreativeName) = + @"creative_name"; + +/// The name of a creative slot (String). +///
+///     let params = [
+///       AnalyticsParameterCreativeSlot : "summer_banner2",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCreativeSlot NS_SWIFT_NAME(AnalyticsParameterCreativeSlot) = + @"creative_slot"; + +/// Currency of the purchase or items associated with the event, in 3-letter +/// ISO_4217 format (String). +///
+///     let params = [
+///       AnalyticsParameterCurrency : "USD",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterCurrency NS_SWIFT_NAME(AnalyticsParameterCurrency) = + @"currency"; + +/// Flight or Travel destination (String). +///
+///     let params = [
+///       AnalyticsParameterDestination : "Mountain View, CA",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterDestination NS_SWIFT_NAME(AnalyticsParameterDestination) = + @"destination"; + +/// Monetary value of discount associated with a purchase (Double). +///
+///     let params = [
+///       AnalyticsParameterDiscount : 2.0,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $2.00 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterDiscount NS_SWIFT_NAME(AnalyticsParameterDiscount) = + @"discount"; + +/// The arrival date, check-out date or rental end date for the item. This should be in +/// YYYY-MM-DD format (String). +///
+///     let params = [
+///       AnalyticsParameterEndDate : "2015-09-14",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterEndDate NS_SWIFT_NAME(AnalyticsParameterEndDate) = @"end_date"; + +/// Indicates that the associated event should either extend the current session or start a new +/// session if no session was active when the event was logged. Specify 1 to extend the current +/// session or to start a new session; any other value will not extend or start a session. +///
+///     let params = [
+///       AnalyticsParameterExtendSession : 1,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterExtendSession NS_SWIFT_NAME(AnalyticsParameterExtendSession) = + @"extend_session"; + +/// Flight number for travel events (String). +///
+///     let params = [
+///       AnalyticsParameterFlightNumber : "ZZ800",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterFlightNumber NS_SWIFT_NAME(AnalyticsParameterFlightNumber) = + @"flight_number"; + +/// Group/clan/guild ID (String). +///
+///     let params = [
+///       AnalyticsParameterGroupID : "g1",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterGroupID NS_SWIFT_NAME(AnalyticsParameterGroupID) = @"group_id"; + +/// The index of the item in a list (Int). +///
+///     let params = [
+///       AnalyticsParameterIndex : 5,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterIndex NS_SWIFT_NAME(AnalyticsParameterIndex) = @"index"; + +/// Item brand (String). +///
+///     let params = [
+///       AnalyticsParameterItemBrand : "Google",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemBrand NS_SWIFT_NAME(AnalyticsParameterItemBrand) = + @"item_brand"; + +/// Item category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory NS_SWIFT_NAME(AnalyticsParameterItemCategory) = + @"item_category"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory2 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory2 NS_SWIFT_NAME(AnalyticsParameterItemCategory2) = + @"item_category2"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory3 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory3 NS_SWIFT_NAME(AnalyticsParameterItemCategory3) = + @"item_category3"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory4 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory4 NS_SWIFT_NAME(AnalyticsParameterItemCategory4) = + @"item_category4"; + +/// Item Category (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemCategory5 : "pants",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemCategory5 NS_SWIFT_NAME(AnalyticsParameterItemCategory5) = + @"item_category5"; + +/// Item ID (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemID : "SKU_12345",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemID NS_SWIFT_NAME(AnalyticsParameterItemID) = @"item_id"; + +/// The ID of the list in which the item was presented to the user (String). +///
+///     let params = [
+///       AnalyticsParameterItemListID : "ABC123",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemListID NS_SWIFT_NAME(AnalyticsParameterItemListID) = + @"item_list_id"; + +/// The name of the list in which the item was presented to the user (String). +///
+///     let params = [
+///       AnalyticsParameterItemListName : "Related products",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemListName NS_SWIFT_NAME(AnalyticsParameterItemListName) = + @"item_list_name"; + +/// Item Name (context-specific) (String). +///
+///     let params = [
+///       AnalyticsParameterItemName : "jeggings",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemName NS_SWIFT_NAME(AnalyticsParameterItemName) = + @"item_name"; + +/// Item variant (String). +///
+///     let params = [
+///       AnalyticsParameterItemVariant : "Black",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterItemVariant NS_SWIFT_NAME(AnalyticsParameterItemVariant) = + @"item_variant"; + +/// The list of items involved in the transaction expressed as `[[String: Any]]`. +///
+///     let params = [
+///       AnalyticsParameterItems : [
+///         [AnalyticsParameterItemName : "jeggings", AnalyticsParameterItemCategory : "pants"],
+///         [AnalyticsParameterItemName : "boots", AnalyticsParameterItemCategory : "shoes"],
+///       ],
+///     ]
+/// 
+static NSString *const kFIRParameterItems NS_SWIFT_NAME(AnalyticsParameterItems) = @"items"; + +/// Level in game (Int). +///
+///     let params = [
+///       AnalyticsParameterLevel : 42,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLevel NS_SWIFT_NAME(AnalyticsParameterLevel) = @"level"; + +/// The name of a level in a game (String). +///
+///     let params = [
+///       AnalyticsParameterLevelName : "room_1",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLevelName NS_SWIFT_NAME(AnalyticsParameterLevelName) = + @"level_name"; + +/// Location (String). The Google Place ID +/// that corresponds to the associated event. Alternatively, you can supply your own custom +/// Location ID. +///
+///     let params = [
+///       AnalyticsParameterLocation : "ChIJiyj437sx3YAR9kUWC8QkLzQ",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLocation NS_SWIFT_NAME(AnalyticsParameterLocation) = + @"location"; + +/// The location associated with the event. Preferred to be the Google +/// Place ID that corresponds to the +/// associated item but could be overridden to a custom location ID string.(String). +///
+///     let params = [
+///       AnalyticsParameterLocationID : "ChIJiyj437sx3YAR9kUWC8QkLzQ",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterLocationID NS_SWIFT_NAME(AnalyticsParameterLocationID) = + @"location_id"; + +/// Marketing Tactic (String). Used to identify the targeting criteria applied to a specific +/// campaign. +///
+///     let params = [
+///       AnalyticsParameterMarketingTactic : "Remarketing",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterMarketingTactic + NS_SWIFT_NAME(AnalyticsParameterMarketingTactic) = @"marketing_tactic"; + +/// The advertising or marketing medium, for example: cpc, banner, email, push. Highly recommended +/// (String). +///
+///     let params = [
+///       AnalyticsParameterMedium : "email",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterMedium NS_SWIFT_NAME(AnalyticsParameterMedium) = @"medium"; + +/// A particular approach used in an operation; for example, "facebook" or "email" in the context +/// of a sign_up or login event. (String). +///
+///     let params = [
+///       AnalyticsParameterMethod : "google",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterMethod NS_SWIFT_NAME(AnalyticsParameterMethod) = @"method"; + +/// Number of nights staying at hotel (Int). +///
+///     let params = [
+///       AnalyticsParameterNumberOfNights : 3,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterNumberOfNights + NS_SWIFT_NAME(AnalyticsParameterNumberOfNights) = @"number_of_nights"; + +/// Number of passengers traveling (Int). +///
+///     let params = [
+///       AnalyticsParameterNumberOfPassengers : 11,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterNumberOfPassengers + NS_SWIFT_NAME(AnalyticsParameterNumberOfPassengers) = @"number_of_passengers"; + +/// Number of rooms for travel events (Int). +///
+///     let params = [
+///       AnalyticsParameterNumberOfRooms : 2,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterNumberOfRooms NS_SWIFT_NAME(AnalyticsParameterNumberOfRooms) = + @"number_of_rooms"; + +/// Flight or Travel origin (String). +///
+///     let params = [
+///       AnalyticsParameterOrigin : "Mountain View, CA",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterOrigin NS_SWIFT_NAME(AnalyticsParameterOrigin) = @"origin"; + +/// The chosen method of payment (String). +///
+///     let params = [
+///       AnalyticsParameterPaymentType : "Visa",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPaymentType NS_SWIFT_NAME(AnalyticsParameterPaymentType) = + @"payment_type"; + +/// Purchase price (Double). +///
+///     let params = [
+///       AnalyticsParameterPrice : 1.0,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $1.00 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPrice NS_SWIFT_NAME(AnalyticsParameterPrice) = @"price"; + +/// The ID of a product promotion (String). +///
+///     let params = [
+///       AnalyticsParameterPromotionID : "ABC123",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPromotionID NS_SWIFT_NAME(AnalyticsParameterPromotionID) = + @"promotion_id"; + +/// The name of a product promotion (String). +///
+///     let params = [
+///       AnalyticsParameterPromotionName : "Summer Sale",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterPromotionName NS_SWIFT_NAME(AnalyticsParameterPromotionName) = + @"promotion_name"; + +/// Purchase quantity (Int). +///
+///     let params = [
+///       AnalyticsParameterQuantity : 1,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterQuantity NS_SWIFT_NAME(AnalyticsParameterQuantity) = + @"quantity"; + +/// Score in game (Int). +///
+///     let params = [
+///       AnalyticsParameterScore : 4200,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterScore NS_SWIFT_NAME(AnalyticsParameterScore) = @"score"; + +/// Current screen class, such as the class name of the UIViewController, logged with screen_view +/// event and added to every event (String). +///
+///     let params = [
+///       AnalyticsParameterScreenClass : "LoginViewController",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterScreenClass NS_SWIFT_NAME(AnalyticsParameterScreenClass) = + @"screen_class"; + +/// Current screen name, such as the name of the UIViewController, logged with screen_view event and +/// added to every event (String). +///
+///     let params = [
+///       AnalyticsParameterScreenName : "LoginView",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterScreenName NS_SWIFT_NAME(AnalyticsParameterScreenName) = + @"screen_name"; + +/// The search string/keywords used (String). +///
+///     let params = [
+///       AnalyticsParameterSearchTerm : "periodic table",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSearchTerm NS_SWIFT_NAME(AnalyticsParameterSearchTerm) = + @"search_term"; + +/// Shipping cost associated with a transaction (Double). +///
+///     let params = [
+///       AnalyticsParameterShipping : 5.99,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $5.99 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterShipping NS_SWIFT_NAME(AnalyticsParameterShipping) = + @"shipping"; + +/// The shipping tier (e.g. Ground, Air, Next-day) selected for delivery of the purchased item +/// (String). +///
+///     let params = [
+///       AnalyticsParameterShippingTier : "Ground",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterShippingTier NS_SWIFT_NAME(AnalyticsParameterShippingTier) = + @"shipping_tier"; + +/// The origin of your traffic, such as an Ad network (for example, google) or partner (urban +/// airship). Identify the advertiser, site, publication, etc. that is sending traffic to your +/// property. Highly recommended (String). +///
+///     let params = [
+///       AnalyticsParameterSource : "InMobi",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSource NS_SWIFT_NAME(AnalyticsParameterSource) = @"source"; + +/// Source Platform (String). Used to identify the platform responsible for directing traffic to a +/// given Analytics property (e.g., a buying platform where budgets, targeting criteria, etc. are +/// set, a platform for managing organic traffic data, etc.). +///
+///     let params = [
+///       AnalyticsParameterSourcePlatform : "sa360",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSourcePlatform NS_SWIFT_NAME(AnalyticsParameterSourcePlatform) = + @"source_platform"; + +/// The departure date, check-in date or rental start date for the item. This should be in +/// YYYY-MM-DD format (String). +///
+///     let params = [
+///       AnalyticsParameterStartDate : "2015-09-14",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterStartDate NS_SWIFT_NAME(AnalyticsParameterStartDate) = + @"start_date"; + +/// The result of an operation. Specify 1 to indicate success and 0 to indicate failure (Int). +///
+///     let params = [
+///       AnalyticsParameterSuccess : 1,
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterSuccess NS_SWIFT_NAME(AnalyticsParameterSuccess) = @"success"; + +/// Tax cost associated with a transaction (Double). +///
+///     let params = [
+///       AnalyticsParameterTax : 2.43,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $2.43 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTax NS_SWIFT_NAME(AnalyticsParameterTax) = @"tax"; + +/// If you're manually tagging keyword campaigns, you should use utm_term to specify the keyword +/// (String). +///
+///     let params = [
+///       AnalyticsParameterTerm : "game",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTerm NS_SWIFT_NAME(AnalyticsParameterTerm) = @"term"; + +/// The unique identifier of a transaction (String). +///
+///     let params = [
+///       AnalyticsParameterTransactionID : "T12345",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTransactionID NS_SWIFT_NAME(AnalyticsParameterTransactionID) = + @"transaction_id"; + +/// Travel class (String). +///
+///     let params = [
+///       AnalyticsParameterTravelClass : "business",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterTravelClass NS_SWIFT_NAME(AnalyticsParameterTravelClass) = + @"travel_class"; + +/// A context-specific numeric value which is accumulated automatically for each event type. This is +/// a general purpose parameter that is useful for accumulating a key metric that pertains to an +/// event. Examples include revenue, distance, time and points. Value should be specified as Int or +/// Double. +/// Notes: Values for pre-defined currency-related events (such as @c AnalyticsEventAddToCart) +/// should be supplied using Double and must be accompanied by a @c AnalyticsParameterCurrency +/// parameter. The valid range of accumulated values is +/// [-9,223,372,036,854.77, 9,223,372,036,854.77]. Supplying a non-numeric value, omitting the +/// corresponding @c AnalyticsParameterCurrency parameter, or supplying an invalid +/// currency code for conversion events will cause that +/// conversion to be omitted from reporting. +///
+///     let params = [
+///       AnalyticsParameterValue : 3.99,
+///       AnalyticsParameterCurrency : "USD",  // e.g. $3.99 USD
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterValue NS_SWIFT_NAME(AnalyticsParameterValue) = @"value"; + +/// Name of virtual currency type (String). +///
+///     let params = [
+///       AnalyticsParameterVirtualCurrencyName : "virtual_currency_name",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRParameterVirtualCurrencyName + NS_SWIFT_NAME(AnalyticsParameterVirtualCurrencyName) = @"virtual_currency_name"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h new file mode 100644 index 0000000..2442d8a --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h @@ -0,0 +1,28 @@ +/// @file FIRUserPropertyNames.h +/// +/// Predefined user property names. +/// +/// A UserProperty is an attribute that describes the app-user. By supplying UserProperties, you can +/// later analyze different behaviors of various segments of your userbase. You may supply up to 25 +/// unique UserProperties per app, and you can use the name and value of your choosing for each one. +/// UserProperty names can be up to 24 characters long, may only contain alphanumeric characters and +/// underscores ("_"), and must start with an alphabetic character. UserProperty values can be up to +/// 36 characters long. The "firebase_", "google_", and "ga_" prefixes are reserved and should not +/// be used. + +#import + +/// Indicates whether events logged by Google Analytics can be used to personalize ads for the user. +/// Set to "YES" to enable, or "NO" to disable. Default is enabled. See the +/// documentation for +/// more details and information about related settings. +/// +///
+///     Analytics.setUserProperty("NO", forName: AnalyticsUserPropertyAllowAdPersonalizationSignals)
+/// 
+static NSString *const kFIRUserPropertyAllowAdPersonalizationSignals + NS_SWIFT_NAME(AnalyticsUserPropertyAllowAdPersonalizationSignals) = @"allow_personalized_ads"; + +/// The method used to sign in. For example, "google", "facebook" or "twitter". +static NSString *const kFIRUserPropertySignUpMethod + NS_SWIFT_NAME(AnalyticsUserPropertySignUpMethod) = @"sign_up_method"; diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-Swift.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-Swift.h new file mode 100644 index 0000000..3dbf01a --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-Swift.h @@ -0,0 +1,620 @@ +#if 0 +#elif defined(__arm64__) && __arm64__ +// Generated by Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +#ifndef FIREBASEANALYTICS_SWIFT_H +#define FIREBASEANALYTICS_SWIFT_H +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgcc-compat" + +#if !defined(__has_include) +# define __has_include(x) 0 +#endif +#if !defined(__has_attribute) +# define __has_attribute(x) 0 +#endif +#if !defined(__has_feature) +# define __has_feature(x) 0 +#endif +#if !defined(__has_warning) +# define __has_warning(x) 0 +#endif + +#if __has_include() +# include +#endif + +#pragma clang diagnostic ignored "-Wauto-import" +#if defined(__OBJC__) +#include +#endif +#if defined(__cplusplus) +#include +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#endif +#if defined(__cplusplus) +#if defined(__arm64e__) && __has_include() +# include +#else +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreserved-macro-identifier" +# ifndef __ptrauth_swift_value_witness_function_pointer +# define __ptrauth_swift_value_witness_function_pointer(x) +# endif +# ifndef __ptrauth_swift_class_method_pointer +# define __ptrauth_swift_class_method_pointer(x) +# endif +#pragma clang diagnostic pop +#endif +#endif + +#if !defined(SWIFT_TYPEDEFS) +# define SWIFT_TYPEDEFS 1 +# if __has_include() +# include +# elif !defined(__cplusplus) +typedef uint_least16_t char16_t; +typedef uint_least32_t char32_t; +# endif +typedef float swift_float2 __attribute__((__ext_vector_type__(2))); +typedef float swift_float3 __attribute__((__ext_vector_type__(3))); +typedef float swift_float4 __attribute__((__ext_vector_type__(4))); +typedef double swift_double2 __attribute__((__ext_vector_type__(2))); +typedef double swift_double3 __attribute__((__ext_vector_type__(3))); +typedef double swift_double4 __attribute__((__ext_vector_type__(4))); +typedef int swift_int2 __attribute__((__ext_vector_type__(2))); +typedef int swift_int3 __attribute__((__ext_vector_type__(3))); +typedef int swift_int4 __attribute__((__ext_vector_type__(4))); +typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2))); +typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3))); +typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); +#endif + +#if !defined(SWIFT_PASTE) +# define SWIFT_PASTE_HELPER(x, y) x##y +# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) +#endif +#if !defined(SWIFT_METATYPE) +# define SWIFT_METATYPE(X) Class +#endif +#if !defined(SWIFT_CLASS_PROPERTY) +# if __has_feature(objc_class_property) +# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__ +# else +# define SWIFT_CLASS_PROPERTY(...) +# endif +#endif +#if !defined(SWIFT_RUNTIME_NAME) +# if __has_attribute(objc_runtime_name) +# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) +# else +# define SWIFT_RUNTIME_NAME(X) +# endif +#endif +#if !defined(SWIFT_COMPILE_NAME) +# if __has_attribute(swift_name) +# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) +# else +# define SWIFT_COMPILE_NAME(X) +# endif +#endif +#if !defined(SWIFT_METHOD_FAMILY) +# if __has_attribute(objc_method_family) +# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X))) +# else +# define SWIFT_METHOD_FAMILY(X) +# endif +#endif +#if !defined(SWIFT_NOESCAPE) +# if __has_attribute(noescape) +# define SWIFT_NOESCAPE __attribute__((noescape)) +# else +# define SWIFT_NOESCAPE +# endif +#endif +#if !defined(SWIFT_RELEASES_ARGUMENT) +# if __has_attribute(ns_consumed) +# define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed)) +# else +# define SWIFT_RELEASES_ARGUMENT +# endif +#endif +#if !defined(SWIFT_WARN_UNUSED_RESULT) +# if __has_attribute(warn_unused_result) +# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +# else +# define SWIFT_WARN_UNUSED_RESULT +# endif +#endif +#if !defined(SWIFT_NORETURN) +# if __has_attribute(noreturn) +# define SWIFT_NORETURN __attribute__((noreturn)) +# else +# define SWIFT_NORETURN +# endif +#endif +#if !defined(SWIFT_CLASS_EXTRA) +# define SWIFT_CLASS_EXTRA +#endif +#if !defined(SWIFT_PROTOCOL_EXTRA) +# define SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_ENUM_EXTRA) +# define SWIFT_ENUM_EXTRA +#endif +#if !defined(SWIFT_CLASS) +# if __has_attribute(objc_subclassing_restricted) +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# else +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# endif +#endif +#if !defined(SWIFT_RESILIENT_CLASS) +# if __has_attribute(objc_class_stub) +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub)) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME) +# else +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME) +# endif +#endif +#if !defined(SWIFT_PROTOCOL) +# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_EXTENSION) +# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) +#endif +#if !defined(OBJC_DESIGNATED_INITIALIZER) +# if __has_attribute(objc_designated_initializer) +# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +# else +# define OBJC_DESIGNATED_INITIALIZER +# endif +#endif +#if !defined(SWIFT_ENUM_ATTR) +# if __has_attribute(enum_extensibility) +# define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility))) +# else +# define SWIFT_ENUM_ATTR(_extensibility) +# endif +#endif +#if !defined(SWIFT_ENUM) +# define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# if __has_feature(generalized_swift_name) +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# else +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility) +# endif +#endif +#if !defined(SWIFT_UNAVAILABLE) +# define SWIFT_UNAVAILABLE __attribute__((unavailable)) +#endif +#if !defined(SWIFT_UNAVAILABLE_MSG) +# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg))) +#endif +#if !defined(SWIFT_AVAILABILITY) +# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__))) +#endif +#if !defined(SWIFT_WEAK_IMPORT) +# define SWIFT_WEAK_IMPORT __attribute__((weak_import)) +#endif +#if !defined(SWIFT_DEPRECATED) +# define SWIFT_DEPRECATED __attribute__((deprecated)) +#endif +#if !defined(SWIFT_DEPRECATED_MSG) +# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__))) +#endif +#if !defined(SWIFT_DEPRECATED_OBJC) +# if __has_feature(attribute_diagnose_if_objc) +# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning"))) +# else +# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) +# endif +#endif +#if defined(__OBJC__) +#if !defined(IBSegueAction) +# define IBSegueAction +#endif +#endif +#if !defined(SWIFT_EXTERN) +# if defined(__cplusplus) +# define SWIFT_EXTERN extern "C" +# else +# define SWIFT_EXTERN extern +# endif +#endif +#if !defined(SWIFT_CALL) +# define SWIFT_CALL __attribute__((swiftcall)) +#endif +#if !defined(SWIFT_INDIRECT_RESULT) +# define SWIFT_INDIRECT_RESULT __attribute__((swift_indirect_result)) +#endif +#if !defined(SWIFT_CONTEXT) +# define SWIFT_CONTEXT __attribute__((swift_context)) +#endif +#if !defined(SWIFT_ERROR_RESULT) +# define SWIFT_ERROR_RESULT __attribute__((swift_error_result)) +#endif +#if defined(__cplusplus) +# define SWIFT_NOEXCEPT noexcept +#else +# define SWIFT_NOEXCEPT +#endif +#if !defined(SWIFT_C_INLINE_THUNK) +# if __has_attribute(always_inline) +# if __has_attribute(nodebug) +# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) __attribute__((nodebug)) +# else +# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) +# endif +# else +# define SWIFT_C_INLINE_THUNK inline +# endif +#endif +#if defined(_WIN32) +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL __declspec(dllimport) +#endif +#else +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL +#endif +#endif +#if defined(__OBJC__) +#if __has_feature(objc_modules) +#if __has_warning("-Watimport-in-framework-header") +#pragma clang diagnostic ignored "-Watimport-in-framework-header" +#endif +#endif + +#endif +#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" +#pragma clang diagnostic ignored "-Wduplicate-method-arg" +#if __has_warning("-Wpragma-clang-attribute") +# pragma clang diagnostic ignored "-Wpragma-clang-attribute" +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wnullability" +#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension" + +#if __has_attribute(external_source_symbol) +# pragma push_macro("any") +# undef any +# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="FirebaseAnalytics",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) +# pragma pop_macro("any") +#endif + +#if defined(__OBJC__) + +#endif +#if __has_attribute(external_source_symbol) +# pragma clang attribute pop +#endif +#if defined(__cplusplus) +#endif +#pragma clang diagnostic pop +#endif + +#elif defined(__x86_64__) && __x86_64__ +// Generated by Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +#ifndef FIREBASEANALYTICS_SWIFT_H +#define FIREBASEANALYTICS_SWIFT_H +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgcc-compat" + +#if !defined(__has_include) +# define __has_include(x) 0 +#endif +#if !defined(__has_attribute) +# define __has_attribute(x) 0 +#endif +#if !defined(__has_feature) +# define __has_feature(x) 0 +#endif +#if !defined(__has_warning) +# define __has_warning(x) 0 +#endif + +#if __has_include() +# include +#endif + +#pragma clang diagnostic ignored "-Wauto-import" +#if defined(__OBJC__) +#include +#endif +#if defined(__cplusplus) +#include +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#endif +#if defined(__cplusplus) +#if defined(__arm64e__) && __has_include() +# include +#else +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreserved-macro-identifier" +# ifndef __ptrauth_swift_value_witness_function_pointer +# define __ptrauth_swift_value_witness_function_pointer(x) +# endif +# ifndef __ptrauth_swift_class_method_pointer +# define __ptrauth_swift_class_method_pointer(x) +# endif +#pragma clang diagnostic pop +#endif +#endif + +#if !defined(SWIFT_TYPEDEFS) +# define SWIFT_TYPEDEFS 1 +# if __has_include() +# include +# elif !defined(__cplusplus) +typedef uint_least16_t char16_t; +typedef uint_least32_t char32_t; +# endif +typedef float swift_float2 __attribute__((__ext_vector_type__(2))); +typedef float swift_float3 __attribute__((__ext_vector_type__(3))); +typedef float swift_float4 __attribute__((__ext_vector_type__(4))); +typedef double swift_double2 __attribute__((__ext_vector_type__(2))); +typedef double swift_double3 __attribute__((__ext_vector_type__(3))); +typedef double swift_double4 __attribute__((__ext_vector_type__(4))); +typedef int swift_int2 __attribute__((__ext_vector_type__(2))); +typedef int swift_int3 __attribute__((__ext_vector_type__(3))); +typedef int swift_int4 __attribute__((__ext_vector_type__(4))); +typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2))); +typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3))); +typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); +#endif + +#if !defined(SWIFT_PASTE) +# define SWIFT_PASTE_HELPER(x, y) x##y +# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) +#endif +#if !defined(SWIFT_METATYPE) +# define SWIFT_METATYPE(X) Class +#endif +#if !defined(SWIFT_CLASS_PROPERTY) +# if __has_feature(objc_class_property) +# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__ +# else +# define SWIFT_CLASS_PROPERTY(...) +# endif +#endif +#if !defined(SWIFT_RUNTIME_NAME) +# if __has_attribute(objc_runtime_name) +# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) +# else +# define SWIFT_RUNTIME_NAME(X) +# endif +#endif +#if !defined(SWIFT_COMPILE_NAME) +# if __has_attribute(swift_name) +# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) +# else +# define SWIFT_COMPILE_NAME(X) +# endif +#endif +#if !defined(SWIFT_METHOD_FAMILY) +# if __has_attribute(objc_method_family) +# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X))) +# else +# define SWIFT_METHOD_FAMILY(X) +# endif +#endif +#if !defined(SWIFT_NOESCAPE) +# if __has_attribute(noescape) +# define SWIFT_NOESCAPE __attribute__((noescape)) +# else +# define SWIFT_NOESCAPE +# endif +#endif +#if !defined(SWIFT_RELEASES_ARGUMENT) +# if __has_attribute(ns_consumed) +# define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed)) +# else +# define SWIFT_RELEASES_ARGUMENT +# endif +#endif +#if !defined(SWIFT_WARN_UNUSED_RESULT) +# if __has_attribute(warn_unused_result) +# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +# else +# define SWIFT_WARN_UNUSED_RESULT +# endif +#endif +#if !defined(SWIFT_NORETURN) +# if __has_attribute(noreturn) +# define SWIFT_NORETURN __attribute__((noreturn)) +# else +# define SWIFT_NORETURN +# endif +#endif +#if !defined(SWIFT_CLASS_EXTRA) +# define SWIFT_CLASS_EXTRA +#endif +#if !defined(SWIFT_PROTOCOL_EXTRA) +# define SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_ENUM_EXTRA) +# define SWIFT_ENUM_EXTRA +#endif +#if !defined(SWIFT_CLASS) +# if __has_attribute(objc_subclassing_restricted) +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# else +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# endif +#endif +#if !defined(SWIFT_RESILIENT_CLASS) +# if __has_attribute(objc_class_stub) +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub)) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME) +# else +# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) +# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME) +# endif +#endif +#if !defined(SWIFT_PROTOCOL) +# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_EXTENSION) +# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) +#endif +#if !defined(OBJC_DESIGNATED_INITIALIZER) +# if __has_attribute(objc_designated_initializer) +# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +# else +# define OBJC_DESIGNATED_INITIALIZER +# endif +#endif +#if !defined(SWIFT_ENUM_ATTR) +# if __has_attribute(enum_extensibility) +# define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility))) +# else +# define SWIFT_ENUM_ATTR(_extensibility) +# endif +#endif +#if !defined(SWIFT_ENUM) +# define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# if __has_feature(generalized_swift_name) +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type +# else +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility) +# endif +#endif +#if !defined(SWIFT_UNAVAILABLE) +# define SWIFT_UNAVAILABLE __attribute__((unavailable)) +#endif +#if !defined(SWIFT_UNAVAILABLE_MSG) +# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg))) +#endif +#if !defined(SWIFT_AVAILABILITY) +# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__))) +#endif +#if !defined(SWIFT_WEAK_IMPORT) +# define SWIFT_WEAK_IMPORT __attribute__((weak_import)) +#endif +#if !defined(SWIFT_DEPRECATED) +# define SWIFT_DEPRECATED __attribute__((deprecated)) +#endif +#if !defined(SWIFT_DEPRECATED_MSG) +# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__))) +#endif +#if !defined(SWIFT_DEPRECATED_OBJC) +# if __has_feature(attribute_diagnose_if_objc) +# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning"))) +# else +# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) +# endif +#endif +#if defined(__OBJC__) +#if !defined(IBSegueAction) +# define IBSegueAction +#endif +#endif +#if !defined(SWIFT_EXTERN) +# if defined(__cplusplus) +# define SWIFT_EXTERN extern "C" +# else +# define SWIFT_EXTERN extern +# endif +#endif +#if !defined(SWIFT_CALL) +# define SWIFT_CALL __attribute__((swiftcall)) +#endif +#if !defined(SWIFT_INDIRECT_RESULT) +# define SWIFT_INDIRECT_RESULT __attribute__((swift_indirect_result)) +#endif +#if !defined(SWIFT_CONTEXT) +# define SWIFT_CONTEXT __attribute__((swift_context)) +#endif +#if !defined(SWIFT_ERROR_RESULT) +# define SWIFT_ERROR_RESULT __attribute__((swift_error_result)) +#endif +#if defined(__cplusplus) +# define SWIFT_NOEXCEPT noexcept +#else +# define SWIFT_NOEXCEPT +#endif +#if !defined(SWIFT_C_INLINE_THUNK) +# if __has_attribute(always_inline) +# if __has_attribute(nodebug) +# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) __attribute__((nodebug)) +# else +# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) +# endif +# else +# define SWIFT_C_INLINE_THUNK inline +# endif +#endif +#if defined(_WIN32) +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL __declspec(dllimport) +#endif +#else +#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL) +# define SWIFT_IMPORT_STDLIB_SYMBOL +#endif +#endif +#if defined(__OBJC__) +#if __has_feature(objc_modules) +#if __has_warning("-Watimport-in-framework-header") +#pragma clang diagnostic ignored "-Watimport-in-framework-header" +#endif +#endif + +#endif +#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" +#pragma clang diagnostic ignored "-Wduplicate-method-arg" +#if __has_warning("-Wpragma-clang-attribute") +# pragma clang diagnostic ignored "-Wpragma-clang-attribute" +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wnullability" +#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension" + +#if __has_attribute(external_source_symbol) +# pragma push_macro("any") +# undef any +# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="FirebaseAnalytics",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) +# pragma pop_macro("any") +#endif + +#if defined(__OBJC__) + +#endif +#if __has_attribute(external_source_symbol) +# pragma clang attribute pop +#endif +#if defined(__cplusplus) +#endif +#pragma clang diagnostic pop +#endif + +#else +#error unsupported Swift architecture +#endif diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-umbrella.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-umbrella.h new file mode 100644 index 0000000..ad84fbb --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics-umbrella.h @@ -0,0 +1,24 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "FIRAnalytics+AppDelegate.h" +#import "FIRAnalytics+Consent.h" +#import "FIRAnalytics+OnDevice.h" +#import "FIRAnalytics.h" +#import "FirebaseAnalytics.h" +#import "FIREventNames.h" +#import "FIRParameterNames.h" +#import "FIRUserPropertyNames.h" + +FOUNDATION_EXPORT double FirebaseAnalyticsVersionNumber; +FOUNDATION_EXPORT const unsigned char FirebaseAnalyticsVersionString[]; + diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h new file mode 100644 index 0000000..351da20 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h @@ -0,0 +1,7 @@ +#import "FIRAnalytics+AppDelegate.h" +#import "FIRAnalytics+Consent.h" +#import "FIRAnalytics+OnDevice.h" +#import "FIRAnalytics.h" +#import "FIREventNames.h" +#import "FIRParameterNames.h" +#import "FIRUserPropertyNames.h" diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Info.plist b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Info.plist new file mode 100644 index 0000000..3358335 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Info.plist @@ -0,0 +1,52 @@ + + + + + BuildMachineOSBuild + 23F79 + CFBundleDevelopmentRegion + en + CFBundleExecutable + FirebaseAnalytics + CFBundleIdentifier + org.cocoapods.FirebaseAnalytics + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + FirebaseAnalytics + CFBundlePackageType + FMWK + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + AppleTVSimulator + + CFBundleVersion + 1 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 21K354 + DTPlatformName + appletvsimulator + DTPlatformVersion + 17.2 + DTSDKBuild + 21K354 + DTSDKName + appletvsimulator17.2 + DTXcode + 1520 + DTXcodeBuild + 15C500b + MinimumOSVersion + 100.0 + UIDeviceFamily + + 3 + + + diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-tvos-simulator.swiftsourceinfo b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-tvos-simulator.swiftsourceinfo new file mode 100644 index 0000000..4ef3d56 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/arm64-apple-tvos-simulator.swiftsourceinfo differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/x86_64-apple-tvos-simulator.swiftsourceinfo b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/x86_64-apple-tvos-simulator.swiftsourceinfo new file mode 100644 index 0000000..b4b9664 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/Project/x86_64-apple-tvos-simulator.swiftsourceinfo differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos-simulator.abi.json b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos-simulator.abi.json new file mode 100644 index 0000000..fde2b92 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos-simulator.abi.json @@ -0,0 +1,239 @@ +{ + "ABIRoot": { + "kind": "Root", + "name": "TopLevel", + "printedName": "TopLevel", + "children": [ + { + "kind": "Import", + "name": "StoreKit", + "printedName": "StoreKit", + "declKind": "Import", + "moduleName": "FirebaseAnalytics" + }, + { + "kind": "Import", + "name": "SwiftUI", + "printedName": "SwiftUI", + "declKind": "Import", + "moduleName": "FirebaseAnalytics" + }, + { + "kind": "TypeDecl", + "name": "Analytics", + "printedName": "Analytics", + "children": [ + { + "kind": "Function", + "name": "logTransaction", + "printedName": "logTransaction(_:)", + "children": [ + { + "kind": "TypeNominal", + "name": "Void", + "printedName": "()" + }, + { + "kind": "TypeNominal", + "name": "Transaction", + "printedName": "StoreKit.Transaction", + "usr": "s:8StoreKit11TransactionV" + } + ], + "declKind": "Func", + "usr": "s:So12FIRAnalyticsC17FirebaseAnalyticsE14logTransactionyy8StoreKit0E0VFZ", + "mangledName": "$sSo12FIRAnalyticsC17FirebaseAnalyticsE14logTransactionyy8StoreKit0E0VFZ", + "moduleName": "FirebaseAnalytics", + "static": true, + "declAttributes": [ + "Final", + "AccessControl", + "RawDocComment" + ], + "isFromExtension": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Class", + "usr": "c:objc(cs)FIRAnalytics", + "moduleName": "FirebaseAnalytics", + "isOpen": true, + "objc_name": "FIRAnalytics", + "declAttributes": [ + "ObjC", + "Dynamic" + ], + "superclassUsr": "c:objc(cs)NSObject", + "isExternal": true, + "inheritsConvenienceInitializers": true, + "superclassNames": [ + "ObjectiveC.NSObject" + ], + "conformances": [ + { + "kind": "Conformance", + "name": "Equatable", + "printedName": "Equatable", + "usr": "s:SQ", + "mangledName": "$sSQ" + }, + { + "kind": "Conformance", + "name": "Hashable", + "printedName": "Hashable", + "usr": "s:SH", + "mangledName": "$sSH" + }, + { + "kind": "Conformance", + "name": "CVarArg", + "printedName": "CVarArg", + "usr": "s:s7CVarArgP", + "mangledName": "$ss7CVarArgP" + }, + { + "kind": "Conformance", + "name": "_KeyValueCodingAndObservingPublishing", + "printedName": "_KeyValueCodingAndObservingPublishing", + "usr": "s:10Foundation37_KeyValueCodingAndObservingPublishingP", + "mangledName": "$s10Foundation37_KeyValueCodingAndObservingPublishingP" + }, + { + "kind": "Conformance", + "name": "_KeyValueCodingAndObserving", + "printedName": "_KeyValueCodingAndObserving", + "usr": "s:10Foundation27_KeyValueCodingAndObservingP", + "mangledName": "$s10Foundation27_KeyValueCodingAndObservingP" + }, + { + "kind": "Conformance", + "name": "CustomStringConvertible", + "printedName": "CustomStringConvertible", + "usr": "s:s23CustomStringConvertibleP", + "mangledName": "$ss23CustomStringConvertibleP" + }, + { + "kind": "Conformance", + "name": "CustomDebugStringConvertible", + "printedName": "CustomDebugStringConvertible", + "usr": "s:s28CustomDebugStringConvertibleP", + "mangledName": "$ss28CustomDebugStringConvertibleP" + } + ] + }, + { + "kind": "TypeDecl", + "name": "View", + "printedName": "View", + "children": [ + { + "kind": "Function", + "name": "analyticsScreen", + "printedName": "analyticsScreen(name:class:extraParameters:)", + "children": [ + { + "kind": "TypeNominal", + "name": "ModifiedContent", + "printedName": "SwiftUI.ModifiedContent<τ_0_0, FirebaseAnalytics.LoggedAnalyticsModifier>", + "children": [ + { + "kind": "TypeNominal", + "name": "GenericTypeParam", + "printedName": "τ_0_0" + }, + { + "kind": "TypeNominal", + "name": "LoggedAnalyticsModifier", + "printedName": "FirebaseAnalytics.LoggedAnalyticsModifier", + "usr": "s:17FirebaseAnalytics06LoggedB8ModifierV" + } + ], + "usr": "s:7SwiftUI15ModifiedContentV" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "hasDefaultArg": true, + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "Dictionary", + "printedName": "[Swift.String : Any]", + "children": [ + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "ProtocolComposition", + "printedName": "Any" + } + ], + "hasDefaultArg": true, + "usr": "s:SD" + } + ], + "declKind": "Func", + "usr": "s:7SwiftUI4ViewP17FirebaseAnalyticsE15analyticsScreen4name5class15extraParametersQrSS_SSSDySSypGtF", + "mangledName": "$s7SwiftUI4ViewP17FirebaseAnalyticsE15analyticsScreen4name5class15extraParametersQrSS_SSSDySSypGtF", + "moduleName": "FirebaseAnalytics", + "genericSig": "<τ_0_0 where τ_0_0 : SwiftUI.View>", + "sugared_genericSig": "", + "declAttributes": [ + "AccessControl", + "RawDocComment" + ], + "isFromExtension": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Protocol", + "usr": "s:7SwiftUI4ViewP", + "mangledName": "$s7SwiftUI4ViewP", + "moduleName": "SwiftUI", + "genericSig": "<τ_0_0.Body : SwiftUI.View>", + "sugared_genericSig": "", + "intro_Macosx": "10.15", + "intro_iOS": "13.0", + "intro_tvOS": "13.0", + "intro_watchOS": "6.0", + "declAttributes": [ + "TypeEraser", + "Available", + "Available", + "Available", + "Available" + ], + "isExternal": true + } + ], + "json_format_version": 8 + }, + "ConstValues": [ + { + "filePath": "\/Volumes\/google\/src\/cloud\/pdchen\/firebaserelease\/google3\/googlemac\/iPhone\/Firebase\/Analytics\/Sources\/Swift\/Analytics+SwiftUI.swift", + "kind": "StringLiteral", + "offset": 2654, + "length": 6, + "value": "\"View\"" + }, + { + "filePath": "\/Volumes\/google\/src\/cloud\/pdchen\/firebaserelease\/google3\/googlemac\/iPhone\/Firebase\/Analytics\/Sources\/Swift\/Analytics+SwiftUI.swift", + "kind": "Dictionary", + "offset": 2701, + "length": 3, + "value": "[]" + } + ] +} \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos-simulator.private.swiftinterface b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos-simulator.private.swiftinterface new file mode 100644 index 0000000..0ab8d65 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos-simulator.private.swiftinterface @@ -0,0 +1,22 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +// swift-module-flags: -target arm64-apple-tvos12.0-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name FirebaseAnalytics +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import FirebaseAnalytics +import StoreKit +import Swift +import SwiftUI +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *) +@available(watchOS, unavailable) +extension FirebaseAnalytics.Analytics { + public static func logTransaction(_ transaction: StoreKit.Transaction) +} +@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *) +@available(watchOS, unavailable) +extension SwiftUI.View { + public func analyticsScreen(name: Swift.String, class: Swift.String = "View", extraParameters: [Swift.String : Any] = [:]) -> some SwiftUI.View + +} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos-simulator.swiftdoc b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos-simulator.swiftdoc new file mode 100644 index 0000000..9c5c4f8 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos-simulator.swiftdoc differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos-simulator.swiftinterface b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos-simulator.swiftinterface new file mode 100644 index 0000000..0ab8d65 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/arm64-apple-tvos-simulator.swiftinterface @@ -0,0 +1,22 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +// swift-module-flags: -target arm64-apple-tvos12.0-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name FirebaseAnalytics +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import FirebaseAnalytics +import StoreKit +import Swift +import SwiftUI +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *) +@available(watchOS, unavailable) +extension FirebaseAnalytics.Analytics { + public static func logTransaction(_ transaction: StoreKit.Transaction) +} +@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *) +@available(watchOS, unavailable) +extension SwiftUI.View { + public func analyticsScreen(name: Swift.String, class: Swift.String = "View", extraParameters: [Swift.String : Any] = [:]) -> some SwiftUI.View + +} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-tvos-simulator.abi.json b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-tvos-simulator.abi.json new file mode 100644 index 0000000..fde2b92 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-tvos-simulator.abi.json @@ -0,0 +1,239 @@ +{ + "ABIRoot": { + "kind": "Root", + "name": "TopLevel", + "printedName": "TopLevel", + "children": [ + { + "kind": "Import", + "name": "StoreKit", + "printedName": "StoreKit", + "declKind": "Import", + "moduleName": "FirebaseAnalytics" + }, + { + "kind": "Import", + "name": "SwiftUI", + "printedName": "SwiftUI", + "declKind": "Import", + "moduleName": "FirebaseAnalytics" + }, + { + "kind": "TypeDecl", + "name": "Analytics", + "printedName": "Analytics", + "children": [ + { + "kind": "Function", + "name": "logTransaction", + "printedName": "logTransaction(_:)", + "children": [ + { + "kind": "TypeNominal", + "name": "Void", + "printedName": "()" + }, + { + "kind": "TypeNominal", + "name": "Transaction", + "printedName": "StoreKit.Transaction", + "usr": "s:8StoreKit11TransactionV" + } + ], + "declKind": "Func", + "usr": "s:So12FIRAnalyticsC17FirebaseAnalyticsE14logTransactionyy8StoreKit0E0VFZ", + "mangledName": "$sSo12FIRAnalyticsC17FirebaseAnalyticsE14logTransactionyy8StoreKit0E0VFZ", + "moduleName": "FirebaseAnalytics", + "static": true, + "declAttributes": [ + "Final", + "AccessControl", + "RawDocComment" + ], + "isFromExtension": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Class", + "usr": "c:objc(cs)FIRAnalytics", + "moduleName": "FirebaseAnalytics", + "isOpen": true, + "objc_name": "FIRAnalytics", + "declAttributes": [ + "ObjC", + "Dynamic" + ], + "superclassUsr": "c:objc(cs)NSObject", + "isExternal": true, + "inheritsConvenienceInitializers": true, + "superclassNames": [ + "ObjectiveC.NSObject" + ], + "conformances": [ + { + "kind": "Conformance", + "name": "Equatable", + "printedName": "Equatable", + "usr": "s:SQ", + "mangledName": "$sSQ" + }, + { + "kind": "Conformance", + "name": "Hashable", + "printedName": "Hashable", + "usr": "s:SH", + "mangledName": "$sSH" + }, + { + "kind": "Conformance", + "name": "CVarArg", + "printedName": "CVarArg", + "usr": "s:s7CVarArgP", + "mangledName": "$ss7CVarArgP" + }, + { + "kind": "Conformance", + "name": "_KeyValueCodingAndObservingPublishing", + "printedName": "_KeyValueCodingAndObservingPublishing", + "usr": "s:10Foundation37_KeyValueCodingAndObservingPublishingP", + "mangledName": "$s10Foundation37_KeyValueCodingAndObservingPublishingP" + }, + { + "kind": "Conformance", + "name": "_KeyValueCodingAndObserving", + "printedName": "_KeyValueCodingAndObserving", + "usr": "s:10Foundation27_KeyValueCodingAndObservingP", + "mangledName": "$s10Foundation27_KeyValueCodingAndObservingP" + }, + { + "kind": "Conformance", + "name": "CustomStringConvertible", + "printedName": "CustomStringConvertible", + "usr": "s:s23CustomStringConvertibleP", + "mangledName": "$ss23CustomStringConvertibleP" + }, + { + "kind": "Conformance", + "name": "CustomDebugStringConvertible", + "printedName": "CustomDebugStringConvertible", + "usr": "s:s28CustomDebugStringConvertibleP", + "mangledName": "$ss28CustomDebugStringConvertibleP" + } + ] + }, + { + "kind": "TypeDecl", + "name": "View", + "printedName": "View", + "children": [ + { + "kind": "Function", + "name": "analyticsScreen", + "printedName": "analyticsScreen(name:class:extraParameters:)", + "children": [ + { + "kind": "TypeNominal", + "name": "ModifiedContent", + "printedName": "SwiftUI.ModifiedContent<τ_0_0, FirebaseAnalytics.LoggedAnalyticsModifier>", + "children": [ + { + "kind": "TypeNominal", + "name": "GenericTypeParam", + "printedName": "τ_0_0" + }, + { + "kind": "TypeNominal", + "name": "LoggedAnalyticsModifier", + "printedName": "FirebaseAnalytics.LoggedAnalyticsModifier", + "usr": "s:17FirebaseAnalytics06LoggedB8ModifierV" + } + ], + "usr": "s:7SwiftUI15ModifiedContentV" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "hasDefaultArg": true, + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "Dictionary", + "printedName": "[Swift.String : Any]", + "children": [ + { + "kind": "TypeNominal", + "name": "String", + "printedName": "Swift.String", + "usr": "s:SS" + }, + { + "kind": "TypeNominal", + "name": "ProtocolComposition", + "printedName": "Any" + } + ], + "hasDefaultArg": true, + "usr": "s:SD" + } + ], + "declKind": "Func", + "usr": "s:7SwiftUI4ViewP17FirebaseAnalyticsE15analyticsScreen4name5class15extraParametersQrSS_SSSDySSypGtF", + "mangledName": "$s7SwiftUI4ViewP17FirebaseAnalyticsE15analyticsScreen4name5class15extraParametersQrSS_SSSDySSypGtF", + "moduleName": "FirebaseAnalytics", + "genericSig": "<τ_0_0 where τ_0_0 : SwiftUI.View>", + "sugared_genericSig": "", + "declAttributes": [ + "AccessControl", + "RawDocComment" + ], + "isFromExtension": true, + "funcSelfKind": "NonMutating" + } + ], + "declKind": "Protocol", + "usr": "s:7SwiftUI4ViewP", + "mangledName": "$s7SwiftUI4ViewP", + "moduleName": "SwiftUI", + "genericSig": "<τ_0_0.Body : SwiftUI.View>", + "sugared_genericSig": "", + "intro_Macosx": "10.15", + "intro_iOS": "13.0", + "intro_tvOS": "13.0", + "intro_watchOS": "6.0", + "declAttributes": [ + "TypeEraser", + "Available", + "Available", + "Available", + "Available" + ], + "isExternal": true + } + ], + "json_format_version": 8 + }, + "ConstValues": [ + { + "filePath": "\/Volumes\/google\/src\/cloud\/pdchen\/firebaserelease\/google3\/googlemac\/iPhone\/Firebase\/Analytics\/Sources\/Swift\/Analytics+SwiftUI.swift", + "kind": "StringLiteral", + "offset": 2654, + "length": 6, + "value": "\"View\"" + }, + { + "filePath": "\/Volumes\/google\/src\/cloud\/pdchen\/firebaserelease\/google3\/googlemac\/iPhone\/Firebase\/Analytics\/Sources\/Swift\/Analytics+SwiftUI.swift", + "kind": "Dictionary", + "offset": 2701, + "length": 3, + "value": "[]" + } + ] +} \ No newline at end of file diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-tvos-simulator.private.swiftinterface b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-tvos-simulator.private.swiftinterface new file mode 100644 index 0000000..54b3c29 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-tvos-simulator.private.swiftinterface @@ -0,0 +1,22 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +// swift-module-flags: -target x86_64-apple-tvos12.0-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name FirebaseAnalytics +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import FirebaseAnalytics +import StoreKit +import Swift +import SwiftUI +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *) +@available(watchOS, unavailable) +extension FirebaseAnalytics.Analytics { + public static func logTransaction(_ transaction: StoreKit.Transaction) +} +@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *) +@available(watchOS, unavailable) +extension SwiftUI.View { + public func analyticsScreen(name: Swift.String, class: Swift.String = "View", extraParameters: [Swift.String : Any] = [:]) -> some SwiftUI.View + +} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-tvos-simulator.swiftdoc b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-tvos-simulator.swiftdoc new file mode 100644 index 0000000..8d82f37 Binary files /dev/null and b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-tvos-simulator.swiftdoc differ diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-tvos-simulator.swiftinterface b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-tvos-simulator.swiftinterface new file mode 100644 index 0000000..54b3c29 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/FirebaseAnalytics.swiftmodule/x86_64-apple-tvos-simulator.swiftinterface @@ -0,0 +1,22 @@ +// swift-interface-format-version: 1.0 +// swift-compiler-version: Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5) +// swift-module-flags: -target x86_64-apple-tvos12.0-simulator -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name FirebaseAnalytics +// swift-module-flags-ignorable: -enable-bare-slash-regex +@_exported import FirebaseAnalytics +import StoreKit +import Swift +import SwiftUI +import _Concurrency +import _StringProcessing +import _SwiftConcurrencyShims +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, *) +@available(watchOS, unavailable) +extension FirebaseAnalytics.Analytics { + public static func logTransaction(_ transaction: StoreKit.Transaction) +} +@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, *) +@available(watchOS, unavailable) +extension SwiftUI.View { + public func analyticsScreen(name: Swift.String, class: Swift.String = "View", extraParameters: [Swift.String : Any] = [:]) -> some SwiftUI.View + +} diff --git a/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/module.modulemap b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/module.modulemap new file mode 100644 index 0000000..fa10817 --- /dev/null +++ b/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator/FirebaseAnalytics.framework/Modules/module.modulemap @@ -0,0 +1,16 @@ +framework module FirebaseAnalytics { +umbrella header "FirebaseAnalytics-umbrella.h" +export * +module * { export * } + link framework "Foundation" + link framework "Security" + link framework "SystemConfiguration" + link framework "UIKit" + link "c++" + link "sqlite3" + link "z" +} +module FirebaseAnalytics.Swift { + header "FirebaseAnalytics-Swift.h" + requires objc +} \ No newline at end of file diff --git a/Pods/FirebaseCore/FirebaseCore/Extension/FIRAppInternal.h b/Pods/FirebaseCore/FirebaseCore/Extension/FIRAppInternal.h new file mode 100644 index 0000000..49104f0 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Extension/FIRAppInternal.h @@ -0,0 +1,159 @@ +/* + * 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 + +@class FIRComponentContainer; +@class FIRHeartbeatLogger; +@protocol FIRLibrary; + +/** + * The internal interface to `FirebaseApp`. This is meant for first-party integrators, who need to + * receive `FirebaseApp` notifications, log info about the success or failure of their + * configuration, and access other internal functionality of `FirebaseApp`. + */ +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSInteger, FIRConfigType) { + FIRConfigTypeCore = 1, + FIRConfigTypeSDK = 2, +}; + +extern NSString *const kFIRDefaultAppName; +extern NSString *const kFIRAppReadyToConfigureSDKNotification; +extern NSString *const kFIRAppDeleteNotification; +extern NSString *const kFIRAppIsDefaultAppKey; +extern NSString *const kFIRAppNameKey; +extern NSString *const kFIRGoogleAppIDKey; +extern NSString *const kFirebaseCoreErrorDomain; + +/** The `UserDefaults` suite name for `FirebaseCore`, for those storage locations that use it. */ +extern NSString *const kFirebaseCoreDefaultsSuiteName; + +/** + * The format string for the `UserDefaults` key used for storing the data collection enabled flag. + * This includes formatting to append the `FirebaseApp`'s name. + */ +extern NSString *const kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat; + +/** + * The plist key used for storing the data collection enabled flag. + */ +extern NSString *const kFIRGlobalAppDataCollectionEnabledPlistKey; + +/** @var FirebaseAuthStateDidChangeInternalNotification + @brief The name of the @c NotificationCenter notification which is posted when the auth state + changes (e.g. a new token has been produced, a user logs in or out). The object parameter of + the notification is a dictionary possibly containing the key: + @c FirebaseAuthStateDidChangeInternalNotificationTokenKey (the new access token.) If it does not + contain this key it indicates a sign-out event took place. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotification; + +/** @var FirebaseAuthStateDidChangeInternalNotificationTokenKey + @brief A key present in the dictionary object parameter of the + @c FirebaseAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the new access token. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationTokenKey; + +/** @var FirebaseAuthStateDidChangeInternalNotificationAppKey + @brief A key present in the dictionary object parameter of the + @c FirebaseAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the FirebaseApp associated with the auth instance. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationAppKey; + +/** @var FirebaseAuthStateDidChangeInternalNotificationUIDKey + @brief A key present in the dictionary object parameter of the + @c FirebaseAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the new user's UID (or nil if there is no longer a user signed in). + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationUIDKey; + +@interface FIRApp () + +/** + * A flag indicating if this is the default app (has the default app name). + */ +@property(nonatomic, readonly) BOOL isDefaultApp; + +/** + * The container of interop SDKs for this app. + */ +@property(nonatomic) FIRComponentContainer *container; + +/** + * The heartbeat logger associated with this app. + * + * Firebase apps have a 1:1 relationship with heartbeat loggers. + */ +@property(readonly) FIRHeartbeatLogger *heartbeatLogger; + +/** + * Checks if the default app is configured without trying to configure it. + */ ++ (BOOL)isDefaultAppConfigured; + +/** + * Registers a given third-party library with the given version number to be reported for + * analytics. + * + * @param name Name of the library. + * @param version Version of the library. + */ ++ (void)registerLibrary:(nonnull NSString *)name withVersion:(nonnull NSString *)version; + +/** + * Registers a given internal library to be reported for analytics. + * + * @param library Optional parameter for component registration. + * @param name Name of the library. + */ ++ (void)registerInternalLibrary:(nonnull Class)library + withName:(nonnull NSString *)name; + +/** + * Registers a given internal library with the given version number to be reported for + * analytics. This should only be used for non-Firebase libraries that have their own versioning + * scheme. + * + * @param library Optional parameter for component registration. + * @param name Name of the library. + * @param version Version of the library. + */ ++ (void)registerInternalLibrary:(nonnull Class)library + withName:(nonnull NSString *)name + withVersion:(nonnull NSString *)version; + +/** + * A concatenated string representing all the third-party libraries and version numbers. + */ ++ (NSString *)firebaseUserAgent; + +/** + * Can be used by the unit tests in each SDK to reset `FirebaseApp`. This method is thread unsafe. + */ ++ (void)resetApps; + +/** + * Can be used by the unit tests in each SDK to set customized options. + */ +- (instancetype)initInstanceWithName:(NSString *)name options:(FIROptions *)options; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/FirebaseCore/Extension/FIRComponent.h b/Pods/FirebaseCore/FirebaseCore/Extension/FIRComponent.h new file mode 100644 index 0000000..e4c8a27 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Extension/FIRComponent.h @@ -0,0 +1,91 @@ +/* + * 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 + +@class FIRApp; +@class FIRComponentContainer; + +NS_ASSUME_NONNULL_BEGIN + +/// Provides a system to clean up cached instances returned from the component system. +NS_SWIFT_NAME(ComponentLifecycleMaintainer) +@protocol FIRComponentLifecycleMaintainer +/// The associated app will be deleted, clean up any resources as they are about to be deallocated. +- (void)appWillBeDeleted:(FIRApp *)app; +@end + +typedef _Nullable id (^FIRComponentCreationBlock)(FIRComponentContainer *container, + BOOL *isCacheable) + NS_SWIFT_NAME(ComponentCreationBlock); + +@class FIRDependency; + +/// Describes the timing of instantiation. Note: new components should default to lazy unless there +/// is a strong reason to be eager. +typedef NS_ENUM(NSInteger, FIRInstantiationTiming) { + FIRInstantiationTimingLazy, + FIRInstantiationTimingAlwaysEager, + FIRInstantiationTimingEagerInDefaultApp +} NS_SWIFT_NAME(InstantiationTiming); + +/// A component that can be used from other Firebase SDKs. +NS_SWIFT_NAME(Component) +@interface FIRComponent : NSObject + +/// The protocol describing functionality provided from the `Component`. +@property(nonatomic, strong, readonly) Protocol *protocol; + +/// The timing of instantiation. +@property(nonatomic, readonly) FIRInstantiationTiming instantiationTiming; + +/// An array of dependencies for the component. +@property(nonatomic, copy, readonly) NSArray *dependencies; + +/// A block to instantiate an instance of the component with the appropriate dependencies. +@property(nonatomic, copy, readonly) FIRComponentCreationBlock creationBlock; + +// There's an issue with long NS_SWIFT_NAMES that causes compilation to fail, disable clang-format +// for the next two methods. +// clang-format off + +/// Creates a component with no dependencies that will be lazily initialized. ++ (instancetype)componentWithProtocol:(Protocol *)protocol + creationBlock:(FIRComponentCreationBlock)creationBlock +NS_SWIFT_NAME(init(_:creationBlock:)); + +/// Creates a component to be registered with the component container. +/// +/// @param protocol - The protocol describing functionality provided by the component. +/// @param instantiationTiming - When the component should be initialized. Use .lazy unless there's +/// a good reason to be instantiated earlier. +/// @param dependencies - Any dependencies the `implementingClass` has, optional or required. +/// @param creationBlock - A block to instantiate the component with a container, and if +/// @return A component that can be registered with the component container. ++ (instancetype)componentWithProtocol:(Protocol *)protocol + instantiationTiming:(FIRInstantiationTiming)instantiationTiming + dependencies:(NSArray *)dependencies + creationBlock:(FIRComponentCreationBlock)creationBlock +NS_SWIFT_NAME(init(_:instantiationTiming:dependencies:creationBlock:)); + +// clang-format on + +/// Unavailable. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/FirebaseCore/Extension/FIRComponentContainer.h b/Pods/FirebaseCore/FirebaseCore/Extension/FIRComponentContainer.h new file mode 100644 index 0000000..6ec6147 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Extension/FIRComponentContainer.h @@ -0,0 +1,45 @@ +/* + * 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 + +NS_ASSUME_NONNULL_BEGIN + +/// A type-safe macro to retrieve a component from a container. This should be used to retrieve +/// components instead of using the container directly. +#define FIR_COMPONENT(type, container) \ + [FIRComponentType> instanceForProtocol:@protocol(type) inContainer:container] + +@class FIRApp; + +/// A container that holds different components that are registered via the +/// `registerAsComponentRegistrant` call. These classes should conform to `ComponentRegistrant` +/// in order to properly register components for Core. +NS_SWIFT_NAME(FirebaseComponentContainer) +@interface FIRComponentContainer : NSObject + +/// A weak reference to the app that an instance of the container belongs to. +@property(nonatomic, weak, readonly) FIRApp *app; + +// TODO: See if we can get improved type safety here. +/// A Swift only API for fetching an instance since the top macro isn't available. +- (nullable id)__instanceForProtocol:(Protocol *)protocol NS_SWIFT_NAME(instance(for:)); + +/// Unavailable. Use the `container` property on `FirebaseApp`. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/FirebaseCore/Extension/FIRComponentType.h b/Pods/FirebaseCore/FirebaseCore/Extension/FIRComponentType.h new file mode 100644 index 0000000..c69085d --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Extension/FIRComponentType.h @@ -0,0 +1,35 @@ +/* + * 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 + +@class FIRComponentContainer; + +NS_ASSUME_NONNULL_BEGIN + +/// Do not use directly. A placeholder type in order to provide a macro that will warn users of +/// mis-matched protocols. +NS_SWIFT_NAME(ComponentType) +@interface FIRComponentType<__covariant T> : NSObject + +/// Do not use directly. A factory method to retrieve an instance that provides a specific +/// functionality. ++ (nullable T)instanceForProtocol:(Protocol *)protocol + inContainer:(FIRComponentContainer *)container; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/FirebaseCore/Extension/FIRDependency.h b/Pods/FirebaseCore/FirebaseCore/Extension/FIRDependency.h new file mode 100644 index 0000000..a070557 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Extension/FIRDependency.h @@ -0,0 +1,45 @@ +/* + * 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 + +NS_ASSUME_NONNULL_BEGIN + +/// A dependency on a specific protocol's functionality. +NS_SWIFT_NAME(Dependency) +@interface FIRDependency : NSObject + +/// The protocol describing functionality being depended on. +@property(nonatomic, strong, readonly) Protocol *protocol; + +/// A flag to specify if the dependency is required or not. +@property(nonatomic, readonly) BOOL isRequired; + +/// Initializes a dependency that is required. Calls `init(protocol:isRequired:)` with true for +/// the required parameter. +/// Creates a required dependency on the specified protocol's functionality. ++ (instancetype)dependencyWithProtocol:(Protocol *)protocol; + +/// Creates a dependency on the specified protocol's functionality and specify if it's required for +/// the class's functionality. ++ (instancetype)dependencyWithProtocol:(Protocol *)protocol isRequired:(BOOL)required; + +/// Use `init(withProtocol:isRequired:)` instead. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/FirebaseCore/Extension/FIRHeartbeatLogger.h b/Pods/FirebaseCore/FirebaseCore/Extension/FIRHeartbeatLogger.h new file mode 100644 index 0000000..0f39ad9 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Extension/FIRHeartbeatLogger.h @@ -0,0 +1,90 @@ +// Copyright 2021 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 + +NS_ASSUME_NONNULL_BEGIN + +#ifndef FIREBASE_BUILD_CMAKE +@class FIRHeartbeatsPayload; +#endif // FIREBASE_BUILD_CMAKE + +/// Enum representing different daily heartbeat codes. +/// This enum is only used by clients using platform logging V1. This is because +/// the V1 payload only supports a single daily heartbeat. +typedef NS_ENUM(NSInteger, FIRDailyHeartbeatCode) { + /// Represents the absence of a daily heartbeat. + FIRDailyHeartbeatCodeNone = 0, + /// Represents the presence of a daily heartbeat. + FIRDailyHeartbeatCodeSome = 2, +}; + +@protocol FIRHeartbeatLoggerProtocol + +/// Asynchronously logs a heartbeat. +- (void)log; + +#ifndef FIREBASE_BUILD_CMAKE +/// Flushes heartbeats from storage into a structured payload of heartbeats. +- (FIRHeartbeatsPayload *)flushHeartbeatsIntoPayload; +#endif // FIREBASE_BUILD_CMAKE + +/// Gets the heartbeat code for today. +- (FIRDailyHeartbeatCode)heartbeatCodeForToday; + +@end + +#ifndef FIREBASE_BUILD_CMAKE +/// Returns a nullable string header value from a given heartbeats payload. +/// +/// This API returns `nil` when the given heartbeats payload is considered empty. +/// +/// @param heartbeatsPayload The heartbeats payload. +NSString *_Nullable FIRHeaderValueFromHeartbeatsPayload(FIRHeartbeatsPayload *heartbeatsPayload); +#endif // FIREBASE_BUILD_CMAKE + +/// A thread safe, synchronized object that logs and flushes platform logging info. +@interface FIRHeartbeatLogger : NSObject + +/// Designated initializer. +/// +/// @param appID The app ID that this heartbeat logger corresponds to. +- (instancetype)initWithAppID:(NSString *)appID; + +/// Asynchronously logs a new heartbeat corresponding to the Firebase User Agent, if needed. +/// +/// @note This API is thread-safe. +- (void)log; + +#ifndef FIREBASE_BUILD_CMAKE +/// Flushes heartbeats from storage into a structured payload of heartbeats. +/// +/// This API is for clients using platform logging V2. +/// +/// @note This API is thread-safe. +/// @return A payload of heartbeats. +- (FIRHeartbeatsPayload *)flushHeartbeatsIntoPayload; +#endif // FIREBASE_BUILD_CMAKE + +/// Gets today's corresponding heartbeat code. +/// +/// This API is for clients using platform logging V1. +/// +/// @note This API is thread-safe. +/// @return Heartbeat code indicating whether or not there is an unsent global heartbeat. +- (FIRDailyHeartbeatCode)heartbeatCodeForToday; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/FirebaseCore/Extension/FIRLibrary.h b/Pods/FirebaseCore/FirebaseCore/Extension/FIRLibrary.h new file mode 100644 index 0000000..15e2865 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Extension/FIRLibrary.h @@ -0,0 +1,44 @@ +/* + * 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. + */ + +#ifndef FIRLibrary_h +#define FIRLibrary_h + +#import + +@class FIRApp; +@class FIRComponent; + +NS_ASSUME_NONNULL_BEGIN + +/// Provide an interface to register a library for userAgent logging and availability to others. +NS_SWIFT_NAME(Library) +@protocol FIRLibrary + +/// Returns one or more Components that will be registered in +/// FirebaseApp and participate in dependency resolution and injection. ++ (NSArray *)componentsToRegister; + +@optional +/// Implement this method if the library needs notifications for lifecycle events. This method is +/// called when the developer calls `FirebaseApp.configure()`. ++ (void)configureWithApp:(FIRApp *)app; + +@end + +NS_ASSUME_NONNULL_END + +#endif /* FIRLibrary_h */ diff --git a/Pods/FirebaseCore/FirebaseCore/Extension/FIRLogger.h b/Pods/FirebaseCore/FirebaseCore/Extension/FIRLogger.h new file mode 100644 index 0000000..41c5653 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Extension/FIRLogger.h @@ -0,0 +1,193 @@ +/* + * 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 + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * The Firebase services used in Firebase logger. + */ +typedef NSString *const FIRLoggerService; + +extern FIRLoggerService kFIRLoggerAnalytics; +extern FIRLoggerService kFIRLoggerCrash; +extern FIRLoggerService kFIRLoggerCore; +extern FIRLoggerService kFIRLoggerRemoteConfig; + +/** + * The key used to store the logger's error count. + */ +extern NSString *const kFIRLoggerErrorCountKey; + +/** + * The key used to store the logger's warning count. + */ +extern NSString *const kFIRLoggerWarningCountKey; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * Enables or disables Analytics debug mode. + * If set to true, the logging level for Analytics will be set to FirebaseLoggerLevelDebug. + * Enabling the debug mode has no effect if the app is running from App Store. + * (required) analytics debug mode flag. + */ +void FIRSetAnalyticsDebugMode(BOOL analyticsDebugMode); + +/** + * Gets the current FIRLoggerLevel. + */ +FIRLoggerLevel FIRGetLoggerLevel(void); + +/** + * Changes the default logging level of FirebaseLoggerLevelNotice to a user-specified level. + * The default level cannot be set above FirebaseLoggerLevelNotice if the app is running from App + * Store. (required) log level (one of the FirebaseLoggerLevel enum values). + */ +void FIRSetLoggerLevel(FIRLoggerLevel loggerLevel); + +/** + * Checks if the specified logger level is loggable given the current settings. + * (required) log level (one of the FirebaseLoggerLevel enum values). + * (required) whether or not this function is called from the Analytics component. + */ +BOOL FIRIsLoggableLevel(FIRLoggerLevel loggerLevel, BOOL analyticsComponent); + +/** + * 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 FirebaseLoggerLevelNotice to avoid log spamming. + * (required) log level (one of the FirebaseLoggerLevel enum values). + * (required) service name of type FirebaseLoggerService. + * (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 FIRLogBasic(FIRLoggerLevel level, + FIRLoggerService service, + 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 FirebaseLoggerService. + * (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: + * FirebaseLogError(kFirebaseLoggerCore, @"I-COR000001", @"Configuration of %@ failed.", app.name); + */ +extern void FIRLogError(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogWarning(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogNotice(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogInfo(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogDebug(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); + +// TODO: Come up with a better logging scheme for Swift. +/** + * Logs a debug message to the Xcode console and the device log. If running from AppStore, will + * not log any messages with a level higher than FirebaseLoggerLevelNotice to avoid log spamming. + * This function is intended to be used by Swift clients that do not support variadic parameters. + * + * @param service The service name of type `FirebaseLoggerService`. + * @param messageCode The mesage 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". + * @param message The message string. + */ +extern void FIRLogDebugSwift(FIRLoggerService service, NSString *messageCode, NSString *message); + +/** + * Logs a warning message to the Xcode console and the device log. If running from AppStore, will + * not log any messages with a level higher than FirebaseLoggerLevelNotice to avoid log spamming. + * This function is intended to be used by Swift clients that do not support variadic parameters. + * + * @param service The service name of type `FirebaseLoggerService`. + * @param messageCode The mesage 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". + * @param message The message string. + */ +extern void FIRLogWarningSwift(FIRLoggerService service, NSString *messageCode, NSString *message); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +NS_SWIFT_NAME(FirebaseLogger) +@interface FIRLoggerWrapper : NSObject + +/// Logs a given message at a given log level. This API is effectively a wrapper for the +/// `FIRLogBasic` C API. +/// +/// - Parameters: +/// - level: The log level to use (defined by `FirebaseLoggerLevel` enum values). +/// - service: The service name of type `FirebaseLoggerService`. +/// - code: The mesage 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". +/// - message: Formatted string to be used as the log's message. +/// - args: Arguments list obtained from calling `va_start`, used when message is a format string. ++ (void)logWithLevel:(FIRLoggerLevel)level + withService:(FIRLoggerService)service + withCode:(NSString *)messageCode + withMessage:(NSString *)message + withArgs:(va_list)args; + +/// Logs a given message at a given log level. +/// +/// - Parameters: +/// - level: The log level to use (defined by `FirebaseLoggerLevel` enum values). +/// - service: The service name of type `FirebaseLoggerService`. +/// - code: The mesage 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". +/// - message: Formatted string to be used as the log's message. +/// - args: Arguments list obtained from calling `va_start`, used when message is a format string. ++ (void)logWithLevel:(FIRLoggerLevel)level + service:(FIRLoggerService)service + code:(NSString *)code + message:(NSString *)message + __attribute__((__swift_name__("log(level:service:code:message:)"))); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/FirebaseCore/Extension/FIROptionsInternal.h b/Pods/FirebaseCore/FirebaseCore/Extension/FIROptionsInternal.h new file mode 100644 index 0000000..93a03d6 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Extension/FIROptionsInternal.h @@ -0,0 +1,106 @@ +/* + * 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 + +/** + * Keys for the strings in the plist file. + */ +extern NSString *const kFIRAPIKey; +extern NSString *const kFIRTrackingID; +extern NSString *const kFIRGoogleAppID; +extern NSString *const kFIRClientID; +extern NSString *const kFIRGCMSenderID; +extern NSString *const kFIRAndroidClientID; +extern NSString *const kFIRDatabaseURL; +extern NSString *const kFIRStorageBucket; +extern NSString *const kFIRBundleID; +extern NSString *const kFIRProjectID; + +/** + * Keys for the plist file name + */ +extern NSString *const kServiceInfoFileName; + +extern NSString *const kServiceInfoFileType; + +/** + * This header file exposes the initialization of FirebaseOptions to internal use. + */ +@interface FIROptions () + +/** + * `resetDefaultOptions` and `initInternalWithOptionsDictionary` are exposed only for unit tests. + */ ++ (void)resetDefaultOptions; + +/** + * Initializes the options with dictionary. The above strings are the keys of the dictionary. + * This is the designated initializer. + */ +- (instancetype)initInternalWithOptionsDictionary:(NSDictionary *)serviceInfoDictionary + NS_DESIGNATED_INITIALIZER; + +/** + * `defaultOptions` and `defaultOptionsDictionary` are exposed in order to be used in FirebaseApp + * and other first party services. + */ ++ (FIROptions *)defaultOptions; + ++ (NSDictionary *)defaultOptionsDictionary; + +/** + * Indicates whether or not Analytics collection was explicitly enabled via a plist flag or at + * runtime. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionExplicitlySet; + +/** + * Whether or not Analytics Collection was enabled. Analytics Collection is enabled unless + * explicitly disabled in GoogleService-Info.plist. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionEnabled; + +/** + * Whether or not Analytics Collection was completely disabled. If true, then + * isAnalyticsCollectionEnabled will be false. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionDeactivated; + +/** + * The version ID of the client library, e.g. @"1100000". + */ +@property(nonatomic, readonly, copy) NSString *libraryVersionID; + +/** + * The flag indicating whether this object was constructed with the values in the default plist + * file. + */ +@property(nonatomic) BOOL usingOptionsFromDefaultPlist; + +/** + * Whether or not Measurement was enabled. Measurement is enabled unless explicitly disabled in + * GoogleService-Info.plist. + */ +@property(nonatomic, readonly) BOOL isMeasurementEnabled; + +/** + * Whether or not editing is locked. This should occur after `FirebaseOptions` has been set on a + * `FirebaseApp`. + */ +@property(nonatomic, getter=isEditingLocked) BOOL editingLocked; + +@end diff --git a/Pods/FirebaseCore/FirebaseCore/Extension/FirebaseCoreInternal.h b/Pods/FirebaseCore/FirebaseCore/Extension/FirebaseCoreInternal.h new file mode 100644 index 0000000..0669ae6 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Extension/FirebaseCoreInternal.h @@ -0,0 +1,25 @@ +// 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 FirebaseCore; + +#import "FIRAppInternal.h" +#import "FIRComponent.h" +#import "FIRComponentContainer.h" +#import "FIRComponentType.h" +#import "FIRDependency.h" +#import "FIRHeartbeatLogger.h" +#import "FIRLibrary.h" +#import "FIRLogger.h" +#import "FIROptionsInternal.h" diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/FIRAnalyticsConfiguration.h b/Pods/FirebaseCore/FirebaseCore/Sources/FIRAnalyticsConfiguration.h new file mode 100644 index 0000000..6429ac7 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/FIRAnalyticsConfiguration.h @@ -0,0 +1,56 @@ +/* + * 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 + +/// Values stored in analyticsEnabledState. Never alter these constants since they must match with +/// values persisted to disk. +typedef NS_ENUM(int64_t, FIRAnalyticsEnabledState) { + // 0 is the default value for keys not found stored in persisted config, so it cannot represent + // kFIRAnalyticsEnabledStateSetNo. It must represent kFIRAnalyticsEnabledStateNotSet. + kFIRAnalyticsEnabledStateNotSet = 0, + kFIRAnalyticsEnabledStateSetYes = 1, + kFIRAnalyticsEnabledStateSetNo = 2, +}; + +/// The user defaults key for the persisted measurementEnabledState value. FIRAPersistedConfig reads +/// measurementEnabledState using this same key. +static NSString *const kFIRAPersistedConfigMeasurementEnabledStateKey = + @"/google/measurement/measurement_enabled_state"; + +static NSString *const kFIRAnalyticsConfigurationSetEnabledNotification = + @"FIRAnalyticsConfigurationSetEnabledNotification"; +static NSString *const kFIRAnalyticsConfigurationSetMinimumSessionIntervalNotification = + @"FIRAnalyticsConfigurationSetMinimumSessionIntervalNotification"; +static NSString *const kFIRAnalyticsConfigurationSetSessionTimeoutIntervalNotification = + @"FIRAnalyticsConfigurationSetSessionTimeoutIntervalNotification"; + +@interface FIRAnalyticsConfiguration : NSObject + +/// Returns the shared instance of FIRAnalyticsConfiguration. ++ (FIRAnalyticsConfiguration *)sharedInstance; + +// Sets whether analytics collection is enabled for this app on this device. This setting is +// persisted across app sessions. By default it is enabled. +- (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled; + +/// Sets whether analytics collection is enabled for this app on this device, and a flag to persist +/// the value or not. The setting should not be persisted if being set by the global data collection +/// flag. +- (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled + persistSetting:(BOOL)shouldPersist; + +@end diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/FIRAnalyticsConfiguration.m b/Pods/FirebaseCore/FirebaseCore/Sources/FIRAnalyticsConfiguration.m new file mode 100644 index 0000000..07c786c --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/FIRAnalyticsConfiguration.m @@ -0,0 +1,62 @@ +// 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 + +#import "FirebaseCore/Sources/FIRAnalyticsConfiguration.h" + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" +@implementation FIRAnalyticsConfiguration +#pragma clang diagnostic pop + ++ (FIRAnalyticsConfiguration *)sharedInstance { + static FIRAnalyticsConfiguration *sharedInstance = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedInstance = [[FIRAnalyticsConfiguration alloc] init]; + }); + return sharedInstance; +} + +- (void)postNotificationName:(NSString *)name value:(id)value { + if (!name.length || !value) { + return; + } + [[NSNotificationCenter defaultCenter] postNotificationName:name + object:self + userInfo:@{name : value}]; +} + +- (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled { + [self setAnalyticsCollectionEnabled:analyticsCollectionEnabled persistSetting:YES]; +} + +- (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled + persistSetting:(BOOL)shouldPersist { + // Persist the measurementEnabledState. Use FIRAnalyticsEnabledState values instead of YES/NO. + FIRAnalyticsEnabledState analyticsEnabledState = + analyticsCollectionEnabled ? kFIRAnalyticsEnabledStateSetYes : kFIRAnalyticsEnabledStateSetNo; + if (shouldPersist) { + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:@(analyticsEnabledState) + forKey:kFIRAPersistedConfigMeasurementEnabledStateKey]; + [userDefaults synchronize]; + } + + [self postNotificationName:kFIRAnalyticsConfigurationSetEnabledNotification + value:@(analyticsCollectionEnabled)]; +} + +@end diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/FIRApp.m b/Pods/FirebaseCore/FirebaseCore/Sources/FIRApp.m new file mode 100644 index 0000000..c942cec --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/FIRApp.m @@ -0,0 +1,919 @@ +// 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. + +#include + +#if __has_include() +#import +#endif + +#if __has_include() +#import +#endif + +#if __has_include() +#import +#endif + +#import "FirebaseCore/Sources/Public/FirebaseCore/FIRApp.h" + +#import "FirebaseCore/Sources/FIRAnalyticsConfiguration.h" +#import "FirebaseCore/Sources/FIRBundleUtil.h" +#import "FirebaseCore/Sources/FIRComponentContainerInternal.h" +#import "FirebaseCore/Sources/FIRConfigurationInternal.h" +#import "FirebaseCore/Sources/FIRFirebaseUserAgent.h" + +#import "FirebaseCore/Extension/FIRAppInternal.h" +#import "FirebaseCore/Extension/FIRHeartbeatLogger.h" +#import "FirebaseCore/Extension/FIRLibrary.h" +#import "FirebaseCore/Extension/FIRLogger.h" +#import "FirebaseCore/Extension/FIROptionsInternal.h" +#import "FirebaseCore/Sources/Public/FirebaseCore/FIRVersion.h" + +#import + +#import + +NSString *const kFIRDefaultAppName = @"__FIRAPP_DEFAULT"; +NSString *const kFIRAppReadyToConfigureSDKNotification = @"FIRAppReadyToConfigureSDKNotification"; +NSString *const kFIRAppDeleteNotification = @"FIRAppDeleteNotification"; +NSString *const kFIRAppIsDefaultAppKey = @"FIRAppIsDefaultAppKey"; +NSString *const kFIRAppNameKey = @"FIRAppNameKey"; +NSString *const kFIRGoogleAppIDKey = @"FIRGoogleAppIDKey"; + +NSString *const kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat = + @"/google/firebase/global_data_collection_enabled:%@"; +NSString *const kFIRGlobalAppDataCollectionEnabledPlistKey = + @"FirebaseDataCollectionDefaultEnabled"; + +NSString *const kFIRAppDiagnosticsConfigurationTypeKey = @"ConfigType"; +NSString *const kFIRAppDiagnosticsErrorKey = @"Error"; +NSString *const kFIRAppDiagnosticsFIRAppKey = @"FIRApp"; +NSString *const kFIRAppDiagnosticsSDKNameKey = @"SDKName"; +NSString *const kFIRAppDiagnosticsSDKVersionKey = @"SDKVersion"; +NSString *const kFIRAppDiagnosticsApplePlatformPrefix = @"apple-platform"; + +// Auth internal notification notification and key. +NSString *const FIRAuthStateDidChangeInternalNotification = + @"FIRAuthStateDidChangeInternalNotification"; +NSString *const FIRAuthStateDidChangeInternalNotificationAppKey = + @"FIRAuthStateDidChangeInternalNotificationAppKey"; +NSString *const FIRAuthStateDidChangeInternalNotificationTokenKey = + @"FIRAuthStateDidChangeInternalNotificationTokenKey"; +NSString *const FIRAuthStateDidChangeInternalNotificationUIDKey = + @"FIRAuthStateDidChangeInternalNotificationUIDKey"; + +/** + * Error domain for exceptions and NSError construction. + */ +NSString *const kFirebaseCoreErrorDomain = @"com.firebase.core"; + +/** The NSUserDefaults suite name for FirebaseCore, for those storage locations that use it. */ +NSString *const kFirebaseCoreDefaultsSuiteName = @"com.firebase.core"; + +/** + * The URL to download plist files. + */ +static NSString *const kPlistURL = @"https://console.firebase.google.com/"; + +/** + * An array of all classes that registered as `FIRCoreConfigurable` in order to receive lifecycle + * events from Core. + */ +static NSMutableArray> *sRegisteredAsConfigurable; + +@interface FIRApp () + +#ifdef DEBUG +@property(nonatomic) BOOL alreadyOutputDataCollectionFlag; +#endif // DEBUG + +@end + +@implementation FIRApp + +// This is necessary since our custom getter prevents `_options` from being created. +@synthesize options = _options; + +static NSMutableDictionary *sAllApps; +static FIRApp *sDefaultApp; + ++ (void)configure { + FIROptions *options = [FIROptions defaultOptions]; + if (!options) { +#if DEBUG + [self findMisnamedGoogleServiceInfoPlist]; +#endif // DEBUG + [NSException raise:kFirebaseCoreErrorDomain + format:@"`FirebaseApp.configure()` could not find " + @"a valid GoogleService-Info.plist in your project. Please download one " + @"from %@.", + kPlistURL]; + } + [FIRApp configureWithOptions:options]; +} + ++ (void)configureWithOptions:(FIROptions *)options { + if (!options) { + [NSException raise:kFirebaseCoreErrorDomain + format:@"Options is nil. Please pass a valid options."]; + } + [FIRApp configureWithName:kFIRDefaultAppName options:options]; +} + ++ (NSCharacterSet *)applicationNameAllowedCharacters { + static NSCharacterSet *applicationNameAllowedCharacters; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSMutableCharacterSet *allowedNameCharacters = [NSMutableCharacterSet alphanumericCharacterSet]; + [allowedNameCharacters addCharactersInString:@"-_"]; + applicationNameAllowedCharacters = [allowedNameCharacters copy]; + }); + return applicationNameAllowedCharacters; +} + ++ (void)configureWithName:(NSString *)name options:(FIROptions *)options { + if (!name || !options) { + [NSException raise:kFirebaseCoreErrorDomain format:@"Neither name nor options can be nil."]; + } + if (name.length == 0) { + [NSException raise:kFirebaseCoreErrorDomain format:@"Name cannot be empty."]; + } + + if ([name isEqualToString:kFIRDefaultAppName]) { + if (sDefaultApp) { + // The default app already exists. Handle duplicate `configure` calls and return. + [self appWasConfiguredTwice:sDefaultApp usingOptions:options]; + return; + } + + FIRLogDebug(kFIRLoggerCore, @"I-COR000001", @"Configuring the default app."); + } else { + // Validate the app name and ensure it hasn't been configured already. + NSCharacterSet *nameCharacters = [NSCharacterSet characterSetWithCharactersInString:name]; + + if (![[self applicationNameAllowedCharacters] isSupersetOfSet:nameCharacters]) { + [NSException raise:kFirebaseCoreErrorDomain + format:@"App name can only contain alphanumeric, " + @"hyphen (-), and underscore (_) characters"]; + } + + @synchronized(self) { + if (sAllApps && sAllApps[name]) { + // The app already exists. Handle a duplicate `configure` call and return. + [self appWasConfiguredTwice:sAllApps[name] usingOptions:options]; + return; + } + } + + FIRLogDebug(kFIRLoggerCore, @"I-COR000002", @"Configuring app named %@", name); + } + + // Default instantiation, make sure we populate with Swift SDKs that can't register in time. + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + [self registerSwiftComponents]; + }); + + @synchronized(self) { + FIRApp *app = [[FIRApp alloc] initInstanceWithName:name options:options]; + if (app.isDefaultApp) { + sDefaultApp = app; + } + + [FIRApp addAppToAppDictionary:app]; + + // The FIRApp instance is ready to go, `sDefaultApp` is assigned, other SDKs are now ready to be + // instantiated. + [app.container instantiateEagerComponents]; + [FIRApp sendNotificationsToSDKs:app]; + } +} + +/// Called when `configure` has been called multiple times for the same app. This can either throw +/// an exception (most cases) or ignore the duplicate configuration in situations where it's allowed +/// like an extension. ++ (void)appWasConfiguredTwice:(FIRApp *)app usingOptions:(FIROptions *)options { + // Only extensions should potentially be able to call `configure` more than once. + if (![GULAppEnvironmentUtil isAppExtension]) { + // Throw an exception since this is now an invalid state. + if (app.isDefaultApp) { + [NSException raise:kFirebaseCoreErrorDomain + format:@"Default app has already been configured."]; + } else { + [NSException raise:kFirebaseCoreErrorDomain + format:@"App named %@ has already been configured.", app.name]; + } + } + + // In an extension, the entry point could be called multiple times. As long as the options are + // identical we should allow multiple `configure` calls. + if ([options isEqual:app.options]) { + // Everything is identical but the extension's lifecycle triggered `configure` twice. + // Ignore duplicate calls and return since everything should still be in a valid state. + FIRLogDebug(kFIRLoggerCore, @"I-COR000035", + @"Ignoring second `configure` call in an extension."); + return; + } else { + [NSException raise:kFirebaseCoreErrorDomain + format:@"App named %@ has already been configured.", app.name]; + } +} + ++ (FIRApp *)defaultApp { + if (sDefaultApp) { + return sDefaultApp; + } + FIRLogError(kFIRLoggerCore, @"I-COR000003", + @"The default Firebase app has not yet been " + @"configured. Add `FirebaseApp.configure()` to your " + @"application initialization. This can be done in " + @"in the App Delegate's application(_:didFinishLaunchingWithOptions:)` " + @"(or the `@main` struct's initializer in SwiftUI). " + @"Read more: https://goo.gl/ctyzm8."); + return nil; +} + ++ (FIRApp *)appNamed:(NSString *)name { + @synchronized(self) { + if (sAllApps) { + FIRApp *app = sAllApps[name]; + if (app) { + return app; + } + } + FIRLogError(kFIRLoggerCore, @"I-COR000004", @"App with name %@ does not exist.", name); + return nil; + } +} + ++ (NSDictionary *)allApps { + @synchronized(self) { + if (!sAllApps) { + FIRLogError(kFIRLoggerCore, @"I-COR000005", @"No app has been configured yet."); + } + return [sAllApps copy]; + } +} + +// Public only for tests ++ (void)resetApps { + @synchronized(self) { + sDefaultApp = nil; + [sAllApps removeAllObjects]; + sAllApps = nil; + [[self userAgent] reset]; + } +} + +- (void)deleteApp:(FIRAppVoidBoolCallback)completion { + @synchronized([self class]) { + if (sAllApps && sAllApps[self.name]) { + FIRLogDebug(kFIRLoggerCore, @"I-COR000006", @"Deleting app named %@", self.name); + + // Remove all registered libraries from the container to avoid creating new instances. + [self.container removeAllComponents]; + // Remove all cached instances from the container before deleting the app. + [self.container removeAllCachedInstances]; + + [sAllApps removeObjectForKey:self.name]; + [self clearDataCollectionSwitchFromUserDefaults]; + if ([self.name isEqualToString:kFIRDefaultAppName]) { + sDefaultApp = nil; + } + NSDictionary *appInfoDict = @{kFIRAppNameKey : self.name}; + [[NSNotificationCenter defaultCenter] postNotificationName:kFIRAppDeleteNotification + object:[self class] + userInfo:appInfoDict]; + completion(YES); + } else { + FIRLogError(kFIRLoggerCore, @"I-COR000007", @"App does not exist."); + completion(NO); + } + } +} + ++ (void)addAppToAppDictionary:(FIRApp *)app { + if (!sAllApps) { + sAllApps = [NSMutableDictionary dictionary]; + } + if ([app configureCore]) { + sAllApps[app.name] = app; + } else { + [NSException raise:kFirebaseCoreErrorDomain + format:@"Configuration fails. It may be caused by an invalid GOOGLE_APP_ID in " + @"GoogleService-Info.plist or set in the customized options."]; + } +} + +- (instancetype)initInstanceWithName:(NSString *)name options:(FIROptions *)options { + self = [super init]; + if (self) { + _name = [name copy]; + _options = [options copy]; + _options.editingLocked = YES; + _isDefaultApp = [name isEqualToString:kFIRDefaultAppName]; + _container = [[FIRComponentContainer alloc] initWithApp:self]; + _heartbeatLogger = [[FIRHeartbeatLogger alloc] initWithAppID:self.options.googleAppID]; + } + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (BOOL)configureCore { + [self checkExpectedBundleID]; + if (![self isAppIDValid]) { + return NO; + } + + // Initialize the Analytics once there is a valid options under default app. Analytics should + // always initialize first by itself before the other SDKs. + if ([self.name isEqualToString:kFIRDefaultAppName]) { + Class firAnalyticsClass = NSClassFromString(@"FIRAnalytics"); + if (firAnalyticsClass) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundeclared-selector" + SEL startWithConfigurationSelector = @selector(startWithConfiguration:options:); +#pragma clang diagnostic pop + if ([firAnalyticsClass respondsToSelector:startWithConfigurationSelector]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [firAnalyticsClass performSelector:startWithConfigurationSelector + withObject:[FIRConfiguration sharedInstance].analyticsConfiguration + withObject:_options]; +#pragma clang diagnostic pop + } + } + } + + [self subscribeForAppDidBecomeActiveNotifications]; + + return YES; +} + +- (FIROptions *)options { + return [_options copy]; +} + +- (void)setDataCollectionDefaultEnabled:(BOOL)dataCollectionDefaultEnabled { +#ifdef DEBUG + FIRLogDebug(kFIRLoggerCore, @"I-COR000034", @"Explicitly %@ data collection flag.", + dataCollectionDefaultEnabled ? @"enabled" : @"disabled"); + self.alreadyOutputDataCollectionFlag = YES; +#endif // DEBUG + + NSString *key = + [NSString stringWithFormat:kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat, self.name]; + [[NSUserDefaults standardUserDefaults] setBool:dataCollectionDefaultEnabled forKey:key]; + + // Core also controls the FirebaseAnalytics flag, so check if the Analytics flags are set + // within FIROptions and change the Analytics value if necessary. Analytics only works with the + // default app, so return if this isn't the default app. + if (!self.isDefaultApp) { + return; + } + + // Check if the Analytics flag is explicitly set. If so, no further actions are necessary. + if ([self.options isAnalyticsCollectionExplicitlySet]) { + return; + } + + // The Analytics flag has not been explicitly set, so update with the value being set. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [[FIRAnalyticsConfiguration sharedInstance] + setAnalyticsCollectionEnabled:dataCollectionDefaultEnabled + persistSetting:NO]; +#pragma clang diagnostic pop +} + +- (BOOL)isDataCollectionDefaultEnabled { + // Check if it's been manually set before in code, and use that as the higher priority value. + NSNumber *defaultsObject = [[self class] readDataCollectionSwitchFromUserDefaultsForApp:self]; + if (defaultsObject != nil) { +#ifdef DEBUG + if (!self.alreadyOutputDataCollectionFlag) { + FIRLogDebug(kFIRLoggerCore, @"I-COR000031", @"Data Collection flag is %@ in user defaults.", + [defaultsObject boolValue] ? @"enabled" : @"disabled"); + self.alreadyOutputDataCollectionFlag = YES; + } +#endif // DEBUG + return [defaultsObject boolValue]; + } + + // Read the Info.plist to see if the flag is set. If it's not set, it should default to `YES`. + // As per the implementation of `readDataCollectionSwitchFromPlist`, it's a cached value and has + // no performance impact calling multiple times. + NSNumber *collectionEnabledPlistValue = [[self class] readDataCollectionSwitchFromPlist]; + if (collectionEnabledPlistValue != nil) { +#ifdef DEBUG + if (!self.alreadyOutputDataCollectionFlag) { + FIRLogDebug(kFIRLoggerCore, @"I-COR000032", @"Data Collection flag is %@ in plist.", + [collectionEnabledPlistValue boolValue] ? @"enabled" : @"disabled"); + self.alreadyOutputDataCollectionFlag = YES; + } +#endif // DEBUG + return [collectionEnabledPlistValue boolValue]; + } + +#ifdef DEBUG + if (!self.alreadyOutputDataCollectionFlag) { + FIRLogDebug(kFIRLoggerCore, @"I-COR000033", @"Data Collection flag is not set."); + self.alreadyOutputDataCollectionFlag = YES; + } +#endif // DEBUG + return YES; +} + +#pragma mark - private + ++ (void)sendNotificationsToSDKs:(FIRApp *)app { + // TODO: Remove this notification once all SDKs are registered with `FIRCoreConfigurable`. + NSNumber *isDefaultApp = [NSNumber numberWithBool:app.isDefaultApp]; + NSDictionary *appInfoDict = @{ + kFIRAppNameKey : app.name, + kFIRAppIsDefaultAppKey : isDefaultApp, + kFIRGoogleAppIDKey : app.options.googleAppID + }; + [[NSNotificationCenter defaultCenter] postNotificationName:kFIRAppReadyToConfigureSDKNotification + object:self + userInfo:appInfoDict]; + + // This is the new way of sending information to SDKs. + // TODO: Do we want this on a background thread, maybe? + @synchronized(self) { + for (Class library in sRegisteredAsConfigurable) { + [library configureWithApp:app]; + } + } +} + ++ (NSError *)errorForMissingOptions { + NSDictionary *errorDict = @{ + NSLocalizedDescriptionKey : + @"Unable to parse GoogleService-Info.plist in order to configure services.", + NSLocalizedRecoverySuggestionErrorKey : + @"Check formatting and location of GoogleService-Info.plist." + }; + return [NSError errorWithDomain:kFirebaseCoreErrorDomain code:-100 userInfo:errorDict]; +} + ++ (NSError *)errorForInvalidAppID { + NSDictionary *errorDict = @{ + NSLocalizedDescriptionKey : @"Unable to validate Google App ID", + NSLocalizedRecoverySuggestionErrorKey : + @"Check formatting and location of GoogleService-Info.plist or GoogleAppID set in the " + @"customized options." + }; + return [NSError errorWithDomain:kFirebaseCoreErrorDomain code:-101 userInfo:errorDict]; +} + ++ (BOOL)isDefaultAppConfigured { + return (sDefaultApp != nil); +} + ++ (void)registerLibrary:(nonnull NSString *)name withVersion:(nonnull NSString *)version { + // Create the set of characters which aren't allowed, only if this feature is used. + NSMutableCharacterSet *allowedSet = [NSMutableCharacterSet alphanumericCharacterSet]; + [allowedSet addCharactersInString:@"-_."]; + NSCharacterSet *disallowedSet = [allowedSet invertedSet]; + // Make sure the library name and version strings do not contain unexpected characters, and + // add the name/version pair to the dictionary. + if ([name rangeOfCharacterFromSet:disallowedSet].location == NSNotFound && + [version rangeOfCharacterFromSet:disallowedSet].location == NSNotFound) { + [[self userAgent] setValue:version forComponent:name]; + } else { + FIRLogError(kFIRLoggerCore, @"I-COR000027", + @"The library name (%@) or version number (%@) contain invalid characters. " + @"Only alphanumeric, dash, underscore and period characters are allowed.", + name, version); + } +} + ++ (void)registerInternalLibrary:(nonnull Class)library + withName:(nonnull NSString *)name { + [self registerInternalLibrary:library withName:name withVersion:FIRFirebaseVersion()]; +} + ++ (void)registerInternalLibrary:(nonnull Class)library + withName:(nonnull NSString *)name + withVersion:(nonnull NSString *)version { + // This is called at +load time, keep the work to a minimum. + + // Ensure the class given conforms to the proper protocol. + if (![(Class)library conformsToProtocol:@protocol(FIRLibrary)] || + ![(Class)library respondsToSelector:@selector(componentsToRegister)]) { + [NSException raise:NSInvalidArgumentException + format:@"Class %@ attempted to register components, but it does not conform to " + @"`FIRLibrary or provide a `componentsToRegister:` method.", + library]; + } + + [FIRComponentContainer registerAsComponentRegistrant:library]; + if ([(Class)library respondsToSelector:@selector(configureWithApp:)]) { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sRegisteredAsConfigurable = [[NSMutableArray alloc] init]; + }); + @synchronized(self) { + [sRegisteredAsConfigurable addObject:library]; + } + } + [self registerLibrary:name withVersion:version]; +} + ++ (FIRFirebaseUserAgent *)userAgent { + static dispatch_once_t onceToken; + static FIRFirebaseUserAgent *_userAgent; + dispatch_once(&onceToken, ^{ + _userAgent = [[FIRFirebaseUserAgent alloc] init]; + [_userAgent setValue:FIRFirebaseVersion() forComponent:@"fire-ios"]; + }); + return _userAgent; +} + ++ (NSString *)firebaseUserAgent { + return [[self userAgent] firebaseUserAgent]; +} + +- (void)checkExpectedBundleID { + NSArray *bundles = [FIRBundleUtil relevantBundles]; + NSString *expectedBundleID = [self expectedBundleID]; + // The checking is only done when the bundle ID is provided in the serviceInfo dictionary for + // backward compatibility. + if (expectedBundleID != nil && ![FIRBundleUtil hasBundleIdentifierPrefix:expectedBundleID + inBundles:bundles]) { + FIRLogError(kFIRLoggerCore, @"I-COR000008", + @"The project's Bundle ID is inconsistent with " + @"either the Bundle ID in '%@.%@', or the Bundle ID in the options if you are " + @"using a customized options. To ensure that everything can be configured " + @"correctly, you may need to make the Bundle IDs consistent. To continue with this " + @"plist file, you may change your app's bundle identifier to '%@'. Or you can " + @"download a new configuration file that matches your bundle identifier from %@ " + @"and replace the current one.", + kServiceInfoFileName, kServiceInfoFileType, expectedBundleID, kPlistURL); + } +} + +#pragma mark - private - App ID Validation + +/** + * Validates the format of app ID and its included bundle ID hash contained in GOOGLE_APP_ID in the + * plist file. This is the main method for validating app ID. + * + * @return YES if the app ID fulfills the expected format and contains a hashed bundle ID, NO + * otherwise. + */ +- (BOOL)isAppIDValid { + NSString *appID = _options.googleAppID; + BOOL isValid = [FIRApp validateAppID:appID]; + if (!isValid) { + NSString *expectedBundleID = [self expectedBundleID]; + FIRLogError(kFIRLoggerCore, @"I-COR000009", + @"The GOOGLE_APP_ID either in the plist file " + @"'%@.%@' or the one set in the customized options is invalid. If you are using " + @"the plist file, use the iOS version of bundle identifier to download the file, " + @"and do not manually edit the GOOGLE_APP_ID. You may change your app's bundle " + @"identifier to '%@'. Or you can download a new configuration file that matches " + @"your bundle identifier from %@ and replace the current one.", + kServiceInfoFileName, kServiceInfoFileType, expectedBundleID, kPlistURL); + }; + return isValid; +} + ++ (BOOL)validateAppID:(NSString *)appID { + // Failing validation only occurs when we are sure we are looking at a V2 app ID and it does not + // have a valid hashed bundle ID, otherwise we just warn about the potential issue. + if (!appID.length) { + return NO; + } + + NSScanner *stringScanner = [NSScanner scannerWithString:appID]; + stringScanner.charactersToBeSkipped = nil; + + NSString *appIDVersion; + if (![stringScanner scanCharactersFromSet:[NSCharacterSet decimalDigitCharacterSet] + intoString:&appIDVersion]) { + return NO; + } + + if (![stringScanner scanString:@":" intoString:NULL]) { + // appIDVersion must be separated by ":" + return NO; + } + + NSArray *knownVersions = @[ @"1" ]; + if (![knownVersions containsObject:appIDVersion]) { + // Permit unknown yet properly formatted app ID versions. + FIRLogInfo(kFIRLoggerCore, @"I-COR000010", @"Unknown GOOGLE_APP_ID version: %@", appIDVersion); + return YES; + } + + if (![self validateAppIDFormat:appID withVersion:appIDVersion]) { + return NO; + } + + if (![self validateBundleIDHashWithinAppID:appID forVersion:appIDVersion]) { + return NO; + } + + return YES; +} + ++ (NSString *)actualBundleID { + return [[NSBundle mainBundle] bundleIdentifier]; +} + +/** + * Validates that the format of the app ID string is what is expected based on the supplied version. + * The version must end in ":". + * + * For v1 app ids the format is expected to be + * '::ios:'. + * + * This method does not verify that the contents of the app id are correct, just that they fulfill + * the expected format. + * + * @param appID Contents of GOOGLE_APP_ID from the plist file. + * @param version Indicates what version of the app id format this string should be. + * @return YES if provided string fufills the expected format, NO otherwise. + */ ++ (BOOL)validateAppIDFormat:(NSString *)appID withVersion:(NSString *)version { + if (!appID.length || !version.length) { + return NO; + } + + NSScanner *stringScanner = [NSScanner scannerWithString:appID]; + stringScanner.charactersToBeSkipped = nil; + + // Skip version part + // '**::ios:' + if (![stringScanner scanString:version intoString:NULL]) { + // The version part is missing or mismatched + return NO; + } + + // Validate version part (see part between '*' symbols below) + // '*:*:ios:' + if (![stringScanner scanString:@":" intoString:NULL]) { + // appIDVersion must be separated by ":" + return NO; + } + + // Validate version part (see part between '*' symbols below) + // ':**:ios:'. + NSInteger projectNumber = NSNotFound; + if (![stringScanner scanInteger:&projectNumber]) { + // NO project number found. + return NO; + } + + // Validate version part (see part between '*' symbols below) + // ':*:*ios:'. + if (![stringScanner scanString:@":" intoString:NULL]) { + // The project number must be separated by ":" + return NO; + } + + // Validate version part (see part between '*' symbols below) + // '::*ios*:'. + NSString *platform; + if (![stringScanner scanUpToString:@":" intoString:&platform]) { + return NO; + } + + if (![platform isEqualToString:@"ios"]) { + // The platform must be @"ios" + return NO; + } + + // Validate version part (see part between '*' symbols below) + // '::ios*:*'. + if (![stringScanner scanString:@":" intoString:NULL]) { + // The platform must be separated by ":" + return NO; + } + + // Validate version part (see part between '*' symbols below) + // '::ios:**'. + unsigned long long bundleIDHash = NSNotFound; + if (![stringScanner scanHexLongLong:&bundleIDHash]) { + // Hashed bundleID part is missing + return NO; + } + + if (!stringScanner.isAtEnd) { + // There are not allowed characters in the hashed bundle ID part + return NO; + } + + return YES; +} + +/** + * Validates that the hashed bundle ID included in the app ID string is what is expected based on + * the supplied version. + * + * Note that the v1 hash algorithm is not permitted on the client and cannot be fully validated. + * + * @param appID Contents of GOOGLE_APP_ID from the plist file. + * @param version Indicates what version of the app id format this string should be. + * @return YES if provided string fufills the expected hashed bundle ID and the version is known, NO + * otherwise. + */ ++ (BOOL)validateBundleIDHashWithinAppID:(NSString *)appID forVersion:(NSString *)version { + // Extract the hashed bundle ID from the given app ID. + // This assumes the app ID format is the same for all known versions below. + // If the app ID format changes in future versions, the tokenizing of the app + // ID format will need to take into account the version of the app ID. + NSArray *components = [appID componentsSeparatedByString:@":"]; + if (components.count != 4) { + return NO; + } + + NSString *suppliedBundleIDHashString = components[3]; + if (!suppliedBundleIDHashString.length) { + return NO; + } + + uint64_t suppliedBundleIDHash; + NSScanner *scanner = [NSScanner scannerWithString:suppliedBundleIDHashString]; + if (![scanner scanHexLongLong:&suppliedBundleIDHash]) { + return NO; + } + + if ([version isEqual:@"1"]) { + // The v1 hash algorithm is not permitted on the client so the actual hash cannot be validated. + return YES; + } + + // Unknown version. + return NO; +} + +- (NSString *)expectedBundleID { + return _options.bundleID; +} + +// end App ID validation + +#pragma mark - Reading From Plist & User Defaults + +/** + * Clears the data collection switch from the standard NSUserDefaults for easier testing and + * readability. + */ +- (void)clearDataCollectionSwitchFromUserDefaults { + NSString *key = + [NSString stringWithFormat:kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat, self.name]; + [[NSUserDefaults standardUserDefaults] removeObjectForKey:key]; +} + +/** + * Reads the data collection switch from the standard NSUserDefaults for easier testing and + * readability. + */ ++ (nullable NSNumber *)readDataCollectionSwitchFromUserDefaultsForApp:(FIRApp *)app { + // Read the object in user defaults, and only return if it's an NSNumber. + NSString *key = + [NSString stringWithFormat:kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat, app.name]; + id collectionEnabledDefaultsObject = [[NSUserDefaults standardUserDefaults] objectForKey:key]; + if ([collectionEnabledDefaultsObject isKindOfClass:[NSNumber class]]) { + return collectionEnabledDefaultsObject; + } + + return nil; +} + +/** + * Reads the data collection switch from the Info.plist for easier testing and readability. Will + * only read once from the plist and return the cached value. + */ ++ (nullable NSNumber *)readDataCollectionSwitchFromPlist { + static NSNumber *collectionEnabledPlistObject; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // Read the data from the `Info.plist`, only assign it if it's there and an NSNumber. + id plistValue = [[NSBundle mainBundle] + objectForInfoDictionaryKey:kFIRGlobalAppDataCollectionEnabledPlistKey]; + if (plistValue && [plistValue isKindOfClass:[NSNumber class]]) { + collectionEnabledPlistObject = (NSNumber *)plistValue; + } + }); + + return collectionEnabledPlistObject; +} + +#pragma mark - Swift Components. + ++ (void)registerSwiftComponents { + SEL componentsToRegisterSEL = @selector(componentsToRegister); + // Dictionary of class names that conform to `FIRLibrary` and their user agents. These should only + // be SDKs that are written in Swift but still visible to ObjC. + NSDictionary *swiftComponents = @{ + @"FIRSessions" : @"fire-ses", + @"FIRFunctionsComponent" : @"fire-fun", + @"FIRStorageComponent" : @"fire-str", + @"FIRVertexAIComponent" : @"fire-vertex", + }; + for (NSString *className in swiftComponents.allKeys) { + Class klass = NSClassFromString(className); + if (klass && [klass respondsToSelector:componentsToRegisterSEL]) { + [FIRApp registerInternalLibrary:klass withName:swiftComponents[className]]; + } + } + + // Swift libraries that don't need component behaviour + NSDictionary *swiftLibraries = @{ + @"FIRCombineAuthLibrary" : @"comb-auth", + @"FIRCombineFirestoreLibrary" : @"comb-firestore", + @"FIRCombineFunctionsLibrary" : @"comb-functions", + @"FIRCombineStorageLibrary" : @"comb-storage", + }; + for (NSString *className in swiftLibraries.allKeys) { + Class klass = NSClassFromString(className); + if (klass) { + [FIRApp registerLibrary:swiftLibraries[className] withVersion:FIRFirebaseVersion()]; + } + } +} + +#pragma mark - App Life Cycle + +- (void)subscribeForAppDidBecomeActiveNotifications { +#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION + NSNotificationName notificationName = UIApplicationDidBecomeActiveNotification; +#elif TARGET_OS_OSX + NSNotificationName notificationName = NSApplicationDidBecomeActiveNotification; +#elif TARGET_OS_WATCH + // TODO(ncooke3): Remove when minimum supported watchOS version is watchOS 7.0. + // On watchOS 7.0+, heartbeats are logged when the watch app becomes active. + // On watchOS 6.0, heartbeats are logged when the Firebase app is configuring. + // While it does not cover all use cases, logging when the Firebase app is + // configuring is done because watchOS lifecycle notifications are a + // watchOS 7.0+ feature. + NSNotificationName notificationName = kFIRAppReadyToConfigureSDKNotification; + if (@available(watchOS 7.0, *)) { + notificationName = WKApplicationDidBecomeActiveNotification; + } +#endif + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(appDidBecomeActive:) + name:notificationName + object:nil]; +} + +- (void)appDidBecomeActive:(NSNotification *)notification { + if ([self isDataCollectionDefaultEnabled]) { + // If changing the below line, consult with the Games team to ensure they + // are not negatively impacted. For more details, see + // go/firebase-game-sdk-user-agent-register-timing. + [self.heartbeatLogger log]; + } +} + +#if DEBUG ++ (void)findMisnamedGoogleServiceInfoPlist { + for (NSBundle *bundle in [NSBundle allBundles]) { + // Not recursive, but we're looking for misnames, not people accidentally + // hiding their config file in a subdirectory of their bundle. + NSArray *plistPaths = [bundle pathsForResourcesOfType:@"plist" inDirectory:nil]; + for (NSString *path in plistPaths) { + @autoreleasepool { + NSDictionary *contents = [NSDictionary dictionaryWithContentsOfFile:path]; + if (contents == nil) { + continue; + } + + NSString *projectID = contents[@"PROJECT_ID"]; + if (projectID != nil) { + [NSException raise:kFirebaseCoreErrorDomain + format:@"`FirebaseApp.configure()` could not find the default " + @"configuration plist in your project, but did find one at " + @"%@. Please rename this file to GoogleService-Info.plist to " + @"use it as the default configuration.", + path]; + } + } + } + } +} +#endif // DEBUG + +@end diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/FIRBundleUtil.h b/Pods/FirebaseCore/FirebaseCore/Sources/FIRBundleUtil.h new file mode 100644 index 0000000..d9475dd --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/FIRBundleUtil.h @@ -0,0 +1,53 @@ +/* + * 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 + +/** + * This class provides utilities for accessing resources in bundles. + */ +@interface FIRBundleUtil : NSObject + +/** + * Finds all relevant bundles, starting with [NSBundle mainBundle]. + */ ++ (NSArray *)relevantBundles; + +/** + * Reads the options dictionary from one of the provided bundles. + * + * @param resourceName The resource name, e.g. @"GoogleService-Info". + * @param fileType The file type (extension), e.g. @"plist". + * @param bundles The bundles to expect, in priority order. See also + * +[FIRBundleUtil relevantBundles]. + */ ++ (NSString *)optionsDictionaryPathWithResourceName:(NSString *)resourceName + andFileType:(NSString *)fileType + inBundles:(NSArray *)bundles; + +/** + * Finds URL schemes defined in all relevant bundles, starting with those from + * [NSBundle mainBundle]. + */ ++ (NSArray *)relevantURLSchemes; + +/** + * Checks if any of the given bundles have a matching bundle identifier prefix (removing extension + * suffixes). + */ ++ (BOOL)hasBundleIdentifierPrefix:(NSString *)bundleIdentifier inBundles:(NSArray *)bundles; + +@end diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/FIRBundleUtil.m b/Pods/FirebaseCore/FirebaseCore/Sources/FIRBundleUtil.m new file mode 100644 index 0000000..de2c295 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/FIRBundleUtil.m @@ -0,0 +1,79 @@ +// 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 "FirebaseCore/Sources/FIRBundleUtil.h" + +#import + +@implementation FIRBundleUtil + ++ (NSArray *)relevantBundles { + return @[ [NSBundle mainBundle], [NSBundle bundleForClass:[self class]] ]; +} + ++ (NSString *)optionsDictionaryPathWithResourceName:(NSString *)resourceName + andFileType:(NSString *)fileType + inBundles:(NSArray *)bundles { + // Loop through all bundles to find the config dict. + for (NSBundle *bundle in bundles) { + NSString *path = [bundle pathForResource:resourceName ofType:fileType]; + // Use the first one we find. + if (path) { + return path; + } + } + return nil; +} + ++ (NSArray *)relevantURLSchemes { + NSMutableArray *result = [[NSMutableArray alloc] init]; + for (NSBundle *bundle in [[self class] relevantBundles]) { + NSArray *urlTypes = [bundle objectForInfoDictionaryKey:@"CFBundleURLTypes"]; + for (NSDictionary *urlType in urlTypes) { + [result addObjectsFromArray:urlType[@"CFBundleURLSchemes"]]; + } + } + return result; +} + ++ (BOOL)hasBundleIdentifierPrefix:(NSString *)bundleIdentifier inBundles:(NSArray *)bundles { + for (NSBundle *bundle in bundles) { + if ([bundle.bundleIdentifier isEqualToString:bundleIdentifier]) { + return YES; + } + + if ([GULAppEnvironmentUtil isAppExtension]) { + // A developer could be using the same `FIROptions` for both their app and extension. Since + // extensions have a suffix added to the bundleID, we consider a matching prefix as valid. + NSString *appBundleIDFromExtension = + [self bundleIdentifierByRemovingLastPartFrom:bundle.bundleIdentifier]; + if ([appBundleIDFromExtension isEqualToString:bundleIdentifier]) { + return YES; + } + } + } + return NO; +} + ++ (NSString *)bundleIdentifierByRemovingLastPartFrom:(NSString *)bundleIdentifier { + NSString *bundleIDComponentsSeparator = @"."; + + NSMutableArray *bundleIDComponents = + [[bundleIdentifier componentsSeparatedByString:bundleIDComponentsSeparator] mutableCopy]; + [bundleIDComponents removeLastObject]; + + return [bundleIDComponents componentsJoinedByString:bundleIDComponentsSeparator]; +} + +@end diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponent.m b/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponent.m new file mode 100644 index 0000000..d64d296 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponent.m @@ -0,0 +1,65 @@ +/* + * 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 "FirebaseCore/Extension/FIRComponent.h" + +#import "FirebaseCore/Extension/FIRComponentContainer.h" +#import "FirebaseCore/Extension/FIRDependency.h" + +@interface FIRComponent () + +- (instancetype)initWithProtocol:(Protocol *)protocol + instantiationTiming:(FIRInstantiationTiming)instantiationTiming + dependencies:(NSArray *)dependencies + creationBlock:(FIRComponentCreationBlock)creationBlock; + +@end + +@implementation FIRComponent + ++ (instancetype)componentWithProtocol:(Protocol *)protocol + creationBlock:(FIRComponentCreationBlock)creationBlock { + return [[FIRComponent alloc] initWithProtocol:protocol + instantiationTiming:FIRInstantiationTimingLazy + dependencies:@[] + creationBlock:creationBlock]; +} + ++ (instancetype)componentWithProtocol:(Protocol *)protocol + instantiationTiming:(FIRInstantiationTiming)instantiationTiming + dependencies:(NSArray *)dependencies + creationBlock:(FIRComponentCreationBlock)creationBlock { + return [[FIRComponent alloc] initWithProtocol:protocol + instantiationTiming:instantiationTiming + dependencies:dependencies + creationBlock:creationBlock]; +} + +- (instancetype)initWithProtocol:(Protocol *)protocol + instantiationTiming:(FIRInstantiationTiming)instantiationTiming + dependencies:(NSArray *)dependencies + creationBlock:(FIRComponentCreationBlock)creationBlock { + self = [super init]; + if (self) { + _protocol = protocol; + _instantiationTiming = instantiationTiming; + _dependencies = [dependencies copy]; + _creationBlock = creationBlock; + } + return self; +} + +@end diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponentContainer.m b/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponentContainer.m new file mode 100644 index 0000000..d830ab9 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponentContainer.m @@ -0,0 +1,251 @@ +/* + * 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 "FirebaseCore/Extension/FIRComponentContainer.h" + +#import "FirebaseCore/Extension/FIRAppInternal.h" +#import "FirebaseCore/Extension/FIRComponent.h" +#import "FirebaseCore/Extension/FIRLibrary.h" +#import "FirebaseCore/Extension/FIRLogger.h" +#import "FirebaseCore/Extension/FIROptionsInternal.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRComponentContainer () + +/// The dictionary of components that are registered for a particular app. The key is an `NSString` +/// of the protocol. +@property(nonatomic, strong) NSMutableDictionary *components; + +/// Cached instances of components that requested to be cached. +@property(nonatomic, strong) NSMutableDictionary *cachedInstances; + +/// Protocols of components that have requested to be eagerly instantiated. +@property(nonatomic, strong, nullable) NSMutableArray *eagerProtocolsToInstantiate; + +@end + +@implementation FIRComponentContainer + +// Collection of all classes that register to provide components. +static NSMutableSet *sFIRComponentRegistrants; + +#pragma mark - Public Registration + ++ (void)registerAsComponentRegistrant:(Class)klass { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sFIRComponentRegistrants = [[NSMutableSet alloc] init]; + }); + + [self registerAsComponentRegistrant:klass inSet:sFIRComponentRegistrants]; +} + ++ (void)registerAsComponentRegistrant:(Class)klass + inSet:(NSMutableSet *)allRegistrants { + [allRegistrants addObject:klass]; +} + +#pragma mark - Internal Initialization + +- (instancetype)initWithApp:(FIRApp *)app { + NSMutableSet *componentRegistrants = sFIRComponentRegistrants; + // If the app being created is for the ARCore SDK, remove the App Check + // component (if it exists) since it does not support App Check. + if ([self isAppForARCore:app]) { + Class klass = NSClassFromString(@"FIRAppCheckComponent"); + if (klass && [sFIRComponentRegistrants containsObject:klass]) { + componentRegistrants = [componentRegistrants mutableCopy]; + [componentRegistrants removeObject:klass]; + } + } + + return [self initWithApp:app registrants:componentRegistrants]; +} + +- (instancetype)initWithApp:(FIRApp *)app registrants:(NSMutableSet *)allRegistrants { + self = [super init]; + if (self) { + _app = app; + _cachedInstances = [NSMutableDictionary dictionary]; + _components = [NSMutableDictionary dictionary]; + + [self populateComponentsFromRegisteredClasses:allRegistrants forApp:app]; + } + return self; +} + +- (void)populateComponentsFromRegisteredClasses:(NSSet *)classes forApp:(FIRApp *)app { + // Keep track of any components that need to eagerly instantiate after all components are added. + self.eagerProtocolsToInstantiate = [[NSMutableArray alloc] init]; + + // Loop through the verified component registrants and populate the components array. + for (Class klass in classes) { + // Loop through all the components being registered and store them as appropriate. + // Classes which do not provide functionality should use a dummy FIRComponentRegistrant + // protocol. + for (FIRComponent *component in [klass componentsToRegister]) { + // Check if the component has been registered before, and error out if so. + NSString *protocolName = NSStringFromProtocol(component.protocol); + if (self.components[protocolName]) { + FIRLogError(kFIRLoggerCore, @"I-COR000029", + @"Attempted to register protocol %@, but it already has an implementation.", + protocolName); + continue; + } + + // Store the creation block for later usage. + self.components[protocolName] = component.creationBlock; + + // Queue any protocols that should be eagerly instantiated. Don't instantiate them yet + // because they could depend on other components that haven't been added to the components + // array yet. + BOOL shouldInstantiateEager = + (component.instantiationTiming == FIRInstantiationTimingAlwaysEager); + BOOL shouldInstantiateDefaultEager = + (component.instantiationTiming == FIRInstantiationTimingEagerInDefaultApp && + [app isDefaultApp]); + if (shouldInstantiateEager || shouldInstantiateDefaultEager) { + [self.eagerProtocolsToInstantiate addObject:component.protocol]; + } + } + } +} + +#pragma mark - Instance Creation + +- (void)instantiateEagerComponents { + // After all components are registered, instantiate the ones that are requesting eager + // instantiation. + @synchronized(self) { + for (Protocol *protocol in self.eagerProtocolsToInstantiate) { + // Get an instance for the protocol, which will instantiate it since it couldn't have been + // cached yet. Ignore the instance coming back since we don't need it. + __unused id unusedInstance = [self instanceForProtocol:protocol]; + } + + // All eager instantiation is complete, clear the stored property now. + self.eagerProtocolsToInstantiate = nil; + } +} + +/// Instantiate an instance of a class that conforms to the specified protocol. +/// This will: +/// - Call the block to create an instance if possible, +/// - Validate that the instance returned conforms to the protocol it claims to, +/// - Cache the instance if the block requests it +/// +/// Note that this method assumes the caller already has @sychronized on self. +- (nullable id)instantiateInstanceForProtocol:(Protocol *)protocol + withBlock:(FIRComponentCreationBlock)creationBlock { + if (!creationBlock) { + return nil; + } + + // Create an instance using the creation block. + BOOL shouldCache = NO; + id instance = creationBlock(self, &shouldCache); + if (!instance) { + return nil; + } + + // An instance was created, validate that it conforms to the protocol it claims to. + NSString *protocolName = NSStringFromProtocol(protocol); + if (![instance conformsToProtocol:protocol]) { + FIRLogError(kFIRLoggerCore, @"I-COR000030", + @"An instance conforming to %@ was requested, but the instance provided does not " + @"conform to the protocol", + protocolName); + } + + // The instance is ready to be returned, but check if it should be cached first before returning. + if (shouldCache) { + self.cachedInstances[protocolName] = instance; + } + + return instance; +} + +#pragma mark - Internal Retrieval + +// Redirected for Swift users. +- (nullable id)__instanceForProtocol:(Protocol *)protocol { + return [self instanceForProtocol:protocol]; +} + +- (nullable id)instanceForProtocol:(Protocol *)protocol { + // Check if there is a cached instance, and return it if so. + NSString *protocolName = NSStringFromProtocol(protocol); + + id cachedInstance; + @synchronized(self) { + cachedInstance = self.cachedInstances[protocolName]; + if (!cachedInstance) { + // Use the creation block to instantiate an instance and return it. + FIRComponentCreationBlock creationBlock = self.components[protocolName]; + cachedInstance = [self instantiateInstanceForProtocol:protocol withBlock:creationBlock]; + } + } + return cachedInstance; +} + +#pragma mark - Lifecycle + +- (void)removeAllCachedInstances { + @synchronized(self) { + // Loop through the cache and notify each instance that is a maintainer to clean up after + // itself. + for (id instance in self.cachedInstances.allValues) { + if ([instance conformsToProtocol:@protocol(FIRComponentLifecycleMaintainer)] && + [instance respondsToSelector:@selector(appWillBeDeleted:)]) { + [instance appWillBeDeleted:self.app]; + } + } + + // Empty the cache. + [self.cachedInstances removeAllObjects]; + } +} + +- (void)removeAllComponents { + @synchronized(self) { + [self.components removeAllObjects]; + } +} + +#pragma mark - Helpers + +- (BOOL)isAppForARCore:(FIRApp *)app { + // First, check if the app name matches that of the one used by ARCore. + if ([app.name isEqualToString:@"ARCoreFIRApp"]) { + // Second, check if the app's gcmSenderID matches that of ARCore. This + // prevents false positives in the unlikely event a 3P Firebase app is + // named `ARCoreFIRApp`. + const char *p1 = "406756"; + const char *p2 = "893798"; + const char gcmSenderIDKey[27] = {p1[0], p2[0], p1[1], p2[1], p1[2], p2[2], p1[3], + p2[3], p1[4], p2[4], p1[5], p2[5], p1[6], p2[6], + p1[7], p2[7], p1[8], p2[8], p1[9], p2[9], p1[10], + p2[10], p1[11], p2[11], p1[12], p2[12], '\0'}; + NSString *gcmSenderID = [NSString stringWithUTF8String:gcmSenderIDKey]; + return [app.options.GCMSenderID isEqualToString:gcmSenderID]; + } + return NO; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponentContainerInternal.h b/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponentContainerInternal.h new file mode 100644 index 0000000..169e181 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponentContainerInternal.h @@ -0,0 +1,50 @@ +/* + * 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 + +#import "FirebaseCore/Extension/FIRComponentContainer.h" +#import "FirebaseCore/Extension/FIRLibrary.h" + +@class FIRApp; + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRComponentContainer (Private) + +/// Initializes a container for a given app. This should only be called by the app itself. +- (instancetype)initWithApp:(FIRApp *)app; + +/// Retrieves an instance that conforms to the specified protocol. This will return `nil` if the +/// protocol wasn't registered, or if the instance couldn't be instantiated for the provided app. +- (nullable id)instanceForProtocol:(Protocol *)protocol + NS_SWIFT_UNAVAILABLE("Use `instance(for:)` from the FirebaseCoreExtension module instead."); + +/// Instantiates all the components that have registered as "eager" after initialization. +- (void)instantiateEagerComponents; + +/// Remove all of the cached instances stored and allow them to clean up after themselves. +- (void)removeAllCachedInstances; + +/// Removes all the components. After calling this method no new instances will be created. +- (void)removeAllComponents; + +/// Register a class to provide components for the interoperability system. The class should conform +/// to `FIRComponentRegistrant` and provide an array of `FIRComponent` objects. ++ (void)registerAsComponentRegistrant:(Class)klass; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponentType.m b/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponentType.m new file mode 100644 index 0000000..2204fd6 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/FIRComponentType.m @@ -0,0 +1,29 @@ +/* + * 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 "FirebaseCore/Extension/FIRComponentType.h" + +#import "FirebaseCore/Sources/FIRComponentContainerInternal.h" + +@implementation FIRComponentType + ++ (nullable id)instanceForProtocol:(Protocol *)protocol + inContainer:(FIRComponentContainer *)container { + // Forward the call to the container. + return [container instanceForProtocol:protocol]; +} + +@end diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/FIRConfiguration.m b/Pods/FirebaseCore/FirebaseCore/Sources/FIRConfiguration.m new file mode 100644 index 0000000..83b3248 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/FIRConfiguration.m @@ -0,0 +1,46 @@ +// 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 "FirebaseCore/Sources/FIRConfigurationInternal.h" + +#import "FirebaseCore/Sources/FIRAnalyticsConfiguration.h" + +extern void FIRSetLoggerLevel(FIRLoggerLevel loggerLevel); + +@implementation FIRConfiguration + ++ (instancetype)sharedInstance { + static FIRConfiguration *sharedInstance = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedInstance = [[FIRConfiguration alloc] init]; + }); + return sharedInstance; +} + +- (instancetype)init { + self = [super init]; + if (self) { + _analyticsConfiguration = [FIRAnalyticsConfiguration sharedInstance]; + } + return self; +} + +- (void)setLoggerLevel:(FIRLoggerLevel)loggerLevel { + NSAssert(loggerLevel <= FIRLoggerLevelMax && loggerLevel >= FIRLoggerLevelMin, + @"Invalid logger level, %ld", (long)loggerLevel); + FIRSetLoggerLevel(loggerLevel); +} + +@end diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/FIRConfigurationInternal.h b/Pods/FirebaseCore/FirebaseCore/Sources/FIRConfigurationInternal.h new file mode 100644 index 0000000..9361e73 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/FIRConfigurationInternal.h @@ -0,0 +1,29 @@ +/* + * 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 "FirebaseCore/Sources/Public/FirebaseCore/FIRConfiguration.h" + +@class FIRAnalyticsConfiguration; + +@interface FIRConfiguration () + +/** + * The configuration class for Firebase Analytics. This should be removed once the logic for + * enabling and disabling Analytics is moved to Analytics. + */ +@property(nonatomic, readwrite) FIRAnalyticsConfiguration *analyticsConfiguration; + +@end diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/FIRDependency.m b/Pods/FirebaseCore/FirebaseCore/Sources/FIRDependency.m new file mode 100644 index 0000000..5c5bf7c --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/FIRDependency.m @@ -0,0 +1,44 @@ +/* + * 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 "FirebaseCore/Extension/FIRDependency.h" + +@interface FIRDependency () + +- (instancetype)initWithProtocol:(Protocol *)protocol isRequired:(BOOL)required; + +@end + +@implementation FIRDependency + ++ (instancetype)dependencyWithProtocol:(Protocol *)protocol { + return [[self alloc] initWithProtocol:protocol isRequired:YES]; +} + ++ (instancetype)dependencyWithProtocol:(Protocol *)protocol isRequired:(BOOL)required { + return [[self alloc] initWithProtocol:protocol isRequired:required]; +} + +- (instancetype)initWithProtocol:(Protocol *)protocol isRequired:(BOOL)required { + self = [super init]; + if (self) { + _protocol = protocol; + _isRequired = required; + } + return self; +} + +@end diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/FIRFirebaseUserAgent.h b/Pods/FirebaseCore/FirebaseCore/Sources/FIRFirebaseUserAgent.h new file mode 100644 index 0000000..ffb11fb --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/FIRFirebaseUserAgent.h @@ -0,0 +1,36 @@ +/* + * 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 + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRFirebaseUserAgent : NSObject + +/** Returns the firebase user agent which consists of environment part and the components added via + * `setValue:forComponent` method. */ +- (NSString *)firebaseUserAgent; + +/** Sets value associated with the specified component. If value is `nil` then the component is + * removed. */ +- (void)setValue:(nullable NSString *)value forComponent:(NSString *)componentName; + +/** Resets manually added components. */ +- (void)reset; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/FIRFirebaseUserAgent.m b/Pods/FirebaseCore/FirebaseCore/Sources/FIRFirebaseUserAgent.m new file mode 100644 index 0000000..04e7566 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/FIRFirebaseUserAgent.m @@ -0,0 +1,107 @@ +/* + * 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 "FirebaseCore/Sources/FIRFirebaseUserAgent.h" + +#import + +@interface FIRFirebaseUserAgent () + +@property(nonatomic, readonly) NSMutableDictionary *valuesByComponent; +@property(nonatomic, readonly) NSDictionary *environmentComponents; +@property(nonatomic, readonly) NSString *firebaseUserAgent; + +@end + +@implementation FIRFirebaseUserAgent + +@synthesize firebaseUserAgent = _firebaseUserAgent; +@synthesize environmentComponents = _environmentComponents; + +- (instancetype)init { + self = [super init]; + if (self) { + _valuesByComponent = [[NSMutableDictionary alloc] init]; + } + return self; +} + +- (NSString *)firebaseUserAgent { + @synchronized(self) { + if (_firebaseUserAgent == nil) { + NSMutableDictionary *allComponents = + [self.valuesByComponent mutableCopy]; + [allComponents setValuesForKeysWithDictionary:self.environmentComponents]; + + __block NSMutableArray *components = + [[NSMutableArray alloc] initWithCapacity:self.valuesByComponent.count]; + [allComponents enumerateKeysAndObjectsUsingBlock:^( + NSString *_Nonnull name, NSString *_Nonnull value, BOOL *_Nonnull stop) { + [components addObject:[NSString stringWithFormat:@"%@/%@", name, value]]; + }]; + [components sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; + _firebaseUserAgent = [components componentsJoinedByString:@" "]; + } + return _firebaseUserAgent; + } +} + +- (void)setValue:(nullable NSString *)value forComponent:(NSString *)componentName { + @synchronized(self) { + self.valuesByComponent[componentName] = value; + // Reset cached user agent string. + _firebaseUserAgent = nil; + } +} + +- (void)reset { + @synchronized(self) { + // Reset components. + _valuesByComponent = [[[self class] environmentComponents] mutableCopy]; + // Reset cached user agent string. + _firebaseUserAgent = nil; + } +} + +#pragma mark - Environment components + +- (NSDictionary *)environmentComponents { + if (_environmentComponents == nil) { + _environmentComponents = [[self class] environmentComponents]; + } + return _environmentComponents; +} + ++ (NSDictionary *)environmentComponents { + NSMutableDictionary *components = [NSMutableDictionary dictionary]; + + NSDictionary *info = [[NSBundle mainBundle] infoDictionary]; + NSString *xcodeVersion = info[@"DTXcodeBuild"]; + NSString *appleSdkVersion = info[@"DTSDKBuild"]; + NSString *isFromAppstoreFlagValue = [GULAppEnvironmentUtil isFromAppStore] ? @"true" : @"false"; + + components[@"apple-platform"] = [GULAppEnvironmentUtil applePlatform]; + components[@"apple-sdk"] = appleSdkVersion; + components[@"appstore"] = isFromAppstoreFlagValue; + components[@"deploy"] = [GULAppEnvironmentUtil deploymentType]; + components[@"device"] = [GULAppEnvironmentUtil deviceModel]; + components[@"os-version"] = [GULAppEnvironmentUtil systemVersion]; + components[@"xcode"] = xcodeVersion; + + return [components copy]; +} + +@end diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/FIRHeartbeatLogger.m b/Pods/FirebaseCore/FirebaseCore/Sources/FIRHeartbeatLogger.m new file mode 100644 index 0000000..5b0c309 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/FIRHeartbeatLogger.m @@ -0,0 +1,93 @@ +// Copyright 2021 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 + +#ifndef FIREBASE_BUILD_CMAKE +@import FirebaseCoreInternal; +#endif // FIREBASE_BUILD_CMAKE + +#import "FirebaseCore/Extension/FIRAppInternal.h" +#import "FirebaseCore/Extension/FIRHeartbeatLogger.h" + +#ifndef FIREBASE_BUILD_CMAKE +NSString *_Nullable FIRHeaderValueFromHeartbeatsPayload(FIRHeartbeatsPayload *heartbeatsPayload) { + if ([heartbeatsPayload isEmpty]) { + return nil; + } + + return [heartbeatsPayload headerValue]; +} +#endif // FIREBASE_BUILD_CMAKE + +@interface FIRHeartbeatLogger () +#ifndef FIREBASE_BUILD_CMAKE +@property(nonatomic, readonly) FIRHeartbeatController *heartbeatController; +#endif // FIREBASE_BUILD_CMAKE +@property(copy, readonly) NSString * (^userAgentProvider)(void); +@end + +@implementation FIRHeartbeatLogger + +- (instancetype)initWithAppID:(NSString *)appID { + return [self initWithAppID:appID userAgentProvider:[[self class] currentUserAgentProvider]]; +} + +- (instancetype)initWithAppID:(NSString *)appID + userAgentProvider:(NSString * (^)(void))userAgentProvider { + self = [super init]; + if (self) { +#ifndef FIREBASE_BUILD_CMAKE + _heartbeatController = [[FIRHeartbeatController alloc] initWithId:[appID copy]]; +#endif // FIREBASE_BUILD_CMAKE + _userAgentProvider = [userAgentProvider copy]; + } + return self; +} + ++ (NSString * (^)(void))currentUserAgentProvider { + return ^NSString * { + return [FIRApp firebaseUserAgent]; + }; +} + +- (void)log { + NSString *userAgent = _userAgentProvider(); +#ifndef FIREBASE_BUILD_CMAKE + [_heartbeatController log:userAgent]; +#endif // FIREBASE_BUILD_CMAKE +} + +#ifndef FIREBASE_BUILD_CMAKE +- (FIRHeartbeatsPayload *)flushHeartbeatsIntoPayload { + FIRHeartbeatsPayload *payload = [_heartbeatController flush]; + return payload; +} +#endif // FIREBASE_BUILD_CMAKE + +- (FIRDailyHeartbeatCode)heartbeatCodeForToday { +#ifndef FIREBASE_BUILD_CMAKE + FIRHeartbeatsPayload *todaysHeartbeatPayload = [_heartbeatController flushHeartbeatFromToday]; + + if ([todaysHeartbeatPayload isEmpty]) { + return FIRDailyHeartbeatCodeNone; + } else { + return FIRDailyHeartbeatCodeSome; + } +#else + return FIRDailyHeartbeatCodeNone; +#endif // FIREBASE_BUILD_CMAKE +} + +@end diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/FIRLogger.m b/Pods/FirebaseCore/FirebaseCore/Sources/FIRLogger.m new file mode 100644 index 0000000..b9aa3d9 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/FIRLogger.m @@ -0,0 +1,185 @@ +// 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 "FirebaseCore/Extension/FIRLogger.h" + +#import +#import +#import "FirebaseCore/Sources/Public/FirebaseCore/FIRLoggerLevel.h" + +#import "FirebaseCore/Sources/Public/FirebaseCore/FIRVersion.h" + +FIRLoggerService kFIRLoggerCore = @"[FirebaseCore]"; + +// All the FIRLoggerService definitions should be migrated to clients. Do not add new ones! +FIRLoggerService kFIRLoggerAnalytics = @"[FirebaseAnalytics]"; +FIRLoggerService kFIRLoggerCrash = @"[FirebaseCrash]"; +FIRLoggerService kFIRLoggerRemoteConfig = @"[FirebaseRemoteConfig]"; + +/// Arguments passed on launch. +NSString *const kFIRDisableDebugModeApplicationArgument = @"-FIRDebugDisabled"; +NSString *const kFIREnableDebugModeApplicationArgument = @"-FIRDebugEnabled"; +NSString *const kFIRLoggerForceSDTERRApplicationArgument = @"-FIRLoggerForceSTDERR"; + +/// Key for the debug mode bit in NSUserDefaults. +NSString *const kFIRPersistedDebugModeKey = @"/google/firebase/debug_mode"; + +/// NSUserDefaults that should be used to store and read variables. If nil, `standardUserDefaults` +/// will be used. +static NSUserDefaults *sFIRLoggerUserDefaults; + +static dispatch_once_t sFIRLoggerOnceToken; + +// The sFIRAnalyticsDebugMode flag is here to support the -FIRDebugEnabled/-FIRDebugDisabled +// flags used by Analytics. Users who use those flags expect Analytics to log verbosely, +// while the rest of Firebase logs at the default level. This flag is introduced to support +// that behavior. +static BOOL sFIRAnalyticsDebugMode; + +#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 FIRLoggerInitializeASL(void) { + dispatch_once(&sFIRLoggerOnceToken, ^{ + // Register Firebase Version with GULLogger. + GULLoggerRegisterVersion(FIRFirebaseVersion()); + + // Override the aslOptions to ASL_OPT_STDERR if the override argument is passed in. + NSArray *arguments = [NSProcessInfo processInfo].arguments; + BOOL overrideSTDERR = [arguments containsObject:kFIRLoggerForceSDTERRApplicationArgument]; + + // Use the standard NSUserDefaults if it hasn't been explicitly set. + if (sFIRLoggerUserDefaults == nil) { + sFIRLoggerUserDefaults = [NSUserDefaults standardUserDefaults]; + } + + BOOL forceDebugMode = NO; + BOOL debugMode = [sFIRLoggerUserDefaults boolForKey:kFIRPersistedDebugModeKey]; + if ([arguments containsObject:kFIRDisableDebugModeApplicationArgument]) { // Default mode + [sFIRLoggerUserDefaults removeObjectForKey:kFIRPersistedDebugModeKey]; + } else if ([arguments containsObject:kFIREnableDebugModeApplicationArgument] || + debugMode) { // Debug mode + [sFIRLoggerUserDefaults setBool:YES forKey:kFIRPersistedDebugModeKey]; + forceDebugMode = YES; + } + GULLoggerInitializeASL(); + if (overrideSTDERR) { + GULLoggerEnableSTDERR(); + } + if (forceDebugMode) { + GULLoggerForceDebug(); + } + }); +} + +__attribute__((no_sanitize("thread"))) void FIRSetAnalyticsDebugMode(BOOL analyticsDebugMode) { + sFIRAnalyticsDebugMode = analyticsDebugMode; +} + +FIRLoggerLevel FIRGetLoggerLevel(void) { + return (FIRLoggerLevel)GULGetLoggerLevel(); +} + +void FIRSetLoggerLevel(FIRLoggerLevel loggerLevel) { + FIRLoggerInitializeASL(); + GULSetLoggerLevel((GULLoggerLevel)loggerLevel); +} + +#ifdef DEBUG +void FIRResetLogger(void) { + extern void GULResetLogger(void); + sFIRLoggerOnceToken = 0; + [sFIRLoggerUserDefaults removeObjectForKey:kFIRPersistedDebugModeKey]; + sFIRLoggerUserDefaults = nil; + GULResetLogger(); +} + +void FIRSetLoggerUserDefaults(NSUserDefaults *defaults) { + sFIRLoggerUserDefaults = defaults; +} +#endif + +/** + * Check if the level is high enough to be loggable. + * + * Analytics can override the log level with an intentional race condition. + * Add the attribute to get a clean thread sanitizer run. + */ +__attribute__((no_sanitize("thread"))) BOOL FIRIsLoggableLevel(FIRLoggerLevel loggerLevel, + BOOL analyticsComponent) { + FIRLoggerInitializeASL(); + if (sFIRAnalyticsDebugMode && analyticsComponent) { + return YES; + } + return GULIsLoggableLevel((GULLoggerLevel)loggerLevel); +} + +void FIRLogBasic(FIRLoggerLevel level, + FIRLoggerService service, + NSString *messageCode, + NSString *message, + va_list args_ptr) { + FIRLoggerInitializeASL(); + GULLogBasic((GULLoggerLevel)level, service, + sFIRAnalyticsDebugMode && [kFIRLoggerAnalytics isEqualToString:service], messageCode, + message, args_ptr); +} + +/** + * Generates the logging functions using macros. + * + * Calling FIRLogError(kFIRLoggerCore, @"I-COR000001", @"Configure %@ failed.", @"blah") shows: + * yyyy-mm-dd hh:mm:ss.SSS sender[PID] [Firebase/Core][I-COR000001] Configure blah failed. + * Calling FIRLogDebug(kFIRLoggerCore, @"I-COR000001", @"Configure succeed.") shows: + * yyyy-mm-dd hh:mm:ss.SSS sender[PID] [Firebase/Core][I-COR000001] Configure succeed. + */ +#define FIR_LOGGING_FUNCTION(level) \ + void FIRLog##level(FIRLoggerService service, NSString *messageCode, NSString *message, ...) { \ + va_list args_ptr; \ + va_start(args_ptr, message); \ + FIRLogBasic(FIRLoggerLevel##level, service, messageCode, message, args_ptr); \ + va_end(args_ptr); \ + } + +FIR_LOGGING_FUNCTION(Error) +FIR_LOGGING_FUNCTION(Warning) +FIR_LOGGING_FUNCTION(Notice) +FIR_LOGGING_FUNCTION(Info) +FIR_LOGGING_FUNCTION(Debug) + +#undef FIR_MAKE_LOGGER + +#pragma mark - FIRLoggerWrapper + +@implementation FIRLoggerWrapper + ++ (void)logWithLevel:(FIRLoggerLevel)level + withService:(FIRLoggerService)service + withCode:(NSString *)messageCode + withMessage:(NSString *)message + withArgs:(va_list)args { + FIRLogBasic(level, service, messageCode, message, args); +} + ++ (void)logWithLevel:(FIRLoggerLevel)level + service:(FIRLoggerService)service + code:(NSString *)code + message:(NSString *)message { + FIRLogBasic(level, service, code, message, NULL); +} + +@end diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/FIROptions.m b/Pods/FirebaseCore/FirebaseCore/Sources/FIROptions.m new file mode 100644 index 0000000..c0625a8 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/FIROptions.m @@ -0,0 +1,487 @@ +// 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 "FirebaseCore/Extension/FIRAppInternal.h" +#import "FirebaseCore/Extension/FIRLogger.h" +#import "FirebaseCore/Extension/FIROptionsInternal.h" +#import "FirebaseCore/Sources/FIRBundleUtil.h" +#import "FirebaseCore/Sources/Public/FirebaseCore/FIRVersion.h" + +// Keys for the strings in the plist file. +NSString *const kFIRAPIKey = @"API_KEY"; +NSString *const kFIRTrackingID = @"TRACKING_ID"; +NSString *const kFIRGoogleAppID = @"GOOGLE_APP_ID"; +NSString *const kFIRClientID = @"CLIENT_ID"; +NSString *const kFIRGCMSenderID = @"GCM_SENDER_ID"; +NSString *const kFIRAndroidClientID = @"ANDROID_CLIENT_ID"; +NSString *const kFIRDatabaseURL = @"DATABASE_URL"; +NSString *const kFIRStorageBucket = @"STORAGE_BUCKET"; +// The key to locate the expected bundle identifier in the plist file. +NSString *const kFIRBundleID = @"BUNDLE_ID"; +// The key to locate the project identifier in the plist file. +NSString *const kFIRProjectID = @"PROJECT_ID"; + +NSString *const kFIRIsMeasurementEnabled = @"IS_MEASUREMENT_ENABLED"; +NSString *const kFIRIsAnalyticsCollectionEnabled = @"FIREBASE_ANALYTICS_COLLECTION_ENABLED"; +NSString *const kFIRIsAnalyticsCollectionDeactivated = @"FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED"; + +// Library version ID formatted like: +// @"5" // Major version (one or more digits) +// @"04" // Minor version (exactly 2 digits) +// @"01" // Build number (exactly 2 digits) +// @"000"; // Fixed "000" +NSString *kFIRLibraryVersionID; + +// Plist file name. +NSString *const kServiceInfoFileName = @"GoogleService-Info"; +// Plist file type. +NSString *const kServiceInfoFileType = @"plist"; + +// Exception raised from attempting to modify a FIROptions after it's been copied to a FIRApp. +NSString *const kFIRExceptionBadModification = + @"Attempted to modify options after it's set on FIRApp. Please modify all properties before " + @"initializing FIRApp."; + +@interface FIROptions () + +/** + * This property maintains the actual configuration key-value pairs. + */ +@property(nonatomic, readwrite) NSMutableDictionary *optionsDictionary; + +/** + * Calls `analyticsOptionsDictionaryWithInfoDictionary:` using [NSBundle mainBundle].infoDictionary. + * It combines analytics options from both the infoDictionary and the GoogleService-Info.plist. + * Values which are present in the main plist override values from the GoogleService-Info.plist. + */ +@property(nonatomic, readonly) NSDictionary *analyticsOptionsDictionary; + +/** + * Combination of analytics options from both the infoDictionary and the GoogleService-Info.plist. + * Values which are present in the infoDictionary override values from the GoogleService-Info.plist. + */ +- (NSDictionary *)analyticsOptionsDictionaryWithInfoDictionary:(NSDictionary *)infoDictionary; + +/** + * Throw exception if editing is locked when attempting to modify an option. + */ +- (void)checkEditingLocked; + +@end + +@implementation FIROptions { + /// Backing variable for self.analyticsOptionsDictionary. + NSDictionary *_analyticsOptionsDictionary; +} + +static FIROptions *sDefaultOptions = nil; +static NSDictionary *sDefaultOptionsDictionary = nil; +static dispatch_once_t sDefaultOptionsOnceToken; +static dispatch_once_t sDefaultOptionsDictionaryOnceToken; + +#pragma mark - Public only for internal class methods + ++ (FIROptions *)defaultOptions { + dispatch_once(&sDefaultOptionsOnceToken, ^{ + NSDictionary *defaultOptionsDictionary = [self defaultOptionsDictionary]; + if (defaultOptionsDictionary != nil) { + sDefaultOptions = + [[FIROptions alloc] initInternalWithOptionsDictionary:defaultOptionsDictionary]; + } + }); + + return sDefaultOptions; +} + +#pragma mark - Private class methods + ++ (NSDictionary *)defaultOptionsDictionary { + dispatch_once(&sDefaultOptionsDictionaryOnceToken, ^{ + NSString *plistFilePath = [FIROptions plistFilePathWithName:kServiceInfoFileName]; + if (plistFilePath == nil) { + return; + } + sDefaultOptionsDictionary = [NSDictionary dictionaryWithContentsOfFile:plistFilePath]; + if (sDefaultOptionsDictionary == nil) { + FIRLogError(kFIRLoggerCore, @"I-COR000011", + @"The configuration file is not a dictionary: " + @"'%@.%@'.", + kServiceInfoFileName, kServiceInfoFileType); + } + }); + + return sDefaultOptionsDictionary; +} + +// Returns the path of the plist file with a given file name. ++ (NSString *)plistFilePathWithName:(NSString *)fileName { + NSArray *bundles = [FIRBundleUtil relevantBundles]; + NSString *plistFilePath = + [FIRBundleUtil optionsDictionaryPathWithResourceName:fileName + andFileType:kServiceInfoFileType + inBundles:bundles]; + if (plistFilePath == nil) { + FIRLogError(kFIRLoggerCore, @"I-COR000012", @"Could not locate configuration file: '%@.%@'.", + fileName, kServiceInfoFileType); + } + return plistFilePath; +} + ++ (void)resetDefaultOptions { + sDefaultOptions = nil; + sDefaultOptionsDictionary = nil; + sDefaultOptionsOnceToken = 0; + sDefaultOptionsDictionaryOnceToken = 0; +} + +#pragma mark - Private instance methods + +- (instancetype)initInternalWithOptionsDictionary:(NSDictionary *)optionsDictionary { + self = [super init]; + if (self) { + _optionsDictionary = [optionsDictionary mutableCopy]; + _usingOptionsFromDefaultPlist = YES; + } + return self; +} + +- (id)copyWithZone:(NSZone *)zone { + FIROptions *newOptions = [(FIROptions *)[[self class] allocWithZone:zone] + initInternalWithOptionsDictionary:self.optionsDictionary]; + if (newOptions) { + newOptions.deepLinkURLScheme = self.deepLinkURLScheme; + newOptions.appGroupID = self.appGroupID; + newOptions.editingLocked = self.isEditingLocked; + newOptions.usingOptionsFromDefaultPlist = self.usingOptionsFromDefaultPlist; + } + return newOptions; +} + +#pragma mark - Public instance methods + +- (instancetype)init { + // Unavailable. + [self doesNotRecognizeSelector:_cmd]; + return nil; +} + +- (instancetype)initWithContentsOfFile:(NSString *)plistPath { + self = [super init]; + if (self) { + if (plistPath == nil) { + FIRLogError(kFIRLoggerCore, @"I-COR000013", @"The plist file path is nil."); + return nil; + } + _optionsDictionary = [[NSDictionary dictionaryWithContentsOfFile:plistPath] mutableCopy]; + if (_optionsDictionary == nil) { + FIRLogError(kFIRLoggerCore, @"I-COR000014", + @"The configuration file at %@ does not exist or " + @"is not a well-formed plist file.", + plistPath); + return nil; + } + // TODO: Do we want to validate the dictionary here? It says we do that already in + // the public header. + } + return self; +} + +- (instancetype)initWithGoogleAppID:(NSString *)googleAppID GCMSenderID:(NSString *)GCMSenderID { + self = [super init]; + if (self) { + NSMutableDictionary *mutableOptionsDict = [NSMutableDictionary dictionary]; + [mutableOptionsDict setValue:googleAppID forKey:kFIRGoogleAppID]; + [mutableOptionsDict setValue:GCMSenderID forKey:kFIRGCMSenderID]; + [mutableOptionsDict setValue:[[NSBundle mainBundle] bundleIdentifier] forKey:kFIRBundleID]; + self.optionsDictionary = mutableOptionsDict; + } + return self; +} + +- (NSString *)APIKey { + return self.optionsDictionary[kFIRAPIKey]; +} + +- (void)checkEditingLocked { + if (self.isEditingLocked) { + [NSException raise:kFirebaseCoreErrorDomain format:kFIRExceptionBadModification]; + } +} + +- (void)setAPIKey:(NSString *)APIKey { + [self checkEditingLocked]; + _optionsDictionary[kFIRAPIKey] = [APIKey copy]; +} + +- (NSString *)clientID { + return self.optionsDictionary[kFIRClientID]; +} + +- (void)setClientID:(NSString *)clientID { + [self checkEditingLocked]; + _optionsDictionary[kFIRClientID] = [clientID copy]; +} + +- (NSString *)trackingID { + return self.optionsDictionary[kFIRTrackingID]; +} + +- (void)setTrackingID:(NSString *)trackingID { + [self checkEditingLocked]; + _optionsDictionary[kFIRTrackingID] = [trackingID copy]; +} + +- (NSString *)GCMSenderID { + return self.optionsDictionary[kFIRGCMSenderID]; +} + +- (void)setGCMSenderID:(NSString *)GCMSenderID { + [self checkEditingLocked]; + _optionsDictionary[kFIRGCMSenderID] = [GCMSenderID copy]; +} + +- (NSString *)projectID { + return self.optionsDictionary[kFIRProjectID]; +} + +- (void)setProjectID:(NSString *)projectID { + [self checkEditingLocked]; + _optionsDictionary[kFIRProjectID] = [projectID copy]; +} + +- (NSString *)androidClientID { + return self.optionsDictionary[kFIRAndroidClientID]; +} + +- (void)setAndroidClientID:(NSString *)androidClientID { + [self checkEditingLocked]; + _optionsDictionary[kFIRAndroidClientID] = [androidClientID copy]; +} + +- (NSString *)googleAppID { + return self.optionsDictionary[kFIRGoogleAppID]; +} + +- (void)setGoogleAppID:(NSString *)googleAppID { + [self checkEditingLocked]; + _optionsDictionary[kFIRGoogleAppID] = [googleAppID copy]; +} + +- (NSString *)libraryVersionID { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // The unit tests are set up to catch anything that does not properly convert. + NSString *version = FIRFirebaseVersion(); + NSArray *components = [version componentsSeparatedByString:@"."]; + NSString *major = [NSString stringWithFormat:@"%02d", [[components objectAtIndex:0] intValue]]; + NSString *minor = [NSString stringWithFormat:@"%02d", [[components objectAtIndex:1] intValue]]; + NSString *patch = [NSString stringWithFormat:@"%02d", [[components objectAtIndex:2] intValue]]; + kFIRLibraryVersionID = [NSString stringWithFormat:@"%@%@%@000", major, minor, patch]; + }); + return kFIRLibraryVersionID; +} + +- (void)setLibraryVersionID:(NSString *)libraryVersionID { + _optionsDictionary[kFIRLibraryVersionID] = [libraryVersionID copy]; +} + +- (NSString *)databaseURL { + return self.optionsDictionary[kFIRDatabaseURL]; +} + +- (void)setDatabaseURL:(NSString *)databaseURL { + [self checkEditingLocked]; + + _optionsDictionary[kFIRDatabaseURL] = [databaseURL copy]; +} + +- (NSString *)storageBucket { + return self.optionsDictionary[kFIRStorageBucket]; +} + +- (void)setStorageBucket:(NSString *)storageBucket { + [self checkEditingLocked]; + _optionsDictionary[kFIRStorageBucket] = [storageBucket copy]; +} + +- (void)setDeepLinkURLScheme:(NSString *)deepLinkURLScheme { + [self checkEditingLocked]; + _deepLinkURLScheme = [deepLinkURLScheme copy]; +} + +- (NSString *)bundleID { + return self.optionsDictionary[kFIRBundleID]; +} + +- (void)setBundleID:(NSString *)bundleID { + [self checkEditingLocked]; + _optionsDictionary[kFIRBundleID] = [bundleID copy]; +} + +- (void)setAppGroupID:(NSString *)appGroupID { + [self checkEditingLocked]; + _appGroupID = [appGroupID copy]; +} + +#pragma mark - Equality + +- (BOOL)isEqual:(id)object { + if (!object || ![object isKindOfClass:[FIROptions class]]) { + return NO; + } + + return [self isEqualToOptions:(FIROptions *)object]; +} + +- (BOOL)isEqualToOptions:(FIROptions *)options { + // Skip any non-FIROptions classes. + if (![options isKindOfClass:[FIROptions class]]) { + return NO; + } + + // Check the internal dictionary and custom properties for differences. + if (![options.optionsDictionary isEqualToDictionary:self.optionsDictionary]) { + return NO; + } + + // Validate extra properties not contained in the dictionary. Only validate it if one of the + // objects has the property set. + if ((options.deepLinkURLScheme != nil || self.deepLinkURLScheme != nil) && + ![options.deepLinkURLScheme isEqualToString:self.deepLinkURLScheme]) { + return NO; + } + + if ((options.appGroupID != nil || self.appGroupID != nil) && + ![options.appGroupID isEqualToString:self.appGroupID]) { + return NO; + } + + // Validate the Analytics options haven't changed with the Info.plist. + if (![options.analyticsOptionsDictionary isEqualToDictionary:self.analyticsOptionsDictionary]) { + return NO; + } + + // We don't care about the `editingLocked` or `usingOptionsFromDefaultPlist` properties since + // those relate to lifecycle and construction, we only care if the contents of the options + // themselves are equal. + return YES; +} + +- (NSUInteger)hash { + // This is strongly recommended for any object that implements a custom `isEqual:` method to + // ensure that dictionary and set behavior matches other `isEqual:` checks. + // Note: `self.analyticsOptionsDictionary` was left out here since it solely relies on the + // contents of the main bundle's `Info.plist`. We should avoid reading that file and the contents + // should be identical. + return self.optionsDictionary.hash ^ self.deepLinkURLScheme.hash ^ self.appGroupID.hash; +} + +#pragma mark - Internal instance methods + +- (NSDictionary *)analyticsOptionsDictionaryWithInfoDictionary:(NSDictionary *)infoDictionary { + if (_analyticsOptionsDictionary == nil) { + NSMutableDictionary *tempAnalyticsOptions = [[NSMutableDictionary alloc] init]; + NSArray *measurementKeys = @[ + kFIRIsMeasurementEnabled, kFIRIsAnalyticsCollectionEnabled, + kFIRIsAnalyticsCollectionDeactivated + ]; + for (NSString *key in measurementKeys) { + id value = infoDictionary[key] ?: self.optionsDictionary[key] ?: nil; + if (!value) { + continue; + } + tempAnalyticsOptions[key] = value; + } + _analyticsOptionsDictionary = tempAnalyticsOptions; + } + return _analyticsOptionsDictionary; +} + +- (NSDictionary *)analyticsOptionsDictionary { + return [self analyticsOptionsDictionaryWithInfoDictionary:[NSBundle mainBundle].infoDictionary]; +} + +/** + * Whether or not Measurement was enabled. Measurement is enabled unless explicitly disabled in + * GoogleService-Info.plist. This uses the old plist flag IS_MEASUREMENT_ENABLED, which should still + * be supported. + */ +- (BOOL)isMeasurementEnabled { + if (self.isAnalyticsCollectionDeactivated) { + return NO; + } + NSNumber *value = self.analyticsOptionsDictionary[kFIRIsMeasurementEnabled]; + if (value == nil) { + // TODO: This could probably be cleaned up since FIROptions shouldn't know about FIRApp or have + // to check if it's the default app. The FIROptions instance can't be modified after + // `+configure` is called, so it's not a good place to copy it either in case the flag is + // changed at runtime. + + // If no values are set for Analytics, fall back to the global collection switch in FIRApp. + // Analytics only supports the default FIRApp, so check that first. + if (![FIRApp isDefaultAppConfigured]) { + return NO; + } + + // Fall back to the default app's collection switch when the key is not in the dictionary. + return [FIRApp defaultApp].isDataCollectionDefaultEnabled; + } + return [value boolValue]; +} + +- (BOOL)isAnalyticsCollectionExplicitlySet { + // If it's de-activated, it classifies as explicity set. If not, it's not a good enough indication + // that the developer wants FirebaseAnalytics enabled so continue checking. + if (self.isAnalyticsCollectionDeactivated) { + return YES; + } + + // Check if the current Analytics flag is set. + id collectionEnabledObject = self.analyticsOptionsDictionary[kFIRIsAnalyticsCollectionEnabled]; + if (collectionEnabledObject && [collectionEnabledObject isKindOfClass:[NSNumber class]]) { + // It doesn't matter what the value is, it's explicitly set. + return YES; + } + + // Check if the old measurement flag is set. + id measurementEnabledObject = self.analyticsOptionsDictionary[kFIRIsMeasurementEnabled]; + if (measurementEnabledObject && [measurementEnabledObject isKindOfClass:[NSNumber class]]) { + // It doesn't matter what the value is, it's explicitly set. + return YES; + } + + // No flags are set to explicitly enable or disable FirebaseAnalytics. + return NO; +} + +- (BOOL)isAnalyticsCollectionEnabled { + if (self.isAnalyticsCollectionDeactivated) { + return NO; + } + NSNumber *value = self.analyticsOptionsDictionary[kFIRIsAnalyticsCollectionEnabled]; + if (value == nil) { + return self.isMeasurementEnabled; // Fall back to older plist flag. + } + return [value boolValue]; +} + +- (BOOL)isAnalyticsCollectionDeactivated { + NSNumber *value = self.analyticsOptionsDictionary[kFIRIsAnalyticsCollectionDeactivated]; + if (value == nil) { + return NO; // Analytics Collection is not deactivated when the key is not in the dictionary. + } + return [value boolValue]; +} + +@end diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/FIRVersion.m b/Pods/FirebaseCore/FirebaseCore/Sources/FIRVersion.m new file mode 100644 index 0000000..f458a3a --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/FIRVersion.m @@ -0,0 +1,32 @@ +/* + * 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 "FirebaseCore/Sources/Public/FirebaseCore/FIRVersion.h" + +#ifndef Firebase_VERSION +#error "Firebase_VERSION is not defined: add -DFirebase_VERSION=... to the build invocation" +#endif + +// The following two macros supply the incantation so that the C +// preprocessor does not try to parse the version as a floating +// point number. See +// https://www.guyrutenberg.com/2008/12/20/expanding-macros-into-string-constants-in-c/ +#define STR(x) STR_EXPAND(x) +#define STR_EXPAND(x) #x + +NSString* FIRFirebaseVersion(void) { + return @STR(Firebase_VERSION); +} diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FIRApp.h b/Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FIRApp.h new file mode 100644 index 0000000..58ef2a6 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FIRApp.h @@ -0,0 +1,129 @@ +/* + * 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 + +@class FIROptions; + +NS_ASSUME_NONNULL_BEGIN + +/** A block that takes a BOOL and has no return value. */ +typedef void (^FIRAppVoidBoolCallback)(BOOL success) + NS_SWIFT_UNAVAILABLE("Use Swift's closure syntax instead."); + +/** + * The entry point of Firebase SDKs. + * + * Initialize and configure `FirebaseApp` using `FirebaseApp.configure()` + * or other customized ways as shown below. + * + * The logging system has two modes: default mode and debug mode. In default mode, only logs with + * log level Notice, Warning and Error will be sent to device. In debug mode, all logs will be sent + * to device. The log levels that Firebase uses are consistent with the ASL log levels. + * + * Enable debug mode by passing the `-FIRDebugEnabled` argument to the application. You can add this + * argument in the application's Xcode scheme. When debug mode is enabled via `-FIRDebugEnabled`, + * further executions of the application will also be in debug mode. In order to return to default + * mode, you must explicitly disable the debug mode with the application argument + * `-FIRDebugDisabled`. + * + * It is also possible to change the default logging level in code by calling + * `FirebaseConfiguration.shared.setLoggerLevel(_:)` with the desired level. + */ +NS_SWIFT_NAME(FirebaseApp) +@interface FIRApp : NSObject + +/** + * Configures a default Firebase app. Raises an exception if any configuration step fails. The + * default app is named "__FIRAPP_DEFAULT". This method should be called after the app is launched + * and before using Firebase services. This method should be called from the main thread and + * contains synchronous file I/O (reading GoogleService-Info.plist from disk). + */ ++ (void)configure; + +/** + * Configures the default Firebase app with the provided options. The default app is named + * "__FIRAPP_DEFAULT". Raises an exception if any configuration step fails. This method should be + * called from the main thread. + * + * @param options The Firebase application options used to configure the service. + */ ++ (void)configureWithOptions:(FIROptions *)options NS_SWIFT_NAME(configure(options:)); + +/** + * Configures a Firebase app with the given name and options. Raises an exception if any + * configuration step fails. This method should be called from the main thread. + * + * @param name The application's name given by the developer. The name should should only contain + Letters, Numbers and Underscore. + * @param options The Firebase application options used to configure the services. + */ +// clang-format off ++ (void)configureWithName:(NSString *)name + options:(FIROptions *)options NS_SWIFT_NAME(configure(name:options:)); +// clang-format on + +/** + * Returns the default app, or `nil` if the default app does not exist. + */ ++ (nullable FIRApp *)defaultApp NS_SWIFT_NAME(app()); + +/** + * Returns a previously created `FirebaseApp` instance with the given name, or `nil` if no such app + * exists. This method is thread safe. + */ ++ (nullable FIRApp *)appNamed:(NSString *)name NS_SWIFT_NAME(app(name:)); + +/** + * Returns the set of all extant `FirebaseApp` instances, or `nil` if there are no `FirebaseApp` + * instances. This method is thread safe. + */ +@property(class, readonly, nullable) NSDictionary *allApps; + +/** + * Cleans up the current `FirebaseApp`, freeing associated data and returning its name to the pool + * for future use. This method is thread safe. + */ +- (void)deleteApp:(void (^)(BOOL success))completion; + +/** + * `FirebaseApp` instances should not be initialized directly. Call `FirebaseApp.configure()`, + * `FirebaseApp.configure(options:)`, or `FirebaseApp.configure(name:options:)` directly. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Gets the name of this app. + */ +@property(nonatomic, copy, readonly) NSString *name; + +/** + * Gets a copy of the options for this app. These are non-modifiable. + */ +@property(nonatomic, copy, readonly) FIROptions *options; + +/** + * Gets or sets whether automatic data collection is enabled for all products. Defaults to `true` + * unless `FirebaseDataCollectionDefaultEnabled` is set to `NO` in your app's Info.plist. This value + * is persisted across runs of the app so that it can be set once when users have consented to + * collection. + */ +@property(nonatomic, readwrite, getter=isDataCollectionDefaultEnabled) + BOOL dataCollectionDefaultEnabled; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FIRConfiguration.h b/Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FIRConfiguration.h new file mode 100644 index 0000000..408bcad --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FIRConfiguration.h @@ -0,0 +1,45 @@ +/* + * 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 + +#import "FIRLoggerLevel.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * This interface provides global level properties that the developer can tweak. + */ +NS_SWIFT_NAME(FirebaseConfiguration) +@interface FIRConfiguration : NSObject + +/** Returns the shared configuration object. */ +@property(class, nonatomic, readonly) FIRConfiguration *sharedInstance NS_SWIFT_NAME(shared); + +/** + * Sets the logging level for internal Firebase logging. Firebase will only log messages + * that are logged at or below `loggerLevel`. The messages are logged both to the Xcode + * console and to the device's log. Note that if an app is running from AppStore, it will + * never log above `.notice` even if `loggerLevel` is set to a higher (more verbose) + * setting. + * + * @param loggerLevel The maximum logging level. The default level is set to FIRLoggerLevelNotice. + */ +- (void)setLoggerLevel:(FIRLoggerLevel)loggerLevel; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FIRLoggerLevel.h b/Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FIRLoggerLevel.h new file mode 100644 index 0000000..dca3aa0 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FIRLoggerLevel.h @@ -0,0 +1,38 @@ +/* + * 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. + */ + +// Note that importing GULLoggerLevel.h will lead to a non-modular header +// import error. + +/** + * The log levels used by internal logging. + */ +typedef NS_ENUM(NSInteger, FIRLoggerLevel) { + /** Error level, matches ASL_LEVEL_ERR. */ + FIRLoggerLevelError = 3, + /** Warning level, matches ASL_LEVEL_WARNING. */ + FIRLoggerLevelWarning = 4, + /** Notice level, matches ASL_LEVEL_NOTICE. */ + FIRLoggerLevelNotice = 5, + /** Info level, matches ASL_LEVEL_INFO. */ + FIRLoggerLevelInfo = 6, + /** Debug level, matches ASL_LEVEL_DEBUG. */ + FIRLoggerLevelDebug = 7, + /** Minimum log level. */ + FIRLoggerLevelMin = FIRLoggerLevelError, + /** Maximum log level. */ + FIRLoggerLevelMax = FIRLoggerLevelDebug +} NS_SWIFT_NAME(FirebaseLoggerLevel); diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FIROptions.h b/Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FIROptions.h new file mode 100644 index 0000000..8f8d945 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FIROptions.h @@ -0,0 +1,131 @@ +/* + * 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 + +NS_ASSUME_NONNULL_BEGIN + +/** + * This class provides constant fields of Google APIs. + */ +NS_SWIFT_NAME(FirebaseOptions) +@interface FIROptions : NSObject + +/** + * Returns the default options. The first time this is called it synchronously reads + * GoogleService-Info.plist from disk. + */ ++ (nullable FIROptions *)defaultOptions NS_SWIFT_NAME(defaultOptions()); + +/** + * An API key used for authenticating requests from your Apple app, e.g. + * The key must begin with "A" and contain exactly 39 alphanumeric characters, used to identify your + * app to Google servers. + */ +@property(nonatomic, copy, nullable) NSString *APIKey NS_SWIFT_NAME(apiKey); + +/** + * The bundle ID for the application. Defaults to `Bundle.main.bundleIdentifier` when not set + * manually or in a plist. + */ +@property(nonatomic, copy) NSString *bundleID; + +/** + * The OAuth2 client ID for Apple applications used to authenticate Google users, for example + * @"12345.apps.googleusercontent.com", used for signing in with Google. + */ +@property(nonatomic, copy, nullable) NSString *clientID; + +/** + * Unused. + */ +@property(nonatomic, copy, nullable) NSString *trackingID DEPRECATED_ATTRIBUTE; + +/** + * The Project Number from the Google Developer's console, for example @"012345678901", used to + * configure Firebase Cloud Messaging. + */ +@property(nonatomic, copy) NSString *GCMSenderID NS_SWIFT_NAME(gcmSenderID); + +/** + * The Project ID from the Firebase console, for example @"abc-xyz-123". + */ +@property(nonatomic, copy, nullable) NSString *projectID; + +/** + * Unused. + */ +@property(nonatomic, copy, nullable) NSString *androidClientID DEPRECATED_ATTRIBUTE; + +/** + * The Google App ID that is used to uniquely identify an instance of an app. + */ +@property(nonatomic, copy) NSString *googleAppID; + +/** + * The database root URL, e.g. @"http://abc-xyz-123.firebaseio.com". + */ +@property(nonatomic, copy, nullable) NSString *databaseURL; + +/** + * The URL scheme used to set up Durable Deep Link service. + */ +@property(nonatomic, copy, nullable) NSString *deepLinkURLScheme; + +/** + * The Google Cloud Storage bucket name, e.g. @"abc-xyz-123.storage.firebase.com". + */ +@property(nonatomic, copy, nullable) NSString *storageBucket; + +/** + * The App Group identifier to share data between the application and the application extensions. + * The App Group must be configured in the application and on the Apple Developer Portal. Default + * value `nil`. + */ +@property(nonatomic, copy, nullable) NSString *appGroupID; + +/** + * Initializes a customized instance of FirebaseOptions from the file at the given plist file path. + * This will read the file synchronously from disk. + * For example: + * ```swift + * if let path = Bundle.main.path(forResource:"GoogleServices-Info", ofType:"plist") { + * let options = FirebaseOptions(contentsOfFile: path) + * } + * ``` + * Note that it is not possible to customize `FirebaseOptions` for Firebase Analytics which expects + * a static file named `GoogleServices-Info.plist` - + * https://github.com/firebase/firebase-ios-sdk/issues/230. + * Returns `nil` if the plist file does not exist or is invalid. + */ +- (nullable instancetype)initWithContentsOfFile:(NSString *)plistPath NS_DESIGNATED_INITIALIZER; + +/** + * Initializes a customized instance of `FirebaseOptions` with required fields. Use the mutable + * properties to modify fields for configuring specific services. Note that it is not possible to + * customize `FirebaseOptions` for Firebase Analytics which expects a static file named + * `GoogleServices-Info.plist` - https://github.com/firebase/firebase-ios-sdk/issues/230. + */ +- (instancetype)initWithGoogleAppID:(NSString *)googleAppID + GCMSenderID:(NSString *)GCMSenderID + NS_SWIFT_NAME(init(googleAppID:gcmSenderID:))NS_DESIGNATED_INITIALIZER; + +/** Unavailable. Please use `init(contentsOfFile:)` or `init(googleAppID:gcmSenderID:)` instead. */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FIRVersion.h b/Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FIRVersion.h new file mode 100644 index 0000000..651edaf --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FIRVersion.h @@ -0,0 +1,25 @@ +/* + * 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 + +NS_ASSUME_NONNULL_BEGIN + +/** Returns the current version of Firebase. */ +NS_SWIFT_NAME(FirebaseVersion()) +NSString* FIRFirebaseVersion(void); + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FirebaseCore.h b/Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FirebaseCore.h new file mode 100644 index 0000000..680d604 --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/Public/FirebaseCore/FirebaseCore.h @@ -0,0 +1,21 @@ +/* + * 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 "FIRApp.h" +#import "FIRConfiguration.h" +#import "FIRLoggerLevel.h" +#import "FIROptions.h" +#import "FIRVersion.h" diff --git a/Pods/FirebaseCore/FirebaseCore/Sources/Resources/PrivacyInfo.xcprivacy b/Pods/FirebaseCore/FirebaseCore/Sources/Resources/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..0244f2f --- /dev/null +++ b/Pods/FirebaseCore/FirebaseCore/Sources/Resources/PrivacyInfo.xcprivacy @@ -0,0 +1,26 @@ + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + + NSPrivacyCollectedDataTypes + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPITypeReasons + + CA92.1 + + + + + + diff --git a/Pods/FirebaseCore/LICENSE b/Pods/FirebaseCore/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/Pods/FirebaseCore/LICENSE @@ -0,0 +1,202 @@ + + 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. diff --git a/Pods/FirebaseCore/README.md b/Pods/FirebaseCore/README.md new file mode 100644 index 0000000..4c915ab --- /dev/null +++ b/Pods/FirebaseCore/README.md @@ -0,0 +1,297 @@ +

+ + + + + + + + +
+ + + + + + +

+ +# Firebase Apple Open Source Development + +This repository contains the source code for all Apple platform Firebase SDKs except FirebaseAnalytics. + +Firebase is an app development platform with tools to help you build, grow, and +monetize your app. More information about Firebase can be found on the +[official Firebase website](https://firebase.google.com). + +## Installation + +See the subsections below for details about the different installation methods. Where +available, it's recommended to install any libraries with a `Swift` suffix to get the +best experience when writing your app in Swift. + +1. [Standard pod install](#standard-pod-install) +2. [Swift Package Manager](#swift-package-manager) +3. [Installing from the GitHub repo](#installing-from-github) +4. [Experimental Carthage](#carthage-ios-only) + +### Standard pod install + +For instructions on the standard pod install, visit: +[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup). + +### Swift Package Manager + +Instructions for [Swift Package Manager](https://swift.org/package-manager/) support can be +found in the [SwiftPackageManager.md](SwiftPackageManager.md) Markdown file. + +### Installing from GitHub + +These instructions can be used to access the Firebase repo at other branches, +tags, or commits. + +#### Background + +See [the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod) +for instructions and options about overriding pod source locations. + +#### Accessing Firebase Source Snapshots + +All official releases are tagged in this repo and available via CocoaPods. To access a local +source snapshot or unreleased branch, use Podfile directives like the following: + +To access FirebaseFirestore via a branch: +```ruby +pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'main' +pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'main' +``` + +To access FirebaseMessaging via a checked-out version of the firebase-ios-sdk repo: +```ruby +pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk' +pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk' +``` + +### Carthage (iOS only) + +Instructions for the experimental Carthage distribution can be found at +[Carthage.md](Carthage.md). + +### Using Firebase from a Framework or a library + +For details on using Firebase from a Framework or a library, refer to [firebase_in_libraries.md](docs/firebase_in_libraries.md). + +## Development + +To develop Firebase software in this repository, ensure that you have at least +the following software: + +* Xcode 15.2 (or later) + +CocoaPods is still the canonical way to develop, but much of the repo now supports +development with Swift Package Manager. + +### CocoaPods + +Install the following: +* CocoaPods 1.12.0 (or later) +* [CocoaPods generate](https://github.com/square/cocoapods-generate) + +For the pod that you want to develop: + +```ruby +pod gen Firebase{name here}.podspec --local-sources=./ --auto-open --platforms=ios +``` + +Note: If the CocoaPods cache is out of date, you may need to run +`pod repo update` before the `pod gen` command. + +Note: Set the `--platforms` option to `macos` or `tvos` to develop/test for +those platforms. Since 10.2, Xcode does not properly handle multi-platform +CocoaPods workspaces. + +Firestore has a self-contained Xcode project. See +[Firestore/README](Firestore/README.md) Markdown file. + +#### Development for Catalyst +* `pod gen {name here}.podspec --local-sources=./ --auto-open --platforms=ios` +* Check the Mac box in the App-iOS Build Settings +* Sign the App in the Settings Signing & Capabilities tab +* Click Pods in the Project Manager +* Add Signing to the iOS host app and unit test targets +* Select the Unit-unit scheme +* Run it to build and test + +Alternatively, disable signing in each target: +* Go to Build Settings tab +* Click `+` +* Select `Add User-Defined Setting` +* Add `CODE_SIGNING_REQUIRED` setting with a value of `NO` + +### Swift Package Manager +* To enable test schemes: `./scripts/setup_spm_tests.sh` +* `open Package.swift` or double click `Package.swift` in Finder. +* Xcode will open the project + * Choose a scheme for a library to build or test suite to run + * Choose a target platform by selecting the run destination along with the scheme + +### Adding a New Firebase Pod + +Refer to [AddNewPod](AddNewPod.md) Markdown file for details. + +### Managing Headers and Imports + +For information about managing headers and imports, see [HeadersImports](HeadersImports.md) Markdown file. + +### Code Formatting + +To ensure that the code is formatted consistently, run the script +[./scripts/check.sh](https://github.com/firebase/firebase-ios-sdk/blob/main/scripts/check.sh) +before creating a pull request (PR). + +GitHub Actions will verify that any code changes are done in a style-compliant +way. Install `clang-format` and `mint`: + +```console +brew install clang-format@18 +brew install mint +``` + +### Running Unit Tests + +Select a scheme and press Command-u to build a component and run its unit tests. + +### Running Sample Apps +To run the sample apps and integration tests, you'll need a valid +`GoogleService-Info.plist +` file. The Firebase Xcode project contains dummy plist +files without real values, but they can be replaced with real plist files. To get your own +`GoogleService-Info.plist` files: + +1. Go to the [Firebase Console](https://console.firebase.google.com/) +2. Create a new Firebase project, if you don't already have one +3. For each sample app you want to test, create a new Firebase app with the sample app's bundle +identifier (e.g., `com.google.Database-Example`) +4. Download the resulting `GoogleService-Info.plist` and add it to the Xcode project. + +### Coverage Report Generation + +For coverage report generation instructions, see [scripts/code_coverage_report/README](scripts/code_coverage_report/README.md) Markdown file. + +## Specific Component Instructions +See the sections below for any special instructions for those components. + +### Firebase Auth + +For specific Firebase Auth development, refer to the [Auth Sample README](FirebaseAuth/Tests/Sample/README.md) for instructions about +building and running the FirebaseAuth pod along with various samples and tests. + +### Firebase Database + +The Firebase Database Integration tests can be run against a locally running Database Emulator +or against a production instance. + +To run against a local emulator instance, invoke `./scripts/run_database_emulator.sh start` before +running the integration test. + +To run against a production instance, provide a valid `GoogleServices-Info.plist` and copy it to +`FirebaseDatabase/Tests/Resources/GoogleService-Info.plist`. Your Security Rule must be set to +[public](https://firebase.google.com/docs/database/security/quickstart) while your tests are +running. + +### Firebase Dynamic Links + +Firebase Dynamic Links is **deprecated** and should not be used in new projects. The service will shut down on August 25, 2025. + +Please see our [Dynamic Links Deprecation FAQ documentation](https://firebase.google.com/support/dynamic-links-faq) for more guidance. + +### Firebase Performance Monitoring + +For specific Firebase Performance Monitoring development, see +[the Performance README](FirebasePerformance/README.md) for instructions about building the SDK +and [the Performance TestApp README](FirebasePerformance/Tests/TestApp/README.md) for instructions about +integrating Performance with the dev test App. + +### Firebase Storage + +To run the Storage Integration tests, follow the instructions in +[StorageIntegration.swift](FirebaseStorage/Tests/Integration/StorageIntegration.swift). + +#### Push Notifications + +Push notifications can only be delivered to specially provisioned App IDs in the developer portal. +In order to test receiving push notifications, you will need to: + +1. Change the bundle identifier of the sample app to something you own in your Apple Developer +account and enable that App ID for push notifications. +2. You'll also need to +[upload your APNs Provider Authentication Key or certificate to the +Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs) +at **Project Settings > Cloud Messaging > [Your Firebase App]**. +3. Ensure your iOS device is added to your Apple Developer portal as a test device. + +#### iOS Simulator + +The iOS Simulator cannot register for remote notifications and will not receive push notifications. +To receive push notifications, follow the steps above and run the app on a physical device. + +## Building with Firebase on Apple platforms + +Firebase provides official beta support for macOS, Catalyst, and tvOS. visionOS and watchOS +are community supported. Thanks to community contributions for many of the multi-platform PRs. + +At this time, most of Firebase's products are available across Apple platforms. There are still +a few gaps, especially on visionOS and watchOS. For details about the current support matrix, see +[this chart](https://firebase.google.com/docs/ios/learn-more#firebase_library_support_by_platform) +in Firebase's documentation. + +### visionOS + +Where supported, visionOS works as expected with the exception of Firestore via Swift Package +Manager where it is required to use the source distribution. + +To enable the Firestore source distribution, quit Xcode and open the desired +project from the command line with the `FIREBASE_SOURCE_FIRESTORE` environment +variable: `open --env FIREBASE_SOURCE_FIRESTORE /path/to/project.xcodeproj`. +To go back to using the binary distribution of Firestore, quit Xcode and open +Xcode like normal, without the environment variable. + +### watchOS +Thanks to contributions from the community, many of Firebase SDKs now compile, run unit tests, and +work on watchOS. See the [Independent Watch App Sample](Example/watchOSSample). + +Keep in mind that watchOS is not officially supported by Firebase. While we can catch basic unit +test issues with GitHub Actions, there may be some changes where the SDK no longer works as expected +on watchOS. If you encounter this, please +[file an issue](https://github.com/firebase/firebase-ios-sdk/issues). + +During app setup in the console, you may get to a step that mentions something like "Checking if the +app has communicated with our servers". This relies on Analytics and will not work on watchOS. +**It's safe to ignore the message and continue**, the rest of the SDKs will work as expected. + +#### Additional Crashlytics Notes +* watchOS has limited support. Due to watchOS restrictions, mach exceptions and signal crashes are +not recorded. (Crashes in SwiftUI are generated as mach exceptions, so will not be recorded) + +## Combine +Thanks to contributions from the community, _FirebaseCombineSwift_ contains support for Apple's Combine +framework. This module is currently under development and not yet supported for use in production +environments. For more details, please refer to the [docs](FirebaseCombineSwift/README.md). + +## Roadmap + +See [Roadmap](ROADMAP.md) for more about the Firebase Apple SDK Open Source +plans and directions. + +## Contributing + +See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase +Apple SDK. + +## License + +The contents of this repository are licensed under the +[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +Your use of Firebase is governed by the +[Terms of Service for Firebase Services](https://firebase.google.com/terms/). diff --git a/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/Heartbeat.swift b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/Heartbeat.swift new file mode 100644 index 0000000..aa265ed --- /dev/null +++ b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/Heartbeat.swift @@ -0,0 +1,76 @@ +// Copyright 2021 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 + +/// An enumeration of time periods. +enum TimePeriod: Int, CaseIterable, Codable { + /// The raw value is the number of calendar days within each time period. + /// More types can be enabled in future iterations (i.e. `weekly = 7, monthly = 28`). + case daily = 1 + + /// The number of seconds in a given time period. + var timeInterval: TimeInterval { + Double(rawValue) * 86400 /* seconds in day */ + } +} + +/// A structure representing SDK usage. +struct Heartbeat: Codable, Equatable { + /// The version of the heartbeat. + private static let version: Int = 0 + + /// An anonymous string of information (i.e. user agent) to associate the heartbeat with. + let agent: String + + /// The date when the heartbeat was recorded. + let date: Date + + /// The heartbeat's model version. + let version: Int + + /// An array of `TimePeriod`s that the heartbeat is tagged with. See `TimePeriod`. + /// + /// Heartbeats represent anonymous data points that measure SDK usage in moving averages for + /// various time periods. Because a single heartbeat can help calculate moving averages for + /// multiple + /// time periods, this property serves to capture all the time periods that the heartbeat can + /// represent in + /// a moving average. + let timePeriods: [TimePeriod] + + /// Designated initializer. + /// - Parameters: + /// - agent: An anonymous string of information to associate the heartbeat with. + /// - date: The date when the heartbeat was recorded. + /// - version: The heartbeat's version. Defaults to the current version. + init(agent: String, + date: Date, + timePeriods: [TimePeriod] = [], + version: Int = version) { + self.agent = agent + self.date = date + self.timePeriods = timePeriods + self.version = version + } +} + +extension Heartbeat: HeartbeatsPayloadConvertible { + func makeHeartbeatsPayload() -> HeartbeatsPayload { + let userAgentPayloads = [ + HeartbeatsPayload.UserAgentPayload(agent: agent, dates: [date]), + ] + return HeartbeatsPayload(userAgentPayloads: userAgentPayloads) + } +} diff --git a/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatController.swift b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatController.swift new file mode 100644 index 0000000..20a021d --- /dev/null +++ b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatController.swift @@ -0,0 +1,148 @@ +// Copyright 2021 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 + +/// An object that provides API to log and flush heartbeats from a synchronized storage container. +public final class HeartbeatController { + /// The thread-safe storage object to log and flush heartbeats from. + private let storage: HeartbeatStorageProtocol + /// The max capacity of heartbeats to store in storage. + private let heartbeatsStorageCapacity: Int = 30 + /// Current date provider. It is used for testability. + private let dateProvider: () -> Date + /// Used for standardizing dates for calendar-day comparision. + static let dateStandardizer: (Date) -> (Date) = { + var calendar = Calendar(identifier: .iso8601) + calendar.locale = Locale(identifier: "en_US_POSIX") + calendar.timeZone = TimeZone(secondsFromGMT: 0)! + return calendar.startOfDay(for:) + }() + + /// Public initializer. + /// - Parameter id: The `id` to associate this controller's heartbeat storage with. + public convenience init(id: String) { + self.init(id: id, dateProvider: Date.init) + } + + /// Convenience initializer. Mirrors the semantics of the public initializer with the added + /// benefit of + /// injecting a custom date provider for improved testability. + /// - Parameters: + /// - id: The id to associate this controller's heartbeat storage with. + /// - dateProvider: A date provider. + convenience init(id: String, dateProvider: @escaping () -> Date) { + let storage = HeartbeatStorage.getInstance(id: id) + self.init(storage: storage, dateProvider: dateProvider) + } + + /// Designated initializer. + /// - Parameters: + /// - storage: A heartbeat storage container. + /// - dateProvider: A date provider. Defaults to providing the current date. + init(storage: HeartbeatStorageProtocol, + dateProvider: @escaping () -> Date = Date.init) { + self.storage = storage + self.dateProvider = { Self.dateStandardizer(dateProvider()) } + } + + /// Asynchronously logs a new heartbeat, if needed. + /// + /// - Note: This API is thread-safe. + /// - Parameter agent: The string agent (i.e. Firebase User Agent) to associate the logged + /// heartbeat with. + public func log(_ agent: String) { + let date = dateProvider() + + storage.readAndWriteAsync { heartbeatsBundle in + var heartbeatsBundle = heartbeatsBundle ?? + HeartbeatsBundle(capacity: self.heartbeatsStorageCapacity) + + // Filter for the time periods where the last heartbeat to be logged for + // that time period was logged more than one time period (i.e. day) ago. + let timePeriods = heartbeatsBundle.lastAddedHeartbeatDates.filter { timePeriod, lastDate in + date.timeIntervalSince(lastDate) >= timePeriod.timeInterval + } + .map { timePeriod, _ in timePeriod } + + if !timePeriods.isEmpty { + // A heartbeat should only be logged if there is a time period(s) to + // associate it with. + let heartbeat = Heartbeat(agent: agent, date: date, timePeriods: timePeriods) + heartbeatsBundle.append(heartbeat) + } + + return heartbeatsBundle + } + } + + /// Synchronously flushes heartbeats from storage into a heartbeats payload. + /// + /// - Note: This API is thread-safe. + /// - Returns: The flushed heartbeats in the form of `HeartbeatsPayload`. + @discardableResult + public func flush() -> HeartbeatsPayload { + let resetTransform = { (heartbeatsBundle: HeartbeatsBundle?) -> HeartbeatsBundle? in + guard let oldHeartbeatsBundle = heartbeatsBundle else { + return nil // Storage was empty. + } + // The new value that's stored will use the old's cache to prevent the + // logging of duplicates after flushing. + return HeartbeatsBundle( + capacity: self.heartbeatsStorageCapacity, + cache: oldHeartbeatsBundle.lastAddedHeartbeatDates + ) + } + + do { + // Synchronously gets and returns the stored heartbeats, resetting storage + // using the given transform. + let heartbeatsBundle = try storage.getAndSet(using: resetTransform) + // If no heartbeats bundle was stored, return an empty payload. + return heartbeatsBundle?.makeHeartbeatsPayload() ?? HeartbeatsPayload.emptyPayload + } catch { + // If the operation throws, assume no heartbeat(s) were retrieved or set. + return HeartbeatsPayload.emptyPayload + } + } + + /// Synchronously flushes the heartbeat for today. + /// + /// If no heartbeat was logged today, the returned payload is empty. + /// + /// - Note: This API is thread-safe. + /// - Returns: A heartbeats payload for the flushed heartbeat. + @discardableResult + public func flushHeartbeatFromToday() -> HeartbeatsPayload { + let todaysDate = dateProvider() + var todaysHeartbeat: Heartbeat? + + storage.readAndWriteSync { heartbeatsBundle in + guard var heartbeatsBundle = heartbeatsBundle else { + return nil // Storage was empty. + } + + todaysHeartbeat = heartbeatsBundle.removeHeartbeat(from: todaysDate) + + return heartbeatsBundle + } + + // Note that `todaysHeartbeat` is updated in the above read/write block. + if todaysHeartbeat != nil { + return todaysHeartbeat!.makeHeartbeatsPayload() + } else { + return HeartbeatsPayload.emptyPayload + } + } +} diff --git a/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatLoggingTestUtils.swift b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatLoggingTestUtils.swift new file mode 100644 index 0000000..96dbcf8 --- /dev/null +++ b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatLoggingTestUtils.swift @@ -0,0 +1,140 @@ +// Copyright 2021 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. + +#if DEBUG + + import Foundation + + /// A utility class intended to be used only in testing contexts. + @objc(FIRHeartbeatLoggingTestUtils) + @objcMembers + public class HeartbeatLoggingTestUtils: NSObject { + /// This should mirror the `Constants` enum in the `HeartbeatLogging` module. + /// See `HeartbeatLogging/Sources/StorageFactory.swift`. + public enum Constants { + /// The name of the file system directory where heartbeat data is stored. + public static let heartbeatFileStorageDirectoryPath = "google-heartbeat-storage" + /// The name of the user defaults suite where heartbeat data is stored. + public static let heartbeatUserDefaultsSuiteName = "com.google.heartbeat.storage" + } + + public static var dateFormatter: DateFormatter { + HeartbeatsPayload.dateFormatter + } + + public static var emptyHeartbeatsPayload: _ObjC_HeartbeatsPayload { + let literalData = """ + { + "version": 2, + "heartbeats": [] + } + """ + .data(using: .utf8)! + + let decoder = JSONDecoder() + decoder.dateDecodingStrategy = .formatted(HeartbeatsPayload.dateFormatter) + + let heartbeatsPayload = try! decoder.decode(HeartbeatsPayload.self, from: literalData) + return _ObjC_HeartbeatsPayload(heartbeatsPayload) + } + + public static var nonEmptyHeartbeatsPayload: _ObjC_HeartbeatsPayload { + let literalData = """ + { + "version": 2, + "heartbeats": [ + { + "agent": "dummy_agent_1", + "dates": ["2021-11-01", "2021-11-02"] + }, + { + "agent": "dummy_agent_2", + "dates": ["2021-11-03"] + } + ] + } + """ + .data(using: .utf8)! + + let decoder = JSONDecoder() + decoder.dateDecodingStrategy = .formatted(HeartbeatsPayload.dateFormatter) + + let heartbeatsPayload = try! decoder.decode(HeartbeatsPayload.self, from: literalData) + return _ObjC_HeartbeatsPayload(heartbeatsPayload) + } + + @objc(assertEncodedPayloadString:isEqualToLiteralString:withError:) + public static func assertEqualPayloadStrings(_ encoded: String, _ literal: String) throws { + var encodedData = Data(base64URLEncoded: encoded)! + if encodedData.count > 0 { + encodedData = try! encodedData.unzipped() + } + + let literalData = literal.data(using: .utf8)! + + let decoder = JSONDecoder() + decoder.dateDecodingStrategy = .formatted(HeartbeatsPayload.dateFormatter) + + let payloadFromEncoded = try? decoder.decode(HeartbeatsPayload.self, from: encodedData) + + let payloadFromLiteral = try? decoder.decode(HeartbeatsPayload.self, from: literalData) + + let encoder = JSONEncoder() + encoder.dateEncodingStrategy = .formatted(HeartbeatsPayload.dateFormatter) + encoder.outputFormatting = .prettyPrinted + + let payloadDataFromEncoded = try! encoder.encode(payloadFromEncoded) + let payloadDataFromLiteral = try! encoder.encode(payloadFromLiteral) + + assert( + payloadFromEncoded == payloadFromLiteral, + """ + Mismatched payloads! + + Payload 1: + \(String(data: payloadDataFromEncoded, encoding: .utf8) ?? "") + + Payload 2: + \(String(data: payloadDataFromLiteral, encoding: .utf8) ?? "") + + """ + ) + } + + /// Removes all underlying storage containers used by the module. + /// - Throws: An error if the storage container could not be removed. + public static func removeUnderlyingHeartbeatStorageContainers() throws { + #if os(tvOS) + UserDefaults().removePersistentDomain(forName: Constants.heartbeatUserDefaultsSuiteName) + #else + + let applicationSupportDirectory = FileManager.default + .urls(for: .applicationSupportDirectory, in: .userDomainMask).first! + + let heartbeatsDirectoryURL = applicationSupportDirectory + .appendingPathComponent( + Constants.heartbeatFileStorageDirectoryPath, isDirectory: true + ) + do { + try FileManager.default.removeItem(at: heartbeatsDirectoryURL) + } catch CocoaError.fileNoSuchFile { + // Do nothing. + } catch { + throw error + } + #endif // os(tvOS) + } + } + +#endif // ENABLE_FIREBASE_CORE_INTERNAL_TESTING_UTILS diff --git a/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatStorage.swift b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatStorage.swift new file mode 100644 index 0000000..d400944 --- /dev/null +++ b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatStorage.swift @@ -0,0 +1,180 @@ +// Copyright 2021 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 + +/// A type that can perform atomic operations using block-based transformations. +protocol HeartbeatStorageProtocol { + func readAndWriteSync(using transform: (HeartbeatsBundle?) -> HeartbeatsBundle?) + func readAndWriteAsync(using transform: @escaping (HeartbeatsBundle?) -> HeartbeatsBundle?) + func getAndSet(using transform: (HeartbeatsBundle?) -> HeartbeatsBundle?) throws + -> HeartbeatsBundle? +} + +/// Thread-safe storage object designed for transforming heartbeat data that is persisted to disk. +final class HeartbeatStorage: HeartbeatStorageProtocol { + /// The identifier used to differentiate instances. + private let id: String + /// The underlying storage container to read from and write to. + private let storage: Storage + /// The encoder used for encoding heartbeat data. + private let encoder: JSONEncoder = .init() + /// The decoder used for decoding heartbeat data. + private let decoder: JSONDecoder = .init() + /// The queue for synchronizing storage operations. + private let queue: DispatchQueue + + /// Designated initializer. + /// - Parameters: + /// - id: A string identifer. + /// - storage: The underlying storage container where heartbeat data is stored. + init(id: String, + storage: Storage) { + self.id = id + self.storage = storage + queue = DispatchQueue(label: "com.heartbeat.storage.\(id)") + } + + // MARK: - Instance Management + + /// Statically allocated cache of `HeartbeatStorage` instances keyed by string IDs. + private static var cachedInstances: [String: WeakContainer] = [:] + + /// Gets an existing `HeartbeatStorage` instance with the given `id` if one exists. Otherwise, + /// makes a new instance with the given `id`. + /// + /// - Parameter id: A string identifier. + /// - Returns: A `HeartbeatStorage` instance. + static func getInstance(id: String) -> HeartbeatStorage { + if let cachedInstance = cachedInstances[id]?.object { + return cachedInstance + } else { + let newInstance = HeartbeatStorage.makeHeartbeatStorage(id: id) + cachedInstances[id] = WeakContainer(object: newInstance) + return newInstance + } + } + + /// Makes a `HeartbeatStorage` instance using a given `String` identifier. + /// + /// The created persistent storage object is platform dependent. For tvOS, user defaults + /// is used as the underlying storage container due to system storage limits. For all other + /// platforms, + /// the file system is used. + /// + /// - Parameter id: A `String` identifier used to create the `HeartbeatStorage`. + /// - Returns: A `HeartbeatStorage` instance. + private static func makeHeartbeatStorage(id: String) -> HeartbeatStorage { + #if os(tvOS) + let storage = UserDefaultsStorage.makeStorage(id: id) + #else + let storage = FileStorage.makeStorage(id: id) + #endif // os(tvOS) + return HeartbeatStorage(id: id, storage: storage) + } + + deinit { + // Removes the instance if it was cached. + Self.cachedInstances.removeValue(forKey: id) + } + + // MARK: - HeartbeatStorageProtocol + + /// Synchronously reads from and writes to storage using the given transform block. + /// - Parameter transform: A block to transform the currently stored heartbeats bundle to a new + /// heartbeats bundle value. + func readAndWriteSync(using transform: (HeartbeatsBundle?) -> HeartbeatsBundle?) { + queue.sync { + let oldHeartbeatsBundle = try? load(from: storage) + let newHeartbeatsBundle = transform(oldHeartbeatsBundle) + try? save(newHeartbeatsBundle, to: storage) + } + } + + /// Asynchronously reads from and writes to storage using the given transform block. + /// - Parameter transform: A block to transform the currently stored heartbeats bundle to a new + /// heartbeats bundle value. + func readAndWriteAsync(using transform: @escaping (HeartbeatsBundle?) -> HeartbeatsBundle?) { + queue.async { [self] in + let oldHeartbeatsBundle = try? load(from: storage) + let newHeartbeatsBundle = transform(oldHeartbeatsBundle) + try? save(newHeartbeatsBundle, to: storage) + } + } + + /// Synchronously gets the current heartbeat data from storage and resets the storage using the + /// given transform block. + /// + /// This API is like any `getAndSet`-style API in that it gets (and returns) the current value and + /// uses + /// a block to transform the current value (or, soon-to-be old value) to a new value. + /// + /// - Parameter transform: An optional block used to reset the currently stored heartbeat. + /// - Returns: The heartbeat data that was stored (before the `transform` was applied). + @discardableResult + func getAndSet(using transform: (HeartbeatsBundle?) -> HeartbeatsBundle?) throws + -> HeartbeatsBundle? { + let heartbeatsBundle: HeartbeatsBundle? = try queue.sync { + let oldHeartbeatsBundle = try? load(from: storage) + let newHeartbeatsBundle = transform(oldHeartbeatsBundle) + try save(newHeartbeatsBundle, to: storage) + return oldHeartbeatsBundle + } + return heartbeatsBundle + } + + /// Loads and decodes the stored heartbeats bundle from a given storage object. + /// - Parameter storage: The storage container to read from. + /// - Returns: The decoded `HeartbeatsBundle` loaded from storage; `nil` if storage is empty. + /// - Throws: An error if storage could not be read or the data could not be decoded. + private func load(from storage: Storage) throws -> HeartbeatsBundle? { + let data = try storage.read() + if data.isEmpty { + return nil + } else { + let heartbeatData = try data.decoded(using: decoder) as HeartbeatsBundle + return heartbeatData + } + } + + /// Saves the encoding of the given value to the given storage container. + /// - Parameters: + /// - heartbeatsBundle: The heartbeats bundle to encode and save. + /// - storage: The storage container to write to. + private func save(_ heartbeatsBundle: HeartbeatsBundle?, to storage: Storage) throws { + if let heartbeatsBundle { + let data = try heartbeatsBundle.encoded(using: encoder) + try storage.write(data) + } else { + try storage.write(nil) + } + } +} + +private extension Data { + /// Returns the decoded value of this `Data` using the given decoder. Defaults to `JSONDecoder`. + /// - Returns: The decoded value. + func decoded(using decoder: JSONDecoder = .init()) throws -> T where T: Decodable { + try decoder.decode(T.self, from: self) + } +} + +private extension Encodable { + /// Returns the `Data` encoding of this value using the given encoder. + /// - Parameter encoder: An encoder used to encode the value. Defaults to `JSONEncoder`. + /// - Returns: The data encoding of the value. + func encoded(using encoder: JSONEncoder = .init()) throws -> Data { + try encoder.encode(self) + } +} diff --git a/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatsBundle.swift b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatsBundle.swift new file mode 100644 index 0000000..776dfb8 --- /dev/null +++ b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatsBundle.swift @@ -0,0 +1,151 @@ +// Copyright 2021 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 + +/// A type that can be converted to a `HeartbeatsPayload`. +protocol HeartbeatsPayloadConvertible { + func makeHeartbeatsPayload() -> HeartbeatsPayload +} + +/// A codable collection of heartbeats that has a fixed capacity and optimizations for storing +/// heartbeats of +/// multiple time periods. +struct HeartbeatsBundle: Codable, HeartbeatsPayloadConvertible { + /// The maximum number of heartbeats that can be stored in the buffer. + let capacity: Int + /// A cache used for keeping track of the last heartbeat date recorded for a given time period. + /// + /// The cache contains the last added date for each time period. The reason only the date is + /// cached is + /// because it's the only piece of information that should be used by clients to determine whether + /// or not + /// to append a new heartbeat. + private(set) var lastAddedHeartbeatDates: [TimePeriod: Date] + /// A ring buffer of heartbeats. + private var buffer: RingBuffer + + /// A default cache provider that provides a dictionary of all time periods mapping to a default + /// date. + static var cacheProvider: () -> [TimePeriod: Date] { + let timePeriodsAndDates = TimePeriod.allCases.map { ($0, Date.distantPast) } + return { Dictionary(uniqueKeysWithValues: timePeriodsAndDates) } + } + + /// Designated initializer. + /// - Parameters: + /// - capacity: The heartbeat capacity of the inititialized collection. + /// - cache: A cache of time periods mapping to dates. Defaults to using static `cacheProvider`. + init(capacity: Int, + cache: [TimePeriod: Date] = cacheProvider()) { + buffer = RingBuffer(capacity: capacity) + self.capacity = capacity + lastAddedHeartbeatDates = cache + } + + /// Appends a heartbeat to this collection. + /// - Parameter heartbeat: The heartbeat to append. + mutating func append(_ heartbeat: Heartbeat) { + guard capacity > 0 else { + return // Do not append if capacity is non-positive. + } + + do { + // Push the heartbeat to the back of the buffer. + if let overwrittenHeartbeat = try buffer.push(heartbeat) { + // If a heartbeat was overwritten, update the cache to ensure it's date + // is removed. + lastAddedHeartbeatDates = lastAddedHeartbeatDates.mapValues { date in + overwrittenHeartbeat.date == date ? .distantPast : date + } + } + + // Update cache with the new heartbeat's date. + for timePeriod in heartbeat.timePeriods { + lastAddedHeartbeatDates[timePeriod] = heartbeat.date + } + + } catch let error as RingBuffer.Error { + // A ring buffer error occurred while pushing to the buffer so the bundle + // is reset. + self = HeartbeatsBundle(capacity: capacity) + + // Create a diagnostic heartbeat to capture the failure and add it to the + // buffer. The failure is added as a key/value pair to the agent string. + // Given that the ring buffer has been reset, it is not expected for the + // second push attempt to fail. + let errorDescription = error.errorDescription.replacingOccurrences(of: " ", with: "-") + let diagnosticHeartbeat = Heartbeat( + agent: "\(heartbeat.agent) error/\(errorDescription)", + date: heartbeat.date, + timePeriods: heartbeat.timePeriods + ) + + let secondPushAttempt = Result { + try buffer.push(diagnosticHeartbeat) + } + + if case .success = secondPushAttempt { + // Update cache with the new heartbeat's date. + for timePeriod in diagnosticHeartbeat.timePeriods { + lastAddedHeartbeatDates[timePeriod] = diagnosticHeartbeat.date + } + } + } catch { + // Ignore other error. + } + } + + /// Removes the heartbeat associated with the given date. + /// - Parameter date: The date of the heartbeat needing removal. + /// - Returns: The heartbeat that was removed or `nil` if there was no heartbeat to remove. + @discardableResult + mutating func removeHeartbeat(from date: Date) -> Heartbeat? { + var removedHeartbeat: Heartbeat? + + var poppedHeartbeats: [Heartbeat] = [] + + while let poppedHeartbeat = buffer.pop() { + if poppedHeartbeat.date == date { + removedHeartbeat = poppedHeartbeat + break + } + poppedHeartbeats.append(poppedHeartbeat) + } + + for poppedHeartbeat in poppedHeartbeats.reversed() { + do { + try buffer.push(poppedHeartbeat) + } catch { + // Ignore error. + } + } + + return removedHeartbeat + } + + /// Makes and returns a `HeartbeatsPayload` from this heartbeats bundle. + /// - Returns: A heartbeats payload. + func makeHeartbeatsPayload() -> HeartbeatsPayload { + let agentAndDates = buffer.map { heartbeat in + (heartbeat.agent, [heartbeat.date]) + } + + let userAgentPayloads = [String: [Date]](agentAndDates, uniquingKeysWith: +) + .map(HeartbeatsPayload.UserAgentPayload.init) + .sorted { $0.agent < $1.agent } // Sort payloads by user agent. + + return HeartbeatsPayload(userAgentPayloads: userAgentPayloads) + } +} diff --git a/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatsPayload.swift b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatsPayload.swift new file mode 100644 index 0000000..34256b8 --- /dev/null +++ b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatsPayload.swift @@ -0,0 +1,185 @@ +// Copyright 2021 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 + +#if SWIFT_PACKAGE + @_implementationOnly import GoogleUtilities_NSData +#else + @_implementationOnly import GoogleUtilities +#endif // SWIFT_PACKAGE + +/// A type that provides a string representation for use in an HTTP header. +public protocol HTTPHeaderRepresentable { + func headerValue() -> String +} + +/// A value type representing a payload of heartbeat data intended for sending in network requests. +/// +/// This type's structure is optimized for type-safe encoding into a HTTP payload format. +/// The current encoding format for the payload's current version is: +/// +/// { +/// "version": 2, +/// "heartbeats": [ +/// { +/// "agent": "dummy_agent_1", +/// "dates": ["2021-11-01", "2021-11-02"] +/// }, +/// { +/// "agent": "dummy_agent_2", +/// "dates": ["2021-11-03"] +/// } +/// ] +/// } +/// +public struct HeartbeatsPayload: Codable { + /// The version of the payload. See go/firebase-apple-heartbeats for details regarding current + /// version. + static let version: Int = 2 + + /// A payload component composed of a user agent and array of dates (heartbeats). + struct UserAgentPayload: Codable { + /// An anonymous agent string. + let agent: String + /// An array of dates where each date represents a "heartbeat". + let dates: [Date] + } + + /// An array of user agent payloads. + let userAgentPayloads: [UserAgentPayload] + /// The version of the payload structure. + let version: Int + + /// Alternative keys for properties so encoding follows platform-wide payload structure. + enum CodingKeys: String, CodingKey { + case userAgentPayloads = "heartbeats" + case version + } + + /// Designated initializer. + /// - Parameters: + /// - userAgentPayloads: An array of payloads containing heartbeat data corresponding to a + /// given user agent. + /// - version: A version of the payload. Defaults to the static default. + init(userAgentPayloads: [UserAgentPayload] = [], version: Int = version) { + self.userAgentPayloads = userAgentPayloads + self.version = version + } + + /// A Boolean value indicating whether the payload is empty. + public var isEmpty: Bool { + userAgentPayloads.isEmpty + } +} + +// MARK: - HTTPHeaderRepresentable + +extension HeartbeatsPayload: HTTPHeaderRepresentable { + /// Returns a processed payload string intended for use in a HTTP header. + /// - Returns: A string value from the heartbeats payload. + public func headerValue() -> String { + let encoder = JSONEncoder() + encoder.dateEncodingStrategy = .formatted(Self.dateFormatter) + #if DEBUG + // TODO: Remove the following #available check when FirebaseCore's minimum deployment target + // is iOS 11+; all other supported platforms already meet the minimum for `.sortedKeys`. + if #available(iOS 11, *) { + // Sort keys in debug builds to simplify output comparisons in unit tests. + encoder.outputFormatting = .sortedKeys + } + #endif // DEBUG + + guard let data = try? encoder.encode(self) else { + // If encoding fails, fall back to encoding with an empty payload. + return Self.emptyPayload.headerValue() + } + + do { + let gzippedData = try data.zipped() + return gzippedData.base64URLEncodedString() + } catch { + // If gzipping fails, fall back to encoding with base64URL. + return data.base64URLEncodedString() + } + } +} + +// MARK: - Static Defaults + +extension HeartbeatsPayload { + /// Convenience instance that represents an empty payload. + static let emptyPayload = HeartbeatsPayload() + + /// A default date formatter that uses `yyyy-MM-dd` format. + public static let dateFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd" + formatter.locale = Locale(identifier: "en_US_POSIX") + formatter.timeZone = TimeZone(secondsFromGMT: 0) + return formatter + }() +} + +// MARK: - Equatable + +extension HeartbeatsPayload: Equatable {} +extension HeartbeatsPayload.UserAgentPayload: Equatable {} + +// MARK: - Data + +public extension Data { + /// Returns a Base-64 URL-safe encoded string. + /// + /// - parameter options: The options to use for the encoding. Default value is `[]`. + /// - returns: The Base-64 URL-safe encoded string. + func base64URLEncodedString(options: Data.Base64EncodingOptions = []) -> String { + base64EncodedString() + .replacingOccurrences(of: "/", with: "_") + .replacingOccurrences(of: "+", with: "-") + .replacingOccurrences(of: "=", with: "") + } + + /// Initialize a `Data` from a Base-64 URL encoded String using the given options. + /// + /// Returns nil when the input is not recognized as valid Base-64. + /// - parameter base64URLString: The string to parse. + /// - parameter options: Encoding options. Default value is `[]`. + init?(base64URLEncoded base64URLString: String, options: Data.Base64DecodingOptions = []) { + var base64Encoded = base64URLString + .replacingOccurrences(of: "_", with: "/") + .replacingOccurrences(of: "-", with: "+") + + // Pad the string with "=" signs until the string's length is a multiple of 4. + while !base64Encoded.count.isMultiple(of: 4) { + base64Encoded.append("=") + } + + self.init(base64Encoded: base64Encoded, options: options) + } + + /// Returns the compressed data. + /// - Returns: The compressed data. + /// - Throws: An error if compression failed. + func zipped() throws -> Data { + try NSData.gul_data(byGzippingData: self) + } + + /// Returns the uncompressed data. + /// - Returns: The decompressed data. + /// - Throws: An error if decompression failed. + func unzipped() throws -> Data { + try NSData.gul_data(byInflatingGzippedData: self) + } +} diff --git a/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/RingBuffer.swift b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/RingBuffer.swift new file mode 100644 index 0000000..6ba8c33 --- /dev/null +++ b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/RingBuffer.swift @@ -0,0 +1,111 @@ +// Copyright 2021 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 + +/// A generic circular queue structure. +struct RingBuffer: Sequence { + /// An array of heartbeats treated as a circular queue and intialized with a fixed capacity. + private var circularQueue: [Element?] + /// The current "tail" and insert point for the `circularQueue`. + private var tailIndex: Array.Index + + /// Error types for `RingBuffer` operations. + enum Error: LocalizedError { + case outOfBoundsPush(pushIndex: Array.Index, endIndex: Array.Index) + + var errorDescription: String { + switch self { + case let .outOfBoundsPush(pushIndex, endIndex): + return "Out-of-bounds push at index \(pushIndex) to ring buffer with" + + "end index of \(endIndex)." + } + } + } + + /// Designated initializer. + /// - Parameter capacity: An `Int` representing the capacity. + init(capacity: Int) { + circularQueue = Array(repeating: nil, count: capacity) + tailIndex = circularQueue.startIndex + } + + /// Pushes an element to the back of the buffer, returning the element (`Element?`) that was + /// overwritten. + /// - Parameter element: The element to push to the back of the buffer. + /// - Returns: The element that was overwritten or `nil` if nothing was overwritten. + /// - Complexity: O(1) + @discardableResult + mutating func push(_ element: Element) throws -> Element? { + guard circularQueue.count > 0 else { + // Do not push if `circularQueue` is a fixed empty array. + return nil + } + + guard circularQueue.indices.contains(tailIndex) else { + // We have somehow entered an invalid state (#10025). + throw Self.Error.outOfBoundsPush( + pushIndex: tailIndex, + endIndex: circularQueue.endIndex + ) + } + + let replaced = circularQueue[tailIndex] + circularQueue[tailIndex] = element + + // Increment index, wrapping around to the start if needed. + tailIndex += 1 + if tailIndex >= circularQueue.endIndex { + tailIndex = circularQueue.startIndex + } + + return replaced + } + + /// Pops an element from the back of the buffer, returning the element (`Element?`) that was + /// popped. + /// - Returns: The element that was popped or `nil` if there was no element to pop. + /// - Complexity: O(1) + @discardableResult + mutating func pop() -> Element? { + guard circularQueue.count > 0 else { + // Do not pop if `circularQueue` is a fixed empty array. + return nil + } + + // Decrement index, wrapping around to the back if needed. + tailIndex -= 1 + if tailIndex < circularQueue.startIndex { + tailIndex = circularQueue.endIndex - 1 + } + + guard let popped = circularQueue[tailIndex] else { + return nil // There is no element to pop. + } + + circularQueue[tailIndex] = nil + + return popped + } + + func makeIterator() -> IndexingIterator<[Element]> { + circularQueue + .compactMap { $0 } // Remove `nil` elements. + .makeIterator() + } +} + +// MARK: - Codable + +extension RingBuffer: Codable where Element: Codable {} diff --git a/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/Storage.swift b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/Storage.swift new file mode 100644 index 0000000..a4cac33 --- /dev/null +++ b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/Storage.swift @@ -0,0 +1,145 @@ +// Copyright 2021 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 + +/// A type that reads from and writes to an underlying storage container. +protocol Storage { + /// Reads and returns the data stored by this storage type. + /// - Returns: The data read from storage. + /// - Throws: An error if the read failed. + func read() throws -> Data + + /// Writes the given data to this storage type. + /// - Throws: An error if the write failed. + func write(_ data: Data?) throws +} + +/// Error types for `Storage` operations. +enum StorageError: Error { + case readError + case writeError +} + +// MARK: - FileStorage + +/// A object that provides API for reading and writing to a file system resource. +final class FileStorage: Storage { + /// A file system URL to the underlying file resource. + private let url: URL + /// The file manager used to perform file system operations. + private let fileManager: FileManager + + /// Designated initializer. + /// - Parameters: + /// - url: A file system URL for the underlying file resource. + /// - fileManager: A file manager. Defaults to `default` manager. + init(url: URL, fileManager: FileManager = .default) { + self.url = url + self.fileManager = fileManager + } + + /// Reads and returns the data from this object's associated file resource. + /// + /// - Returns: The data stored on disk. + /// - Throws: An error if reading the contents of the file resource fails (i.e. file doesn't + /// exist). + func read() throws -> Data { + do { + return try Data(contentsOf: url) + } catch { + throw StorageError.readError + } + } + + /// Writes the given data to this object's associated file resource. + /// + /// When the given `data` is `nil`, this object's associated file resource is emptied. + /// + /// - Parameter data: The `Data?` to write to this object's associated file resource. + func write(_ data: Data?) throws { + do { + try createDirectories(in: url.deletingLastPathComponent()) + if let data { + try data.write(to: url, options: .atomic) + } else { + let emptyData = Data() + try emptyData.write(to: url, options: .atomic) + } + } catch { + throw StorageError.writeError + } + } + + /// Creates all directories in the given file system URL. + /// + /// If the directory for the given URL already exists, the error is ignored because the directory + /// has already been created. + /// + /// - Parameter url: The URL to create directories in. + private func createDirectories(in url: URL) throws { + do { + try fileManager.createDirectory( + at: url, + withIntermediateDirectories: true + ) + } catch CocoaError.fileWriteFileExists { + // Directory already exists. + } catch { throw error } + } +} + +// MARK: - UserDefaultsStorage + +/// A object that provides API for reading and writing to a user defaults resource. +final class UserDefaultsStorage: Storage { + /// The underlying defaults container. + private let defaults: UserDefaults + /// The key mapping to the object's associated resource in `defaults`. + private let key: String + + /// Designated initializer. + /// - Parameters: + /// - defaults: The defaults container. + /// - key: The key mapping to the value stored in the defaults container. + init(defaults: UserDefaults, key: String) { + self.defaults = defaults + self.key = key + } + + /// Reads and returns the data from this object's associated defaults resource. + /// + /// - Returns: The data stored on disk. + /// - Throws: An error if no data has been stored to the defaults container. + func read() throws -> Data { + if let data = defaults.data(forKey: key) { + return data + } else { + throw StorageError.readError + } + } + + /// Writes the given data to this object's associated defaults. + /// + /// When the given `data` is `nil`, the associated default is removed. + /// + /// - Parameter data: The `Data?` to write to this object's associated defaults. + func write(_ data: Data?) throws { + if let data { + defaults.set(data, forKey: key) + } else { + defaults.removeObject(forKey: key) + } + } +} diff --git a/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/StorageFactory.swift b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/StorageFactory.swift new file mode 100644 index 0000000..6552a31 --- /dev/null +++ b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/StorageFactory.swift @@ -0,0 +1,66 @@ +// Copyright 2021 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 + +private enum Constants { + /// The name of the file system directory where heartbeat data is stored. + static let heartbeatFileStorageDirectoryPath = "google-heartbeat-storage" + /// The name of the user defaults suite where heartbeat data is stored. + static let heartbeatUserDefaultsSuiteName = "com.google.heartbeat.storage" +} + +/// A factory type for `Storage`. +protocol StorageFactory { + static func makeStorage(id: String) -> Storage +} + +// MARK: - FileStorage + StorageFactory + +extension FileStorage: StorageFactory { + static func makeStorage(id: String) -> Storage { + let rootDirectory = FileManager.default.applicationSupportDirectory + let heartbeatDirectoryPath = Constants.heartbeatFileStorageDirectoryPath + + // Sanitize the `id` so the heartbeat file name does not include a ":". + let sanitizedID = id.replacingOccurrences(of: ":", with: "_") + let heartbeatFilePath = "heartbeats-\(sanitizedID)" + + let storageURL = rootDirectory + .appendingPathComponent(heartbeatDirectoryPath, isDirectory: true) + .appendingPathComponent(heartbeatFilePath, isDirectory: false) + + return FileStorage(url: storageURL) + } +} + +extension FileManager { + var applicationSupportDirectory: URL { + urls(for: .applicationSupportDirectory, in: .userDomainMask).first! + } +} + +// MARK: - UserDefaultsStorage + StorageFactory + +extension UserDefaultsStorage: StorageFactory { + static func makeStorage(id: String) -> Storage { + let suiteName = Constants.heartbeatUserDefaultsSuiteName + // It's safe to force unwrap the below defaults instance because the + // initializer only returns `nil` when the bundle id or `globalDomain` + // is passed in as the `suiteName`. + let defaults = UserDefaults(suiteName: suiteName)! + let key = "heartbeats-\(id)" + return UserDefaultsStorage(defaults: defaults, key: key) + } +} diff --git a/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/WeakContainer.swift b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/WeakContainer.swift new file mode 100644 index 0000000..f1dd177 --- /dev/null +++ b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/WeakContainer.swift @@ -0,0 +1,20 @@ +// Copyright 2021 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 + +/// A structure used to weakly box reference types. +struct WeakContainer { + weak var object: Object? +} diff --git a/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift new file mode 100644 index 0000000..50cd247 --- /dev/null +++ b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift @@ -0,0 +1,58 @@ +// Copyright 2021 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 + +/// An object that provides API to log and flush heartbeats from a synchronized storage container. +@objc(FIRHeartbeatController) +@objcMembers +public class _ObjC_HeartbeatController: NSObject { + /// The underlying Swift object. + private let heartbeatController: HeartbeatController + + /// Public initializer. + /// - Parameter id: The `id` to associate this controller's heartbeat storage with. + public init(id: String) { + heartbeatController = HeartbeatController(id: id) + } + + /// Asynchronously logs a new heartbeat, if needed. + /// + /// - Note: This API is thread-safe. + /// - Parameter agent: The string agent (i.e. Firebase User Agent) to associate the logged + /// heartbeat with. + public func log(_ agent: String) { + heartbeatController.log(agent) + } + + /// Synchronously flushes heartbeats from storage into a heartbeats payload. + /// + /// - Note: This API is thread-safe. + /// - Returns: A heartbeats payload for the flushed heartbeat(s). + public func flush() -> _ObjC_HeartbeatsPayload { + let heartbeatsPayload = heartbeatController.flush() + return _ObjC_HeartbeatsPayload(heartbeatsPayload) + } + + /// Synchronously flushes the heartbeat for today. + /// + /// If no heartbeat was logged today, the returned payload is empty. + /// + /// - Note: This API is thread-safe. + /// - Returns: A heartbeats payload for the flushed heartbeat. + public func flushHeartbeatFromToday() -> _ObjC_HeartbeatsPayload { + let heartbeatsPayload = heartbeatController.flushHeartbeatFromToday() + return _ObjC_HeartbeatsPayload(heartbeatsPayload) + } +} diff --git a/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatsPayload.swift b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatsPayload.swift new file mode 100644 index 0000000..83d72a2 --- /dev/null +++ b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatsPayload.swift @@ -0,0 +1,40 @@ +// Copyright 2021 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 + +/// A model object representing a payload of heartbeat data intended for sending in network +/// requests. +@objc(FIRHeartbeatsPayload) +public class _ObjC_HeartbeatsPayload: NSObject, HTTPHeaderRepresentable { + /// The underlying Swift structure. + private let heartbeatsPayload: HeartbeatsPayload + + /// Designated initializer. + /// - Parameter heartbeatsPayload: A native-Swift heartbeats payload. + public init(_ heartbeatsPayload: HeartbeatsPayload) { + self.heartbeatsPayload = heartbeatsPayload + } + + /// Returns a processed payload string intended for use in a HTTP header. + /// - Returns: A string value from the heartbeats payload. + @objc public func headerValue() -> String { + heartbeatsPayload.headerValue() + } + + /// A Boolean value indicating whether the payload is empty. + @objc public var isEmpty: Bool { + heartbeatsPayload.isEmpty + } +} diff --git a/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/Resources/PrivacyInfo.xcprivacy b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/Resources/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..3fb515f --- /dev/null +++ b/Pods/FirebaseCoreInternal/FirebaseCore/Internal/Sources/Resources/PrivacyInfo.xcprivacy @@ -0,0 +1,26 @@ + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + + NSPrivacyCollectedDataTypes + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPITypeReasons + + 1C8F.1 + + + + + + diff --git a/Pods/FirebaseCoreInternal/LICENSE b/Pods/FirebaseCoreInternal/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/Pods/FirebaseCoreInternal/LICENSE @@ -0,0 +1,202 @@ + + 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. diff --git a/Pods/FirebaseCoreInternal/README.md b/Pods/FirebaseCoreInternal/README.md new file mode 100644 index 0000000..4c915ab --- /dev/null +++ b/Pods/FirebaseCoreInternal/README.md @@ -0,0 +1,297 @@ +

+ + + + + + + + +
+ + + + + + +

+ +# Firebase Apple Open Source Development + +This repository contains the source code for all Apple platform Firebase SDKs except FirebaseAnalytics. + +Firebase is an app development platform with tools to help you build, grow, and +monetize your app. More information about Firebase can be found on the +[official Firebase website](https://firebase.google.com). + +## Installation + +See the subsections below for details about the different installation methods. Where +available, it's recommended to install any libraries with a `Swift` suffix to get the +best experience when writing your app in Swift. + +1. [Standard pod install](#standard-pod-install) +2. [Swift Package Manager](#swift-package-manager) +3. [Installing from the GitHub repo](#installing-from-github) +4. [Experimental Carthage](#carthage-ios-only) + +### Standard pod install + +For instructions on the standard pod install, visit: +[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup). + +### Swift Package Manager + +Instructions for [Swift Package Manager](https://swift.org/package-manager/) support can be +found in the [SwiftPackageManager.md](SwiftPackageManager.md) Markdown file. + +### Installing from GitHub + +These instructions can be used to access the Firebase repo at other branches, +tags, or commits. + +#### Background + +See [the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod) +for instructions and options about overriding pod source locations. + +#### Accessing Firebase Source Snapshots + +All official releases are tagged in this repo and available via CocoaPods. To access a local +source snapshot or unreleased branch, use Podfile directives like the following: + +To access FirebaseFirestore via a branch: +```ruby +pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'main' +pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'main' +``` + +To access FirebaseMessaging via a checked-out version of the firebase-ios-sdk repo: +```ruby +pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk' +pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk' +``` + +### Carthage (iOS only) + +Instructions for the experimental Carthage distribution can be found at +[Carthage.md](Carthage.md). + +### Using Firebase from a Framework or a library + +For details on using Firebase from a Framework or a library, refer to [firebase_in_libraries.md](docs/firebase_in_libraries.md). + +## Development + +To develop Firebase software in this repository, ensure that you have at least +the following software: + +* Xcode 15.2 (or later) + +CocoaPods is still the canonical way to develop, but much of the repo now supports +development with Swift Package Manager. + +### CocoaPods + +Install the following: +* CocoaPods 1.12.0 (or later) +* [CocoaPods generate](https://github.com/square/cocoapods-generate) + +For the pod that you want to develop: + +```ruby +pod gen Firebase{name here}.podspec --local-sources=./ --auto-open --platforms=ios +``` + +Note: If the CocoaPods cache is out of date, you may need to run +`pod repo update` before the `pod gen` command. + +Note: Set the `--platforms` option to `macos` or `tvos` to develop/test for +those platforms. Since 10.2, Xcode does not properly handle multi-platform +CocoaPods workspaces. + +Firestore has a self-contained Xcode project. See +[Firestore/README](Firestore/README.md) Markdown file. + +#### Development for Catalyst +* `pod gen {name here}.podspec --local-sources=./ --auto-open --platforms=ios` +* Check the Mac box in the App-iOS Build Settings +* Sign the App in the Settings Signing & Capabilities tab +* Click Pods in the Project Manager +* Add Signing to the iOS host app and unit test targets +* Select the Unit-unit scheme +* Run it to build and test + +Alternatively, disable signing in each target: +* Go to Build Settings tab +* Click `+` +* Select `Add User-Defined Setting` +* Add `CODE_SIGNING_REQUIRED` setting with a value of `NO` + +### Swift Package Manager +* To enable test schemes: `./scripts/setup_spm_tests.sh` +* `open Package.swift` or double click `Package.swift` in Finder. +* Xcode will open the project + * Choose a scheme for a library to build or test suite to run + * Choose a target platform by selecting the run destination along with the scheme + +### Adding a New Firebase Pod + +Refer to [AddNewPod](AddNewPod.md) Markdown file for details. + +### Managing Headers and Imports + +For information about managing headers and imports, see [HeadersImports](HeadersImports.md) Markdown file. + +### Code Formatting + +To ensure that the code is formatted consistently, run the script +[./scripts/check.sh](https://github.com/firebase/firebase-ios-sdk/blob/main/scripts/check.sh) +before creating a pull request (PR). + +GitHub Actions will verify that any code changes are done in a style-compliant +way. Install `clang-format` and `mint`: + +```console +brew install clang-format@18 +brew install mint +``` + +### Running Unit Tests + +Select a scheme and press Command-u to build a component and run its unit tests. + +### Running Sample Apps +To run the sample apps and integration tests, you'll need a valid +`GoogleService-Info.plist +` file. The Firebase Xcode project contains dummy plist +files without real values, but they can be replaced with real plist files. To get your own +`GoogleService-Info.plist` files: + +1. Go to the [Firebase Console](https://console.firebase.google.com/) +2. Create a new Firebase project, if you don't already have one +3. For each sample app you want to test, create a new Firebase app with the sample app's bundle +identifier (e.g., `com.google.Database-Example`) +4. Download the resulting `GoogleService-Info.plist` and add it to the Xcode project. + +### Coverage Report Generation + +For coverage report generation instructions, see [scripts/code_coverage_report/README](scripts/code_coverage_report/README.md) Markdown file. + +## Specific Component Instructions +See the sections below for any special instructions for those components. + +### Firebase Auth + +For specific Firebase Auth development, refer to the [Auth Sample README](FirebaseAuth/Tests/Sample/README.md) for instructions about +building and running the FirebaseAuth pod along with various samples and tests. + +### Firebase Database + +The Firebase Database Integration tests can be run against a locally running Database Emulator +or against a production instance. + +To run against a local emulator instance, invoke `./scripts/run_database_emulator.sh start` before +running the integration test. + +To run against a production instance, provide a valid `GoogleServices-Info.plist` and copy it to +`FirebaseDatabase/Tests/Resources/GoogleService-Info.plist`. Your Security Rule must be set to +[public](https://firebase.google.com/docs/database/security/quickstart) while your tests are +running. + +### Firebase Dynamic Links + +Firebase Dynamic Links is **deprecated** and should not be used in new projects. The service will shut down on August 25, 2025. + +Please see our [Dynamic Links Deprecation FAQ documentation](https://firebase.google.com/support/dynamic-links-faq) for more guidance. + +### Firebase Performance Monitoring + +For specific Firebase Performance Monitoring development, see +[the Performance README](FirebasePerformance/README.md) for instructions about building the SDK +and [the Performance TestApp README](FirebasePerformance/Tests/TestApp/README.md) for instructions about +integrating Performance with the dev test App. + +### Firebase Storage + +To run the Storage Integration tests, follow the instructions in +[StorageIntegration.swift](FirebaseStorage/Tests/Integration/StorageIntegration.swift). + +#### Push Notifications + +Push notifications can only be delivered to specially provisioned App IDs in the developer portal. +In order to test receiving push notifications, you will need to: + +1. Change the bundle identifier of the sample app to something you own in your Apple Developer +account and enable that App ID for push notifications. +2. You'll also need to +[upload your APNs Provider Authentication Key or certificate to the +Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs) +at **Project Settings > Cloud Messaging > [Your Firebase App]**. +3. Ensure your iOS device is added to your Apple Developer portal as a test device. + +#### iOS Simulator + +The iOS Simulator cannot register for remote notifications and will not receive push notifications. +To receive push notifications, follow the steps above and run the app on a physical device. + +## Building with Firebase on Apple platforms + +Firebase provides official beta support for macOS, Catalyst, and tvOS. visionOS and watchOS +are community supported. Thanks to community contributions for many of the multi-platform PRs. + +At this time, most of Firebase's products are available across Apple platforms. There are still +a few gaps, especially on visionOS and watchOS. For details about the current support matrix, see +[this chart](https://firebase.google.com/docs/ios/learn-more#firebase_library_support_by_platform) +in Firebase's documentation. + +### visionOS + +Where supported, visionOS works as expected with the exception of Firestore via Swift Package +Manager where it is required to use the source distribution. + +To enable the Firestore source distribution, quit Xcode and open the desired +project from the command line with the `FIREBASE_SOURCE_FIRESTORE` environment +variable: `open --env FIREBASE_SOURCE_FIRESTORE /path/to/project.xcodeproj`. +To go back to using the binary distribution of Firestore, quit Xcode and open +Xcode like normal, without the environment variable. + +### watchOS +Thanks to contributions from the community, many of Firebase SDKs now compile, run unit tests, and +work on watchOS. See the [Independent Watch App Sample](Example/watchOSSample). + +Keep in mind that watchOS is not officially supported by Firebase. While we can catch basic unit +test issues with GitHub Actions, there may be some changes where the SDK no longer works as expected +on watchOS. If you encounter this, please +[file an issue](https://github.com/firebase/firebase-ios-sdk/issues). + +During app setup in the console, you may get to a step that mentions something like "Checking if the +app has communicated with our servers". This relies on Analytics and will not work on watchOS. +**It's safe to ignore the message and continue**, the rest of the SDKs will work as expected. + +#### Additional Crashlytics Notes +* watchOS has limited support. Due to watchOS restrictions, mach exceptions and signal crashes are +not recorded. (Crashes in SwiftUI are generated as mach exceptions, so will not be recorded) + +## Combine +Thanks to contributions from the community, _FirebaseCombineSwift_ contains support for Apple's Combine +framework. This module is currently under development and not yet supported for use in production +environments. For more details, please refer to the [docs](FirebaseCombineSwift/README.md). + +## Roadmap + +See [Roadmap](ROADMAP.md) for more about the Firebase Apple SDK Open Source +plans and directions. + +## Contributing + +See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase +Apple SDK. + +## License + +The contents of this repository are licensed under the +[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +Your use of Firebase is governed by the +[Terms of Service for Firebase Services](https://firebase.google.com/terms/). diff --git a/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRAppInternal.h b/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRAppInternal.h new file mode 100644 index 0000000..49104f0 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRAppInternal.h @@ -0,0 +1,159 @@ +/* + * 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 + +@class FIRComponentContainer; +@class FIRHeartbeatLogger; +@protocol FIRLibrary; + +/** + * The internal interface to `FirebaseApp`. This is meant for first-party integrators, who need to + * receive `FirebaseApp` notifications, log info about the success or failure of their + * configuration, and access other internal functionality of `FirebaseApp`. + */ +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSInteger, FIRConfigType) { + FIRConfigTypeCore = 1, + FIRConfigTypeSDK = 2, +}; + +extern NSString *const kFIRDefaultAppName; +extern NSString *const kFIRAppReadyToConfigureSDKNotification; +extern NSString *const kFIRAppDeleteNotification; +extern NSString *const kFIRAppIsDefaultAppKey; +extern NSString *const kFIRAppNameKey; +extern NSString *const kFIRGoogleAppIDKey; +extern NSString *const kFirebaseCoreErrorDomain; + +/** The `UserDefaults` suite name for `FirebaseCore`, for those storage locations that use it. */ +extern NSString *const kFirebaseCoreDefaultsSuiteName; + +/** + * The format string for the `UserDefaults` key used for storing the data collection enabled flag. + * This includes formatting to append the `FirebaseApp`'s name. + */ +extern NSString *const kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat; + +/** + * The plist key used for storing the data collection enabled flag. + */ +extern NSString *const kFIRGlobalAppDataCollectionEnabledPlistKey; + +/** @var FirebaseAuthStateDidChangeInternalNotification + @brief The name of the @c NotificationCenter notification which is posted when the auth state + changes (e.g. a new token has been produced, a user logs in or out). The object parameter of + the notification is a dictionary possibly containing the key: + @c FirebaseAuthStateDidChangeInternalNotificationTokenKey (the new access token.) If it does not + contain this key it indicates a sign-out event took place. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotification; + +/** @var FirebaseAuthStateDidChangeInternalNotificationTokenKey + @brief A key present in the dictionary object parameter of the + @c FirebaseAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the new access token. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationTokenKey; + +/** @var FirebaseAuthStateDidChangeInternalNotificationAppKey + @brief A key present in the dictionary object parameter of the + @c FirebaseAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the FirebaseApp associated with the auth instance. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationAppKey; + +/** @var FirebaseAuthStateDidChangeInternalNotificationUIDKey + @brief A key present in the dictionary object parameter of the + @c FirebaseAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the new user's UID (or nil if there is no longer a user signed in). + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationUIDKey; + +@interface FIRApp () + +/** + * A flag indicating if this is the default app (has the default app name). + */ +@property(nonatomic, readonly) BOOL isDefaultApp; + +/** + * The container of interop SDKs for this app. + */ +@property(nonatomic) FIRComponentContainer *container; + +/** + * The heartbeat logger associated with this app. + * + * Firebase apps have a 1:1 relationship with heartbeat loggers. + */ +@property(readonly) FIRHeartbeatLogger *heartbeatLogger; + +/** + * Checks if the default app is configured without trying to configure it. + */ ++ (BOOL)isDefaultAppConfigured; + +/** + * Registers a given third-party library with the given version number to be reported for + * analytics. + * + * @param name Name of the library. + * @param version Version of the library. + */ ++ (void)registerLibrary:(nonnull NSString *)name withVersion:(nonnull NSString *)version; + +/** + * Registers a given internal library to be reported for analytics. + * + * @param library Optional parameter for component registration. + * @param name Name of the library. + */ ++ (void)registerInternalLibrary:(nonnull Class)library + withName:(nonnull NSString *)name; + +/** + * Registers a given internal library with the given version number to be reported for + * analytics. This should only be used for non-Firebase libraries that have their own versioning + * scheme. + * + * @param library Optional parameter for component registration. + * @param name Name of the library. + * @param version Version of the library. + */ ++ (void)registerInternalLibrary:(nonnull Class)library + withName:(nonnull NSString *)name + withVersion:(nonnull NSString *)version; + +/** + * A concatenated string representing all the third-party libraries and version numbers. + */ ++ (NSString *)firebaseUserAgent; + +/** + * Can be used by the unit tests in each SDK to reset `FirebaseApp`. This method is thread unsafe. + */ ++ (void)resetApps; + +/** + * Can be used by the unit tests in each SDK to set customized options. + */ +- (instancetype)initInstanceWithName:(NSString *)name options:(FIROptions *)options; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRComponent.h b/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRComponent.h new file mode 100644 index 0000000..e4c8a27 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRComponent.h @@ -0,0 +1,91 @@ +/* + * 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 + +@class FIRApp; +@class FIRComponentContainer; + +NS_ASSUME_NONNULL_BEGIN + +/// Provides a system to clean up cached instances returned from the component system. +NS_SWIFT_NAME(ComponentLifecycleMaintainer) +@protocol FIRComponentLifecycleMaintainer +/// The associated app will be deleted, clean up any resources as they are about to be deallocated. +- (void)appWillBeDeleted:(FIRApp *)app; +@end + +typedef _Nullable id (^FIRComponentCreationBlock)(FIRComponentContainer *container, + BOOL *isCacheable) + NS_SWIFT_NAME(ComponentCreationBlock); + +@class FIRDependency; + +/// Describes the timing of instantiation. Note: new components should default to lazy unless there +/// is a strong reason to be eager. +typedef NS_ENUM(NSInteger, FIRInstantiationTiming) { + FIRInstantiationTimingLazy, + FIRInstantiationTimingAlwaysEager, + FIRInstantiationTimingEagerInDefaultApp +} NS_SWIFT_NAME(InstantiationTiming); + +/// A component that can be used from other Firebase SDKs. +NS_SWIFT_NAME(Component) +@interface FIRComponent : NSObject + +/// The protocol describing functionality provided from the `Component`. +@property(nonatomic, strong, readonly) Protocol *protocol; + +/// The timing of instantiation. +@property(nonatomic, readonly) FIRInstantiationTiming instantiationTiming; + +/// An array of dependencies for the component. +@property(nonatomic, copy, readonly) NSArray *dependencies; + +/// A block to instantiate an instance of the component with the appropriate dependencies. +@property(nonatomic, copy, readonly) FIRComponentCreationBlock creationBlock; + +// There's an issue with long NS_SWIFT_NAMES that causes compilation to fail, disable clang-format +// for the next two methods. +// clang-format off + +/// Creates a component with no dependencies that will be lazily initialized. ++ (instancetype)componentWithProtocol:(Protocol *)protocol + creationBlock:(FIRComponentCreationBlock)creationBlock +NS_SWIFT_NAME(init(_:creationBlock:)); + +/// Creates a component to be registered with the component container. +/// +/// @param protocol - The protocol describing functionality provided by the component. +/// @param instantiationTiming - When the component should be initialized. Use .lazy unless there's +/// a good reason to be instantiated earlier. +/// @param dependencies - Any dependencies the `implementingClass` has, optional or required. +/// @param creationBlock - A block to instantiate the component with a container, and if +/// @return A component that can be registered with the component container. ++ (instancetype)componentWithProtocol:(Protocol *)protocol + instantiationTiming:(FIRInstantiationTiming)instantiationTiming + dependencies:(NSArray *)dependencies + creationBlock:(FIRComponentCreationBlock)creationBlock +NS_SWIFT_NAME(init(_:instantiationTiming:dependencies:creationBlock:)); + +// clang-format on + +/// Unavailable. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRComponentContainer.h b/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRComponentContainer.h new file mode 100644 index 0000000..6ec6147 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRComponentContainer.h @@ -0,0 +1,45 @@ +/* + * 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 + +NS_ASSUME_NONNULL_BEGIN + +/// A type-safe macro to retrieve a component from a container. This should be used to retrieve +/// components instead of using the container directly. +#define FIR_COMPONENT(type, container) \ + [FIRComponentType> instanceForProtocol:@protocol(type) inContainer:container] + +@class FIRApp; + +/// A container that holds different components that are registered via the +/// `registerAsComponentRegistrant` call. These classes should conform to `ComponentRegistrant` +/// in order to properly register components for Core. +NS_SWIFT_NAME(FirebaseComponentContainer) +@interface FIRComponentContainer : NSObject + +/// A weak reference to the app that an instance of the container belongs to. +@property(nonatomic, weak, readonly) FIRApp *app; + +// TODO: See if we can get improved type safety here. +/// A Swift only API for fetching an instance since the top macro isn't available. +- (nullable id)__instanceForProtocol:(Protocol *)protocol NS_SWIFT_NAME(instance(for:)); + +/// Unavailable. Use the `container` property on `FirebaseApp`. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRComponentType.h b/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRComponentType.h new file mode 100644 index 0000000..c69085d --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRComponentType.h @@ -0,0 +1,35 @@ +/* + * 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 + +@class FIRComponentContainer; + +NS_ASSUME_NONNULL_BEGIN + +/// Do not use directly. A placeholder type in order to provide a macro that will warn users of +/// mis-matched protocols. +NS_SWIFT_NAME(ComponentType) +@interface FIRComponentType<__covariant T> : NSObject + +/// Do not use directly. A factory method to retrieve an instance that provides a specific +/// functionality. ++ (nullable T)instanceForProtocol:(Protocol *)protocol + inContainer:(FIRComponentContainer *)container; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRDependency.h b/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRDependency.h new file mode 100644 index 0000000..a070557 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRDependency.h @@ -0,0 +1,45 @@ +/* + * 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 + +NS_ASSUME_NONNULL_BEGIN + +/// A dependency on a specific protocol's functionality. +NS_SWIFT_NAME(Dependency) +@interface FIRDependency : NSObject + +/// The protocol describing functionality being depended on. +@property(nonatomic, strong, readonly) Protocol *protocol; + +/// A flag to specify if the dependency is required or not. +@property(nonatomic, readonly) BOOL isRequired; + +/// Initializes a dependency that is required. Calls `init(protocol:isRequired:)` with true for +/// the required parameter. +/// Creates a required dependency on the specified protocol's functionality. ++ (instancetype)dependencyWithProtocol:(Protocol *)protocol; + +/// Creates a dependency on the specified protocol's functionality and specify if it's required for +/// the class's functionality. ++ (instancetype)dependencyWithProtocol:(Protocol *)protocol isRequired:(BOOL)required; + +/// Use `init(withProtocol:isRequired:)` instead. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRHeartbeatLogger.h b/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRHeartbeatLogger.h new file mode 100644 index 0000000..0f39ad9 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRHeartbeatLogger.h @@ -0,0 +1,90 @@ +// Copyright 2021 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 + +NS_ASSUME_NONNULL_BEGIN + +#ifndef FIREBASE_BUILD_CMAKE +@class FIRHeartbeatsPayload; +#endif // FIREBASE_BUILD_CMAKE + +/// Enum representing different daily heartbeat codes. +/// This enum is only used by clients using platform logging V1. This is because +/// the V1 payload only supports a single daily heartbeat. +typedef NS_ENUM(NSInteger, FIRDailyHeartbeatCode) { + /// Represents the absence of a daily heartbeat. + FIRDailyHeartbeatCodeNone = 0, + /// Represents the presence of a daily heartbeat. + FIRDailyHeartbeatCodeSome = 2, +}; + +@protocol FIRHeartbeatLoggerProtocol + +/// Asynchronously logs a heartbeat. +- (void)log; + +#ifndef FIREBASE_BUILD_CMAKE +/// Flushes heartbeats from storage into a structured payload of heartbeats. +- (FIRHeartbeatsPayload *)flushHeartbeatsIntoPayload; +#endif // FIREBASE_BUILD_CMAKE + +/// Gets the heartbeat code for today. +- (FIRDailyHeartbeatCode)heartbeatCodeForToday; + +@end + +#ifndef FIREBASE_BUILD_CMAKE +/// Returns a nullable string header value from a given heartbeats payload. +/// +/// This API returns `nil` when the given heartbeats payload is considered empty. +/// +/// @param heartbeatsPayload The heartbeats payload. +NSString *_Nullable FIRHeaderValueFromHeartbeatsPayload(FIRHeartbeatsPayload *heartbeatsPayload); +#endif // FIREBASE_BUILD_CMAKE + +/// A thread safe, synchronized object that logs and flushes platform logging info. +@interface FIRHeartbeatLogger : NSObject + +/// Designated initializer. +/// +/// @param appID The app ID that this heartbeat logger corresponds to. +- (instancetype)initWithAppID:(NSString *)appID; + +/// Asynchronously logs a new heartbeat corresponding to the Firebase User Agent, if needed. +/// +/// @note This API is thread-safe. +- (void)log; + +#ifndef FIREBASE_BUILD_CMAKE +/// Flushes heartbeats from storage into a structured payload of heartbeats. +/// +/// This API is for clients using platform logging V2. +/// +/// @note This API is thread-safe. +/// @return A payload of heartbeats. +- (FIRHeartbeatsPayload *)flushHeartbeatsIntoPayload; +#endif // FIREBASE_BUILD_CMAKE + +/// Gets today's corresponding heartbeat code. +/// +/// This API is for clients using platform logging V1. +/// +/// @note This API is thread-safe. +/// @return Heartbeat code indicating whether or not there is an unsent global heartbeat. +- (FIRDailyHeartbeatCode)heartbeatCodeForToday; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRLibrary.h b/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRLibrary.h new file mode 100644 index 0000000..15e2865 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRLibrary.h @@ -0,0 +1,44 @@ +/* + * 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. + */ + +#ifndef FIRLibrary_h +#define FIRLibrary_h + +#import + +@class FIRApp; +@class FIRComponent; + +NS_ASSUME_NONNULL_BEGIN + +/// Provide an interface to register a library for userAgent logging and availability to others. +NS_SWIFT_NAME(Library) +@protocol FIRLibrary + +/// Returns one or more Components that will be registered in +/// FirebaseApp and participate in dependency resolution and injection. ++ (NSArray *)componentsToRegister; + +@optional +/// Implement this method if the library needs notifications for lifecycle events. This method is +/// called when the developer calls `FirebaseApp.configure()`. ++ (void)configureWithApp:(FIRApp *)app; + +@end + +NS_ASSUME_NONNULL_END + +#endif /* FIRLibrary_h */ diff --git a/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRLogger.h b/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRLogger.h new file mode 100644 index 0000000..41c5653 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseCore/Extension/FIRLogger.h @@ -0,0 +1,193 @@ +/* + * 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 + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * The Firebase services used in Firebase logger. + */ +typedef NSString *const FIRLoggerService; + +extern FIRLoggerService kFIRLoggerAnalytics; +extern FIRLoggerService kFIRLoggerCrash; +extern FIRLoggerService kFIRLoggerCore; +extern FIRLoggerService kFIRLoggerRemoteConfig; + +/** + * The key used to store the logger's error count. + */ +extern NSString *const kFIRLoggerErrorCountKey; + +/** + * The key used to store the logger's warning count. + */ +extern NSString *const kFIRLoggerWarningCountKey; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * Enables or disables Analytics debug mode. + * If set to true, the logging level for Analytics will be set to FirebaseLoggerLevelDebug. + * Enabling the debug mode has no effect if the app is running from App Store. + * (required) analytics debug mode flag. + */ +void FIRSetAnalyticsDebugMode(BOOL analyticsDebugMode); + +/** + * Gets the current FIRLoggerLevel. + */ +FIRLoggerLevel FIRGetLoggerLevel(void); + +/** + * Changes the default logging level of FirebaseLoggerLevelNotice to a user-specified level. + * The default level cannot be set above FirebaseLoggerLevelNotice if the app is running from App + * Store. (required) log level (one of the FirebaseLoggerLevel enum values). + */ +void FIRSetLoggerLevel(FIRLoggerLevel loggerLevel); + +/** + * Checks if the specified logger level is loggable given the current settings. + * (required) log level (one of the FirebaseLoggerLevel enum values). + * (required) whether or not this function is called from the Analytics component. + */ +BOOL FIRIsLoggableLevel(FIRLoggerLevel loggerLevel, BOOL analyticsComponent); + +/** + * 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 FirebaseLoggerLevelNotice to avoid log spamming. + * (required) log level (one of the FirebaseLoggerLevel enum values). + * (required) service name of type FirebaseLoggerService. + * (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 FIRLogBasic(FIRLoggerLevel level, + FIRLoggerService service, + 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 FirebaseLoggerService. + * (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: + * FirebaseLogError(kFirebaseLoggerCore, @"I-COR000001", @"Configuration of %@ failed.", app.name); + */ +extern void FIRLogError(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogWarning(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogNotice(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogInfo(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogDebug(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); + +// TODO: Come up with a better logging scheme for Swift. +/** + * Logs a debug message to the Xcode console and the device log. If running from AppStore, will + * not log any messages with a level higher than FirebaseLoggerLevelNotice to avoid log spamming. + * This function is intended to be used by Swift clients that do not support variadic parameters. + * + * @param service The service name of type `FirebaseLoggerService`. + * @param messageCode The mesage 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". + * @param message The message string. + */ +extern void FIRLogDebugSwift(FIRLoggerService service, NSString *messageCode, NSString *message); + +/** + * Logs a warning message to the Xcode console and the device log. If running from AppStore, will + * not log any messages with a level higher than FirebaseLoggerLevelNotice to avoid log spamming. + * This function is intended to be used by Swift clients that do not support variadic parameters. + * + * @param service The service name of type `FirebaseLoggerService`. + * @param messageCode The mesage 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". + * @param message The message string. + */ +extern void FIRLogWarningSwift(FIRLoggerService service, NSString *messageCode, NSString *message); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +NS_SWIFT_NAME(FirebaseLogger) +@interface FIRLoggerWrapper : NSObject + +/// Logs a given message at a given log level. This API is effectively a wrapper for the +/// `FIRLogBasic` C API. +/// +/// - Parameters: +/// - level: The log level to use (defined by `FirebaseLoggerLevel` enum values). +/// - service: The service name of type `FirebaseLoggerService`. +/// - code: The mesage 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". +/// - message: Formatted string to be used as the log's message. +/// - args: Arguments list obtained from calling `va_start`, used when message is a format string. ++ (void)logWithLevel:(FIRLoggerLevel)level + withService:(FIRLoggerService)service + withCode:(NSString *)messageCode + withMessage:(NSString *)message + withArgs:(va_list)args; + +/// Logs a given message at a given log level. +/// +/// - Parameters: +/// - level: The log level to use (defined by `FirebaseLoggerLevel` enum values). +/// - service: The service name of type `FirebaseLoggerService`. +/// - code: The mesage 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". +/// - message: Formatted string to be used as the log's message. +/// - args: Arguments list obtained from calling `va_start`, used when message is a format string. ++ (void)logWithLevel:(FIRLoggerLevel)level + service:(FIRLoggerService)service + code:(NSString *)code + message:(NSString *)message + __attribute__((__swift_name__("log(level:service:code:message:)"))); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseCore/Extension/FIROptionsInternal.h b/Pods/FirebaseInstallations/FirebaseCore/Extension/FIROptionsInternal.h new file mode 100644 index 0000000..93a03d6 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseCore/Extension/FIROptionsInternal.h @@ -0,0 +1,106 @@ +/* + * 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 + +/** + * Keys for the strings in the plist file. + */ +extern NSString *const kFIRAPIKey; +extern NSString *const kFIRTrackingID; +extern NSString *const kFIRGoogleAppID; +extern NSString *const kFIRClientID; +extern NSString *const kFIRGCMSenderID; +extern NSString *const kFIRAndroidClientID; +extern NSString *const kFIRDatabaseURL; +extern NSString *const kFIRStorageBucket; +extern NSString *const kFIRBundleID; +extern NSString *const kFIRProjectID; + +/** + * Keys for the plist file name + */ +extern NSString *const kServiceInfoFileName; + +extern NSString *const kServiceInfoFileType; + +/** + * This header file exposes the initialization of FirebaseOptions to internal use. + */ +@interface FIROptions () + +/** + * `resetDefaultOptions` and `initInternalWithOptionsDictionary` are exposed only for unit tests. + */ ++ (void)resetDefaultOptions; + +/** + * Initializes the options with dictionary. The above strings are the keys of the dictionary. + * This is the designated initializer. + */ +- (instancetype)initInternalWithOptionsDictionary:(NSDictionary *)serviceInfoDictionary + NS_DESIGNATED_INITIALIZER; + +/** + * `defaultOptions` and `defaultOptionsDictionary` are exposed in order to be used in FirebaseApp + * and other first party services. + */ ++ (FIROptions *)defaultOptions; + ++ (NSDictionary *)defaultOptionsDictionary; + +/** + * Indicates whether or not Analytics collection was explicitly enabled via a plist flag or at + * runtime. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionExplicitlySet; + +/** + * Whether or not Analytics Collection was enabled. Analytics Collection is enabled unless + * explicitly disabled in GoogleService-Info.plist. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionEnabled; + +/** + * Whether or not Analytics Collection was completely disabled. If true, then + * isAnalyticsCollectionEnabled will be false. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionDeactivated; + +/** + * The version ID of the client library, e.g. @"1100000". + */ +@property(nonatomic, readonly, copy) NSString *libraryVersionID; + +/** + * The flag indicating whether this object was constructed with the values in the default plist + * file. + */ +@property(nonatomic) BOOL usingOptionsFromDefaultPlist; + +/** + * Whether or not Measurement was enabled. Measurement is enabled unless explicitly disabled in + * GoogleService-Info.plist. + */ +@property(nonatomic, readonly) BOOL isMeasurementEnabled; + +/** + * Whether or not editing is locked. This should occur after `FirebaseOptions` has been set on a + * `FirebaseApp`. + */ +@property(nonatomic, getter=isEditingLocked) BOOL editingLocked; + +@end diff --git a/Pods/FirebaseInstallations/FirebaseCore/Extension/FirebaseCoreInternal.h b/Pods/FirebaseInstallations/FirebaseCore/Extension/FirebaseCoreInternal.h new file mode 100644 index 0000000..0669ae6 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseCore/Extension/FirebaseCoreInternal.h @@ -0,0 +1,25 @@ +// 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 FirebaseCore; + +#import "FIRAppInternal.h" +#import "FIRComponent.h" +#import "FIRComponentContainer.h" +#import "FIRComponentType.h" +#import "FIRDependency.h" +#import "FIRHeartbeatLogger.h" +#import "FIRLibrary.h" +#import "FIRLogger.h" +#import "FIROptionsInternal.h" diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h new file mode 100644 index 0000000..8aed7b1 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h @@ -0,0 +1,65 @@ +/* + * 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 + +#import "FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallationsErrors.h" + +@class FIRInstallationsHTTPError; +@class FBLPromise; + +NS_ASSUME_NONNULL_BEGIN + +void FIRInstallationsItemSetErrorToPointer(NSError *error, NSError **pointer); + +@interface FIRInstallationsErrorUtil : NSObject + ++ (NSError *)keyedArchiverErrorWithException:(NSException *)exception; ++ (NSError *)keyedArchiverErrorWithError:(NSError *)error; + ++ (NSError *)keychainErrorWithFunction:(NSString *)keychainFunction status:(OSStatus)status; + ++ (NSError *)installationItemNotFoundForAppID:(NSString *)appID appName:(NSString *)appName; + ++ (NSError *)JSONSerializationError:(NSError *)error; + ++ (NSError *)networkErrorWithError:(NSError *)error; + ++ (NSError *)FIDRegistrationErrorWithResponseMissingField:(NSString *)missingFieldName; + ++ (NSError *)corruptedIIDTokenData; + ++ (FIRInstallationsHTTPError *)APIErrorWithHTTPResponse:(NSHTTPURLResponse *)HTTPResponse + data:(nullable NSData *)data; ++ (BOOL)isAPIError:(NSError *)error withHTTPCode:(NSInteger)HTTPCode; + ++ (NSError *)backoffIntervalWaitError; + +/** + * Returns the passed error if it is already in the public domain or a new error with the passed + * error at `NSUnderlyingErrorKey`. + */ ++ (NSError *)publicDomainErrorWithError:(NSError *)error; + ++ (FBLPromise *)rejectedPromiseWithError:(NSError *)error; + ++ (NSError *)installationsErrorWithCode:(FIRInstallationsErrorCode)code + failureReason:(nullable NSString *)failureReason + underlyingError:(nullable NSError *)underlyingError; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.m b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.m new file mode 100644 index 0000000..5673600 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.m @@ -0,0 +1,145 @@ +/* + * 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 "FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h" + +#import "FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.h" + +#if __has_include() +#import +#else +#import "FBLPromises.h" +#endif + +NSString *const kFirebaseInstallationsErrorDomain = @"com.firebase.installations"; + +void FIRInstallationsItemSetErrorToPointer(NSError *error, NSError **pointer) { + if (pointer != NULL) { + *pointer = error; + } +} + +@implementation FIRInstallationsErrorUtil + ++ (NSError *)keyedArchiverErrorWithException:(NSException *)exception { + NSString *failureReason = [NSString + stringWithFormat:@"NSKeyedArchiver exception with name: %@, reason: %@, userInfo: %@", + exception.name, exception.reason, exception.userInfo]; + return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown + failureReason:failureReason + underlyingError:nil]; +} + ++ (NSError *)keyedArchiverErrorWithError:(NSError *)error { + NSString *failureReason = [NSString stringWithFormat:@"NSKeyedArchiver error."]; + return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown + failureReason:failureReason + underlyingError:error]; +} + ++ (NSError *)keychainErrorWithFunction:(NSString *)keychainFunction status:(OSStatus)status { + NSString *failureReason = [NSString stringWithFormat:@"%@ (%li)", keychainFunction, (long)status]; + return [self installationsErrorWithCode:FIRInstallationsErrorCodeKeychain + failureReason:failureReason + underlyingError:nil]; +} + ++ (NSError *)installationItemNotFoundForAppID:(NSString *)appID appName:(NSString *)appName { + NSString *failureReason = + [NSString stringWithFormat:@"Installation for appID %@ appName %@ not found", appID, appName]; + return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown + failureReason:failureReason + underlyingError:nil]; +} + ++ (NSError *)corruptedIIDTokenData { + NSString *failureReason = + @"IID token data stored in Keychain is corrupted or in an incompatible format."; + return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown + failureReason:failureReason + underlyingError:nil]; +} + ++ (FIRInstallationsHTTPError *)APIErrorWithHTTPResponse:(NSHTTPURLResponse *)HTTPResponse + data:(nullable NSData *)data { + return [[FIRInstallationsHTTPError alloc] initWithHTTPResponse:HTTPResponse data:data]; +} + ++ (BOOL)isAPIError:(NSError *)error withHTTPCode:(NSInteger)HTTPCode { + if (![error isKindOfClass:[FIRInstallationsHTTPError class]]) { + return NO; + } + + return [(FIRInstallationsHTTPError *)error HTTPResponse].statusCode == HTTPCode; +} + ++ (NSError *)JSONSerializationError:(NSError *)error { + NSString *failureReason = [NSString stringWithFormat:@"Failed to serialize JSON data."]; + return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown + failureReason:failureReason + underlyingError:nil]; +} + ++ (NSError *)FIDRegistrationErrorWithResponseMissingField:(NSString *)missingFieldName { + NSString *failureReason = [NSString + stringWithFormat:@"A required response field with name %@ is missing", missingFieldName]; + return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown + failureReason:failureReason + underlyingError:nil]; +} + ++ (NSError *)networkErrorWithError:(NSError *)error { + return [self installationsErrorWithCode:FIRInstallationsErrorCodeServerUnreachable + failureReason:@"Network connection error." + underlyingError:error]; +} + ++ (NSError *)backoffIntervalWaitError { + return [self installationsErrorWithCode:FIRInstallationsErrorCodeServerUnreachable + failureReason:@"Too many server requests." + underlyingError:nil]; +} + ++ (NSError *)publicDomainErrorWithError:(NSError *)error { + if ([error.domain isEqualToString:kFirebaseInstallationsErrorDomain]) { + return error; + } + + return [self installationsErrorWithCode:FIRInstallationsErrorCodeUnknown + failureReason:nil + underlyingError:error]; +} + ++ (NSError *)installationsErrorWithCode:(FIRInstallationsErrorCode)code + failureReason:(nullable NSString *)failureReason + underlyingError:(nullable NSError *)underlyingError { + NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; + userInfo[NSUnderlyingErrorKey] = underlyingError; + userInfo[NSLocalizedFailureReasonErrorKey] = + failureReason + ?: [NSString + stringWithFormat:@"Underlying error: %@", underlyingError.localizedDescription]; + + return [NSError errorWithDomain:kFirebaseInstallationsErrorDomain code:code userInfo:userInfo]; +} + ++ (FBLPromise *)rejectedPromiseWithError:(NSError *)error { + FBLPromise *rejectedPromise = [FBLPromise pendingPromise]; + [rejectedPromise reject:error]; + return rejectedPromise; +} + +@end diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.h new file mode 100644 index 0000000..b978b77 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.h @@ -0,0 +1,53 @@ +/* + * 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 + +NS_ASSUME_NONNULL_BEGIN + +/** Represents an error caused by an unexpected API response. */ +@interface FIRInstallationsHTTPError : NSError + +@property(nonatomic, readonly) NSHTTPURLResponse *HTTPResponse; +@property(nonatomic, readonly, nonnull) NSData *data; + +- (instancetype)init NS_UNAVAILABLE; + +- (instancetype)initWithHTTPResponse:(NSHTTPURLResponse *)HTTPResponse data:(nullable NSData *)data; + +@end + +NS_ASSUME_NONNULL_END + +typedef NS_ENUM(NSInteger, FIRInstallationsHTTPCodes) { + FIRInstallationsHTTPCodesTooManyRequests = 429, + FIRInstallationsHTTPCodesServerInternalError = 500, +}; + +/** Possible response HTTP codes for `CreateInstallation` API request. */ +typedef NS_ENUM(NSInteger, FIRInstallationsRegistrationHTTPCode) { + FIRInstallationsRegistrationHTTPCodeSuccess = 201, + FIRInstallationsRegistrationHTTPCodeInvalidArgument = 400, + FIRInstallationsRegistrationHTTPCodeAPIKeyToProjectIDMismatch = 403, + FIRInstallationsRegistrationHTTPCodeProjectNotFound = 404, + FIRInstallationsRegistrationHTTPCodeTooManyRequests = 429, + FIRInstallationsRegistrationHTTPCodeServerInternalError = 500 +}; + +typedef NS_ENUM(NSInteger, FIRInstallationsAuthTokenHTTPCode) { + FIRInstallationsAuthTokenHTTPCodeInvalidAuthentication = 401, + FIRInstallationsAuthTokenHTTPCodeFIDNotFound = 404, +}; diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.m b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.m new file mode 100644 index 0000000..4236f45 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.m @@ -0,0 +1,79 @@ +/* + * 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 "FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.h" +#import "FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h" + +@implementation FIRInstallationsHTTPError + +- (instancetype)initWithHTTPResponse:(NSHTTPURLResponse *)HTTPResponse + data:(nullable NSData *)data { + NSDictionary *userInfo = [FIRInstallationsHTTPError userInfoWithHTTPResponse:HTTPResponse + data:data]; + self = [super + initWithDomain:kFirebaseInstallationsErrorDomain + code:[FIRInstallationsHTTPError errorCodeWithHTTPCode:HTTPResponse.statusCode] + userInfo:userInfo]; + if (self) { + _HTTPResponse = HTTPResponse; + _data = data; + } + return self; +} + ++ (FIRInstallationsErrorCode)errorCodeWithHTTPCode:(NSInteger)HTTPCode { + return FIRInstallationsErrorCodeUnknown; +} + ++ (NSDictionary *)userInfoWithHTTPResponse:(NSHTTPURLResponse *)HTTPResponse + data:(nullable NSData *)data { + NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + NSString *failureReason = + [NSString stringWithFormat:@"The server responded with an error: \n - URL: %@ \n - HTTP " + @"status code: %ld \n - Response body: %@", + HTTPResponse.URL, (long)HTTPResponse.statusCode, responseString]; + return @{NSLocalizedFailureReasonErrorKey : failureReason}; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone { + return [[FIRInstallationsHTTPError alloc] initWithHTTPResponse:self.HTTPResponse data:self.data]; +} + +#pragma mark - NSSecureCoding + +- (nullable instancetype)initWithCoder:(NSCoder *)coder { + NSHTTPURLResponse *HTTPResponse = [coder decodeObjectOfClass:[NSHTTPURLResponse class] + forKey:@"HTTPResponse"]; + if (!HTTPResponse) { + return nil; + } + NSData *data = [coder decodeObjectOfClass:[NSData class] forKey:@"data"]; + + return [self initWithHTTPResponse:HTTPResponse data:data]; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [coder encodeObject:self.HTTPResponse forKey:@"HTTPResponse"]; + [coder encodeObject:self.data forKey:@"data"]; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +@end diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallations.m b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallations.m new file mode 100644 index 0000000..4748f4f --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallations.m @@ -0,0 +1,273 @@ +/* + * 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 "FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallations.h" + +#if __has_include() +#import +#else +#import "FBLPromises.h" +#endif + +#import "FirebaseCore/Extension/FirebaseCoreInternal.h" + +#import "FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResultInternal.h" + +#import "FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h" +#import "FirebaseInstallations/Source/Library/FIRInstallationsItem.h" +#import "FirebaseInstallations/Source/Library/FIRInstallationsLogger.h" +#import "FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.h" +#import "FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h" + +NS_ASSUME_NONNULL_BEGIN + +static const NSUInteger kExpectedAPIKeyLength = 39; + +@protocol FIRInstallationsInstanceProvider +@end + +@interface FIRInstallations () +@property(nonatomic, readonly) FIROptions *appOptions; +@property(nonatomic, readonly) NSString *appName; + +@property(nonatomic, readonly) FIRInstallationsIDController *installationsIDController; + +@end + +@implementation FIRInstallations + +#pragma mark - Firebase component + ++ (void)load { + [FIRApp registerInternalLibrary:(Class)self withName:@"fire-install"]; +} + ++ (nonnull NSArray *)componentsToRegister { + FIRComponentCreationBlock creationBlock = + ^id _Nullable(FIRComponentContainer *container, BOOL *isCacheable) { + *isCacheable = YES; + FIRInstallations *installations = [[FIRInstallations alloc] initWithApp:container.app]; + return installations; + }; + + FIRComponent *installationsProvider = + [FIRComponent componentWithProtocol:@protocol(FIRInstallationsInstanceProvider) + instantiationTiming:FIRInstantiationTimingAlwaysEager + dependencies:@[] + creationBlock:creationBlock]; + return @[ installationsProvider ]; +} + +- (instancetype)initWithApp:(FIRApp *)app { + FIRInstallationsIDController *IDController = + [[FIRInstallationsIDController alloc] initWithApp:app]; + + // `prefetchAuthToken` is disabled due to b/156746574. + return [self initWithAppOptions:app.options + appName:app.name + installationsIDController:IDController + prefetchAuthToken:NO]; +} + +/// This designated initializer can be exposed for testing. +- (instancetype)initWithAppOptions:(FIROptions *)appOptions + appName:(NSString *)appName + installationsIDController:(FIRInstallationsIDController *)installationsIDController + prefetchAuthToken:(BOOL)prefetchAuthToken { + self = [super init]; + if (self) { + [[self class] validateAppOptions:appOptions appName:appName]; + [[self class] assertCompatibleIIDVersion]; + + _appOptions = [appOptions copy]; + _appName = [appName copy]; + _installationsIDController = installationsIDController; + + // Pre-fetch auth token. + if (prefetchAuthToken) { + [self authTokenWithCompletion:^(FIRInstallationsAuthTokenResult *_Nullable tokenResult, + NSError *_Nullable error){ + }]; + } + } + return self; +} + ++ (void)validateAppOptions:(FIROptions *)appOptions appName:(NSString *)appName { + NSMutableArray *missingFields = [NSMutableArray array]; + if (appName.length < 1) { + [missingFields addObject:@"`FirebaseApp.name`"]; + } + if (appOptions.APIKey.length < 1) { + [missingFields addObject:@"`FirebaseOptions.APIKey`"]; + } + if (appOptions.googleAppID.length < 1) { + [missingFields addObject:@"`FirebaseOptions.googleAppID`"]; + } + + if (appOptions.projectID.length < 1) { + [missingFields addObject:@"`FirebaseOptions.projectID`"]; + } + + if (missingFields.count > 0) { + [NSException + raise:kFirebaseInstallationsErrorDomain + format: + @"%@[%@] Could not configure Firebase Installations due to invalid FirebaseApp " + @"options. The following parameters are nil or empty: %@. If you use " + @"GoogleServices-Info.plist please download the most recent version from the Firebase " + @"Console. If you configure Firebase in code, please make sure you specify all " + @"required parameters.", + kFIRLoggerInstallations, kFIRInstallationsMessageCodeInvalidFirebaseAppOptions, + [missingFields componentsJoinedByString:@", "]]; + } + + [self validateAPIKey:appOptions.APIKey]; +} + ++ (void)validateAPIKey:(nullable NSString *)APIKey { + NSMutableArray *validationIssues = [[NSMutableArray alloc] init]; + + if (APIKey.length != kExpectedAPIKeyLength) { + [validationIssues addObject:[NSString stringWithFormat:@"API Key length must be %lu characters", + (unsigned long)kExpectedAPIKeyLength]]; + } + + if (![[APIKey substringToIndex:1] isEqualToString:@"A"]) { + [validationIssues addObject:@"API Key must start with `A`"]; + } + + NSMutableCharacterSet *allowedCharacters = [NSMutableCharacterSet alphanumericCharacterSet]; + [allowedCharacters + formUnionWithCharacterSet:[NSCharacterSet characterSetWithCharactersInString:@"-_"]]; + + NSCharacterSet *characters = [NSCharacterSet characterSetWithCharactersInString:APIKey]; + if (![allowedCharacters isSupersetOfSet:characters]) { + [validationIssues addObject:@"API Key must contain only base64 url-safe characters characters"]; + } + + if (validationIssues.count > 0) { + [NSException + raise:kFirebaseInstallationsErrorDomain + format: + @"%@[%@] Could not configure Firebase Installations due to invalid FirebaseApp " + @"options. `FirebaseOptions.APIKey` doesn't match the expected format: %@. If you use " + @"GoogleServices-Info.plist please download the most recent version from the Firebase " + @"Console. If you configure Firebase in code, please make sure you specify all " + @"required parameters.", + kFIRLoggerInstallations, kFIRInstallationsMessageCodeInvalidFirebaseAppOptions, + [validationIssues componentsJoinedByString:@", "]]; + } +} + +#pragma mark - Public + ++ (FIRInstallations *)installations { + FIRApp *defaultApp = [FIRApp defaultApp]; + if (!defaultApp) { + [NSException raise:kFirebaseInstallationsErrorDomain + format:@"The default FirebaseApp instance must be configured before the default" + @"FirebaseApp instance can be initialized. One way to ensure this is to " + @"call `FirebaseApp.configure()` in the App Delegate's " + @"`application(_:didFinishLaunchingWithOptions:)` " + @"(or the `@main` struct's initializer in SwiftUI)."]; + } + + return [self installationsWithApp:defaultApp]; +} + ++ (FIRInstallations *)installationsWithApp:(FIRApp *)app { + id installations = + FIR_COMPONENT(FIRInstallationsInstanceProvider, app.container); + return (FIRInstallations *)installations; +} + +- (void)installationIDWithCompletion:(FIRInstallationsIDHandler)completion { + [self.installationsIDController getInstallationItem] + .then(^id(FIRInstallationsItem *installation) { + completion(installation.firebaseInstallationID, nil); + return nil; + }) + .catch(^(NSError *error) { + completion(nil, [FIRInstallationsErrorUtil publicDomainErrorWithError:error]); + }); +} + +- (void)authTokenWithCompletion:(FIRInstallationsTokenHandler)completion { + [self authTokenForcingRefresh:NO completion:completion]; +} + +- (void)authTokenForcingRefresh:(BOOL)forceRefresh + completion:(FIRInstallationsTokenHandler)completion { + [self.installationsIDController getAuthTokenForcingRefresh:forceRefresh] + .then(^FIRInstallationsAuthTokenResult *(FIRInstallationsItem *installation) { + FIRInstallationsAuthTokenResult *result = [[FIRInstallationsAuthTokenResult alloc] + initWithToken:installation.authToken.token + expirationDate:installation.authToken.expirationDate]; + return result; + }) + .then(^id(FIRInstallationsAuthTokenResult *token) { + completion(token, nil); + return nil; + }) + .catch(^void(NSError *error) { + completion(nil, [FIRInstallationsErrorUtil publicDomainErrorWithError:error]); + }); +} + +- (void)deleteWithCompletion:(void (^)(NSError *__nullable error))completion { + [self.installationsIDController deleteInstallation] + .then(^id(id result) { + completion(nil); + return nil; + }) + .catch(^void(NSError *error) { + completion([FIRInstallationsErrorUtil publicDomainErrorWithError:error]); + }); +} + +#pragma mark - IID version compatibility + ++ (void)assertCompatibleIIDVersion { + // We use this flag to disable IID compatibility exception for unit tests. +#ifdef FIR_INSTALLATIONS_ALLOWS_INCOMPATIBLE_IID_VERSION + return; +#else + if (![self isIIDVersionCompatible]) { + [NSException + raise:kFirebaseInstallationsErrorDomain + format:@"Firebase Instance ID is not compatible with Firebase 8.x+. Please remove the " + @"dependency from the app. See the documentation at " + @"https://firebase.google.com/docs/cloud-messaging/ios/" + @"client#fetching-the-current-registration-token."]; + } +#endif +} + ++ (BOOL)isIIDVersionCompatible { + Class IIDClass = NSClassFromString(@"FIRInstanceID"); + if (IIDClass == nil) { + // It is OK if there is no IID at all. + return YES; + } + // We expect a compatible version having the method `+[FIRInstanceID usesFIS]` defined. + BOOL isCompatibleVersion = [IIDClass respondsToSelector:NSSelectorFromString(@"usesFIS")]; + return isCompatibleVersion; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResult.m b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResult.m new file mode 100644 index 0000000..47a71e8 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResult.m @@ -0,0 +1,30 @@ +/* + * 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 "FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResultInternal.h" + +@implementation FIRInstallationsAuthTokenResult + +- (instancetype)initWithToken:(NSString *)token expirationDate:(NSDate *)expirationDate { + self = [super init]; + if (self) { + _authToken = [token copy]; + _expirationDate = expirationDate; + } + return self; +} + +@end diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResultInternal.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResultInternal.h new file mode 100644 index 0000000..662802e --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResultInternal.h @@ -0,0 +1,27 @@ +/* + * 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 "FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallationsAuthTokenResult.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRInstallationsAuthTokenResult (Internal) + +- (instancetype)initWithToken:(NSString *)token expirationDate:(NSDate *)expirationTime; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsItem.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsItem.h new file mode 100644 index 0000000..8aa3a5e --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsItem.h @@ -0,0 +1,93 @@ +/* + * 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 + +#import "FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsStatus.h" + +@class FIRInstallationsStoredItem; +@class FIRInstallationsStoredAuthToken; +@class FIRInstallationsStoredIIDCheckin; + +NS_ASSUME_NONNULL_BEGIN + +/** + * The class represents the required installation ID and auth token data including possible states. + * The data is stored to Keychain via `FIRInstallationsStoredItem` which has only the storage + * relevant data and does not contain any logic. `FIRInstallationsItem` must be used on the logic + * level (not `FIRInstallationsStoredItem`). + */ +@interface FIRInstallationsItem : NSObject + +/// A `FirebaseApp` identifier. +@property(nonatomic, readonly) NSString *appID; +/// A `FirebaseApp` name. +@property(nonatomic, readonly) NSString *firebaseAppName; +/// A stable identifier that uniquely identifies the app instance. +@property(nonatomic, copy, nullable) NSString *firebaseInstallationID; +/// The `refreshToken` is used to authorize the auth token requests. +@property(nonatomic, copy, nullable) NSString *refreshToken; + +@property(nonatomic, nullable) FIRInstallationsStoredAuthToken *authToken; +@property(nonatomic, assign) FIRInstallationsStatus registrationStatus; + +/// Instance ID default token imported from IID store as a part of IID migration. +@property(nonatomic, nullable) NSString *IIDDefaultToken; + +- (instancetype)initWithAppID:(NSString *)appID firebaseAppName:(NSString *)firebaseAppName; + +/** + * Populates `FIRInstallationsItem` properties with data from `FIRInstallationsStoredItem`. + * @param item An instance of `FIRInstallationsStoredItem` to get data from. + */ +- (void)updateWithStoredItem:(FIRInstallationsStoredItem *)item; + +/** + * Creates a stored item with data from the object. + * @return Returns a `FIRInstallationsStoredItem` instance with the data from the object. + */ +- (FIRInstallationsStoredItem *)storedItem; + +/** + * The installation identifier. + * @return Returns a string uniquely identifying the installation. + */ +- (NSString *)identifier; + +/** Validates if all the required item fields are populated and values don't explicitly conflict + * with each other. + * @param outError A reference to be populated with an error containing validation failure details. + * @return `YES` if the item it valid, `NO` otherwise. + */ +- (BOOL)isValid:(NSError *_Nullable *)outError; + +/** + * The installation identifier. + * @param appID A `FirebaseApp` identifier. + * @param appName A `FirebaseApp` name. + * @return Returns a string uniquely identifying the installation. + */ ++ (NSString *)identifierWithAppID:(NSString *)appID appName:(NSString *)appName; + +/** + * Generate a new Firebase Installation Identifier. + * @return Returns a 22 characters long globally unique string created based on UUID. + */ ++ (NSString *)generateFID; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsItem.m b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsItem.m new file mode 100644 index 0000000..0316e45 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsItem.m @@ -0,0 +1,161 @@ +/* + * 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 "FirebaseInstallations/Source/Library/FIRInstallationsItem.h" + +#import "FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h" +#import "FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.h" + +#import "FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h" + +@implementation FIRInstallationsItem + +- (instancetype)initWithAppID:(NSString *)appID firebaseAppName:(NSString *)firebaseAppName { + self = [super init]; + if (self) { + _appID = [appID copy]; + _firebaseAppName = [firebaseAppName copy]; + } + return self; +} + +- (nonnull id)copyWithZone:(nullable NSZone *)zone { + FIRInstallationsItem *clone = [[FIRInstallationsItem alloc] initWithAppID:self.appID + firebaseAppName:self.firebaseAppName]; + clone.firebaseInstallationID = [self.firebaseInstallationID copy]; + clone.refreshToken = [self.refreshToken copy]; + clone.authToken = [self.authToken copy]; + clone.registrationStatus = self.registrationStatus; + clone.IIDDefaultToken = [self.IIDDefaultToken copy]; + + return clone; +} + +- (void)updateWithStoredItem:(FIRInstallationsStoredItem *)item { + self.firebaseInstallationID = item.firebaseInstallationID; + self.refreshToken = item.refreshToken; + self.authToken = item.authToken; + self.registrationStatus = item.registrationStatus; + self.IIDDefaultToken = item.IIDDefaultToken; +} + +- (FIRInstallationsStoredItem *)storedItem { + FIRInstallationsStoredItem *storedItem = [[FIRInstallationsStoredItem alloc] init]; + storedItem.firebaseInstallationID = self.firebaseInstallationID; + storedItem.refreshToken = self.refreshToken; + storedItem.authToken = self.authToken; + storedItem.registrationStatus = self.registrationStatus; + storedItem.IIDDefaultToken = self.IIDDefaultToken; + return storedItem; +} + +- (nonnull NSString *)identifier { + return [[self class] identifierWithAppID:self.appID appName:self.firebaseAppName]; +} + +- (BOOL)isValid:(NSError *_Nullable *)outError { + NSMutableArray *validationIssues = [NSMutableArray array]; + + if (self.appID.length == 0) { + [validationIssues addObject:@"`appID` must not be empty"]; + } + + if (self.firebaseAppName.length == 0) { + [validationIssues addObject:@"`firebaseAppName` must not be empty"]; + } + + if (self.firebaseInstallationID.length == 0) { + [validationIssues addObject:@"`firebaseInstallationID` must not be empty"]; + } + + switch (self.registrationStatus) { + case FIRInstallationStatusUnknown: + [validationIssues addObject:@"invalid `registrationStatus`"]; + break; + + case FIRInstallationStatusRegistered: + if (self.refreshToken == 0) { + [validationIssues addObject:@"registered installation must have non-empty `refreshToken`"]; + } + + if (self.authToken.token == 0) { + [validationIssues + addObject:@"registered installation must have non-empty `authToken.token`"]; + } + + if (self.authToken.expirationDate == nil) { + [validationIssues + addObject:@"registered installation must have non-empty `authToken.expirationDate`"]; + } + + case FIRInstallationStatusUnregistered: + break; + } + + BOOL isValid = validationIssues.count == 0; + + if (!isValid && outError) { + NSString *failureReason = + [NSString stringWithFormat:@"FIRInstallationsItem validation errors: %@", + [validationIssues componentsJoinedByString:@", "]]; + *outError = + [FIRInstallationsErrorUtil installationsErrorWithCode:FIRInstallationsErrorCodeUnknown + failureReason:failureReason + underlyingError:nil]; + } + + return isValid; +} + ++ (NSString *)identifierWithAppID:(NSString *)appID appName:(NSString *)appName { + return [appID stringByAppendingString:appName]; +} + ++ (NSString *)generateFID { + NSUUID *UUID = [NSUUID UUID]; + uuid_t UUIDBytes; + [UUID getUUIDBytes:UUIDBytes]; + + NSUInteger UUIDLength = sizeof(uuid_t); + NSData *UUIDData = [NSData dataWithBytes:UUIDBytes length:UUIDLength]; + + uint8_t UUIDLast4Bits = UUIDBytes[UUIDLength - 1] & 0b00001111; + + // FID first 4 bits must be `0111`. The last 4 UUID bits will be cut later to form a proper FID. + // To keep 16 random bytes we copy these last 4 UUID to the FID 1st byte after `0111` prefix. + uint8_t FIDPrefix = 0b01110000 | UUIDLast4Bits; + NSMutableData *FIDData = [NSMutableData dataWithBytes:&FIDPrefix length:1]; + + [FIDData appendData:UUIDData]; + NSString *FIDString = [self base64URLEncodedStringWithData:FIDData]; + + // A valid FID has exactly 22 base64 characters, which is 132 bits, or 16.5 bytes. + // Our generated ID has 16 bytes UUID + 1 byte prefix which after encoding with base64 will become + // 23 characters plus 1 character for "=" padding. + + // Remove the 23rd character that was added because of the extra 4 bits at the + // end of our 17 byte data and the '=' padding. + return [FIDString substringWithRange:NSMakeRange(0, 22)]; +} + ++ (NSString *)base64URLEncodedStringWithData:(NSData *)data { + NSString *string = [data base64EncodedStringWithOptions:0]; + string = [string stringByReplacingOccurrencesOfString:@"/" withString:@"_"]; + string = [string stringByReplacingOccurrencesOfString:@"+" withString:@"-"]; + return string; +} + +@end diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsLogger.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsLogger.h new file mode 100644 index 0000000..7ad9967 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsLogger.h @@ -0,0 +1,52 @@ +/* + * 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 + +#import "FirebaseCore/Extension/FirebaseCoreInternal.h" + +extern FIRLoggerService kFIRLoggerInstallations; + +// FIRInstallationsAPIService.m +extern NSString *const kFIRInstallationsMessageCodeSendAPIRequest; +extern NSString *const kFIRInstallationsMessageCodeAPIRequestNetworkError; +extern NSString *const kFIRInstallationsMessageCodeAPIRequestResponse; +extern NSString *const kFIRInstallationsMessageCodeUnexpectedAPIRequestResponse; +extern NSString *const kFIRInstallationsMessageCodeParsingAPIResponse; +extern NSString *const kFIRInstallationsMessageCodeAPIResponseParsingInstallationFailed; +extern NSString *const kFIRInstallationsMessageCodeAPIResponseParsingInstallationSucceed; +extern NSString *const kFIRInstallationsMessageCodeAPIResponseParsingAuthTokenFailed; +extern NSString *const kFIRInstallationsMessageCodeAPIResponseParsingAuthTokenSucceed; + +// FIRInstallationsIDController.m +extern NSString *const kFIRInstallationsMessageCodeNewGetInstallationOperationCreated; +extern NSString *const kFIRInstallationsMessageCodeNewGetAuthTokenOperationCreated; +extern NSString *const kFIRInstallationsMessageCodeNewDeleteInstallationOperationCreated; +extern NSString *const kFIRInstallationsMessageCodeInvalidFirebaseConfiguration; +extern NSString *const kFIRInstallationsMessageCodeCorruptedStoredInstallation; + +// FIRInstallationsStoredItem.m +extern NSString *const kFIRInstallationsMessageCodeInstallationCoderVersionMismatch; + +// FIRInstallationsStoredAuthToken.m +extern NSString *const kFIRInstallationsMessageCodeAuthTokenCoderVersionMismatch; + +// FIRInstallationsStoredIIDCheckin.m +extern NSString *const kFIRInstallationsMessageCodeIIDCheckinCoderVersionMismatch; +extern NSString *const kFIRInstallationsMessageCodeIIDCheckinFailedToDecode; + +// FIRInstallations.m +extern NSString *const kFIRInstallationsMessageCodeInvalidFirebaseAppOptions; diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsLogger.m b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsLogger.m new file mode 100644 index 0000000..5187f97 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/FIRInstallationsLogger.m @@ -0,0 +1,50 @@ +/* + * 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 "FirebaseInstallations/Source/Library/FIRInstallationsLogger.h" + +FIRLoggerService kFIRLoggerInstallations = @"[FirebaseInstallations]"; + +// FIRInstallationsAPIService.m +NSString *const kFIRInstallationsMessageCodeSendAPIRequest = @"I-FIS001001"; +NSString *const kFIRInstallationsMessageCodeAPIRequestNetworkError = @"I-FIS001002"; +NSString *const kFIRInstallationsMessageCodeAPIRequestResponse = @"I-FIS001003"; +NSString *const kFIRInstallationsMessageCodeUnexpectedAPIRequestResponse = @"I-FIS001004"; +NSString *const kFIRInstallationsMessageCodeParsingAPIResponse = @"I-FIS001005"; +NSString *const kFIRInstallationsMessageCodeAPIResponseParsingInstallationFailed = @"I-FIS001006"; +NSString *const kFIRInstallationsMessageCodeAPIResponseParsingInstallationSucceed = @"I-FIS001007"; +NSString *const kFIRInstallationsMessageCodeAPIResponseParsingAuthTokenFailed = @"I-FIS001008"; +NSString *const kFIRInstallationsMessageCodeAPIResponseParsingAuthTokenSucceed = @"I-FIS001009"; + +// FIRInstallationsIDController.m +NSString *const kFIRInstallationsMessageCodeNewGetInstallationOperationCreated = @"I-FIS002000"; +NSString *const kFIRInstallationsMessageCodeNewGetAuthTokenOperationCreated = @"I-FIS002001"; +NSString *const kFIRInstallationsMessageCodeNewDeleteInstallationOperationCreated = @"I-FIS002002"; +NSString *const kFIRInstallationsMessageCodeInvalidFirebaseConfiguration = @"I-FIS002003"; +NSString *const kFIRInstallationsMessageCodeCorruptedStoredInstallation = @"I-FIS002004"; + +// FIRInstallationsStoredItem.m +NSString *const kFIRInstallationsMessageCodeInstallationCoderVersionMismatch = @"I-FIS003000"; + +// FIRInstallationsStoredAuthToken.m +NSString *const kFIRInstallationsMessageCodeAuthTokenCoderVersionMismatch = @"I-FIS004000"; + +// FIRInstallationsStoredIIDCheckin.m +NSString *const kFIRInstallationsMessageCodeIIDCheckinCoderVersionMismatch = @"I-FIS007000"; +NSString *const kFIRInstallationsMessageCodeIIDCheckinFailedToDecode = @"I-FIS007001"; + +// FIRInstallations.m +NSString *const kFIRInstallationsMessageCodeInvalidFirebaseAppOptions = @"I-FIS008000"; diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.h new file mode 100644 index 0000000..e2408ca --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.h @@ -0,0 +1,48 @@ +/* + * 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 + +@class FBLPromise; + +NS_ASSUME_NONNULL_BEGIN + +/** The class encapsulates a port of a piece FirebaseInstanceID logic required to migrate IID. */ +@interface FIRInstallationsIIDStore : NSObject + +/** + * Retrieves existing IID if present. + * @return Returns a promise that is resolved with IID string if IID has been found or rejected with + * an error otherwise. + */ +- (FBLPromise *)existingIID; + +/** + * Deletes existing IID if present. + * @return Returns a promise that is resolved with `[NSNull null]` if the IID was successfully. + * deleted or was not found. The promise is rejected otherwise. + */ +- (FBLPromise *)deleteExistingIID; + +#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 diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.m b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.m new file mode 100644 index 0000000..1c2f5d3 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.m @@ -0,0 +1,242 @@ +/* + * 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 "FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.h" + +#if __has_include() +#import +#else +#import "FBLPromises.h" +#endif + +#import +#import "FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h" + +static NSString *const kFIRInstallationsIIDKeyPairPublicTagPrefix = + @"com.google.iid.keypair.public-"; +static NSString *const kFIRInstallationsIIDKeyPairPrivateTagPrefix = + @"com.google.iid.keypair.private-"; +static NSString *const kFIRInstallationsIIDCreationTimePlistKey = @"|S|cre"; + +@implementation FIRInstallationsIIDStore + +- (FBLPromise *)existingIID { + return [FBLPromise onQueue:dispatch_get_global_queue(QOS_CLASS_UTILITY, 0) + do:^id _Nullable { + if (![self hasPlistIIDFlag]) { + return nil; + } + + NSData *IIDPublicKeyData = [self IIDPublicKeyData]; + return [self IIDWithPublicKeyData:IIDPublicKeyData]; + }] + .validate(^BOOL(NSString *_Nullable IID) { + return IID.length > 0; + }); +} + +- (FBLPromise *)deleteExistingIID { + return [FBLPromise onQueue:dispatch_get_global_queue(QOS_CLASS_UTILITY, 0) + do:^id _Nullable { + NSError *error; + if (![self deleteIIDFlagFromPlist:&error]) { + return error; + } + + if (![self deleteIID:&error]) { + return error; + } + + return [NSNull null]; + }]; +} + +#pragma mark - IID decoding + +- (NSString *)IIDWithPublicKeyData:(NSData *)publicKeyData { + NSData *publicKeySHA1 = [self sha1WithData:publicKeyData]; + + const uint8_t *bytes = publicKeySHA1.bytes; + NSMutableData *identityData = [NSMutableData dataWithData:publicKeySHA1]; + + uint8_t b0 = bytes[0]; + // Take the first byte and make the initial four 7 by initially making the initial 4 bits 0 + // and then adding 0x70 to it. + b0 = 0x70 + (0xF & b0); + // failsafe should give you back b0 itself + b0 = (b0 & 0xFF); + [identityData replaceBytesInRange:NSMakeRange(0, 1) withBytes:&b0]; + NSData *data = [identityData subdataWithRange:NSMakeRange(0, 8 * sizeof(Byte))]; + return [self base64URLEncodedStringWithData:data]; +} + +/** FirebaseInstallations SDK uses the SHA1 hash for backwards compatibility with the legacy + * FirebaseInstanceID SDK. The SHA1 hash is used to access Instance IDs stored on the device and not + * for any security-relevant process. This is a one-time step that allows migration of old client + * identifiers. Cryptographic security is not needed here, so potential hash collisions are not a + * problem. + */ +- (NSData *)sha1WithData:(NSData *)data { + unsigned char output[CC_SHA1_DIGEST_LENGTH]; + unsigned int length = (unsigned int)[data length]; + + CC_SHA1(data.bytes, length, output); + return [NSData dataWithBytes:output length:CC_SHA1_DIGEST_LENGTH]; +} + +- (NSString *)base64URLEncodedStringWithData:(NSData *)data { + NSString *string = [data base64EncodedStringWithOptions:0]; + string = [string stringByReplacingOccurrencesOfString:@"/" withString:@"_"]; + string = [string stringByReplacingOccurrencesOfString:@"+" withString:@"-"]; + string = [string stringByReplacingOccurrencesOfString:@"=" withString:@""]; + return string; +} + +#pragma mark - Keychain + +- (NSData *)IIDPublicKeyData { + NSString *tag = [self keychainKeyTagWithPrefix:kFIRInstallationsIIDKeyPairPublicTagPrefix]; + NSDictionary *query = [self keyPairQueryWithTag:tag returnData:YES]; + + CFTypeRef keyRef = NULL; + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&keyRef); + + if (status != noErr) { + if (keyRef) { + CFRelease(keyRef); + } + return nil; + } + + return (__bridge NSData *)keyRef; +} + +- (BOOL)deleteIID:(NSError **)outError { + if (![self deleteKeychainKeyWithTagPrefix:kFIRInstallationsIIDKeyPairPublicTagPrefix + error:outError]) { + return NO; + } + + if (![self deleteKeychainKeyWithTagPrefix:kFIRInstallationsIIDKeyPairPrivateTagPrefix + error:outError]) { + return NO; + } + + return YES; +} + +- (BOOL)deleteKeychainKeyWithTagPrefix:(NSString *)tagPrefix error:(NSError **)outError { + NSString *keyTag = [self keychainKeyTagWithPrefix:kFIRInstallationsIIDKeyPairPublicTagPrefix]; + NSDictionary *keyQuery = [self keyPairQueryWithTag:keyTag returnData:NO]; + + OSStatus status = SecItemDelete((__bridge CFDictionaryRef)keyQuery); + + // When item is not found, it should NOT be considered as an error. The operation should + // continue. + if (status != noErr && status != errSecItemNotFound) { + FIRInstallationsItemSetErrorToPointer( + [FIRInstallationsErrorUtil keychainErrorWithFunction:@"SecItemDelete" status:status], + outError); + return NO; + } + + return YES; +} + +- (NSDictionary *)keyPairQueryWithTag:(NSString *)tag returnData:(BOOL)shouldReturnData { + NSMutableDictionary *query = [NSMutableDictionary dictionary]; + NSData *tagData = [tag dataUsingEncoding:NSUTF8StringEncoding]; + + query[(__bridge id)kSecClass] = (__bridge id)kSecClassKey; + query[(__bridge id)kSecAttrApplicationTag] = tagData; + query[(__bridge id)kSecAttrKeyType] = (__bridge id)kSecAttrKeyTypeRSA; + if (shouldReturnData) { + query[(__bridge id)kSecReturnData] = @(YES); + } + +#if TARGET_OS_OSX + if (self.keychainRef) { + query[(__bridge NSString *)kSecMatchSearchList] = @[ (__bridge id)(self.keychainRef) ]; + } +#endif // TARGET_OSX + + return query; +} + +- (NSString *)keychainKeyTagWithPrefix:(NSString *)prefix { + NSString *mainAppBundleID = [[NSBundle mainBundle] bundleIdentifier]; + if (mainAppBundleID.length == 0) { + return nil; + } + return [NSString stringWithFormat:@"%@%@", prefix, mainAppBundleID]; +} + +- (NSString *)mainbundleIdentifier { + NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier]; + if (!bundleIdentifier.length) { + return nil; + } + return bundleIdentifier; +} + +#pragma mark - Plist + +- (BOOL)deleteIIDFlagFromPlist:(NSError **)outError { + NSString *path = [self plistPath]; + if (![[NSFileManager defaultManager] fileExistsAtPath:path]) { + return YES; + } + + NSMutableDictionary *plistContent = [[NSMutableDictionary alloc] initWithContentsOfFile:path]; + plistContent[kFIRInstallationsIIDCreationTimePlistKey] = nil; + + if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) { + return [plistContent writeToURL:[NSURL fileURLWithPath:path] error:outError]; + } + + return [plistContent writeToFile:path atomically:YES]; +} + +- (BOOL)hasPlistIIDFlag { + NSString *path = [self plistPath]; + if (![[NSFileManager defaultManager] fileExistsAtPath:path]) { + return NO; + } + + NSDictionary *plistContent = [[NSDictionary alloc] initWithContentsOfFile:path]; + return plistContent[kFIRInstallationsIIDCreationTimePlistKey] != nil; +} + +- (NSString *)plistPath { + NSString *plistNameWithExtension = @"com.google.iid-keypair.plist"; + NSString *_subDirectoryName = @"Google/FirebaseInstanceID"; + + NSArray *directoryPaths = + NSSearchPathForDirectoriesInDomains([self supportedDirectory], NSUserDomainMask, YES); + NSArray *components = @[ directoryPaths.lastObject, _subDirectoryName, plistNameWithExtension ]; + + return [NSString pathWithComponents:components]; +} + +- (NSSearchPathDirectory)supportedDirectory { +#if TARGET_OS_TV + return NSCachesDirectory; +#else + return NSApplicationSupportDirectory; +#endif +} + +@end diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.h new file mode 100644 index 0000000..ed98e3d --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.h @@ -0,0 +1,36 @@ +/* + * 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 + +@class FBLPromise; + +NS_ASSUME_NONNULL_BEGIN + +/** + * The class reads a default IID token from IID store if available. + */ +@interface FIRInstallationsIIDTokenStore : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +- (instancetype)initWithGCMSenderID:(NSString *)GCMSenderID; + +- (FBLPromise *)existingIIDDefaultToken; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.m b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.m new file mode 100644 index 0000000..5ef3331 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.m @@ -0,0 +1,158 @@ +/* + * 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 "FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.h" + +#if __has_include() +#import +#else +#import "FBLPromises.h" +#endif + +#import + +#import "FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h" + +static NSString *const kFIRInstallationsIIDTokenKeychainId = @"com.google.iid-tokens"; + +@interface FIRInstallationsIIDTokenInfo : NSObject +@property(nonatomic, nullable, copy) NSString *token; +@end + +@implementation FIRInstallationsIIDTokenInfo + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (void)encodeWithCoder:(nonnull NSCoder *)coder { +} + +- (nullable instancetype)initWithCoder:(nonnull NSCoder *)coder { + self = [super init]; + if (self) { + _token = [coder decodeObjectOfClass:[NSString class] forKey:@"token"]; + } + return self; +} + +@end + +@interface FIRInstallationsIIDTokenStore () +@property(nonatomic, readonly) NSString *GCMSenderID; +@end + +@implementation FIRInstallationsIIDTokenStore + +- (instancetype)initWithGCMSenderID:(NSString *)GCMSenderID { + self = [super init]; + if (self) { + _GCMSenderID = GCMSenderID; + } + return self; +} + +- (FBLPromise *)existingIIDDefaultToken { + return [[FBLPromise onQueue:dispatch_get_global_queue(QOS_CLASS_UTILITY, 0) + do:^id _Nullable { + return [self IIDDefaultTokenData]; + }] onQueue:dispatch_get_global_queue(QOS_CLASS_UTILITY, 0) + then:^id _Nullable(NSData *_Nullable keychainData) { + return [self IIDCheckinWithData:keychainData]; + }]; +} + +- (FBLPromise *)IIDCheckinWithData:(NSData *)data { + FBLPromise *resultPromise = [FBLPromise pendingPromise]; + + NSError *archiverError; + NSKeyedUnarchiver *unarchiver; + if (@available(iOS 11.0, tvOS 11.0, macOS 10.13, *)) { + unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:&archiverError]; + } else { + @try { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; +#pragma clang diagnostic pop + } @catch (NSException *exception) { + archiverError = [FIRInstallationsErrorUtil keyedArchiverErrorWithException:exception]; + } + } + + if (!unarchiver) { + NSError *error = archiverError ?: [FIRInstallationsErrorUtil corruptedIIDTokenData]; + [resultPromise reject:error]; + return resultPromise; + } + + [unarchiver setClass:[FIRInstallationsIIDTokenInfo class] forClassName:@"FIRInstanceIDTokenInfo"]; + FIRInstallationsIIDTokenInfo *IIDTokenInfo = + [unarchiver decodeObjectOfClass:[FIRInstallationsIIDTokenInfo class] + forKey:NSKeyedArchiveRootObjectKey]; + + if (IIDTokenInfo.token.length < 1) { + [resultPromise reject:[FIRInstallationsErrorUtil corruptedIIDTokenData]]; + return resultPromise; + } + + [resultPromise fulfill:IIDTokenInfo.token]; + + return resultPromise; +} + +- (FBLPromise *)IIDDefaultTokenData { + FBLPromise *resultPromise = [FBLPromise pendingPromise]; + + NSMutableDictionary *keychainQuery = [self IIDDefaultTokenDataKeychainQuery]; + NSError *error; + NSData *data = [GULKeychainUtils getItemWithQuery:keychainQuery error:&error]; + + if (data) { + [resultPromise fulfill:data]; + return resultPromise; + } else { + NSError *outError = error ?: [FIRInstallationsErrorUtil corruptedIIDTokenData]; + [resultPromise reject:outError]; + return resultPromise; + } +} + +- (NSMutableDictionary *)IIDDefaultTokenDataKeychainQuery { + NSDictionary *query = @{(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword}; + + NSMutableDictionary *finalQuery = [NSMutableDictionary dictionaryWithDictionary:query]; + finalQuery[(__bridge NSString *)kSecAttrGeneric] = kFIRInstallationsIIDTokenKeychainId; + + NSString *account = [self IIDAppIdentifier]; + if ([account length]) { + finalQuery[(__bridge NSString *)kSecAttrAccount] = account; + } + + finalQuery[(__bridge NSString *)kSecAttrService] = + [self serviceKeyForAuthorizedEntity:self.GCMSenderID scope:@"*"]; + return finalQuery; +} + +- (NSString *)IIDAppIdentifier { + return [[NSBundle mainBundle] bundleIdentifier] ?: @""; +} + +- (NSString *)serviceKeyForAuthorizedEntity:(NSString *)authorizedEntity scope:(NSString *)scope { + return [NSString stringWithFormat:@"%@:%@", authorizedEntity, scope]; +} + +@end diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.h new file mode 100644 index 0000000..1601bdc --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.h @@ -0,0 +1,65 @@ +/* + * 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 + +@class FBLPromise; +@class FIRInstallationsItem; + +@protocol FIRHeartbeatLoggerProtocol; + +NS_ASSUME_NONNULL_BEGIN + +FOUNDATION_EXPORT NSString *const kFIRInstallationsHeartbeatKey; + +/** + * The class is responsible for interacting with HTTP REST API for Installations. + */ +@interface FIRInstallationsAPIService : NSObject + +/** + * The default initializer. + * @param APIKey The Firebase project API key (see `FIROptions.APIKey`). + * @param projectID The Firebase project ID (see `FIROptions.projectID`). + * @param heartbeatLogger The heartbeat logger used to populate heartbeat data in request headers. + */ +- (instancetype)initWithAPIKey:(NSString *)APIKey + projectID:(NSString *)projectID + heartbeatLogger:(id)heartbeatLogger; + +/** + * Sends a request to register a new FID to get auth and refresh tokens. + * @param installation The `FIRInstallationsItem` instance with the FID to register. + * @return A promise that is resolved with a new `FIRInstallationsItem` instance with valid tokens. + * It is rejected with an error in case of a failure. + */ +- (FBLPromise *)registerInstallation:(FIRInstallationsItem *)installation; + +- (FBLPromise *)refreshAuthTokenForInstallation: + (FIRInstallationsItem *)installation; + +/** + * Sends a request to delete the installation, related auth tokens and all related data from the + * server. + * @param installation The installation to delete. + * @return Returns a promise that is resolved with the passed installation on successful deletion or + * is rejected with an error otherwise. + */ +- (FBLPromise *)deleteInstallation:(FIRInstallationsItem *)installation; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.m b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.m new file mode 100644 index 0000000..77408bb --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.m @@ -0,0 +1,383 @@ +/* + * 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 "FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.h" + +#if __has_include() +#import +#else +#import "FBLPromises.h" +#endif + +#import "FirebaseCore/Extension/FirebaseCoreInternal.h" +#import "FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h" +#import "FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.h" +#import "FirebaseInstallations/Source/Library/FIRInstallationsLogger.h" +#import "FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.h" + +NSString *const kFIRInstallationsAPIBaseURL = @"https://firebaseinstallations.googleapis.com"; +NSString *const kFIRInstallationsAPIKey = @"X-Goog-Api-Key"; +NSString *const kFIRInstallationsBundleId = @"X-Ios-Bundle-Identifier"; +NSString *const kFIRInstallationsIIDMigrationAuthHeader = @"x-goog-fis-ios-iid-migration-auth"; +NSString *const kFIRInstallationsHeartbeatKey = @"X-firebase-client"; + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRInstallationsURLSessionResponse : NSObject +@property(nonatomic) NSHTTPURLResponse *HTTPResponse; +@property(nonatomic) NSData *data; + +- (instancetype)initWithResponse:(NSHTTPURLResponse *)response data:(nullable NSData *)data; +@end + +@implementation FIRInstallationsURLSessionResponse + +- (instancetype)initWithResponse:(NSHTTPURLResponse *)response data:(nullable NSData *)data { + self = [super init]; + if (self) { + _HTTPResponse = response; + _data = data ?: [NSData data]; + } + return self; +} + +@end + +@interface FIRInstallationsAPIService () +@property(nonatomic, readonly) NSURLSession *URLSession; +@property(nonatomic, readonly) NSString *APIKey; +@property(nonatomic, readonly) NSString *projectID; +@property(readonly) id heartbeatLogger; +@end + +NS_ASSUME_NONNULL_END + +@implementation FIRInstallationsAPIService + +- (instancetype)initWithAPIKey:(NSString *)APIKey + projectID:(NSString *)projectID + heartbeatLogger:(id)heartbeatLogger { + NSURLSession *URLSession = [NSURLSession + sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]]; + return [self initWithURLSession:URLSession + APIKey:APIKey + projectID:projectID + heartbeatLogger:heartbeatLogger]; +} + +/// The initializer for tests. +- (instancetype)initWithURLSession:(NSURLSession *)URLSession + APIKey:(NSString *)APIKey + projectID:(NSString *)projectID + heartbeatLogger:(id)heartbeatLogger { + self = [super init]; + if (self) { + _URLSession = URLSession; + _APIKey = [APIKey copy]; + _projectID = [projectID copy]; + _heartbeatLogger = heartbeatLogger; + } + return self; +} + +#pragma mark - Public + +- (FBLPromise *)registerInstallation:(FIRInstallationsItem *)installation { + return [self validateInstallation:installation] + .then(^id _Nullable(FIRInstallationsItem *_Nullable validInstallation) { + return [self registerRequestWithInstallation:validInstallation]; + }) + .then(^id _Nullable(NSURLRequest *_Nullable request) { + return [self sendURLRequest:request]; + }) + .then(^id _Nullable(FIRInstallationsURLSessionResponse *response) { + return [self registeredInstallationWithInstallation:installation serverResponse:response]; + }); +} + +- (FBLPromise *)refreshAuthTokenForInstallation: + (FIRInstallationsItem *)installation { + return [self authTokenRequestWithInstallation:installation] + .then(^id _Nullable(NSURLRequest *_Nullable request) { + return [self sendURLRequest:request]; + }) + .then(^FBLPromise *( + FIRInstallationsURLSessionResponse *response) { + return [self authTokenWithServerResponse:response]; + }) + .then(^FIRInstallationsItem *(FIRInstallationsStoredAuthToken *authToken) { + FIRInstallationsItem *updatedInstallation = [installation copy]; + updatedInstallation.authToken = authToken; + return updatedInstallation; + }); +} + +- (FBLPromise *)deleteInstallation:(FIRInstallationsItem *)installation { + return [self deleteInstallationRequestWithInstallation:installation] + .then(^id _Nullable(NSURLRequest *_Nullable request) { + return [self sendURLRequest:request]; + }) + .then(^id _Nullable(FIRInstallationsURLSessionResponse *_Nullable value) { + // Return the original installation on success. + return installation; + }); +} + +#pragma mark - Register Installation + +- (FBLPromise *)registerRequestWithInstallation: + (FIRInstallationsItem *)installation { + NSString *URLString = [NSString stringWithFormat:@"%@/v1/projects/%@/installations/", + kFIRInstallationsAPIBaseURL, self.projectID]; + NSURL *URL = [NSURL URLWithString:URLString]; + + NSDictionary *bodyDict = @{ + // `firebaseInstallationID` is validated before but let's make sure it is not `nil` one more + // time to prevent a crash. + @"fid" : installation.firebaseInstallationID ?: @"", + @"authVersion" : @"FIS_v2", + @"appId" : installation.appID, + @"sdkVersion" : [self SDKVersion] + }; + + NSDictionary *headers; + if (installation.IIDDefaultToken) { + headers = @{kFIRInstallationsIIDMigrationAuthHeader : installation.IIDDefaultToken}; + } + + return [self requestWithURL:URL + HTTPMethod:@"POST" + bodyDict:bodyDict + refreshToken:nil + additionalHeaders:headers]; +} + +- (FBLPromise *) + registeredInstallationWithInstallation:(FIRInstallationsItem *)installation + serverResponse:(FIRInstallationsURLSessionResponse *)response { + return [FBLPromise do:^id { + FIRLogDebug(kFIRLoggerInstallations, kFIRInstallationsMessageCodeParsingAPIResponse, + @"Parsing server response for %@.", response.HTTPResponse.URL); + NSError *error; + FIRInstallationsItem *registeredInstallation = + [installation registeredInstallationWithJSONData:response.data + date:[NSDate date] + error:&error]; + if (registeredInstallation == nil) { + FIRLogDebug(kFIRLoggerInstallations, + kFIRInstallationsMessageCodeAPIResponseParsingInstallationFailed, + @"Failed to parse FIRInstallationsItem: %@.", error); + return error; + } + + FIRLogDebug(kFIRLoggerInstallations, + kFIRInstallationsMessageCodeAPIResponseParsingInstallationSucceed, + @"FIRInstallationsItem parsed successfully."); + return registeredInstallation; + }]; +} + +#pragma mark - Auth token + +- (FBLPromise *)authTokenRequestWithInstallation: + (FIRInstallationsItem *)installation { + NSString *URLString = + [NSString stringWithFormat:@"%@/v1/projects/%@/installations/%@/authTokens:generate", + kFIRInstallationsAPIBaseURL, self.projectID, + installation.firebaseInstallationID]; + NSURL *URL = [NSURL URLWithString:URLString]; + + NSDictionary *bodyDict = @{@"installation" : @{@"sdkVersion" : [self SDKVersion]}}; + return [self requestWithURL:URL + HTTPMethod:@"POST" + bodyDict:bodyDict + refreshToken:installation.refreshToken]; +} + +- (FBLPromise *)authTokenWithServerResponse: + (FIRInstallationsURLSessionResponse *)response { + return [FBLPromise do:^id { + FIRLogDebug(kFIRLoggerInstallations, kFIRInstallationsMessageCodeParsingAPIResponse, + @"Parsing server response for %@.", response.HTTPResponse.URL); + NSError *error; + FIRInstallationsStoredAuthToken *token = + [FIRInstallationsItem authTokenWithGenerateTokenAPIJSONData:response.data + date:[NSDate date] + error:&error]; + if (token == nil) { + FIRLogDebug(kFIRLoggerInstallations, + kFIRInstallationsMessageCodeAPIResponseParsingAuthTokenFailed, + @"Failed to parse FIRInstallationsStoredAuthToken: %@.", error); + return error; + } + + FIRLogDebug(kFIRLoggerInstallations, + kFIRInstallationsMessageCodeAPIResponseParsingAuthTokenSucceed, + @"FIRInstallationsStoredAuthToken parsed successfully."); + return token; + }]; +} + +#pragma mark - Delete Installation + +- (FBLPromise *)deleteInstallationRequestWithInstallation: + (FIRInstallationsItem *)installation { + NSString *URLString = [NSString stringWithFormat:@"%@/v1/projects/%@/installations/%@/", + kFIRInstallationsAPIBaseURL, self.projectID, + installation.firebaseInstallationID]; + NSURL *URL = [NSURL URLWithString:URLString]; + + return [self requestWithURL:URL + HTTPMethod:@"DELETE" + bodyDict:@{} + refreshToken:installation.refreshToken]; +} + +#pragma mark - URL Request +- (FBLPromise *)requestWithURL:(NSURL *)requestURL + HTTPMethod:(NSString *)HTTPMethod + bodyDict:(NSDictionary *)bodyDict + refreshToken:(nullable NSString *)refreshToken { + return [self requestWithURL:requestURL + HTTPMethod:HTTPMethod + bodyDict:bodyDict + refreshToken:refreshToken + additionalHeaders:nil]; +} + +- (FBLPromise *)requestWithURL:(NSURL *)requestURL + HTTPMethod:(NSString *)HTTPMethod + bodyDict:(NSDictionary *)bodyDict + refreshToken:(nullable NSString *)refreshToken + additionalHeaders:(nullable NSDictionary *) + additionalHeaders { + return [FBLPromise + onQueue:dispatch_get_global_queue(QOS_CLASS_UTILITY, 0) + do:^id _Nullable { + __block NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:requestURL]; + request.HTTPMethod = HTTPMethod; + NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier]; + [request addValue:self.APIKey forHTTPHeaderField:kFIRInstallationsAPIKey]; + [request addValue:bundleIdentifier forHTTPHeaderField:kFIRInstallationsBundleId]; + [self setJSONHTTPBody:bodyDict forRequest:request]; + if (refreshToken) { + NSString *authHeader = [NSString stringWithFormat:@"FIS_v2 %@", refreshToken]; + [request setValue:authHeader forHTTPHeaderField:@"Authorization"]; + } + // Heartbeat Header. + [request setValue:FIRHeaderValueFromHeartbeatsPayload( + [self.heartbeatLogger flushHeartbeatsIntoPayload]) + forHTTPHeaderField:kFIRInstallationsHeartbeatKey]; + + [additionalHeaders + enumerateKeysAndObjectsUsingBlock:^(NSString *_Nonnull key, NSString *_Nonnull obj, + BOOL *_Nonnull stop) { + [request setValue:obj forHTTPHeaderField:key]; + }]; + + return [request copy]; + }]; +} + +- (FBLPromise *)URLRequestPromise:(NSURLRequest *)request { + return [[FBLPromise async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) { + FIRLogDebug(kFIRLoggerInstallations, kFIRInstallationsMessageCodeSendAPIRequest, + @"Sending request: %@, body:%@, headers: %@.", request, + [[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding], + request.allHTTPHeaderFields); + [[self.URLSession + dataTaskWithRequest:request + completionHandler:^(NSData *_Nullable data, NSURLResponse *_Nullable response, + NSError *_Nullable error) { + if (error) { + FIRLogDebug(kFIRLoggerInstallations, + kFIRInstallationsMessageCodeAPIRequestNetworkError, + @"Request failed: %@, error: %@.", request, error); + reject(error); + } else { + FIRLogDebug(kFIRLoggerInstallations, kFIRInstallationsMessageCodeAPIRequestResponse, + @"Request response received: %@, error: %@, body: %@.", request, error, + [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); + fulfill([[FIRInstallationsURLSessionResponse alloc] + initWithResponse:(NSHTTPURLResponse *)response + data:data]); + } + }] resume]; + }] then:^id _Nullable(FIRInstallationsURLSessionResponse *response) { + return [self validateHTTPResponseStatusCode:response]; + }]; +} + +- (FBLPromise *)validateHTTPResponseStatusCode: + (FIRInstallationsURLSessionResponse *)response { + NSInteger statusCode = response.HTTPResponse.statusCode; + return [FBLPromise do:^id _Nullable { + if (statusCode < 200 || statusCode >= 300) { + FIRLogDebug(kFIRLoggerInstallations, kFIRInstallationsMessageCodeUnexpectedAPIRequestResponse, + @"Unexpected API response: %@, body: %@.", response.HTTPResponse, + [[NSString alloc] initWithData:response.data encoding:NSUTF8StringEncoding]); + return [FIRInstallationsErrorUtil APIErrorWithHTTPResponse:response.HTTPResponse + data:response.data]; + } + return response; + }]; +} + +- (FBLPromise *)sendURLRequest:(NSURLRequest *)request { + return [FBLPromise attempts:1 + delay:1 + condition:^BOOL(NSInteger remainingAttempts, NSError *_Nonnull error) { + return [FIRInstallationsErrorUtil isAPIError:error + withHTTPCode:FIRInstallationsHTTPCodesServerInternalError]; + } + retry:^id _Nullable { + return [self URLRequestPromise:request]; + }]; +} + +- (NSString *)SDKVersion { + return [NSString stringWithFormat:@"i:%@", FIRFirebaseVersion()]; +} + +#pragma mark - Validation + +- (FBLPromise *)validateInstallation:(FIRInstallationsItem *)installation { + FBLPromise *result = [FBLPromise pendingPromise]; + + NSError *validationError; + if ([installation isValid:&validationError]) { + [result fulfill:installation]; + } else { + [result reject:validationError]; + } + return result; +} + +#pragma mark - JSON + +- (void)setJSONHTTPBody:(NSDictionary *)body + forRequest:(NSMutableURLRequest *)request { + [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; + + NSError *error; + NSData *JSONData = [NSJSONSerialization dataWithJSONObject:body options:0 error:&error]; + if (JSONData == nil) { + // TODO: Log or return an error. + } + request.HTTPBody = JSONData; +} + +@end diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.h new file mode 100644 index 0000000..ec0217f --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.h @@ -0,0 +1,53 @@ +/* + * 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 "FirebaseInstallations/Source/Library/FIRInstallationsItem.h" + +@class FIRInstallationsStoredAuthToken; + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRInstallationsItem (RegisterInstallationAPI) + +/** + * Parses and validates the Register Installation API response and returns a corresponding + * `FIRInstallationsItem` instance on success. + * @param JSONData The data with JSON encoded API response. + * @param date The installation auth token expiration date will be calculated as `date` + + * `response.authToken.expiresIn`. For most of the cases `[NSDate date]` should be passed there. A + * different value may be passed e.g. for unit tests. + * @param outError A pointer to assign a specific `NSError` instance in case of failure. No error is + * assigned in case of success. + * @return Returns a new `FIRInstallationsItem` instance in the success case or `nil` otherwise. + */ +- (nullable FIRInstallationsItem *)registeredInstallationWithJSONData:(NSData *)JSONData + date:(NSDate *)date + error: + (NSError *_Nullable *)outError; + ++ (nullable FIRInstallationsStoredAuthToken *)authTokenWithGenerateTokenAPIJSONData:(NSData *)data + date:(NSDate *)date + error:(NSError **) + outError; + ++ (nullable FIRInstallationsStoredAuthToken *)authTokenWithJSONDict: + (NSDictionary *)dict + date:(NSDate *)date + error:(NSError **)outError; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.m b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.m new file mode 100644 index 0000000..e5c7360 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.m @@ -0,0 +1,142 @@ +/* + * 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 "FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.h" + +#import "FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h" +#import "FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h" + +@implementation FIRInstallationsItem (RegisterInstallationAPI) + +- (nullable FIRInstallationsItem *) + registeredInstallationWithJSONData:(NSData *)data + date:(NSDate *)date + error:(NSError *__autoreleasing _Nullable *_Nullable)outError { + NSDictionary *responseJSON = [FIRInstallationsItem dictionaryFromJSONData:data error:outError]; + if (!responseJSON) { + return nil; + } + + NSString *refreshToken = [FIRInstallationsItem validStringOrNilForKey:@"refreshToken" + fromDict:responseJSON]; + if (refreshToken == nil) { + FIRInstallationsItemSetErrorToPointer( + [FIRInstallationsErrorUtil FIDRegistrationErrorWithResponseMissingField:@"refreshToken"], + outError); + return nil; + } + + NSDictionary *authTokenDict = responseJSON[@"authToken"]; + if (![authTokenDict isKindOfClass:[NSDictionary class]]) { + FIRInstallationsItemSetErrorToPointer( + [FIRInstallationsErrorUtil FIDRegistrationErrorWithResponseMissingField:@"authToken"], + outError); + return nil; + } + + FIRInstallationsStoredAuthToken *authToken = + [FIRInstallationsItem authTokenWithJSONDict:authTokenDict date:date error:outError]; + if (authToken == nil) { + return nil; + } + + FIRInstallationsItem *installation = + [[FIRInstallationsItem alloc] initWithAppID:self.appID firebaseAppName:self.firebaseAppName]; + NSString *installationID = [FIRInstallationsItem validStringOrNilForKey:@"fid" + fromDict:responseJSON]; + installation.firebaseInstallationID = installationID ?: self.firebaseInstallationID; + installation.refreshToken = refreshToken; + installation.authToken = authToken; + installation.registrationStatus = FIRInstallationStatusRegistered; + + return installation; +} + +#pragma mark - Auth token + ++ (nullable FIRInstallationsStoredAuthToken *)authTokenWithGenerateTokenAPIJSONData:(NSData *)data + date:(NSDate *)date + error:(NSError **) + outError { + NSDictionary *dict = [self dictionaryFromJSONData:data error:outError]; + if (!dict) { + return nil; + } + + return [self authTokenWithJSONDict:dict date:date error:outError]; +} + ++ (nullable FIRInstallationsStoredAuthToken *)authTokenWithJSONDict: + (NSDictionary *)dict + date:(NSDate *)date + error:(NSError **)outError { + NSString *token = [self validStringOrNilForKey:@"token" fromDict:dict]; + if (token == nil) { + FIRInstallationsItemSetErrorToPointer( + [FIRInstallationsErrorUtil FIDRegistrationErrorWithResponseMissingField:@"authToken.token"], + outError); + return nil; + } + + NSString *expiresInString = [self validStringOrNilForKey:@"expiresIn" fromDict:dict]; + if (expiresInString == nil) { + FIRInstallationsItemSetErrorToPointer( + [FIRInstallationsErrorUtil + FIDRegistrationErrorWithResponseMissingField:@"authToken.expiresIn"], + outError); + return nil; + } + + // The response should contain the string in format like "604800s". + // The server should never response with anything else except seconds. + // Just drop the last character and parse a number from string. + NSString *expiresInSeconds = [expiresInString substringToIndex:expiresInString.length - 1]; + NSTimeInterval expiresIn = [expiresInSeconds doubleValue]; + NSDate *expirationDate = [date dateByAddingTimeInterval:expiresIn]; + + FIRInstallationsStoredAuthToken *authToken = [[FIRInstallationsStoredAuthToken alloc] init]; + authToken.status = FIRInstallationsAuthTokenStatusTokenReceived; + authToken.token = token; + authToken.expirationDate = expirationDate; + + return authToken; +} + +#pragma mark - JSON + ++ (nullable NSDictionary *)dictionaryFromJSONData:(NSData *)data + error:(NSError **)outError { + NSError *error; + NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; + + if (![responseJSON isKindOfClass:[NSDictionary class]]) { + FIRInstallationsItemSetErrorToPointer([FIRInstallationsErrorUtil JSONSerializationError:error], + outError); + return nil; + } + + return responseJSON; +} + ++ (NSString *)validStringOrNilForKey:(NSString *)key fromDict:(NSDictionary *)dict { + NSString *string = dict[key]; + if ([string isKindOfClass:[NSString class]] && string.length > 0) { + return string; + } + return nil; +} + +@end diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRCurrentDateProvider.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRCurrentDateProvider.h new file mode 100644 index 0000000..4d40338 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRCurrentDateProvider.h @@ -0,0 +1,27 @@ +/* + * 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 + +NS_ASSUME_NONNULL_BEGIN + +/** A block returning current date. */ +typedef NSDate *_Nonnull (^FIRCurrentDateProvider)(void); + +/** The function returns a `FIRCurrentDateProvider` block that returns a real current date. */ +FIRCurrentDateProvider FIRRealCurrentDateProvider(void); + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRCurrentDateProvider.m b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRCurrentDateProvider.m new file mode 100644 index 0000000..d2a1d40 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRCurrentDateProvider.m @@ -0,0 +1,23 @@ +/* + * 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 "FirebaseInstallations/Source/Library/InstallationsIDController/FIRCurrentDateProvider.h" + +FIRCurrentDateProvider FIRRealCurrentDateProvider(void) { + return ^NSDate *(void) { + return [NSDate date]; + }; +} diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsBackoffController.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsBackoffController.h new file mode 100644 index 0000000..5760618 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsBackoffController.h @@ -0,0 +1,54 @@ +/* + * 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 + +#import "FirebaseInstallations/Source/Library/InstallationsIDController/FIRCurrentDateProvider.h" + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSInteger, FIRInstallationsBackoffEvent) { + FIRInstallationsBackoffEventSuccess, + FIRInstallationsBackoffEventRecoverableFailure, + FIRInstallationsBackoffEventUnrecoverableFailure +}; + +/** The protocol defines API for a class that encapsulates backoff logic that prevents the SDK from + * sending unnecessary server requests. See API docs for the methods for more details. */ + +@protocol FIRInstallationsBackoffControllerProtocol + +/** The client must call the method each time a protected server request succeeds of fails. It will + * affect the `isNextRequestAllowed` method result for the current time, e.g. when 3 recoverable + * errors were logged in a row, then `isNextRequestAllowed` will return `YES` only in `pow(2, 3)` + * seconds. */ +- (void)registerEvent:(FIRInstallationsBackoffEvent)event; + +/** Returns if sending a next protected is recommended based on the time and the sequence of logged + * events and the current time. See also `registerEvent:`. */ +- (BOOL)isNextRequestAllowed; + +@end + +/** An implementation of `FIRInstallationsBackoffControllerProtocol` with exponential backoff for + * recoverable errors and constant backoff for recoverable errors. */ +@interface FIRInstallationsBackoffController : NSObject + +- (instancetype)initWithCurrentDateProvider:(FIRCurrentDateProvider)currentDateProvider; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsBackoffController.m b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsBackoffController.m new file mode 100644 index 0000000..1835d08 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsBackoffController.m @@ -0,0 +1,132 @@ +/* + * 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 "FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsBackoffController.h" + +static const NSTimeInterval k24Hours = 24 * 60 * 60; +static const NSTimeInterval k30Minutes = 30 * 60; + +/** The class represents `FIRInstallationsBackoffController` sate required to calculate next allowed + request time. The properties of the class are intentionally immutable because changing them + separately leads to an inconsistent state. */ +@interface FIRInstallationsBackoffEventData : NSObject + +@property(nonatomic, readonly) FIRInstallationsBackoffEvent eventType; +@property(nonatomic, readonly) NSDate *lastEventDate; +@property(nonatomic, readonly) NSInteger eventCount; + +@property(nonatomic, readonly) NSTimeInterval backoffTimeInterval; + +@end + +@implementation FIRInstallationsBackoffEventData + +- (instancetype)initWithEvent:(FIRInstallationsBackoffEvent)eventType + lastEventDate:(NSDate *)lastEventDate + eventCount:(NSInteger)eventCount { + self = [super init]; + if (self) { + _eventType = eventType; + _lastEventDate = lastEventDate; + _eventCount = eventCount; + + _backoffTimeInterval = [[self class] backoffTimeIntervalWithEvent:eventType + eventCount:eventCount]; + } + return self; +} + ++ (NSTimeInterval)backoffTimeIntervalWithEvent:(FIRInstallationsBackoffEvent)eventType + eventCount:(NSInteger)eventCount { + switch (eventType) { + case FIRInstallationsBackoffEventSuccess: + return 0; + break; + + case FIRInstallationsBackoffEventRecoverableFailure: + return [self recoverableErrorBackoffTimeForAttemptNumber:eventCount]; + break; + + case FIRInstallationsBackoffEventUnrecoverableFailure: + return k24Hours; + break; + } +} + ++ (NSTimeInterval)recoverableErrorBackoffTimeForAttemptNumber:(NSInteger)attemptNumber { + NSTimeInterval exponentialInterval = pow(2, attemptNumber) + [self randomMilliseconds]; + return MIN(exponentialInterval, k30Minutes); +} + ++ (NSTimeInterval)randomMilliseconds { + int32_t random_millis = ABS(arc4random() % 1000); + return (double)random_millis * 0.001; +} + +@end + +@interface FIRInstallationsBackoffController () + +@property(nonatomic, readonly) FIRCurrentDateProvider currentDateProvider; + +@property(nonatomic, nullable) FIRInstallationsBackoffEventData *lastEventData; + +@end + +@implementation FIRInstallationsBackoffController + +- (instancetype)init { + return [self initWithCurrentDateProvider:FIRRealCurrentDateProvider()]; +} + +- (instancetype)initWithCurrentDateProvider:(FIRCurrentDateProvider)currentDateProvider { + self = [super init]; + if (self) { + _currentDateProvider = [currentDateProvider copy]; + } + return self; +} + +- (BOOL)isNextRequestAllowed { + @synchronized(self) { + if (self.lastEventData == nil) { + return YES; + } + + NSTimeInterval timeSinceLastEvent = + [self.currentDateProvider() timeIntervalSinceDate:self.lastEventData.lastEventDate]; + return timeSinceLastEvent >= self.lastEventData.backoffTimeInterval; + } +} + +- (void)registerEvent:(FIRInstallationsBackoffEvent)event { + @synchronized(self) { + // Event of the same type as was registered before. + if (self.lastEventData && self.lastEventData.eventType == event) { + self.lastEventData = [[FIRInstallationsBackoffEventData alloc] + initWithEvent:event + lastEventDate:self.currentDateProvider() + eventCount:self.lastEventData.eventCount + 1]; + } else { // A different event. + self.lastEventData = + [[FIRInstallationsBackoffEventData alloc] initWithEvent:event + lastEventDate:self.currentDateProvider() + eventCount:1]; + } + } +} + +@end diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.h new file mode 100644 index 0000000..8e66af9 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.h @@ -0,0 +1,40 @@ +/* + * 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 + +NS_ASSUME_NONNULL_BEGIN + +@class FBLPromise; +@class FIRApp; +@class FIRInstallationsItem; + +/** + * The class is responsible for managing FID for a given `FIRApp`. + */ +@interface FIRInstallationsIDController : NSObject + +- (instancetype)initWithApp:(FIRApp *)app; + +- (FBLPromise *)getInstallationItem; + +- (FBLPromise *)getAuthTokenForcingRefresh:(BOOL)forceRefresh; + +- (FBLPromise *)deleteInstallation; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.m b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.m new file mode 100644 index 0000000..6ade8cc --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.m @@ -0,0 +1,530 @@ +/* + * 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 "FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.h" + +#if __has_include() +#import +#else +#import "FBLPromises.h" +#endif + +#import +#import "FirebaseCore/Extension/FirebaseCoreInternal.h" + +#import "FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h" +#import "FirebaseInstallations/Source/Library/FIRInstallationsItem.h" +#import "FirebaseInstallations/Source/Library/FIRInstallationsLogger.h" +#import "FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.h" +#import "FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.h" +#import "FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.h" +#import "FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsBackoffController.h" +#import "FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.h" +#import "FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.h" + +#import "FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.h" +#import "FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h" + +const NSNotificationName FIRInstallationIDDidChangeNotification = + @"FIRInstallationIDDidChangeNotification"; +NSString *const kFIRInstallationIDDidChangeNotificationAppNameKey = + @"FIRInstallationIDDidChangeNotification"; + +NSTimeInterval const kFIRInstallationsTokenExpirationThreshold = 60 * 60; // 1 hour. + +static NSString *const kKeychainService = @"com.firebase.FIRInstallations.installations"; + +@interface FIRInstallationsIDController () +@property(nonatomic, readonly) NSString *appID; +@property(nonatomic, readonly) NSString *appName; + +@property(nonatomic, readonly) FIRInstallationsStore *installationsStore; +@property(nonatomic, readonly) FIRInstallationsIIDStore *IIDStore; +@property(nonatomic, readonly) FIRInstallationsIIDTokenStore *IIDTokenStore; + +@property(nonatomic, readonly) FIRInstallationsAPIService *APIService; + +@property(nonatomic, readonly) id backoffController; + +@property(nonatomic, readonly) FIRInstallationsSingleOperationPromiseCache + *getInstallationPromiseCache; +@property(nonatomic, readonly) + FIRInstallationsSingleOperationPromiseCache *authTokenPromiseCache; +@property(nonatomic, readonly) FIRInstallationsSingleOperationPromiseCache + *authTokenForcingRefreshPromiseCache; +@property(nonatomic, readonly) + FIRInstallationsSingleOperationPromiseCache *deleteInstallationPromiseCache; +@end + +@implementation FIRInstallationsIDController + +- (instancetype)initWithApp:(FIRApp *)app { + NSString *serviceName = + [FIRInstallationsIDController keychainServiceWithAppID:app.options.googleAppID]; + GULKeychainStorage *secureStorage = [[GULKeychainStorage alloc] initWithService:serviceName]; + FIRInstallationsStore *installationsStore = + [[FIRInstallationsStore alloc] initWithSecureStorage:secureStorage + accessGroup:app.options.appGroupID]; + + FIRInstallationsAPIService *apiService = + [[FIRInstallationsAPIService alloc] initWithAPIKey:app.options.APIKey + projectID:app.options.projectID + heartbeatLogger:app.heartbeatLogger]; + + FIRInstallationsIIDStore *IIDStore = [[FIRInstallationsIIDStore alloc] init]; + FIRInstallationsIIDTokenStore *IIDCheckingStore = + [[FIRInstallationsIIDTokenStore alloc] initWithGCMSenderID:app.options.GCMSenderID]; + + FIRInstallationsBackoffController *backoffController = + [[FIRInstallationsBackoffController alloc] init]; + + return [self initWithGoogleAppID:app.options.googleAppID + appName:app.name + installationsStore:installationsStore + APIService:apiService + IIDStore:IIDStore + IIDTokenStore:IIDCheckingStore + backoffController:backoffController]; +} + +/// The initializer is supposed to be used by tests to inject `installationsStore`. +- (instancetype)initWithGoogleAppID:(NSString *)appID + appName:(NSString *)appName + installationsStore:(FIRInstallationsStore *)installationsStore + APIService:(FIRInstallationsAPIService *)APIService + IIDStore:(FIRInstallationsIIDStore *)IIDStore + IIDTokenStore:(FIRInstallationsIIDTokenStore *)IIDTokenStore + backoffController: + (id)backoffController { + self = [super init]; + if (self) { + _appID = appID; + _appName = appName; + _installationsStore = installationsStore; + _APIService = APIService; + _IIDStore = IIDStore; + _IIDTokenStore = IIDTokenStore; + _backoffController = backoffController; + + __weak FIRInstallationsIDController *weakSelf = self; + + _getInstallationPromiseCache = [[FIRInstallationsSingleOperationPromiseCache alloc] + initWithNewOperationHandler:^FBLPromise *_Nonnull { + FIRInstallationsIDController *strongSelf = weakSelf; + return [strongSelf createGetInstallationItemPromise]; + }]; + + _authTokenPromiseCache = [[FIRInstallationsSingleOperationPromiseCache alloc] + initWithNewOperationHandler:^FBLPromise *_Nonnull { + FIRInstallationsIDController *strongSelf = weakSelf; + return [strongSelf installationWithValidAuthTokenForcingRefresh:NO]; + }]; + + _authTokenForcingRefreshPromiseCache = [[FIRInstallationsSingleOperationPromiseCache alloc] + initWithNewOperationHandler:^FBLPromise *_Nonnull { + FIRInstallationsIDController *strongSelf = weakSelf; + return [strongSelf installationWithValidAuthTokenForcingRefresh:YES]; + }]; + + _deleteInstallationPromiseCache = [[FIRInstallationsSingleOperationPromiseCache alloc] + initWithNewOperationHandler:^FBLPromise *_Nonnull { + FIRInstallationsIDController *strongSelf = weakSelf; + return [strongSelf createDeleteInstallationPromise]; + }]; + } + return self; +} + +#pragma mark - Get Installation. + +- (FBLPromise *)getInstallationItem { + return [self.getInstallationPromiseCache getExistingPendingOrCreateNewPromise]; +} + +- (FBLPromise *)createGetInstallationItemPromise { + FIRLogDebug(kFIRLoggerInstallations, + kFIRInstallationsMessageCodeNewGetInstallationOperationCreated, @"%s, appName: %@", + __PRETTY_FUNCTION__, self.appName); + + FBLPromise *installationItemPromise = + [self getStoredInstallation].recover(^id(NSError *error) { + return [self createAndSaveFID]; + }); + + // Initiate registration process on success if needed, but return the installation without waiting + // for it. + installationItemPromise.then(^id(FIRInstallationsItem *installation) { + [self getAuthTokenForcingRefresh:NO]; + return nil; + }); + + return installationItemPromise; +} + +- (FBLPromise *)getStoredInstallation { + return [self.installationsStore installationForAppID:self.appID appName:self.appName].validate( + ^BOOL(FIRInstallationsItem *installation) { + NSError *validationError; + BOOL isValid = [installation isValid:&validationError]; + + if (!isValid) { + FIRLogWarning( + kFIRLoggerInstallations, kFIRInstallationsMessageCodeCorruptedStoredInstallation, + @"Stored installation validation error: %@", validationError.localizedDescription); + } + + return isValid; + }); +} + +- (FBLPromise *)createAndSaveFID { + return [self migrateOrGenerateInstallation] + .then(^FBLPromise *(FIRInstallationsItem *installation) { + return [self saveInstallation:installation]; + }) + .then(^FIRInstallationsItem *(FIRInstallationsItem *installation) { + [self postFIDDidChangeNotification]; + return installation; + }); +} + +- (FBLPromise *)saveInstallation:(FIRInstallationsItem *)installation { + return [self.installationsStore saveInstallation:installation].then( + ^FIRInstallationsItem *(NSNull *result) { + return installation; + }); +} + +/** + * Tries to migrate IID data stored by FirebaseInstanceID SDK or generates a new Installation ID if + * not found. + */ +- (FBLPromise *)migrateOrGenerateInstallation { + if (![self isDefaultApp]) { + // Existing IID should be used only for default FirebaseApp. + FIRInstallationsItem *installation = + [self createInstallationWithFID:[FIRInstallationsItem generateFID] IIDDefaultToken:nil]; + return [FBLPromise resolvedWith:installation]; + } + + return [[[FBLPromise + all:@[ [self.IIDStore existingIID], [self.IIDTokenStore existingIIDDefaultToken] ]] + then:^id _Nullable(NSArray *_Nullable results) { + NSString *existingIID = results[0]; + NSString *IIDDefaultToken = results[1]; + + return [self createInstallationWithFID:existingIID IIDDefaultToken:IIDDefaultToken]; + }] recover:^id _Nullable(NSError *_Nonnull error) { + return [self createInstallationWithFID:[FIRInstallationsItem generateFID] IIDDefaultToken:nil]; + }]; +} + +- (FIRInstallationsItem *)createInstallationWithFID:(NSString *)FID + IIDDefaultToken:(nullable NSString *)IIDDefaultToken { + FIRInstallationsItem *installation = [[FIRInstallationsItem alloc] initWithAppID:self.appID + firebaseAppName:self.appName]; + installation.firebaseInstallationID = FID; + installation.IIDDefaultToken = IIDDefaultToken; + installation.registrationStatus = FIRInstallationStatusUnregistered; + return installation; +} + +#pragma mark - FID registration + +- (FBLPromise *)registerInstallationIfNeeded: + (FIRInstallationsItem *)installation { + switch (installation.registrationStatus) { + case FIRInstallationStatusRegistered: + // Already registered. Do nothing. + return [FBLPromise resolvedWith:installation]; + + case FIRInstallationStatusUnknown: + case FIRInstallationStatusUnregistered: + // Registration required. Proceed. + break; + } + + // Check for backoff. + if (![self.backoffController isNextRequestAllowed]) { + return [FIRInstallationsErrorUtil + rejectedPromiseWithError:[FIRInstallationsErrorUtil backoffIntervalWaitError]]; + } + + return [self.APIService registerInstallation:installation] + .catch(^(NSError *_Nonnull error) { + [self updateBackoffWithSuccess:NO APIError:error]; + + if ([self doesRegistrationErrorRequireConfigChange:error]) { + FIRLogError(kFIRLoggerInstallations, + kFIRInstallationsMessageCodeInvalidFirebaseConfiguration, + @"Firebase Installation registration failed for app with name: %@, error:\n" + @"%@\nPlease make sure you use valid GoogleService-Info.plist", + self.appName, error.userInfo[NSLocalizedFailureReasonErrorKey]); + } + }) + .then(^id(FIRInstallationsItem *registeredInstallation) { + [self updateBackoffWithSuccess:YES APIError:nil]; + return [self saveInstallation:registeredInstallation]; + }) + .then(^FIRInstallationsItem *(FIRInstallationsItem *registeredInstallation) { + // Server may respond with a different FID if the sent one cannot be accepted. + if (![registeredInstallation.firebaseInstallationID + isEqualToString:installation.firebaseInstallationID]) { + [self postFIDDidChangeNotification]; + } + return registeredInstallation; + }); +} + +- (BOOL)doesRegistrationErrorRequireConfigChange:(NSError *)error { + FIRInstallationsHTTPError *HTTPError = (FIRInstallationsHTTPError *)error; + if (![HTTPError isKindOfClass:[FIRInstallationsHTTPError class]]) { + return NO; + } + + switch (HTTPError.HTTPResponse.statusCode) { + // These are the errors that require Firebase configuration change. + case FIRInstallationsRegistrationHTTPCodeInvalidArgument: + case FIRInstallationsRegistrationHTTPCodeAPIKeyToProjectIDMismatch: + case FIRInstallationsRegistrationHTTPCodeProjectNotFound: + return YES; + + default: + return NO; + } +} + +#pragma mark - Auth Token + +- (FBLPromise *)getAuthTokenForcingRefresh:(BOOL)forceRefresh { + if (forceRefresh || [self.authTokenForcingRefreshPromiseCache getExistingPendingPromise] != nil) { + return [self.authTokenForcingRefreshPromiseCache getExistingPendingOrCreateNewPromise]; + } else { + return [self.authTokenPromiseCache getExistingPendingOrCreateNewPromise]; + } +} + +- (FBLPromise *)installationWithValidAuthTokenForcingRefresh: + (BOOL)forceRefresh { + FIRLogDebug(kFIRLoggerInstallations, kFIRInstallationsMessageCodeNewGetAuthTokenOperationCreated, + @"-[FIRInstallationsIDController installationWithValidAuthTokenForcingRefresh:%@], " + @"appName: %@", + @(forceRefresh), self.appName); + + return [self getInstallationItem] + .then(^FBLPromise *(FIRInstallationsItem *installation) { + return [self registerInstallationIfNeeded:installation]; + }) + .then(^id(FIRInstallationsItem *registeredInstallation) { + BOOL isTokenExpiredOrExpiresSoon = + [registeredInstallation.authToken.expirationDate timeIntervalSinceDate:[NSDate date]] < + kFIRInstallationsTokenExpirationThreshold; + if (forceRefresh || isTokenExpiredOrExpiresSoon) { + return [self refreshAuthTokenForInstallation:registeredInstallation]; + } else { + return registeredInstallation; + } + }) + .recover(^id(NSError *error) { + return [self regenerateFIDOnRefreshTokenErrorIfNeeded:error]; + }); +} + +- (FBLPromise *)refreshAuthTokenForInstallation: + (FIRInstallationsItem *)installation { + // Check for backoff. + if (![self.backoffController isNextRequestAllowed]) { + return [FIRInstallationsErrorUtil + rejectedPromiseWithError:[FIRInstallationsErrorUtil backoffIntervalWaitError]]; + } + + return [[[self.APIService refreshAuthTokenForInstallation:installation] + then:^id _Nullable(FIRInstallationsItem *_Nullable refreshedInstallation) { + [self updateBackoffWithSuccess:YES APIError:nil]; + return [self saveInstallation:refreshedInstallation]; + }] recover:^id _Nullable(NSError *_Nonnull error) { + // Pass the error to the backoff controller. + [self updateBackoffWithSuccess:NO APIError:error]; + return error; + }]; +} + +- (id)regenerateFIDOnRefreshTokenErrorIfNeeded:(NSError *)error { + if (![error isKindOfClass:[FIRInstallationsHTTPError class]]) { + // No recovery possible. Return the same error. + return error; + } + + FIRInstallationsHTTPError *HTTPError = (FIRInstallationsHTTPError *)error; + switch (HTTPError.HTTPResponse.statusCode) { + case FIRInstallationsAuthTokenHTTPCodeInvalidAuthentication: + case FIRInstallationsAuthTokenHTTPCodeFIDNotFound: + // The stored installation was damaged or blocked by the server. + // Delete the stored installation then generate and register a new one. + return [self getInstallationItem] + .then(^FBLPromise *(FIRInstallationsItem *installation) { + return [self deleteInstallationLocally:installation]; + }) + .then(^FBLPromise *(id result) { + return [self installationWithValidAuthTokenForcingRefresh:NO]; + }); + + default: + // No recovery possible. Return the same error. + return error; + } +} + +#pragma mark - Delete FID + +- (FBLPromise *)deleteInstallation { + return [self.deleteInstallationPromiseCache getExistingPendingOrCreateNewPromise]; +} + +- (FBLPromise *)createDeleteInstallationPromise { + FIRLogDebug(kFIRLoggerInstallations, + kFIRInstallationsMessageCodeNewDeleteInstallationOperationCreated, @"%s, appName: %@", + __PRETTY_FUNCTION__, self.appName); + + // Check for ongoing requests first, if there is no a request, then check local storage for + // existing installation. + FBLPromise *currentInstallationPromise = + [self mostRecentInstallationOperation] ?: [self getStoredInstallation]; + + return currentInstallationPromise + .then(^id(FIRInstallationsItem *installation) { + return [self sendDeleteInstallationRequestIfNeeded:installation]; + }) + .then(^id(FIRInstallationsItem *installation) { + // Remove the installation from the local storage. + return [self deleteInstallationLocally:installation]; + }); +} + +- (FBLPromise *)deleteInstallationLocally:(FIRInstallationsItem *)installation { + return [self.installationsStore removeInstallationForAppID:installation.appID + appName:installation.firebaseAppName] + .then(^FBLPromise *(NSNull *result) { + return [self deleteExistingIIDIfNeeded]; + }) + .then(^NSNull *(NSNull *result) { + [self postFIDDidChangeNotification]; + return result; + }); +} + +- (FBLPromise *)sendDeleteInstallationRequestIfNeeded: + (FIRInstallationsItem *)installation { + switch (installation.registrationStatus) { + case FIRInstallationStatusUnknown: + case FIRInstallationStatusUnregistered: + // The installation is not registered, so it is safe to be deleted as is, so return early. + return [FBLPromise resolvedWith:installation]; + break; + + case FIRInstallationStatusRegistered: + // Proceed to de-register the installation on the server. + break; + } + + return [self.APIService deleteInstallation:installation].recover(^id(NSError *APIError) { + if ([FIRInstallationsErrorUtil isAPIError:APIError withHTTPCode:404]) { + // The installation was not found on the server. + // Return success. + return installation; + } else { + // Re-throw the error otherwise. + return APIError; + } + }); +} + +- (FBLPromise *)deleteExistingIIDIfNeeded { + if ([self isDefaultApp]) { + return [self.IIDStore deleteExistingIID]; + } else { + return [FBLPromise resolvedWith:[NSNull null]]; + } +} + +- (nullable FBLPromise *)mostRecentInstallationOperation { + return [self.authTokenForcingRefreshPromiseCache getExistingPendingPromise] + ?: [self.authTokenPromiseCache getExistingPendingPromise] + ?: [self.getInstallationPromiseCache getExistingPendingPromise]; +} + +#pragma mark - Backoff + +- (void)updateBackoffWithSuccess:(BOOL)success APIError:(nullable NSError *)APIError { + if (success) { + [self.backoffController registerEvent:FIRInstallationsBackoffEventSuccess]; + } else if ([APIError isKindOfClass:[FIRInstallationsHTTPError class]]) { + FIRInstallationsHTTPError *HTTPResponseError = (FIRInstallationsHTTPError *)APIError; + NSInteger statusCode = HTTPResponseError.HTTPResponse.statusCode; + + if (statusCode == FIRInstallationsAuthTokenHTTPCodeInvalidAuthentication || + statusCode == FIRInstallationsAuthTokenHTTPCodeFIDNotFound) { + // These errors are explicitly excluded because they are handled by FIS SDK itself so don't + // require backoff. + } else if (statusCode == 400 || statusCode == 403) { // Explicitly unrecoverable errors. + [self.backoffController registerEvent:FIRInstallationsBackoffEventUnrecoverableFailure]; + } else if (statusCode == 429 || + (statusCode >= 500 && statusCode < 600)) { // Explicitly recoverable errors. + [self.backoffController registerEvent:FIRInstallationsBackoffEventRecoverableFailure]; + } else { // Treat all unknown errors as recoverable. + [self.backoffController registerEvent:FIRInstallationsBackoffEventRecoverableFailure]; + } + } + + // If the error class is not `FIRInstallationsHTTPError` it indicates a connection error. Such + // errors should not change backoff interval. +} + +#pragma mark - Notifications + +- (void)postFIDDidChangeNotification { + [[NSNotificationCenter defaultCenter] + postNotificationName:FIRInstallationIDDidChangeNotification + object:nil + userInfo:@{kFIRInstallationIDDidChangeNotificationAppNameKey : self.appName}]; +} + +#pragma mark - Default App + +- (BOOL)isDefaultApp { + return [self.appName isEqualToString:kFIRDefaultAppName]; +} + +#pragma mark - Keychain + ++ (NSString *)keychainServiceWithAppID:(NSString *)appID { +#if TARGET_OS_MACCATALYST || TARGET_OS_OSX + // We need to keep service name unique per application on macOS. + // Applications on macOS may request access to Keychain items stored by other applications. It + // means that when the app looks up for a relevant Keychain item in the service scope it will + // request user password to grant access to the Keychain if there are other Keychain items from + // other applications stored under the same Keychain Service. + return [kKeychainService stringByAppendingFormat:@".%@", appID]; +#else + // Use a constant Keychain service for non-macOS because: + // 1. Keychain items cannot be shared between apps until configured specifically so the service + // name collisions are not a concern + // 2. We don't want to change the service name to avoid doing a migration. + return kKeychainService; +#endif +} + +@end diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.h new file mode 100644 index 0000000..aeb54e5 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.h @@ -0,0 +1,58 @@ +/* + * 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 + +@class FBLPromise; + +NS_ASSUME_NONNULL_BEGIN + +/** + * The class makes sure the a single operation (represented by a promise) is performed at a time. If + * there is an ongoing operation, then its existing corresponding promise will be returned instead + * of starting a new operation. + */ +@interface FIRInstallationsSingleOperationPromiseCache<__covariant ResultType> : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +/** + * The designated initializer. + * @param newOperationHandler The block that must return a new promise representing the + * single-at-a-time operation. The promise should be fulfilled when the operation is completed. The + * factory block will be used to create a new promise when needed. + */ +- (instancetype)initWithNewOperationHandler: + (FBLPromise *_Nonnull (^)(void))newOperationHandler NS_DESIGNATED_INITIALIZER; + +/** + * Creates a new promise or returns an existing pending one. + * @return Returns and existing pending promise if exists. If the pending promise does not exist + * then a new one will be created using the `factory` block passed in the initializer. Once the + * pending promise gets resolved, it is removed, so calling the method again will lead to creating + * and caching another promise. + */ +- (FBLPromise *)getExistingPendingOrCreateNewPromise; + +/** + * Returns an existing pending promise or `nil`. + * @return Returns an existing pending promise if there is one or `nil` otherwise. + */ +- (nullable FBLPromise *)getExistingPendingPromise; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.m b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.m new file mode 100644 index 0000000..7ae8781 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.m @@ -0,0 +1,75 @@ +/* + * 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 "FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.h" + +#if __has_include() +#import +#else +#import "FBLPromises.h" +#endif + +@interface FIRInstallationsSingleOperationPromiseCache () +@property(nonatomic, readonly) FBLPromise *_Nonnull (^newOperationHandler)(void); +@property(nonatomic, nullable) FBLPromise *pendingPromise; +@end + +@implementation FIRInstallationsSingleOperationPromiseCache + +- (instancetype)initWithNewOperationHandler: + (FBLPromise *_Nonnull (^)(void))newOperationHandler { + if (newOperationHandler == nil) { + [NSException raise:NSInvalidArgumentException + format:@"`newOperationHandler` must not be `nil`."]; + } + + self = [super init]; + if (self) { + _newOperationHandler = [newOperationHandler copy]; + } + return self; +} + +- (FBLPromise *)getExistingPendingOrCreateNewPromise { + @synchronized(self) { + if (!self.pendingPromise) { + self.pendingPromise = self.newOperationHandler(); + + self.pendingPromise + .then(^id(id result) { + @synchronized(self) { + self.pendingPromise = nil; + return nil; + } + }) + .catch(^void(NSError *error) { + @synchronized(self) { + self.pendingPromise = nil; + } + }); + } + + return self.pendingPromise; + } +} + +- (nullable FBLPromise *)getExistingPendingPromise { + @synchronized(self) { + return self.pendingPromise; + } +} + +@end diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsStatus.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsStatus.h new file mode 100644 index 0000000..3edc692 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsStatus.h @@ -0,0 +1,35 @@ +/* + * 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 + +/** + * The enum represent possible states of the installation ID. + * + * WARNING: The enum is stored to Keychain as a part of `FIRInstallationsStoredItem`. Modification + * of it can lead to incompatibility with previous version. Any modification must be evaluated and, + * if it is really needed, the `storageVersion` must be bumped and proper migration code added. + */ +typedef NS_ENUM(NSInteger, FIRInstallationsStatus) { + /** Represents either an initial status when a FIRInstallationsItem instance was created but not + * stored to Keychain or an undefined status (e.g. when the status failed to deserialize). + */ + FIRInstallationStatusUnknown, + /// The Firebase Installation has not yet been registered with FIS. + FIRInstallationStatusUnregistered, + /// The Firebase Installation has successfully been registered with FIS. + FIRInstallationStatusRegistered, +}; diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.h new file mode 100644 index 0000000..b86fb39 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.h @@ -0,0 +1,71 @@ +/* + * 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 + +@class FBLPromise; +@class FIRInstallationsItem; +@class GULKeychainStorage; + +NS_ASSUME_NONNULL_BEGIN + +/// The user defaults suite name used to store data. +extern NSString *const kFIRInstallationsStoreUserDefaultsID; + +/// The class is responsible for storing and accessing the installations data. +@interface FIRInstallationsStore : NSObject + +/** + * The default initializer. + * @param storage The secure storage to save installations data. + * @param accessGroup The Keychain Access Group to store and request the installations data. + */ +- (instancetype)initWithSecureStorage:(GULKeychainStorage *)storage + accessGroup:(nullable NSString *)accessGroup; + +/** + * Retrieves existing installation ID if there is. + * @param appID The Firebase(Google) Application ID. + * @param appName The Firebase Application Name. + * + * @return Returns a `FBLPromise` instance. The promise is resolved with a FIRInstallationsItem + * instance if there is a valid installation stored for `appID` and `appName`. The promise is + * rejected with a specific error when the installation has not been found or with another possible + * error. + */ +- (FBLPromise *)installationForAppID:(NSString *)appID + appName:(NSString *)appName; + +/** + * Saves the given installation. + * + * @param installationItem The installation data. + * @return Returns a promise that is resolved with `[NSNull null]` on success. + */ +- (FBLPromise *)saveInstallation:(FIRInstallationsItem *)installationItem; + +/** + * Removes installation data for the given app parameters. + * @param appID The Firebase(Google) Application ID. + * @param appName The Firebase Application Name. + * + * @return Returns a promise that is resolved with `[NSNull null]` on success. + */ +- (FBLPromise *)removeInstallationForAppID:(NSString *)appID appName:(NSString *)appName; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.m b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.m new file mode 100644 index 0000000..40cd5fb --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.m @@ -0,0 +1,126 @@ +/* + * 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 "FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.h" + +#import + +#if __has_include() +#import +#else +#import "FBLPromises.h" +#endif + +#import + +#import "FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h" +#import "FirebaseInstallations/Source/Library/FIRInstallationsItem.h" +#import "FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.h" + +NSString *const kFIRInstallationsStoreUserDefaultsID = @"com.firebase.FIRInstallations"; + +@interface FIRInstallationsStore () +@property(nonatomic, readonly) GULKeychainStorage *secureStorage; +@property(nonatomic, readonly, nullable) NSString *accessGroup; +@property(nonatomic, readonly) dispatch_queue_t queue; +@property(nonatomic, readonly) GULUserDefaults *userDefaults; +@end + +@implementation FIRInstallationsStore + +- (instancetype)initWithSecureStorage:(GULKeychainStorage *)storage + accessGroup:(NSString *)accessGroup { + self = [super init]; + if (self) { + _secureStorage = storage; + _accessGroup = [accessGroup copy]; + _queue = dispatch_queue_create("com.firebase.FIRInstallationsStore", DISPATCH_QUEUE_SERIAL); + + NSString *userDefaultsSuiteName = _accessGroup ?: kFIRInstallationsStoreUserDefaultsID; + _userDefaults = [[GULUserDefaults alloc] initWithSuiteName:userDefaultsSuiteName]; + } + return self; +} + +- (FBLPromise *)installationForAppID:(NSString *)appID + appName:(NSString *)appName { + NSString *itemID = [FIRInstallationsItem identifierWithAppID:appID appName:appName]; + return [self installationExistsForAppID:appID appName:appName] + .then(^id(id result) { + return [self.secureStorage getObjectForKey:itemID + objectClass:[FIRInstallationsStoredItem class] + accessGroup:self.accessGroup]; + }) + .then(^id(FIRInstallationsStoredItem *_Nullable storedItem) { + if (storedItem == nil) { + return [FIRInstallationsErrorUtil installationItemNotFoundForAppID:appID appName:appName]; + } + + FIRInstallationsItem *item = [[FIRInstallationsItem alloc] initWithAppID:appID + firebaseAppName:appName]; + [item updateWithStoredItem:storedItem]; + return item; + }); +} + +- (FBLPromise *)saveInstallation:(FIRInstallationsItem *)installationItem { + FIRInstallationsStoredItem *storedItem = [installationItem storedItem]; + NSString *identifier = [installationItem identifier]; + + return + [self.secureStorage setObject:storedItem forKey:identifier accessGroup:self.accessGroup].then( + ^id(id result) { + return [self setInstallationExists:YES forItemWithIdentifier:identifier]; + }); +} + +- (FBLPromise *)removeInstallationForAppID:(NSString *)appID appName:(NSString *)appName { + NSString *identifier = [FIRInstallationsItem identifierWithAppID:appID appName:appName]; + return [self.secureStorage removeObjectForKey:identifier accessGroup:self.accessGroup].then( + ^id(id result) { + return [self setInstallationExists:NO forItemWithIdentifier:identifier]; + }); +} + +#pragma mark - User defaults + +- (FBLPromise *)installationExistsForAppID:(NSString *)appID appName:(NSString *)appName { + NSString *identifier = [FIRInstallationsItem identifierWithAppID:appID appName:appName]; + return [FBLPromise onQueue:self.queue + do:^id _Nullable { + return [[self userDefaults] objectForKey:identifier] != nil + ? [NSNull null] + : [FIRInstallationsErrorUtil + installationItemNotFoundForAppID:appID + appName:appName]; + }]; +} + +- (FBLPromise *)setInstallationExists:(BOOL)exists + forItemWithIdentifier:(NSString *)identifier { + return [FBLPromise onQueue:self.queue + do:^id _Nullable { + if (exists) { + [[self userDefaults] setBool:YES forKey:identifier]; + } else { + [[self userDefaults] removeObjectForKey:identifier]; + } + + return [NSNull null]; + }]; +} + +@end diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h new file mode 100644 index 0000000..4da2337 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h @@ -0,0 +1,58 @@ +/* + * 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 + +NS_ASSUME_NONNULL_BEGIN + +/** + * The enum represent possible states of the installation auth token. + * + * WARNING: The enum is stored to Keychain as a part of `FIRInstallationsStoredAuthToken`. + * Modification of it can lead to incompatibility with previous version. Any modification must be + * evaluated and, if it is really needed, the `storageVersion` must be bumped and proper migration + * code added. + */ +typedef NS_ENUM(NSInteger, FIRInstallationsAuthTokenStatus) { + /// An initial status or an undefined value. + FIRInstallationsAuthTokenStatusUnknown, + /// The auth token has been received from the server. + FIRInstallationsAuthTokenStatusTokenReceived +}; + +/** + * This class serializes and deserializes the installation data into/from `NSData` to be stored in + * Keychain. This class is primarily used by `FIRInstallationsStore`. It is also used on the logic + * level as a data object (see `FIRInstallationsItem.authToken`). + * + * WARNING: Modification of the class properties can lead to incompatibility with the stored data + * encoded by the previous class versions. Any modification must be evaluated and, if it is really + * needed, the `storageVersion` must be bumped and proper migration code added. + */ +@interface FIRInstallationsStoredAuthToken : NSObject +@property FIRInstallationsAuthTokenStatus status; + +/// The installation auth token string that can be used to authorize requests to Firebase backend. +@property(nullable, copy) NSString *token; +/// The installation auth token expiration date. +@property(nullable, copy) NSDate *expirationDate; + +/// The version of local storage. +@property(nonatomic, readonly) NSInteger storageVersion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.m b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.m new file mode 100644 index 0000000..8236f2a --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.m @@ -0,0 +1,77 @@ +/* + * 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 "FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h" + +#import "FirebaseInstallations/Source/Library/FIRInstallationsLogger.h" + +NSString *const kFIRInstallationsStoredAuthTokenStatusKey = @"status"; +NSString *const kFIRInstallationsStoredAuthTokenTokenKey = @"token"; +NSString *const kFIRInstallationsStoredAuthTokenExpirationDateKey = @"expirationDate"; +NSString *const kFIRInstallationsStoredAuthTokenStorageVersionKey = @"storageVersion"; + +NSInteger const kFIRInstallationsStoredAuthTokenStorageVersion = 1; + +@implementation FIRInstallationsStoredAuthToken + +- (NSInteger)storageVersion { + return kFIRInstallationsStoredAuthTokenStorageVersion; +} + +- (nonnull id)copyWithZone:(nullable NSZone *)zone { + FIRInstallationsStoredAuthToken *clone = [[FIRInstallationsStoredAuthToken alloc] init]; + clone.status = self.status; + clone.token = [self.token copy]; + clone.expirationDate = self.expirationDate; + return clone; +} + +- (void)encodeWithCoder:(nonnull NSCoder *)aCoder { + [aCoder encodeInteger:self.status forKey:kFIRInstallationsStoredAuthTokenStatusKey]; + [aCoder encodeObject:self.token forKey:kFIRInstallationsStoredAuthTokenTokenKey]; + [aCoder encodeObject:self.expirationDate + forKey:kFIRInstallationsStoredAuthTokenExpirationDateKey]; + [aCoder encodeInteger:self.storageVersion + forKey:kFIRInstallationsStoredAuthTokenStorageVersionKey]; +} + +- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder { + NSInteger storageVersion = + [aDecoder decodeIntegerForKey:kFIRInstallationsStoredAuthTokenStorageVersionKey]; + if (storageVersion > kFIRInstallationsStoredAuthTokenStorageVersion) { + FIRLogWarning(kFIRLoggerInstallations, + kFIRInstallationsMessageCodeAuthTokenCoderVersionMismatch, + @"FIRInstallationsStoredAuthToken was encoded by a newer coder version %ld. " + @"Current coder version is %ld. Some auth token data may be lost.", + (long)storageVersion, (long)kFIRInstallationsStoredAuthTokenStorageVersion); + } + + FIRInstallationsStoredAuthToken *object = [[FIRInstallationsStoredAuthToken alloc] init]; + object.status = [aDecoder decodeIntegerForKey:kFIRInstallationsStoredAuthTokenStatusKey]; + object.token = [aDecoder decodeObjectOfClass:[NSString class] + forKey:kFIRInstallationsStoredAuthTokenTokenKey]; + object.expirationDate = + [aDecoder decodeObjectOfClass:[NSDate class] + forKey:kFIRInstallationsStoredAuthTokenExpirationDateKey]; + + return object; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +@end diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.h new file mode 100644 index 0000000..0126eb0 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.h @@ -0,0 +1,51 @@ +/* + * 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 + +#import "FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsStatus.h" + +@class FIRInstallationsStoredAuthToken; +@class FIRInstallationsStoredIIDCheckin; + +NS_ASSUME_NONNULL_BEGIN + +/** + * The class is supposed to be used by `FIRInstallationsStore` only. It is required to + * serialize/deserialize the installation data into/from `NSData` to be stored in Keychain. + * + * WARNING: Modification of the class properties can lead to incompatibility with the stored data + * encoded by the previous class versions. Any modification must be evaluated and, if it is really + * needed, the `storageVersion` must be bumped and proper migration code added. + */ +@interface FIRInstallationsStoredItem : NSObject + +/// A stable identifier that uniquely identifies the app instance. +@property(nonatomic, copy, nullable) NSString *firebaseInstallationID; +/// The `refreshToken` is used to authorize the installation auth token requests. +@property(nonatomic, copy, nullable) NSString *refreshToken; + +@property(nonatomic, nullable) FIRInstallationsStoredAuthToken *authToken; +@property(nonatomic) FIRInstallationsStatus registrationStatus; + +/// Instance ID default auth token imported from IID store as a part of IID migration. +@property(nonatomic, nullable) NSString *IIDDefaultToken; + +/// The version of local storage. +@property(nonatomic, readonly) NSInteger storageVersion; +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.m b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.m new file mode 100644 index 0000000..4e19955 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.m @@ -0,0 +1,80 @@ +/* + * 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 "FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.h" + +#import "FirebaseInstallations/Source/Library/FIRInstallationsLogger.h" +#import "FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h" + +NSString *const kFIRInstallationsStoredItemFirebaseInstallationIDKey = @"firebaseInstallationID"; +NSString *const kFIRInstallationsStoredItemRefreshTokenKey = @"refreshToken"; +NSString *const kFIRInstallationsStoredItemAuthTokenKey = @"authToken"; +NSString *const kFIRInstallationsStoredItemRegistrationStatusKey = @"registrationStatus"; +NSString *const kFIRInstallationsStoredItemIIDDefaultTokenKey = @"IIDDefaultToken"; +NSString *const kFIRInstallationsStoredItemStorageVersionKey = @"storageVersion"; + +NSInteger const kFIRInstallationsStoredItemStorageVersion = 1; + +@implementation FIRInstallationsStoredItem + +- (NSInteger)storageVersion { + return kFIRInstallationsStoredItemStorageVersion; +} + +- (void)encodeWithCoder:(nonnull NSCoder *)aCoder { + [aCoder encodeObject:self.firebaseInstallationID + forKey:kFIRInstallationsStoredItemFirebaseInstallationIDKey]; + [aCoder encodeObject:self.refreshToken forKey:kFIRInstallationsStoredItemRefreshTokenKey]; + [aCoder encodeObject:self.authToken forKey:kFIRInstallationsStoredItemAuthTokenKey]; + [aCoder encodeInteger:self.registrationStatus + forKey:kFIRInstallationsStoredItemRegistrationStatusKey]; + [aCoder encodeObject:self.IIDDefaultToken forKey:kFIRInstallationsStoredItemIIDDefaultTokenKey]; + [aCoder encodeInteger:self.storageVersion forKey:kFIRInstallationsStoredItemStorageVersionKey]; +} + +- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder { + NSInteger storageVersion = + [aDecoder decodeIntegerForKey:kFIRInstallationsStoredItemStorageVersionKey]; + if (storageVersion > self.storageVersion) { + FIRLogWarning(kFIRLoggerInstallations, + kFIRInstallationsMessageCodeInstallationCoderVersionMismatch, + @"FIRInstallationsStoredItem was encoded by a newer coder version %ld. Current " + @"coder version is %ld. Some installation data may be lost.", + (long)storageVersion, (long)kFIRInstallationsStoredItemStorageVersion); + } + + FIRInstallationsStoredItem *item = [[FIRInstallationsStoredItem alloc] init]; + item.firebaseInstallationID = + [aDecoder decodeObjectOfClass:[NSString class] + forKey:kFIRInstallationsStoredItemFirebaseInstallationIDKey]; + item.refreshToken = [aDecoder decodeObjectOfClass:[NSString class] + forKey:kFIRInstallationsStoredItemRefreshTokenKey]; + item.authToken = [aDecoder decodeObjectOfClass:[FIRInstallationsStoredAuthToken class] + forKey:kFIRInstallationsStoredItemAuthTokenKey]; + item.registrationStatus = + [aDecoder decodeIntegerForKey:kFIRInstallationsStoredItemRegistrationStatusKey]; + item.IIDDefaultToken = + [aDecoder decodeObjectOfClass:[NSString class] + forKey:kFIRInstallationsStoredItemIIDDefaultTokenKey]; + + return item; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +@end diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h new file mode 100644 index 0000000..0c850e9 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h @@ -0,0 +1,19 @@ +// 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. + +// An umbrella header, for any other libraries in this repo to access Firebase +// Installations Public headers. Any package manager complexity should be +// handled here. + +#import diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallations.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallations.h new file mode 100644 index 0000000..1811d2b --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallations.h @@ -0,0 +1,127 @@ +/* + * 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 + +@class FIRApp; +@class FIRInstallationsAuthTokenResult; + +NS_ASSUME_NONNULL_BEGIN + +/** A notification with this name is sent each time an installation is created or deleted. */ +// clang-format off +// clang-format12 merges the next two lines. +FOUNDATION_EXPORT const NSNotificationName FIRInstallationIDDidChangeNotification + NS_SWIFT_NAME(InstallationIDDidChange); +/** `userInfo` key for the `FirebaseApp.name` in `InstallationIDDidChangeNotification`. */ +FOUNDATION_EXPORT NSString *const kFIRInstallationIDDidChangeNotificationAppNameKey + NS_SWIFT_NAME(InstallationIDDidChangeAppNameKey); +// clang-format on + +/** + * An installation ID handler block. + * @param identifier The installation ID string if exists or `nil` otherwise. + * @param error The error when `identifier == nil` or `nil` otherwise. + */ +typedef void (^FIRInstallationsIDHandler)(NSString *__nullable identifier, + NSError *__nullable error) + NS_SWIFT_UNAVAILABLE("Use Swift's closure syntax instead."); + +/** + * An authorization token handler block. + * @param tokenResult An instance of `InstallationsAuthTokenResult` in case of success or `nil` + * otherwise. + * @param error The error when `tokenResult == nil` or `nil` otherwise. + */ +typedef void (^FIRInstallationsTokenHandler)( + FIRInstallationsAuthTokenResult *__nullable tokenResult, NSError *__nullable error) + NS_SWIFT_UNAVAILABLE("Use Swift's closure syntax instead."); + +/** + * The class provides API for Firebase Installations. + * Each configured `FirebaseApp` has a corresponding single instance of `Installations`. + * An instance of the class provides access to the installation info for the `FirebaseApp` as well + * as the ability to delete it. A Firebase Installation is unique by `FirebaseApp.name` and + * `FirebaseApp.options.googleAppID` . + */ +NS_SWIFT_NAME(Installations) +@interface FIRInstallations : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +/** + * Returns a default instance of `Installations`. + * @return An instance of `Installations` for `FirebaseApp.defaultApp(). + * @throw Throws an exception if the default app is not configured yet or required `FirebaseApp` + * options are missing. + */ ++ (FIRInstallations *)installations NS_SWIFT_NAME(installations()); + +/** + * Returns an instance of `Installations` for an application. + * @param application A configured `FirebaseApp` instance. + * @return An instance of `Installations` corresponding to the passed application. + * @throw Throws an exception if required `FirebaseApp` options are missing. + */ ++ (FIRInstallations *)installationsWithApp:(FIRApp *)application NS_SWIFT_NAME(installations(app:)); + +/** + * The method creates or retrieves an installation ID. The installation ID is a stable identifier + * that uniquely identifies the app instance. NOTE: If the application already has an existing + * FirebaseInstanceID then the InstanceID identifier will be used. + * @param completion A completion handler which is invoked when the operation completes. + */ +- (void)installationIDWithCompletion:(void (^)(NSString *__nullable identifier, + NSError *__nullable error))completion; + +/** + * Retrieves (locally if it exists or from the server) a valid installation auth token. An existing + * token may be invalidated or expired, so it is recommended to fetch the installation auth token + * before each server request. The method does the same as + * `Installations.authToken(forcingRefresh:completion:)` with forcing refresh `false`. + * @param completion A completion handler which is invoked when the operation completes. + */ +- (void)authTokenWithCompletion:(void (^)(FIRInstallationsAuthTokenResult *__nullable tokenResult, + NSError *__nullable error))completion; + +/** + * Retrieves (locally or from the server depending on `forceRefresh` value) a valid installation + * auth token. An existing token may be invalidated or expire, so it is recommended to fetch the + * installation auth token before each server request. This method should be used with `forceRefresh + * == true` when e.g. a request with the previously fetched installation auth token failed with "Not + * Authorized" error. + * @param forceRefresh If `true` then the locally cached installation auth token will be ignored and + * a new one will be requested from the server. If `false`, then the locally cached installation + * auth token will be returned if exists and has not expired yet. + * @param completion A completion handler which is invoked when the operation completes. See + * `InstallationsTokenHandler` for additional details. + */ +- (void)authTokenForcingRefresh:(BOOL)forceRefresh + completion:(void (^)(FIRInstallationsAuthTokenResult *__nullable tokenResult, + NSError *__nullable error))completion; + +/** + * Deletes all the installation data including the unique identifier, auth tokens and + * all related data on the server side. A network connection is required for the method to + * succeed. If fails, the existing installation data remains untouched. + * @param completion A completion handler which is invoked when the operation completes. `error == + * nil` indicates success. + */ +- (void)deleteWithCompletion:(void (^)(NSError *__nullable error))completion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallationsAuthTokenResult.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallationsAuthTokenResult.h new file mode 100644 index 0000000..501ac4e --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallationsAuthTokenResult.h @@ -0,0 +1,33 @@ +/* + * 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 + +NS_ASSUME_NONNULL_BEGIN + +/** The class represents a result of the installation auth token request. */ +NS_SWIFT_NAME(InstallationsAuthTokenResult) +@interface FIRInstallationsAuthTokenResult : NSObject + +/** The installation auth token string. */ +@property(nonatomic, readonly) NSString *authToken; + +/** The installation auth token expiration date. */ +@property(nonatomic, readonly) NSDate *expirationDate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallationsErrors.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallationsErrors.h new file mode 100644 index 0000000..939ca0a --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallationsErrors.h @@ -0,0 +1,35 @@ +/* + * 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 + +extern NSString *const kFirebaseInstallationsErrorDomain NS_SWIFT_NAME(InstallationsErrorDomain); + +typedef NS_ERROR_ENUM(kFirebaseInstallationsErrorDomain, FIRInstallationsErrorCode){ + /** Unknown error. See `userInfo` for details. */ + FIRInstallationsErrorCodeUnknown = 0, + + /** Keychain error. See `userInfo` for details. */ + FIRInstallationsErrorCodeKeychain = 1, + + /** Server unreachable. A network error or server is unavailable. See `userInfo` for details. */ + FIRInstallationsErrorCodeServerUnreachable = 2, + + /** FirebaseApp configuration issues e.g. invalid GMP-App-ID, etc. See `userInfo` for details. + */ + FIRInstallationsErrorCodeInvalidConfiguration = 3, + +} NS_SWIFT_NAME(InstallationsErrorCode); diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FirebaseInstallations.h b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FirebaseInstallations.h new file mode 100644 index 0000000..8a9b3c1 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FirebaseInstallations.h @@ -0,0 +1,19 @@ +/* + * 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 "FIRInstallations.h" +#import "FIRInstallationsAuthTokenResult.h" +#import "FIRInstallationsErrors.h" diff --git a/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Resources/PrivacyInfo.xcprivacy b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Resources/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..1e83fa6 --- /dev/null +++ b/Pods/FirebaseInstallations/FirebaseInstallations/Source/Library/Resources/PrivacyInfo.xcprivacy @@ -0,0 +1,30 @@ + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + + NSPrivacyCollectedDataTypes + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeOtherDiagnosticData + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAnalytics + + + + NSPrivacyAccessedAPITypes + + + + + diff --git a/Pods/FirebaseInstallations/LICENSE b/Pods/FirebaseInstallations/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/Pods/FirebaseInstallations/LICENSE @@ -0,0 +1,202 @@ + + 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. diff --git a/Pods/FirebaseInstallations/README.md b/Pods/FirebaseInstallations/README.md new file mode 100644 index 0000000..4c915ab --- /dev/null +++ b/Pods/FirebaseInstallations/README.md @@ -0,0 +1,297 @@ +

+ + + + + + + + +
+ + + + + + +

+ +# Firebase Apple Open Source Development + +This repository contains the source code for all Apple platform Firebase SDKs except FirebaseAnalytics. + +Firebase is an app development platform with tools to help you build, grow, and +monetize your app. More information about Firebase can be found on the +[official Firebase website](https://firebase.google.com). + +## Installation + +See the subsections below for details about the different installation methods. Where +available, it's recommended to install any libraries with a `Swift` suffix to get the +best experience when writing your app in Swift. + +1. [Standard pod install](#standard-pod-install) +2. [Swift Package Manager](#swift-package-manager) +3. [Installing from the GitHub repo](#installing-from-github) +4. [Experimental Carthage](#carthage-ios-only) + +### Standard pod install + +For instructions on the standard pod install, visit: +[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup). + +### Swift Package Manager + +Instructions for [Swift Package Manager](https://swift.org/package-manager/) support can be +found in the [SwiftPackageManager.md](SwiftPackageManager.md) Markdown file. + +### Installing from GitHub + +These instructions can be used to access the Firebase repo at other branches, +tags, or commits. + +#### Background + +See [the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod) +for instructions and options about overriding pod source locations. + +#### Accessing Firebase Source Snapshots + +All official releases are tagged in this repo and available via CocoaPods. To access a local +source snapshot or unreleased branch, use Podfile directives like the following: + +To access FirebaseFirestore via a branch: +```ruby +pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'main' +pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'main' +``` + +To access FirebaseMessaging via a checked-out version of the firebase-ios-sdk repo: +```ruby +pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk' +pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk' +``` + +### Carthage (iOS only) + +Instructions for the experimental Carthage distribution can be found at +[Carthage.md](Carthage.md). + +### Using Firebase from a Framework or a library + +For details on using Firebase from a Framework or a library, refer to [firebase_in_libraries.md](docs/firebase_in_libraries.md). + +## Development + +To develop Firebase software in this repository, ensure that you have at least +the following software: + +* Xcode 15.2 (or later) + +CocoaPods is still the canonical way to develop, but much of the repo now supports +development with Swift Package Manager. + +### CocoaPods + +Install the following: +* CocoaPods 1.12.0 (or later) +* [CocoaPods generate](https://github.com/square/cocoapods-generate) + +For the pod that you want to develop: + +```ruby +pod gen Firebase{name here}.podspec --local-sources=./ --auto-open --platforms=ios +``` + +Note: If the CocoaPods cache is out of date, you may need to run +`pod repo update` before the `pod gen` command. + +Note: Set the `--platforms` option to `macos` or `tvos` to develop/test for +those platforms. Since 10.2, Xcode does not properly handle multi-platform +CocoaPods workspaces. + +Firestore has a self-contained Xcode project. See +[Firestore/README](Firestore/README.md) Markdown file. + +#### Development for Catalyst +* `pod gen {name here}.podspec --local-sources=./ --auto-open --platforms=ios` +* Check the Mac box in the App-iOS Build Settings +* Sign the App in the Settings Signing & Capabilities tab +* Click Pods in the Project Manager +* Add Signing to the iOS host app and unit test targets +* Select the Unit-unit scheme +* Run it to build and test + +Alternatively, disable signing in each target: +* Go to Build Settings tab +* Click `+` +* Select `Add User-Defined Setting` +* Add `CODE_SIGNING_REQUIRED` setting with a value of `NO` + +### Swift Package Manager +* To enable test schemes: `./scripts/setup_spm_tests.sh` +* `open Package.swift` or double click `Package.swift` in Finder. +* Xcode will open the project + * Choose a scheme for a library to build or test suite to run + * Choose a target platform by selecting the run destination along with the scheme + +### Adding a New Firebase Pod + +Refer to [AddNewPod](AddNewPod.md) Markdown file for details. + +### Managing Headers and Imports + +For information about managing headers and imports, see [HeadersImports](HeadersImports.md) Markdown file. + +### Code Formatting + +To ensure that the code is formatted consistently, run the script +[./scripts/check.sh](https://github.com/firebase/firebase-ios-sdk/blob/main/scripts/check.sh) +before creating a pull request (PR). + +GitHub Actions will verify that any code changes are done in a style-compliant +way. Install `clang-format` and `mint`: + +```console +brew install clang-format@18 +brew install mint +``` + +### Running Unit Tests + +Select a scheme and press Command-u to build a component and run its unit tests. + +### Running Sample Apps +To run the sample apps and integration tests, you'll need a valid +`GoogleService-Info.plist +` file. The Firebase Xcode project contains dummy plist +files without real values, but they can be replaced with real plist files. To get your own +`GoogleService-Info.plist` files: + +1. Go to the [Firebase Console](https://console.firebase.google.com/) +2. Create a new Firebase project, if you don't already have one +3. For each sample app you want to test, create a new Firebase app with the sample app's bundle +identifier (e.g., `com.google.Database-Example`) +4. Download the resulting `GoogleService-Info.plist` and add it to the Xcode project. + +### Coverage Report Generation + +For coverage report generation instructions, see [scripts/code_coverage_report/README](scripts/code_coverage_report/README.md) Markdown file. + +## Specific Component Instructions +See the sections below for any special instructions for those components. + +### Firebase Auth + +For specific Firebase Auth development, refer to the [Auth Sample README](FirebaseAuth/Tests/Sample/README.md) for instructions about +building and running the FirebaseAuth pod along with various samples and tests. + +### Firebase Database + +The Firebase Database Integration tests can be run against a locally running Database Emulator +or against a production instance. + +To run against a local emulator instance, invoke `./scripts/run_database_emulator.sh start` before +running the integration test. + +To run against a production instance, provide a valid `GoogleServices-Info.plist` and copy it to +`FirebaseDatabase/Tests/Resources/GoogleService-Info.plist`. Your Security Rule must be set to +[public](https://firebase.google.com/docs/database/security/quickstart) while your tests are +running. + +### Firebase Dynamic Links + +Firebase Dynamic Links is **deprecated** and should not be used in new projects. The service will shut down on August 25, 2025. + +Please see our [Dynamic Links Deprecation FAQ documentation](https://firebase.google.com/support/dynamic-links-faq) for more guidance. + +### Firebase Performance Monitoring + +For specific Firebase Performance Monitoring development, see +[the Performance README](FirebasePerformance/README.md) for instructions about building the SDK +and [the Performance TestApp README](FirebasePerformance/Tests/TestApp/README.md) for instructions about +integrating Performance with the dev test App. + +### Firebase Storage + +To run the Storage Integration tests, follow the instructions in +[StorageIntegration.swift](FirebaseStorage/Tests/Integration/StorageIntegration.swift). + +#### Push Notifications + +Push notifications can only be delivered to specially provisioned App IDs in the developer portal. +In order to test receiving push notifications, you will need to: + +1. Change the bundle identifier of the sample app to something you own in your Apple Developer +account and enable that App ID for push notifications. +2. You'll also need to +[upload your APNs Provider Authentication Key or certificate to the +Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs) +at **Project Settings > Cloud Messaging > [Your Firebase App]**. +3. Ensure your iOS device is added to your Apple Developer portal as a test device. + +#### iOS Simulator + +The iOS Simulator cannot register for remote notifications and will not receive push notifications. +To receive push notifications, follow the steps above and run the app on a physical device. + +## Building with Firebase on Apple platforms + +Firebase provides official beta support for macOS, Catalyst, and tvOS. visionOS and watchOS +are community supported. Thanks to community contributions for many of the multi-platform PRs. + +At this time, most of Firebase's products are available across Apple platforms. There are still +a few gaps, especially on visionOS and watchOS. For details about the current support matrix, see +[this chart](https://firebase.google.com/docs/ios/learn-more#firebase_library_support_by_platform) +in Firebase's documentation. + +### visionOS + +Where supported, visionOS works as expected with the exception of Firestore via Swift Package +Manager where it is required to use the source distribution. + +To enable the Firestore source distribution, quit Xcode and open the desired +project from the command line with the `FIREBASE_SOURCE_FIRESTORE` environment +variable: `open --env FIREBASE_SOURCE_FIRESTORE /path/to/project.xcodeproj`. +To go back to using the binary distribution of Firestore, quit Xcode and open +Xcode like normal, without the environment variable. + +### watchOS +Thanks to contributions from the community, many of Firebase SDKs now compile, run unit tests, and +work on watchOS. See the [Independent Watch App Sample](Example/watchOSSample). + +Keep in mind that watchOS is not officially supported by Firebase. While we can catch basic unit +test issues with GitHub Actions, there may be some changes where the SDK no longer works as expected +on watchOS. If you encounter this, please +[file an issue](https://github.com/firebase/firebase-ios-sdk/issues). + +During app setup in the console, you may get to a step that mentions something like "Checking if the +app has communicated with our servers". This relies on Analytics and will not work on watchOS. +**It's safe to ignore the message and continue**, the rest of the SDKs will work as expected. + +#### Additional Crashlytics Notes +* watchOS has limited support. Due to watchOS restrictions, mach exceptions and signal crashes are +not recorded. (Crashes in SwiftUI are generated as mach exceptions, so will not be recorded) + +## Combine +Thanks to contributions from the community, _FirebaseCombineSwift_ contains support for Apple's Combine +framework. This module is currently under development and not yet supported for use in production +environments. For more details, please refer to the [docs](FirebaseCombineSwift/README.md). + +## Roadmap + +See [Roadmap](ROADMAP.md) for more about the Firebase Apple SDK Open Source +plans and directions. + +## Contributing + +See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase +Apple SDK. + +## License + +The contents of this repository are licensed under the +[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +Your use of Firebase is governed by the +[Terms of Service for Firebase Services](https://firebase.google.com/terms/). diff --git a/Pods/FirebaseRemoteConfig/FirebaseABTesting/Sources/Private/ABTExperimentPayload.h b/Pods/FirebaseRemoteConfig/FirebaseABTesting/Sources/Private/ABTExperimentPayload.h new file mode 100644 index 0000000..b2f2da0 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseABTesting/Sources/Private/ABTExperimentPayload.h @@ -0,0 +1,96 @@ +// 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 + +NS_ASSUME_NONNULL_BEGIN + +/// Policy for handling the case where there's an overflow of experiments for an installation +/// instance. +typedef NS_ENUM(int32_t, ABTExperimentPayloadExperimentOverflowPolicy) { + ABTExperimentPayloadExperimentOverflowPolicyUnrecognizedValue = 999, + ABTExperimentPayloadExperimentOverflowPolicyUnspecified = 0, + ABTExperimentPayloadExperimentOverflowPolicyDiscardOldest = 1, + ABTExperimentPayloadExperimentOverflowPolicyIgnoreNewest = 2, +}; + +@interface ABTExperimentLite : NSObject +@property(nonatomic, readonly, copy) NSString *experimentId; + +- (instancetype)initWithExperimentId:(NSString *)experimentId NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +@end + +@interface ABTExperimentPayload : NSObject + +/// Unique identifier for this experiment. +@property(nonatomic, readonly, copy) NSString *experimentId; + +/// Unique identifier for the variant to which an installation instance has been assigned. +@property(nonatomic, readonly, copy) NSString *variantId; + +/// Epoch time that represents when the experiment was started. +@property(nonatomic, readonly) int64_t experimentStartTimeMillis; + +/// The event that triggers this experiment into ON state. +@property(nonatomic, nullable, readonly, copy) NSString *triggerEvent; + +/// Duration in milliseconds for which the experiment can stay in STANDBY state (un-triggered). +@property(nonatomic, readonly) int64_t triggerTimeoutMillis; + +/// Duration in milliseconds for which the experiment can stay in ON state (triggered). +@property(nonatomic, readonly) int64_t timeToLiveMillis; + +/// The event logged when impact service sets the experiment. +@property(nonatomic, readonly, copy) NSString *setEventToLog; + +/// The event logged when an experiment goes to the ON state. +@property(nonatomic, readonly, copy) NSString *activateEventToLog; + +/// The event logged when an experiment is cleared. +@property(nonatomic, readonly, copy) NSString *clearEventToLog; + +/// The event logged when an experiment times out after `triggerTimeoutMillis` milliseconds. +@property(nonatomic, readonly, copy) NSString *timeoutEventToLog; + +/// The event logged when an experiment times out after `timeToLiveMillis` milliseconds. +@property(nonatomic, readonly, copy) NSString *ttlExpiryEventToLog; + +@property(nonatomic, readonly) ABTExperimentPayloadExperimentOverflowPolicy overflowPolicy; + +/// A list of all other ongoing (started, and not yet stopped) experiments at the time this +/// experiment was started. Does not include this experiment; only the others. +@property(nonatomic, readonly) NSArray *ongoingExperiments; + +/// Parses an ABTExperimentPayload directly from JSON data. +/// @param data JSON object as NSData. Must be reconstructible as an NSDictionary. ++ (nullable instancetype)parseFromData:(NSData *)data; + +/// Initializes an ABTExperimentPayload from a dictionary with experiment metadata. +- (instancetype)initWithDictionary:(NSDictionary *)dictionary + NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +/// Clears the trigger event associated with this payload. +- (void)clearTriggerEvent; + +/// Checks if the overflow policy is a valid enum object. +- (BOOL)overflowPolicyIsValid; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseRemoteConfig/FirebaseABTesting/Sources/Private/FirebaseABTestingInternal.h b/Pods/FirebaseRemoteConfig/FirebaseABTesting/Sources/Private/FirebaseABTestingInternal.h new file mode 100644 index 0000000..7259e08 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseABTesting/Sources/Private/FirebaseABTestingInternal.h @@ -0,0 +1,20 @@ +// 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. + +// An umbrella header, for any other libraries in this repo to access Firebase Public and Private +// headers. Any package manager complexity should be handled here. + +#import + +#import "FirebaseABTesting/Sources/Private/ABTExperimentPayload.h" diff --git a/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRAppInternal.h b/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRAppInternal.h new file mode 100644 index 0000000..49104f0 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRAppInternal.h @@ -0,0 +1,159 @@ +/* + * 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 + +@class FIRComponentContainer; +@class FIRHeartbeatLogger; +@protocol FIRLibrary; + +/** + * The internal interface to `FirebaseApp`. This is meant for first-party integrators, who need to + * receive `FirebaseApp` notifications, log info about the success or failure of their + * configuration, and access other internal functionality of `FirebaseApp`. + */ +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSInteger, FIRConfigType) { + FIRConfigTypeCore = 1, + FIRConfigTypeSDK = 2, +}; + +extern NSString *const kFIRDefaultAppName; +extern NSString *const kFIRAppReadyToConfigureSDKNotification; +extern NSString *const kFIRAppDeleteNotification; +extern NSString *const kFIRAppIsDefaultAppKey; +extern NSString *const kFIRAppNameKey; +extern NSString *const kFIRGoogleAppIDKey; +extern NSString *const kFirebaseCoreErrorDomain; + +/** The `UserDefaults` suite name for `FirebaseCore`, for those storage locations that use it. */ +extern NSString *const kFirebaseCoreDefaultsSuiteName; + +/** + * The format string for the `UserDefaults` key used for storing the data collection enabled flag. + * This includes formatting to append the `FirebaseApp`'s name. + */ +extern NSString *const kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat; + +/** + * The plist key used for storing the data collection enabled flag. + */ +extern NSString *const kFIRGlobalAppDataCollectionEnabledPlistKey; + +/** @var FirebaseAuthStateDidChangeInternalNotification + @brief The name of the @c NotificationCenter notification which is posted when the auth state + changes (e.g. a new token has been produced, a user logs in or out). The object parameter of + the notification is a dictionary possibly containing the key: + @c FirebaseAuthStateDidChangeInternalNotificationTokenKey (the new access token.) If it does not + contain this key it indicates a sign-out event took place. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotification; + +/** @var FirebaseAuthStateDidChangeInternalNotificationTokenKey + @brief A key present in the dictionary object parameter of the + @c FirebaseAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the new access token. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationTokenKey; + +/** @var FirebaseAuthStateDidChangeInternalNotificationAppKey + @brief A key present in the dictionary object parameter of the + @c FirebaseAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the FirebaseApp associated with the auth instance. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationAppKey; + +/** @var FirebaseAuthStateDidChangeInternalNotificationUIDKey + @brief A key present in the dictionary object parameter of the + @c FirebaseAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the new user's UID (or nil if there is no longer a user signed in). + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationUIDKey; + +@interface FIRApp () + +/** + * A flag indicating if this is the default app (has the default app name). + */ +@property(nonatomic, readonly) BOOL isDefaultApp; + +/** + * The container of interop SDKs for this app. + */ +@property(nonatomic) FIRComponentContainer *container; + +/** + * The heartbeat logger associated with this app. + * + * Firebase apps have a 1:1 relationship with heartbeat loggers. + */ +@property(readonly) FIRHeartbeatLogger *heartbeatLogger; + +/** + * Checks if the default app is configured without trying to configure it. + */ ++ (BOOL)isDefaultAppConfigured; + +/** + * Registers a given third-party library with the given version number to be reported for + * analytics. + * + * @param name Name of the library. + * @param version Version of the library. + */ ++ (void)registerLibrary:(nonnull NSString *)name withVersion:(nonnull NSString *)version; + +/** + * Registers a given internal library to be reported for analytics. + * + * @param library Optional parameter for component registration. + * @param name Name of the library. + */ ++ (void)registerInternalLibrary:(nonnull Class)library + withName:(nonnull NSString *)name; + +/** + * Registers a given internal library with the given version number to be reported for + * analytics. This should only be used for non-Firebase libraries that have their own versioning + * scheme. + * + * @param library Optional parameter for component registration. + * @param name Name of the library. + * @param version Version of the library. + */ ++ (void)registerInternalLibrary:(nonnull Class)library + withName:(nonnull NSString *)name + withVersion:(nonnull NSString *)version; + +/** + * A concatenated string representing all the third-party libraries and version numbers. + */ ++ (NSString *)firebaseUserAgent; + +/** + * Can be used by the unit tests in each SDK to reset `FirebaseApp`. This method is thread unsafe. + */ ++ (void)resetApps; + +/** + * Can be used by the unit tests in each SDK to set customized options. + */ +- (instancetype)initInstanceWithName:(NSString *)name options:(FIROptions *)options; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRComponent.h b/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRComponent.h new file mode 100644 index 0000000..e4c8a27 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRComponent.h @@ -0,0 +1,91 @@ +/* + * 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 + +@class FIRApp; +@class FIRComponentContainer; + +NS_ASSUME_NONNULL_BEGIN + +/// Provides a system to clean up cached instances returned from the component system. +NS_SWIFT_NAME(ComponentLifecycleMaintainer) +@protocol FIRComponentLifecycleMaintainer +/// The associated app will be deleted, clean up any resources as they are about to be deallocated. +- (void)appWillBeDeleted:(FIRApp *)app; +@end + +typedef _Nullable id (^FIRComponentCreationBlock)(FIRComponentContainer *container, + BOOL *isCacheable) + NS_SWIFT_NAME(ComponentCreationBlock); + +@class FIRDependency; + +/// Describes the timing of instantiation. Note: new components should default to lazy unless there +/// is a strong reason to be eager. +typedef NS_ENUM(NSInteger, FIRInstantiationTiming) { + FIRInstantiationTimingLazy, + FIRInstantiationTimingAlwaysEager, + FIRInstantiationTimingEagerInDefaultApp +} NS_SWIFT_NAME(InstantiationTiming); + +/// A component that can be used from other Firebase SDKs. +NS_SWIFT_NAME(Component) +@interface FIRComponent : NSObject + +/// The protocol describing functionality provided from the `Component`. +@property(nonatomic, strong, readonly) Protocol *protocol; + +/// The timing of instantiation. +@property(nonatomic, readonly) FIRInstantiationTiming instantiationTiming; + +/// An array of dependencies for the component. +@property(nonatomic, copy, readonly) NSArray *dependencies; + +/// A block to instantiate an instance of the component with the appropriate dependencies. +@property(nonatomic, copy, readonly) FIRComponentCreationBlock creationBlock; + +// There's an issue with long NS_SWIFT_NAMES that causes compilation to fail, disable clang-format +// for the next two methods. +// clang-format off + +/// Creates a component with no dependencies that will be lazily initialized. ++ (instancetype)componentWithProtocol:(Protocol *)protocol + creationBlock:(FIRComponentCreationBlock)creationBlock +NS_SWIFT_NAME(init(_:creationBlock:)); + +/// Creates a component to be registered with the component container. +/// +/// @param protocol - The protocol describing functionality provided by the component. +/// @param instantiationTiming - When the component should be initialized. Use .lazy unless there's +/// a good reason to be instantiated earlier. +/// @param dependencies - Any dependencies the `implementingClass` has, optional or required. +/// @param creationBlock - A block to instantiate the component with a container, and if +/// @return A component that can be registered with the component container. ++ (instancetype)componentWithProtocol:(Protocol *)protocol + instantiationTiming:(FIRInstantiationTiming)instantiationTiming + dependencies:(NSArray *)dependencies + creationBlock:(FIRComponentCreationBlock)creationBlock +NS_SWIFT_NAME(init(_:instantiationTiming:dependencies:creationBlock:)); + +// clang-format on + +/// Unavailable. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRComponentContainer.h b/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRComponentContainer.h new file mode 100644 index 0000000..6ec6147 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRComponentContainer.h @@ -0,0 +1,45 @@ +/* + * 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 + +NS_ASSUME_NONNULL_BEGIN + +/// A type-safe macro to retrieve a component from a container. This should be used to retrieve +/// components instead of using the container directly. +#define FIR_COMPONENT(type, container) \ + [FIRComponentType> instanceForProtocol:@protocol(type) inContainer:container] + +@class FIRApp; + +/// A container that holds different components that are registered via the +/// `registerAsComponentRegistrant` call. These classes should conform to `ComponentRegistrant` +/// in order to properly register components for Core. +NS_SWIFT_NAME(FirebaseComponentContainer) +@interface FIRComponentContainer : NSObject + +/// A weak reference to the app that an instance of the container belongs to. +@property(nonatomic, weak, readonly) FIRApp *app; + +// TODO: See if we can get improved type safety here. +/// A Swift only API for fetching an instance since the top macro isn't available. +- (nullable id)__instanceForProtocol:(Protocol *)protocol NS_SWIFT_NAME(instance(for:)); + +/// Unavailable. Use the `container` property on `FirebaseApp`. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRComponentType.h b/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRComponentType.h new file mode 100644 index 0000000..c69085d --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRComponentType.h @@ -0,0 +1,35 @@ +/* + * 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 + +@class FIRComponentContainer; + +NS_ASSUME_NONNULL_BEGIN + +/// Do not use directly. A placeholder type in order to provide a macro that will warn users of +/// mis-matched protocols. +NS_SWIFT_NAME(ComponentType) +@interface FIRComponentType<__covariant T> : NSObject + +/// Do not use directly. A factory method to retrieve an instance that provides a specific +/// functionality. ++ (nullable T)instanceForProtocol:(Protocol *)protocol + inContainer:(FIRComponentContainer *)container; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRDependency.h b/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRDependency.h new file mode 100644 index 0000000..a070557 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRDependency.h @@ -0,0 +1,45 @@ +/* + * 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 + +NS_ASSUME_NONNULL_BEGIN + +/// A dependency on a specific protocol's functionality. +NS_SWIFT_NAME(Dependency) +@interface FIRDependency : NSObject + +/// The protocol describing functionality being depended on. +@property(nonatomic, strong, readonly) Protocol *protocol; + +/// A flag to specify if the dependency is required or not. +@property(nonatomic, readonly) BOOL isRequired; + +/// Initializes a dependency that is required. Calls `init(protocol:isRequired:)` with true for +/// the required parameter. +/// Creates a required dependency on the specified protocol's functionality. ++ (instancetype)dependencyWithProtocol:(Protocol *)protocol; + +/// Creates a dependency on the specified protocol's functionality and specify if it's required for +/// the class's functionality. ++ (instancetype)dependencyWithProtocol:(Protocol *)protocol isRequired:(BOOL)required; + +/// Use `init(withProtocol:isRequired:)` instead. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRHeartbeatLogger.h b/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRHeartbeatLogger.h new file mode 100644 index 0000000..0f39ad9 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRHeartbeatLogger.h @@ -0,0 +1,90 @@ +// Copyright 2021 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 + +NS_ASSUME_NONNULL_BEGIN + +#ifndef FIREBASE_BUILD_CMAKE +@class FIRHeartbeatsPayload; +#endif // FIREBASE_BUILD_CMAKE + +/// Enum representing different daily heartbeat codes. +/// This enum is only used by clients using platform logging V1. This is because +/// the V1 payload only supports a single daily heartbeat. +typedef NS_ENUM(NSInteger, FIRDailyHeartbeatCode) { + /// Represents the absence of a daily heartbeat. + FIRDailyHeartbeatCodeNone = 0, + /// Represents the presence of a daily heartbeat. + FIRDailyHeartbeatCodeSome = 2, +}; + +@protocol FIRHeartbeatLoggerProtocol + +/// Asynchronously logs a heartbeat. +- (void)log; + +#ifndef FIREBASE_BUILD_CMAKE +/// Flushes heartbeats from storage into a structured payload of heartbeats. +- (FIRHeartbeatsPayload *)flushHeartbeatsIntoPayload; +#endif // FIREBASE_BUILD_CMAKE + +/// Gets the heartbeat code for today. +- (FIRDailyHeartbeatCode)heartbeatCodeForToday; + +@end + +#ifndef FIREBASE_BUILD_CMAKE +/// Returns a nullable string header value from a given heartbeats payload. +/// +/// This API returns `nil` when the given heartbeats payload is considered empty. +/// +/// @param heartbeatsPayload The heartbeats payload. +NSString *_Nullable FIRHeaderValueFromHeartbeatsPayload(FIRHeartbeatsPayload *heartbeatsPayload); +#endif // FIREBASE_BUILD_CMAKE + +/// A thread safe, synchronized object that logs and flushes platform logging info. +@interface FIRHeartbeatLogger : NSObject + +/// Designated initializer. +/// +/// @param appID The app ID that this heartbeat logger corresponds to. +- (instancetype)initWithAppID:(NSString *)appID; + +/// Asynchronously logs a new heartbeat corresponding to the Firebase User Agent, if needed. +/// +/// @note This API is thread-safe. +- (void)log; + +#ifndef FIREBASE_BUILD_CMAKE +/// Flushes heartbeats from storage into a structured payload of heartbeats. +/// +/// This API is for clients using platform logging V2. +/// +/// @note This API is thread-safe. +/// @return A payload of heartbeats. +- (FIRHeartbeatsPayload *)flushHeartbeatsIntoPayload; +#endif // FIREBASE_BUILD_CMAKE + +/// Gets today's corresponding heartbeat code. +/// +/// This API is for clients using platform logging V1. +/// +/// @note This API is thread-safe. +/// @return Heartbeat code indicating whether or not there is an unsent global heartbeat. +- (FIRDailyHeartbeatCode)heartbeatCodeForToday; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRLibrary.h b/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRLibrary.h new file mode 100644 index 0000000..15e2865 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRLibrary.h @@ -0,0 +1,44 @@ +/* + * 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. + */ + +#ifndef FIRLibrary_h +#define FIRLibrary_h + +#import + +@class FIRApp; +@class FIRComponent; + +NS_ASSUME_NONNULL_BEGIN + +/// Provide an interface to register a library for userAgent logging and availability to others. +NS_SWIFT_NAME(Library) +@protocol FIRLibrary + +/// Returns one or more Components that will be registered in +/// FirebaseApp and participate in dependency resolution and injection. ++ (NSArray *)componentsToRegister; + +@optional +/// Implement this method if the library needs notifications for lifecycle events. This method is +/// called when the developer calls `FirebaseApp.configure()`. ++ (void)configureWithApp:(FIRApp *)app; + +@end + +NS_ASSUME_NONNULL_END + +#endif /* FIRLibrary_h */ diff --git a/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRLogger.h b/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRLogger.h new file mode 100644 index 0000000..41c5653 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIRLogger.h @@ -0,0 +1,193 @@ +/* + * 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 + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * The Firebase services used in Firebase logger. + */ +typedef NSString *const FIRLoggerService; + +extern FIRLoggerService kFIRLoggerAnalytics; +extern FIRLoggerService kFIRLoggerCrash; +extern FIRLoggerService kFIRLoggerCore; +extern FIRLoggerService kFIRLoggerRemoteConfig; + +/** + * The key used to store the logger's error count. + */ +extern NSString *const kFIRLoggerErrorCountKey; + +/** + * The key used to store the logger's warning count. + */ +extern NSString *const kFIRLoggerWarningCountKey; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * Enables or disables Analytics debug mode. + * If set to true, the logging level for Analytics will be set to FirebaseLoggerLevelDebug. + * Enabling the debug mode has no effect if the app is running from App Store. + * (required) analytics debug mode flag. + */ +void FIRSetAnalyticsDebugMode(BOOL analyticsDebugMode); + +/** + * Gets the current FIRLoggerLevel. + */ +FIRLoggerLevel FIRGetLoggerLevel(void); + +/** + * Changes the default logging level of FirebaseLoggerLevelNotice to a user-specified level. + * The default level cannot be set above FirebaseLoggerLevelNotice if the app is running from App + * Store. (required) log level (one of the FirebaseLoggerLevel enum values). + */ +void FIRSetLoggerLevel(FIRLoggerLevel loggerLevel); + +/** + * Checks if the specified logger level is loggable given the current settings. + * (required) log level (one of the FirebaseLoggerLevel enum values). + * (required) whether or not this function is called from the Analytics component. + */ +BOOL FIRIsLoggableLevel(FIRLoggerLevel loggerLevel, BOOL analyticsComponent); + +/** + * 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 FirebaseLoggerLevelNotice to avoid log spamming. + * (required) log level (one of the FirebaseLoggerLevel enum values). + * (required) service name of type FirebaseLoggerService. + * (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 FIRLogBasic(FIRLoggerLevel level, + FIRLoggerService service, + 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 FirebaseLoggerService. + * (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: + * FirebaseLogError(kFirebaseLoggerCore, @"I-COR000001", @"Configuration of %@ failed.", app.name); + */ +extern void FIRLogError(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogWarning(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogNotice(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogInfo(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogDebug(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); + +// TODO: Come up with a better logging scheme for Swift. +/** + * Logs a debug message to the Xcode console and the device log. If running from AppStore, will + * not log any messages with a level higher than FirebaseLoggerLevelNotice to avoid log spamming. + * This function is intended to be used by Swift clients that do not support variadic parameters. + * + * @param service The service name of type `FirebaseLoggerService`. + * @param messageCode The mesage 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". + * @param message The message string. + */ +extern void FIRLogDebugSwift(FIRLoggerService service, NSString *messageCode, NSString *message); + +/** + * Logs a warning message to the Xcode console and the device log. If running from AppStore, will + * not log any messages with a level higher than FirebaseLoggerLevelNotice to avoid log spamming. + * This function is intended to be used by Swift clients that do not support variadic parameters. + * + * @param service The service name of type `FirebaseLoggerService`. + * @param messageCode The mesage 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". + * @param message The message string. + */ +extern void FIRLogWarningSwift(FIRLoggerService service, NSString *messageCode, NSString *message); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +NS_SWIFT_NAME(FirebaseLogger) +@interface FIRLoggerWrapper : NSObject + +/// Logs a given message at a given log level. This API is effectively a wrapper for the +/// `FIRLogBasic` C API. +/// +/// - Parameters: +/// - level: The log level to use (defined by `FirebaseLoggerLevel` enum values). +/// - service: The service name of type `FirebaseLoggerService`. +/// - code: The mesage 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". +/// - message: Formatted string to be used as the log's message. +/// - args: Arguments list obtained from calling `va_start`, used when message is a format string. ++ (void)logWithLevel:(FIRLoggerLevel)level + withService:(FIRLoggerService)service + withCode:(NSString *)messageCode + withMessage:(NSString *)message + withArgs:(va_list)args; + +/// Logs a given message at a given log level. +/// +/// - Parameters: +/// - level: The log level to use (defined by `FirebaseLoggerLevel` enum values). +/// - service: The service name of type `FirebaseLoggerService`. +/// - code: The mesage 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". +/// - message: Formatted string to be used as the log's message. +/// - args: Arguments list obtained from calling `va_start`, used when message is a format string. ++ (void)logWithLevel:(FIRLoggerLevel)level + service:(FIRLoggerService)service + code:(NSString *)code + message:(NSString *)message + __attribute__((__swift_name__("log(level:service:code:message:)"))); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIROptionsInternal.h b/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIROptionsInternal.h new file mode 100644 index 0000000..93a03d6 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FIROptionsInternal.h @@ -0,0 +1,106 @@ +/* + * 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 + +/** + * Keys for the strings in the plist file. + */ +extern NSString *const kFIRAPIKey; +extern NSString *const kFIRTrackingID; +extern NSString *const kFIRGoogleAppID; +extern NSString *const kFIRClientID; +extern NSString *const kFIRGCMSenderID; +extern NSString *const kFIRAndroidClientID; +extern NSString *const kFIRDatabaseURL; +extern NSString *const kFIRStorageBucket; +extern NSString *const kFIRBundleID; +extern NSString *const kFIRProjectID; + +/** + * Keys for the plist file name + */ +extern NSString *const kServiceInfoFileName; + +extern NSString *const kServiceInfoFileType; + +/** + * This header file exposes the initialization of FirebaseOptions to internal use. + */ +@interface FIROptions () + +/** + * `resetDefaultOptions` and `initInternalWithOptionsDictionary` are exposed only for unit tests. + */ ++ (void)resetDefaultOptions; + +/** + * Initializes the options with dictionary. The above strings are the keys of the dictionary. + * This is the designated initializer. + */ +- (instancetype)initInternalWithOptionsDictionary:(NSDictionary *)serviceInfoDictionary + NS_DESIGNATED_INITIALIZER; + +/** + * `defaultOptions` and `defaultOptionsDictionary` are exposed in order to be used in FirebaseApp + * and other first party services. + */ ++ (FIROptions *)defaultOptions; + ++ (NSDictionary *)defaultOptionsDictionary; + +/** + * Indicates whether or not Analytics collection was explicitly enabled via a plist flag or at + * runtime. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionExplicitlySet; + +/** + * Whether or not Analytics Collection was enabled. Analytics Collection is enabled unless + * explicitly disabled in GoogleService-Info.plist. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionEnabled; + +/** + * Whether or not Analytics Collection was completely disabled. If true, then + * isAnalyticsCollectionEnabled will be false. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionDeactivated; + +/** + * The version ID of the client library, e.g. @"1100000". + */ +@property(nonatomic, readonly, copy) NSString *libraryVersionID; + +/** + * The flag indicating whether this object was constructed with the values in the default plist + * file. + */ +@property(nonatomic) BOOL usingOptionsFromDefaultPlist; + +/** + * Whether or not Measurement was enabled. Measurement is enabled unless explicitly disabled in + * GoogleService-Info.plist. + */ +@property(nonatomic, readonly) BOOL isMeasurementEnabled; + +/** + * Whether or not editing is locked. This should occur after `FirebaseOptions` has been set on a + * `FirebaseApp`. + */ +@property(nonatomic, getter=isEditingLocked) BOOL editingLocked; + +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FirebaseCoreInternal.h b/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FirebaseCoreInternal.h new file mode 100644 index 0000000..0669ae6 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseCore/Extension/FirebaseCoreInternal.h @@ -0,0 +1,25 @@ +// 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 FirebaseCore; + +#import "FIRAppInternal.h" +#import "FIRComponent.h" +#import "FIRComponentContainer.h" +#import "FIRComponentType.h" +#import "FIRDependency.h" +#import "FIRHeartbeatLogger.h" +#import "FIRLibrary.h" +#import "FIRLogger.h" +#import "FIROptionsInternal.h" diff --git a/Pods/FirebaseRemoteConfig/FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h b/Pods/FirebaseRemoteConfig/FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h new file mode 100644 index 0000000..0c850e9 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h @@ -0,0 +1,19 @@ +// 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. + +// An umbrella header, for any other libraries in this repo to access Firebase +// Installations Public headers. Any package manager complexity should be +// handled here. + +#import diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/FIRConfigValue.m b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/FIRConfigValue.m new file mode 100644 index 0000000..8ab2d30 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/FIRConfigValue.m @@ -0,0 +1,91 @@ +/* + * 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 "FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h" + +#import "FirebaseCore/Extension/FirebaseCoreInternal.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h" + +@implementation FIRRemoteConfigValue { + /// Data backing the config value. + NSData *_data; + FIRRemoteConfigSource _source; +} + +/// Designated initializer +- (instancetype)initWithData:(NSData *)data source:(FIRRemoteConfigSource)source { + self = [super init]; + if (self) { + _data = [data copy]; + _source = source; + } + return self; +} + +/// Superclass's designated initializer +- (instancetype)init { + return [self initWithData:nil source:FIRRemoteConfigSourceStatic]; +} + +/// The string is a UTF-8 representation of NSData. +- (NSString *)stringValue { + return [[NSString alloc] initWithData:_data encoding:NSUTF8StringEncoding]; +} + +/// Number representation of a UTF-8 string. +- (NSNumber *)numberValue { + return [NSNumber numberWithDouble:self.stringValue.doubleValue]; +} + +/// Internal representation of the FIRRemoteConfigValue as a NSData object. +- (NSData *)dataValue { + return _data; +} + +/// Boolean representation of a UTF-8 string. +- (BOOL)boolValue { + return self.stringValue.boolValue; +} + +/// Returns a foundation object (NSDictionary / NSArray) representation for JSON data. +- (id)JSONValue { + NSError *error; + if (!_data) { + return nil; + } + id JSONObject = [NSJSONSerialization JSONObjectWithData:_data options:kNilOptions error:&error]; + if (error) { + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000065", @"Error parsing data as JSON."); + return nil; + } + return JSONObject; +} + +/// Debug description showing the representations of all types. +- (NSString *)debugDescription { + NSString *content = [NSString + stringWithFormat:@"Boolean: %d, String: %@, Number: %@, JSON:%@, Data: %@, Source: %zd", + self.boolValue, self.stringValue, self.numberValue, self.JSONValue, _data, + (long)self.source]; + return [NSString stringWithFormat:@"<%@: %p, %@>", [self class], self, content]; +} + +/// Copy method. +- (id)copyWithZone:(NSZone *)zone { + FIRRemoteConfigValue *value = [[[self class] allocWithZone:zone] initWithData:_data]; + return value; +} +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/FIRRemoteConfig.m b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/FIRRemoteConfig.m new file mode 100644 index 0000000..561ada5 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/FIRRemoteConfig.m @@ -0,0 +1,698 @@ +/* + * 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 "FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h" + +#import "FirebaseABTesting/Sources/Private/FirebaseABTestingInternal.h" +#import "FirebaseCore/Extension/FirebaseCoreInternal.h" +#import "FirebaseRemoteConfig/Sources/FIRRemoteConfigComponent.h" +#import "FirebaseRemoteConfig/Sources/Private/FIRRemoteConfig_Private.h" +#import "FirebaseRemoteConfig/Sources/Private/RCNConfigFetch.h" +#import "FirebaseRemoteConfig/Sources/Private/RCNConfigSettings.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigConstants.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigContent.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigDBManager.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigExperiment.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigRealtime.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h" +#import "FirebaseRemoteConfig/Sources/RCNDevice.h" +#import "FirebaseRemoteConfig/Sources/RCNPersonalization.h" + +/// Remote Config Error Domain. +/// TODO: Rename according to obj-c style for constants. +NSString *const FIRRemoteConfigErrorDomain = @"com.google.remoteconfig.ErrorDomain"; +// Remote Config Realtime Error Domain +NSString *const FIRRemoteConfigUpdateErrorDomain = @"com.google.remoteconfig.update.ErrorDomain"; +/// Remote Config Error Info End Time Seconds; +NSString *const FIRRemoteConfigThrottledEndTimeInSecondsKey = @"error_throttled_end_time_seconds"; +/// Minimum required time interval between fetch requests made to the backend. +static NSString *const kRemoteConfigMinimumFetchIntervalKey = @"_rcn_minimum_fetch_interval"; +/// Timeout value for waiting on a fetch response. +static NSString *const kRemoteConfigFetchTimeoutKey = @"_rcn_fetch_timeout"; +/// Notification when config is successfully activated +const NSNotificationName FIRRemoteConfigActivateNotification = + @"FIRRemoteConfigActivateNotification"; +static NSNotificationName FIRRolloutsStateDidChangeNotificationName = + @"FIRRolloutsStateDidChangeNotification"; + +/// Listener for the get methods. +typedef void (^FIRRemoteConfigListener)(NSString *_Nonnull, NSDictionary *_Nonnull); + +@implementation FIRRemoteConfigSettings + +- (instancetype)init { + self = [super init]; + if (self) { + _minimumFetchInterval = RCNDefaultMinimumFetchInterval; + _fetchTimeout = RCNHTTPDefaultConnectionTimeout; + } + return self; +} + +@end + +@implementation FIRRemoteConfig { + /// All the config content. + RCNConfigContent *_configContent; + RCNConfigDBManager *_DBManager; + RCNConfigSettings *_settings; + RCNConfigFetch *_configFetch; + RCNConfigExperiment *_configExperiment; + RCNConfigRealtime *_configRealtime; + dispatch_queue_t _queue; + NSString *_appName; + NSMutableArray *_listeners; +} + +static NSMutableDictionary *> + *RCInstances; + ++ (nonnull FIRRemoteConfig *)remoteConfigWithApp:(FIRApp *_Nonnull)firebaseApp { + return [FIRRemoteConfig + remoteConfigWithFIRNamespace:FIRRemoteConfigConstants.FIRNamespaceGoogleMobilePlatform + app:firebaseApp]; +} + ++ (nonnull FIRRemoteConfig *)remoteConfigWithFIRNamespace:(NSString *_Nonnull)firebaseNamespace { + if (![FIRApp isDefaultAppConfigured]) { + [NSException raise:@"FIRAppNotConfigured" + format:@"The default `FirebaseApp` instance must be configured before the " + @"default Remote Config instance can be initialized. One way to ensure this " + @"is to call `FirebaseApp.configure()` in the App Delegate's " + @"`application(_:didFinishLaunchingWithOptions:)` or the `@main` struct's " + @"initializer in SwiftUI."]; + } + + return [FIRRemoteConfig remoteConfigWithFIRNamespace:firebaseNamespace app:[FIRApp defaultApp]]; +} + ++ (nonnull FIRRemoteConfig *)remoteConfigWithFIRNamespace:(NSString *_Nonnull)firebaseNamespace + app:(FIRApp *_Nonnull)firebaseApp { + // Use the provider to generate and return instances of FIRRemoteConfig for this specific app and + // namespace. This will ensure the app is configured before Remote Config can return an instance. + id provider = + FIR_COMPONENT(FIRRemoteConfigProvider, firebaseApp.container); + return [provider remoteConfigForNamespace:firebaseNamespace]; +} + ++ (FIRRemoteConfig *)remoteConfig { + // If the default app is not configured at this point, warn the developer. + if (![FIRApp isDefaultAppConfigured]) { + [NSException raise:@"FIRAppNotConfigured" + format:@"The default `FirebaseApp` instance must be configured before the " + @"default Remote Config instance can be initialized. One way to ensure this " + @"is to call `FirebaseApp.configure()` in the App Delegate's " + @"`application(_:didFinishLaunchingWithOptions:)` or the `@main` struct's " + @"initializer in SwiftUI."]; + } + + return [FIRRemoteConfig + remoteConfigWithFIRNamespace:FIRRemoteConfigConstants.FIRNamespaceGoogleMobilePlatform + app:[FIRApp defaultApp]]; +} + +/// Singleton instance of serial queue for queuing all incoming RC calls. ++ (dispatch_queue_t)sharedRemoteConfigSerialQueue { + static dispatch_once_t onceToken; + static dispatch_queue_t sharedRemoteConfigQueue; + dispatch_once(&onceToken, ^{ + sharedRemoteConfigQueue = + dispatch_queue_create(RCNRemoteConfigQueueLabel, DISPATCH_QUEUE_SERIAL); + }); + return sharedRemoteConfigQueue; +} + +/// Designated initializer +- (instancetype)initWithAppName:(NSString *)appName + FIROptions:(FIROptions *)options + namespace:(NSString *)FIRNamespace + DBManager:(RCNConfigDBManager *)DBManager + configContent:(RCNConfigContent *)configContent + analytics:(nullable id)analytics { + self = [super init]; + if (self) { + _appName = appName; + _DBManager = DBManager; + // The fully qualified Firebase namespace is namespace:firappname. + _FIRNamespace = [NSString stringWithFormat:@"%@:%@", FIRNamespace, appName]; + + // Initialize RCConfigContent if not already. + _configContent = configContent; + _settings = [[RCNConfigSettings alloc] initWithDatabaseManager:_DBManager + namespace:_FIRNamespace + firebaseAppName:appName + googleAppID:options.googleAppID]; + + FIRExperimentController *experimentController = [FIRExperimentController sharedInstance]; + _configExperiment = [[RCNConfigExperiment alloc] initWithDBManager:_DBManager + experimentController:experimentController]; + /// Serial queue for read and write lock. + _queue = [FIRRemoteConfig sharedRemoteConfigSerialQueue]; + + // Initialize with default config settings. + [self setDefaultConfigSettings]; + _configFetch = [[RCNConfigFetch alloc] initWithContent:_configContent + DBManager:_DBManager + settings:_settings + analytics:analytics + experiment:_configExperiment + queue:_queue + namespace:_FIRNamespace + options:options]; + + _configRealtime = [[RCNConfigRealtime alloc] init:_configFetch + settings:_settings + namespace:_FIRNamespace + options:options]; + + [_settings loadConfigFromMetadataTable]; + + if (analytics) { + _listeners = [[NSMutableArray alloc] init]; + RCNPersonalization *personalization = + [[RCNPersonalization alloc] initWithAnalytics:analytics]; + [self addListener:^(NSString *key, NSDictionary *config) { + [personalization logArmActive:key config:config]; + }]; + } + } + return self; +} + +// Initialize with default config settings. +- (void)setDefaultConfigSettings { + // Set the default config settings. + self->_settings.fetchTimeout = RCNHTTPDefaultConnectionTimeout; + self->_settings.minimumFetchInterval = RCNDefaultMinimumFetchInterval; +} + +- (void)ensureInitializedWithCompletionHandler: + (nonnull FIRRemoteConfigInitializationCompletion)completionHandler { + __weak FIRRemoteConfig *weakSelf = self; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ + FIRRemoteConfig *strongSelf = weakSelf; + if (!strongSelf) { + return; + } + BOOL initializationSuccess = [self->_configContent initializationSuccessful]; + NSError *error = nil; + if (!initializationSuccess) { + error = [[NSError alloc] + initWithDomain:FIRRemoteConfigErrorDomain + code:FIRRemoteConfigErrorInternalError + userInfo:@{NSLocalizedDescriptionKey : @"Timed out waiting for database load."}]; + } + completionHandler(error); + }); +} + +/// Adds a listener that will be called whenever one of the get methods is called. +/// @param listener Function that takes in the parameter key and the config. +- (void)addListener:(nonnull FIRRemoteConfigListener)listener { + @synchronized(_listeners) { + [_listeners addObject:listener]; + } +} + +- (void)callListeners:(NSString *)key config:(NSDictionary *)config { + @synchronized(_listeners) { + for (FIRRemoteConfigListener listener in _listeners) { + dispatch_async(_queue, ^{ + listener(key, config); + }); + } + } +} + +#pragma mark - fetch + +- (void)fetchWithCompletionHandler:(FIRRemoteConfigFetchCompletion)completionHandler { + dispatch_async(_queue, ^{ + [self fetchWithExpirationDuration:self->_settings.minimumFetchInterval + completionHandler:completionHandler]; + }); +} + +- (void)fetchWithExpirationDuration:(NSTimeInterval)expirationDuration + completionHandler:(FIRRemoteConfigFetchCompletion)completionHandler { + FIRRemoteConfigFetchCompletion completionHandlerCopy = nil; + if (completionHandler) { + completionHandlerCopy = [completionHandler copy]; + } + [_configFetch fetchConfigWithExpirationDuration:expirationDuration + completionHandler:completionHandlerCopy]; +} + +#pragma mark - fetchAndActivate + +- (void)fetchAndActivateWithCompletionHandler: + (FIRRemoteConfigFetchAndActivateCompletion)completionHandler { + __weak FIRRemoteConfig *weakSelf = self; + FIRRemoteConfigFetchCompletion fetchCompletion = + ^(FIRRemoteConfigFetchStatus fetchStatus, NSError *fetchError) { + FIRRemoteConfig *strongSelf = weakSelf; + if (!strongSelf) { + return; + } + // Fetch completed. We are being called on the main queue. + // If fetch is successful, try to activate the fetched config + if (fetchStatus == FIRRemoteConfigFetchStatusSuccess && !fetchError) { + [strongSelf activateWithCompletion:^(BOOL changed, NSError *_Nullable activateError) { + if (completionHandler) { + FIRRemoteConfigFetchAndActivateStatus status = + activateError ? FIRRemoteConfigFetchAndActivateStatusSuccessUsingPreFetchedData + : FIRRemoteConfigFetchAndActivateStatusSuccessFetchedFromRemote; + dispatch_async(dispatch_get_main_queue(), ^{ + completionHandler(status, nil); + }); + } + }]; + } else if (completionHandler) { + FIRRemoteConfigFetchAndActivateStatus status = + fetchStatus == FIRRemoteConfigFetchStatusSuccess + ? FIRRemoteConfigFetchAndActivateStatusSuccessUsingPreFetchedData + : FIRRemoteConfigFetchAndActivateStatusError; + dispatch_async(dispatch_get_main_queue(), ^{ + completionHandler(status, fetchError); + }); + } + }; + [self fetchWithCompletionHandler:fetchCompletion]; +} + +#pragma mark - activate + +typedef void (^FIRRemoteConfigActivateChangeCompletion)(BOOL changed, NSError *_Nullable error); + +- (void)activateWithCompletion:(FIRRemoteConfigActivateChangeCompletion)completion { + __weak FIRRemoteConfig *weakSelf = self; + void (^applyBlock)(void) = ^(void) { + FIRRemoteConfig *strongSelf = weakSelf; + if (!strongSelf) { + NSError *error = [NSError errorWithDomain:FIRRemoteConfigErrorDomain + code:FIRRemoteConfigErrorInternalError + userInfo:@{@"ActivationFailureReason" : @"Internal Error."}]; + if (completion) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + completion(NO, error); + }); + } + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000068", @"Internal error activating config."); + return; + } + // Check if the last fetched config has already been activated. Fetches with no data change are + // ignored. + if (strongSelf->_settings.lastETagUpdateTime == 0 || + strongSelf->_settings.lastETagUpdateTime <= strongSelf->_settings.lastApplyTimeInterval) { + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000069", + @"Most recently fetched config is already activated."); + if (completion) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + completion(NO, nil); + }); + } + return; + } + [strongSelf->_configContent copyFromDictionary:self->_configContent.fetchedConfig + toSource:RCNDBSourceActive + forNamespace:self->_FIRNamespace]; + strongSelf->_settings.lastApplyTimeInterval = [[NSDate date] timeIntervalSince1970]; + // New config has been activated at this point + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000069", @"Config activated."); + [strongSelf->_configContent activatePersonalization]; + // Update last active template version number in setting and userDefaults. + [strongSelf->_settings updateLastActiveTemplateVersion]; + // Update activeRolloutMetadata + [strongSelf->_configContent activateRolloutMetadata:^(BOOL success) { + if (success) { + [self notifyRolloutsStateChange:strongSelf->_configContent.activeRolloutMetadata + versionNumber:strongSelf->_settings.lastActiveTemplateVersion]; + } + }]; + + // Update experiments only for 3p namespace + NSString *namespace = [strongSelf->_FIRNamespace + substringToIndex:[strongSelf->_FIRNamespace rangeOfString:@":"].location]; + if ([namespace isEqualToString:FIRRemoteConfigConstants.FIRNamespaceGoogleMobilePlatform]) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self notifyConfigHasActivated]; + }); + [strongSelf->_configExperiment updateExperimentsWithHandler:^(NSError *_Nullable error) { + if (completion) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + completion(YES, nil); + }); + } + }]; + } else { + if (completion) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + completion(YES, nil); + }); + } + } + }; + dispatch_async(_queue, applyBlock); +} + +- (void)notifyConfigHasActivated { + // Need a valid google app name. + if (!_appName) { + return; + } + // The Remote Config Swift SDK will be listening for this notification so it can tell SwiftUI to + // update the UI. + NSDictionary *appInfoDict = @{kFIRAppNameKey : _appName}; + [[NSNotificationCenter defaultCenter] postNotificationName:FIRRemoteConfigActivateNotification + object:self + userInfo:appInfoDict]; +} + +#pragma mark - helpers +- (NSString *)fullyQualifiedNamespace:(NSString *)namespace { + // If this is already a fully qualified namespace, return. + if ([namespace rangeOfString:@":"].location != NSNotFound) { + return namespace; + } + NSString *fullyQualifiedNamespace = [NSString stringWithFormat:@"%@:%@", namespace, _appName]; + return fullyQualifiedNamespace; +} + +- (FIRRemoteConfigValue *)defaultValueForFullyQualifiedNamespace:(NSString *)namespace + key:(NSString *)key { + FIRRemoteConfigValue *value = self->_configContent.defaultConfig[namespace][key]; + if (!value) { + value = [[FIRRemoteConfigValue alloc] + initWithData:[NSData data] + source:(FIRRemoteConfigSource)FIRRemoteConfigSourceStatic]; + } + return value; +} + +#pragma mark - Get Config Result + +- (FIRRemoteConfigValue *)objectForKeyedSubscript:(NSString *)key { + return [self configValueForKey:key]; +} + +- (FIRRemoteConfigValue *)configValueForKey:(NSString *)key { + if (!key) { + return [[FIRRemoteConfigValue alloc] initWithData:[NSData data] + source:FIRRemoteConfigSourceStatic]; + } + NSString *FQNamespace = [self fullyQualifiedNamespace:_FIRNamespace]; + __block FIRRemoteConfigValue *value; + dispatch_sync(_queue, ^{ + value = self->_configContent.activeConfig[FQNamespace][key]; + if (value) { + if (value.source != FIRRemoteConfigSourceRemote) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000001", + @"Key %@ should come from source:%zd instead coming from source: %zd.", key, + (long)FIRRemoteConfigSourceRemote, (long)value.source); + } + [self callListeners:key + config:[self->_configContent getConfigAndMetadataForNamespace:FQNamespace]]; + return; + } + value = [self defaultValueForFullyQualifiedNamespace:FQNamespace key:key]; + }); + return value; +} + +- (FIRRemoteConfigValue *)configValueForKey:(NSString *)key source:(FIRRemoteConfigSource)source { + if (!key) { + return [[FIRRemoteConfigValue alloc] initWithData:[NSData data] + source:FIRRemoteConfigSourceStatic]; + } + NSString *FQNamespace = [self fullyQualifiedNamespace:_FIRNamespace]; + + __block FIRRemoteConfigValue *value; + dispatch_sync(_queue, ^{ + if (source == FIRRemoteConfigSourceRemote) { + value = self->_configContent.activeConfig[FQNamespace][key]; + } else if (source == FIRRemoteConfigSourceDefault) { + value = self->_configContent.defaultConfig[FQNamespace][key]; + } else { + value = [[FIRRemoteConfigValue alloc] initWithData:[NSData data] + source:FIRRemoteConfigSourceStatic]; + } + }); + return value; +} + +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state + objects:(id __unsafe_unretained[])stackbuf + count:(NSUInteger)len { + __block NSUInteger localValue; + dispatch_sync(_queue, ^{ + localValue = + [self->_configContent.activeConfig[self->_FIRNamespace] countByEnumeratingWithState:state + objects:stackbuf + count:len]; + }); + return localValue; +} + +#pragma mark - Properties + +/// Last fetch completion time. +- (NSDate *)lastFetchTime { + __block NSDate *fetchTime; + dispatch_sync(_queue, ^{ + NSTimeInterval lastFetchTime = self->_settings.lastFetchTimeInterval; + fetchTime = [NSDate dateWithTimeIntervalSince1970:lastFetchTime]; + }); + return fetchTime; +} + +- (FIRRemoteConfigFetchStatus)lastFetchStatus { + __block FIRRemoteConfigFetchStatus currentStatus; + dispatch_sync(_queue, ^{ + currentStatus = self->_settings.lastFetchStatus; + }); + return currentStatus; +} + +- (NSArray *)allKeysFromSource:(FIRRemoteConfigSource)source { + __block NSArray *keys = [[NSArray alloc] init]; + dispatch_sync(_queue, ^{ + NSString *FQNamespace = [self fullyQualifiedNamespace:self->_FIRNamespace]; + switch (source) { + case FIRRemoteConfigSourceDefault: + if (self->_configContent.defaultConfig[FQNamespace]) { + keys = [[self->_configContent.defaultConfig[FQNamespace] allKeys] copy]; + } + break; + case FIRRemoteConfigSourceRemote: + if (self->_configContent.activeConfig[FQNamespace]) { + keys = [[self->_configContent.activeConfig[FQNamespace] allKeys] copy]; + } + break; + default: + break; + } + }); + return keys; +} + +- (nonnull NSSet *)keysWithPrefix:(nullable NSString *)prefix { + __block NSMutableSet *keys = [[NSMutableSet alloc] init]; + dispatch_sync(_queue, ^{ + NSString *FQNamespace = [self fullyQualifiedNamespace:self->_FIRNamespace]; + if (self->_configContent.activeConfig[FQNamespace]) { + NSArray *allKeys = [self->_configContent.activeConfig[FQNamespace] allKeys]; + if (!prefix.length) { + keys = [NSMutableSet setWithArray:allKeys]; + } else { + for (NSString *key in allKeys) { + if ([key hasPrefix:prefix]) { + [keys addObject:key]; + } + } + } + } + }); + return [keys copy]; +} + +#pragma mark - Defaults + +- (void)setDefaults:(NSDictionary *)defaultConfig { + NSString *FQNamespace = [self fullyQualifiedNamespace:_FIRNamespace]; + NSDictionary *defaultConfigCopy = [[NSDictionary alloc] init]; + if (defaultConfig) { + defaultConfigCopy = [defaultConfig copy]; + } + void (^setDefaultsBlock)(void) = ^(void) { + NSDictionary *namespaceToDefaults = @{FQNamespace : defaultConfigCopy}; + [self->_configContent copyFromDictionary:namespaceToDefaults + toSource:RCNDBSourceDefault + forNamespace:FQNamespace]; + self->_settings.lastSetDefaultsTimeInterval = [[NSDate date] timeIntervalSince1970]; + }; + dispatch_async(_queue, setDefaultsBlock); +} + +- (FIRRemoteConfigValue *)defaultValueForKey:(NSString *)key { + NSString *FQNamespace = [self fullyQualifiedNamespace:_FIRNamespace]; + __block FIRRemoteConfigValue *value; + dispatch_sync(_queue, ^{ + NSDictionary *defaultConfig = self->_configContent.defaultConfig; + value = defaultConfig[FQNamespace][key]; + if (value) { + if (value.source != FIRRemoteConfigSourceDefault) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000002", + @"Key %@ should come from source:%zd instead coming from source: %zd", key, + (long)FIRRemoteConfigSourceDefault, (long)value.source); + } + } + }); + return value; +} + +- (void)setDefaultsFromPlistFileName:(nullable NSString *)fileName { + if (!fileName || fileName.length == 0) { + FIRLogWarning(kFIRLoggerRemoteConfig, @"I-RCN000037", + @"The plist file '%@' could not be found by Remote Config.", fileName); + return; + } + NSArray *bundles = @[ [NSBundle mainBundle], [NSBundle bundleForClass:[self class]] ]; + + for (NSBundle *bundle in bundles) { + NSString *plistFile = [bundle pathForResource:fileName ofType:@"plist"]; + // Use the first one we find. + if (plistFile) { + NSDictionary *defaultConfig = [[NSDictionary alloc] initWithContentsOfFile:plistFile]; + if (defaultConfig) { + [self setDefaults:defaultConfig]; + } + return; + } + } + FIRLogWarning(kFIRLoggerRemoteConfig, @"I-RCN000037", + @"The plist file '%@' could not be found by Remote Config.", fileName); +} + +#pragma mark - custom variables + +- (FIRRemoteConfigSettings *)configSettings { + __block NSTimeInterval minimumFetchInterval = RCNDefaultMinimumFetchInterval; + __block NSTimeInterval fetchTimeout = RCNHTTPDefaultConnectionTimeout; + dispatch_sync(_queue, ^{ + minimumFetchInterval = self->_settings.minimumFetchInterval; + fetchTimeout = self->_settings.fetchTimeout; + }); + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000066", + @"Successfully read configSettings. Minimum Fetch Interval:%f, " + @"Fetch timeout: %f", + minimumFetchInterval, fetchTimeout); + FIRRemoteConfigSettings *settings = [[FIRRemoteConfigSettings alloc] init]; + settings.minimumFetchInterval = minimumFetchInterval; + settings.fetchTimeout = fetchTimeout; + /// The NSURLSession needs to be recreated whenever the fetch timeout may be updated. + [_configFetch recreateNetworkSession]; + return settings; +} + +- (void)setConfigSettings:(FIRRemoteConfigSettings *)configSettings { + void (^setConfigSettingsBlock)(void) = ^(void) { + if (!configSettings) { + return; + } + + self->_settings.minimumFetchInterval = configSettings.minimumFetchInterval; + self->_settings.fetchTimeout = configSettings.fetchTimeout; + /// The NSURLSession needs to be recreated whenever the fetch timeout may be updated. + [self->_configFetch recreateNetworkSession]; + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000067", + @"Successfully set configSettings. Minimum Fetch Interval:%f, " + @"Fetch timeout:%f", + configSettings.minimumFetchInterval, configSettings.fetchTimeout); + }; + dispatch_async(_queue, setConfigSettingsBlock); +} + +#pragma mark - Realtime + +- (FIRConfigUpdateListenerRegistration *)addOnConfigUpdateListener: + (void (^_Nonnull)(FIRRemoteConfigUpdate *update, NSError *_Nullable error))listener { + return [self->_configRealtime addConfigUpdateListener:listener]; +} + +#pragma mark - Rollout + +- (void)addRemoteConfigInteropSubscriber:(id)subscriber { + [[NSNotificationCenter defaultCenter] + addObserverForName:FIRRolloutsStateDidChangeNotificationName + object:self + queue:nil + usingBlock:^(NSNotification *_Nonnull notification) { + FIRRolloutsState *rolloutsState = + notification.userInfo[FIRRolloutsStateDidChangeNotificationName]; + [subscriber rolloutsStateDidChange:rolloutsState]; + }]; + // Send active rollout metadata stored in persistence while app launched if there is activeConfig + NSString *fullyQualifiedNamespace = [self fullyQualifiedNamespace:_FIRNamespace]; + NSDictionary *activeConfig = self->_configContent.activeConfig; + if (activeConfig[fullyQualifiedNamespace] && activeConfig[fullyQualifiedNamespace].count > 0) { + [self notifyRolloutsStateChange:self->_configContent.activeRolloutMetadata + versionNumber:self->_settings.lastActiveTemplateVersion]; + } +} + +- (void)notifyRolloutsStateChange:(NSArray *)rolloutMetadata + versionNumber:(NSString *)versionNumber { + NSArray *rolloutsAssignments = + [self rolloutsAssignmentsWith:rolloutMetadata versionNumber:versionNumber]; + FIRRolloutsState *rolloutsState = + [[FIRRolloutsState alloc] initWithAssignmentList:rolloutsAssignments]; + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000069", + @"Send rollouts state notification with name %@ to RemoteConfigInterop.", + FIRRolloutsStateDidChangeNotificationName); + [[NSNotificationCenter defaultCenter] + postNotificationName:FIRRolloutsStateDidChangeNotificationName + object:self + userInfo:@{FIRRolloutsStateDidChangeNotificationName : rolloutsState}]; +} + +- (NSArray *)rolloutsAssignmentsWith: + (NSArray *)rolloutMetadata + versionNumber:(NSString *)versionNumber { + NSMutableArray *rolloutsAssignments = [[NSMutableArray alloc] init]; + NSString *FQNamespace = [self fullyQualifiedNamespace:_FIRNamespace]; + for (NSDictionary *metadata in rolloutMetadata) { + NSString *rolloutId = metadata[RCNFetchResponseKeyRolloutID]; + NSString *variantID = metadata[RCNFetchResponseKeyVariantID]; + NSArray *affectedParameterKeys = metadata[RCNFetchResponseKeyAffectedParameterKeys]; + if (rolloutId && variantID && affectedParameterKeys) { + for (NSString *key in affectedParameterKeys) { + FIRRemoteConfigValue *value = self->_configContent.activeConfig[FQNamespace][key]; + if (!value) { + value = [self defaultValueForFullyQualifiedNamespace:FQNamespace key:key]; + } + FIRRolloutAssignment *assignment = + [[FIRRolloutAssignment alloc] initWithRolloutId:rolloutId + variantId:variantID + templateVersion:[versionNumber longLongValue] + parameterKey:key + parameterValue:value.stringValue]; + [rolloutsAssignments addObject:assignment]; + } + } + } + return rolloutsAssignments; +} +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/FIRRemoteConfigComponent.h b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/FIRRemoteConfigComponent.h new file mode 100644 index 0000000..e8dda53 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/FIRRemoteConfigComponent.h @@ -0,0 +1,64 @@ +/* + * 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 + +#import "FirebaseCore/Extension/FirebaseCoreInternal.h" +@import FirebaseRemoteConfigInterop; + +@class FIRApp; +@class FIRRemoteConfig; + +NS_ASSUME_NONNULL_BEGIN + +/// Provides and creates instances of Remote Config based on the namespace provided. Used in the +/// interop registration process to keep track of RC instances for each `FIRApp` instance. +@protocol FIRRemoteConfigProvider + +/// Cached instances of Remote Config objects. +@property(nonatomic, strong) NSMutableDictionary *instances; + +/// Default method for retrieving a Remote Config instance, or creating one if it doesn't exist. +- (FIRRemoteConfig *)remoteConfigForNamespace:(NSString *)remoteConfigNamespace; + +@end + +/// A concrete implementation for FIRRemoteConfigInterop to create Remote Config instances and +/// register with Core's component system. +@interface FIRRemoteConfigComponent + : NSObject + +/// The FIRApp that instances will be set up with. +@property(nonatomic, weak, readonly) FIRApp *app; + +/// Cached instances of Remote Config objects. +@property(nonatomic, strong) NSMutableDictionary *instances; + +/// Clear all the component instances from the singleton which created previously, this is for +/// testing only ++ (void)clearAllComponentInstances; + +/// Default method for retrieving a Remote Config instance, or creating one if it doesn't exist. +- (FIRRemoteConfig *)remoteConfigForNamespace:(NSString *)remoteConfigNamespace; + +/// Default initializer. +- (instancetype)initWithApp:(FIRApp *)app NS_DESIGNATED_INITIALIZER; + +- (instancetype)init __attribute__((unavailable("Use `initWithApp:`."))); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/FIRRemoteConfigComponent.m b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/FIRRemoteConfigComponent.m new file mode 100644 index 0000000..8105545 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/FIRRemoteConfigComponent.m @@ -0,0 +1,155 @@ +/* + * 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 "FirebaseRemoteConfig/Sources/FIRRemoteConfigComponent.h" + +#import "FirebaseCore/Extension/FirebaseCoreInternal.h" +#import "FirebaseRemoteConfig/Sources/Private/FIRRemoteConfig_Private.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigContent.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigDBManager.h" +#import "Interop/Analytics/Public/FIRAnalyticsInterop.h" + +@implementation FIRRemoteConfigComponent + +// Because Component now need to register two protocols (provider and interop), we need a way to +// return the same component instance for both registered protocol, this singleton pattern allow us +// to return the same component object for both registration callback. +static NSMutableDictionary *_componentInstances = nil; + ++ (FIRRemoteConfigComponent *)getComponentForApp:(FIRApp *)app { + @synchronized(_componentInstances) { + // need to init the dictionary first + if (!_componentInstances) { + _componentInstances = [[NSMutableDictionary alloc] init]; + } + if (![_componentInstances objectForKey:app.name]) { + _componentInstances[app.name] = [[self alloc] initWithApp:app]; + } + return _componentInstances[app.name]; + } + return nil; +} + ++ (void)clearAllComponentInstances { + @synchronized(_componentInstances) { + [_componentInstances removeAllObjects]; + } +} + +/// Default method for retrieving a Remote Config instance, or creating one if it doesn't exist. +- (FIRRemoteConfig *)remoteConfigForNamespace:(NSString *)remoteConfigNamespace { + if (!remoteConfigNamespace) { + // TODO: Throw an error? Return nil? What do we want to do? + return nil; + } + + // Validate the required information is available. + FIROptions *options = self.app.options; + NSString *errorPropertyName; + if (options.googleAppID.length == 0) { + errorPropertyName = @"googleAppID"; + } else if (options.GCMSenderID.length == 0) { + errorPropertyName = @"GCMSenderID"; + } else if (options.projectID.length == 0) { + errorPropertyName = @"projectID"; + } + + if (errorPropertyName) { + NSString *const kFirebaseConfigErrorDomain = @"com.firebase.config"; + [NSException + raise:kFirebaseConfigErrorDomain + format:@"%@", + [NSString + stringWithFormat: + @"Firebase Remote Config is missing the required %@ property from the " + @"configured FirebaseApp and will not be able to function properly. Please " + @"fix this issue to ensure that Firebase is correctly configured.", + errorPropertyName]]; + } + + FIRRemoteConfig *instance = self.instances[remoteConfigNamespace]; + if (!instance) { + FIRApp *app = self.app; + id analytics = + app.isDefaultApp ? FIR_COMPONENT(FIRAnalyticsInterop, app.container) : nil; + instance = [[FIRRemoteConfig alloc] initWithAppName:app.name + FIROptions:app.options + namespace:remoteConfigNamespace + DBManager:[RCNConfigDBManager sharedInstance] + configContent:[RCNConfigContent sharedInstance] + analytics:analytics]; + self.instances[remoteConfigNamespace] = instance; + } + + return instance; +} + +/// Default initializer. +- (instancetype)initWithApp:(FIRApp *)app { + self = [super init]; + if (self) { + _app = app; + _instances = [[NSMutableDictionary alloc] initWithCapacity:1]; + } + return self; +} + +#pragma mark - Lifecycle + ++ (void)load { + // Register as an internal library to be part of the initialization process. The name comes from + // go/firebase-sdk-platform-info. + [FIRApp registerInternalLibrary:self withName:@"fire-rc"]; +} + +#pragma mark - Interoperability + ++ (NSArray *)componentsToRegister { + FIRDependency *analyticsDep = [FIRDependency dependencyWithProtocol:@protocol(FIRAnalyticsInterop) + isRequired:NO]; + FIRComponent *rcProvider = [FIRComponent + componentWithProtocol:@protocol(FIRRemoteConfigProvider) + instantiationTiming:FIRInstantiationTimingAlwaysEager + dependencies:@[ analyticsDep ] + creationBlock:^id _Nullable(FIRComponentContainer *container, BOOL *isCacheable) { + // Cache the component so instances of Remote Config are cached. + *isCacheable = YES; + return [FIRRemoteConfigComponent getComponentForApp:container.app]; + }]; + + // Unlike provider needs to setup a hard dependency on remote config, interop allows an optional + // dependency on RC + FIRComponent *rcInterop = [FIRComponent + componentWithProtocol:@protocol(FIRRemoteConfigInterop) + instantiationTiming:FIRInstantiationTimingAlwaysEager + dependencies:@[] + creationBlock:^id _Nullable(FIRComponentContainer *container, BOOL *isCacheable) { + // Cache the component so instances of Remote Config are cached. + *isCacheable = YES; + return [FIRRemoteConfigComponent getComponentForApp:container.app]; + }]; + return @[ rcProvider, rcInterop ]; +} + +#pragma mark - Remote Config Interop Protocol + +- (void)registerRolloutsStateSubscriber:(id)subscriber + for:(NSString * _Nonnull)namespace { + FIRRemoteConfig *instance = [self remoteConfigForNamespace:namespace]; + [instance addRemoteConfigInteropSubscriber:subscriber]; +} + +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/FIRRemoteConfigUpdate.m b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/FIRRemoteConfigUpdate.m new file mode 100644 index 0000000..47a8c89 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/FIRRemoteConfigUpdate.m @@ -0,0 +1,33 @@ +/* + * Copyright 2022 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 + +#import "FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h" + +@implementation FIRRemoteConfigUpdate { + NSSet *_updatedKeys; +} + +- (instancetype)initWithUpdatedKeys:(NSSet *)updatedKeys { + self = [super init]; + if (self) { + _updatedKeys = [updatedKeys copy]; + } + return self; +} + +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/Private/FIRRemoteConfig_Private.h b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/Private/FIRRemoteConfig_Private.h new file mode 100644 index 0000000..4420dcb --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/Private/FIRRemoteConfig_Private.h @@ -0,0 +1,87 @@ +/* + * 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 +#import "RCNConfigSettings.h" // This import is needed to expose settings for the Swift API tests. + +@class FIROptions; +@class RCNConfigContent; +@class RCNConfigDBManager; +@class RCNConfigFetch; +@class RCNConfigRealtime; +@protocol FIRAnalyticsInterop; +@protocol FIRRolloutsStateSubscriber; + +NS_ASSUME_NONNULL_BEGIN + +@class RCNConfigSettings; + +@interface FIRRemoteConfigUpdate () + +/// Designated initializer. +- (instancetype)initWithUpdatedKeys:(NSSet *)updatedKeys; +@end + +@interface FIRRemoteConfig () { + NSString *_FIRNamespace; +} + +/// Internal settings +@property(nonatomic, readonly, strong) RCNConfigSettings *settings; + +/// Config settings are custom settings. +@property(nonatomic, readwrite, strong, nonnull) RCNConfigFetch *configFetch; + +@property(nonatomic, readwrite, strong, nonnull) RCNConfigRealtime *configRealtime; + +/// Returns the FIRRemoteConfig instance for your namespace and for the default Firebase App. +/// This singleton object contains the complete set of Remote Config parameter values available to +/// the app, including the Active Config and Default Config.. This object also caches values fetched +/// from the Remote Config Server until they are copied to the Active Config by calling +/// activateFetched. When you fetch values from the Remote Config Server using the default Firebase +/// namespace service, you should use this class method to create a shared instance of the +/// FIRRemoteConfig object to ensure that your app will function properly with the Remote Config +/// Server and the Firebase service. This API is used internally by 2P teams. ++ (FIRRemoteConfig *)remoteConfigWithFIRNamespace:(NSString *)remoteConfigNamespace + NS_SWIFT_NAME(remoteConfig(FIRNamespace:)); + +/// Returns the FIRRemoteConfig instance for your namespace and for the default 3P developer's app. +/// This singleton object contains the complete set of Remote Config parameter values available to +/// the app, including the Active Config and Default Config. This object also caches values fetched +/// from the Remote Config Server until they are copied to the Active Config by calling +/// activateFetched. When you fetch values from the Remote Config Server using the default Firebase +/// namespace service, you should use this class method to create a shared instance of the +/// FIRRemoteConfig object to ensure that your app will function properly with the Remote Config +/// Server and the Firebase service. ++ (FIRRemoteConfig *)remoteConfigWithFIRNamespace:(NSString *)remoteConfigNamespace + app:(FIRApp *)app + NS_SWIFT_NAME(remoteConfig(FIRNamespace:app:)); + +/// Initialize a FIRRemoteConfig instance with all the required parameters directly. This exists so +/// tests can create FIRRemoteConfig objects without needing FIRApp. +- (instancetype)initWithAppName:(NSString *)appName + FIROptions:(FIROptions *)options + namespace:(NSString *)FIRNamespace + DBManager:(RCNConfigDBManager *)DBManager + configContent:(RCNConfigContent *)configContent + analytics:(nullable id)analytics; + +/// Register RolloutsStateSubcriber to FIRRemoteConfig instance +- (void)addRemoteConfigInteropSubscriber:(id _Nonnull)subscriber; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/Private/RCNConfigFetch.h b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/Private/RCNConfigFetch.h new file mode 100644 index 0000000..dbef87d --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/Private/RCNConfigFetch.h @@ -0,0 +1,76 @@ +/* + * 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 + +#import "FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h" +#import "Interop/Analytics/Public/FIRAnalyticsInterop.h" + +@class FIROptions; +@class RCNConfigContent; +@class RCNConfigSettings; +@class RCNConfigExperiment; +@class RCNConfigDBManager; + +NS_ASSUME_NONNULL_BEGIN + +/// Completion handler invoked by NSSessionFetcher. +typedef void (^RCNConfigFetcherCompletion)(NSData *data, NSURLResponse *response, NSError *error); + +/// Completion handler invoked after a fetch that contains the updated keys +typedef void (^RCNConfigFetchCompletion)(FIRRemoteConfigFetchStatus status, + FIRRemoteConfigUpdate *update, + NSError *error); + +@interface RCNConfigFetch : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +/// Designated initializer +- (instancetype)initWithContent:(RCNConfigContent *)content + DBManager:(RCNConfigDBManager *)DBManager + settings:(RCNConfigSettings *)settings + analytics:(nullable id)analytics + experiment:(nullable RCNConfigExperiment *)experiment + queue:(dispatch_queue_t)queue + namespace:(NSString *)firebaseNamespace + options:(FIROptions *)firebaseOptions NS_DESIGNATED_INITIALIZER; + +/// Fetches config data keyed by namespace. Completion block will be called on the main queue. +/// @param expirationDuration Expiration duration, in seconds. +/// @param completionHandler Callback handler. +- (void)fetchConfigWithExpirationDuration:(NSTimeInterval)expirationDuration + completionHandler:(FIRRemoteConfigFetchCompletion)completionHandler; + +/// Fetches config data immediately, keyed by namespace. Completion block will be called on the main +/// queue. +/// @param fetchAttemptNumber The number of the fetch attempt. +/// @param completionHandler Callback handler. +- (void)realtimeFetchConfigWithNoExpirationDuration:(NSInteger)fetchAttemptNumber + completionHandler:(RCNConfigFetchCompletion)completionHandler; + +/// Add the ability to update NSURLSession's timeout after a session has already been created. +- (void)recreateNetworkSession; + +/// Provide fetchSession for tests to override. +@property(nonatomic, readwrite, strong, nonnull) NSURLSession *fetchSession; + +/// Provide config template version number for Realtime config client. +@property(nonatomic, copy, nonnull) NSString *templateVersionNumber; + +NS_ASSUME_NONNULL_END + +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/Private/RCNConfigSettings.h b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/Private/RCNConfigSettings.h new file mode 100644 index 0000000..36fb8e7 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/Private/RCNConfigSettings.h @@ -0,0 +1,152 @@ +/* + * 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 + +#import + +@class RCNConfigDBManager; + +/// This internal class contains a set of variables that are unique among all the config instances. +/// It also handles all metadata and internal metadata. This class is not thread safe and does not +/// inherently allow for synchronized accesss. Callers are responsible for synchronization +/// (currently using serial dispatch queues). +@interface RCNConfigSettings : NSObject + +/// The time interval that config data stays fresh. +@property(nonatomic, readwrite, assign) NSTimeInterval minimumFetchInterval; + +/// The timeout to set for outgoing fetch requests. +@property(nonatomic, readwrite, assign) NSTimeInterval fetchTimeout; +// The Google App ID of the configured FIRApp. +@property(nonatomic, readwrite, copy) NSString *googleAppID; +#pragma mark - Data required by config request. +/// Device authentication ID required by config request. +@property(nonatomic, copy) NSString *deviceAuthID; +/// Secret Token required by config request. +@property(nonatomic, copy) NSString *secretToken; +/// Device data version of checkin information. +@property(nonatomic, copy) NSString *deviceDataVersion; +/// InstallationsID. +@property(nonatomic, copy) NSString *configInstallationsIdentifier; +/// Installations token. +@property(nonatomic, copy) NSString *configInstallationsToken; + +/// A list of successful fetch timestamps in milliseconds. +/// TODO Not used anymore. Safe to remove. +@property(nonatomic, readonly, copy) NSArray *successFetchTimes; +/// A list of failed fetch timestamps in milliseconds. +@property(nonatomic, readonly, copy) NSArray *failureFetchTimes; +/// Custom variable (aka App context digest). This is the pending custom variables request before +/// fetching. +@property(nonatomic, copy) NSDictionary *customVariables; +/// Cached internal metadata from internal metadata table. It contains customized information such +/// as HTTP connection timeout, HTTP read timeout, success/failure throttling rate and time +/// interval. Client has the default value of each parameters, they are only saved in +/// internalMetadata if they have been customize by developers. +@property(nonatomic, readonly, copy) NSDictionary *internalMetadata; +/// Device conditions since last successful fetch from the backend. Device conditions including +/// app +/// version, iOS version, device localte, language, GMP project ID and Game project ID. Used for +/// determing whether to throttle. +@property(nonatomic, readonly, copy) NSDictionary *deviceContext; +/// Bundle Identifier +@property(nonatomic, readonly, copy) NSString *bundleIdentifier; +/// The time of last successful config fetch. +@property(nonatomic, readonly, assign) NSTimeInterval lastFetchTimeInterval; +/// Last fetch status. +@property(nonatomic, readwrite, assign) FIRRemoteConfigFetchStatus lastFetchStatus; +/// The reason that last fetch failed. +@property(nonatomic, readwrite, assign) FIRRemoteConfigError lastFetchError; +/// The time of last apply timestamp. +@property(nonatomic, readwrite, assign) NSTimeInterval lastApplyTimeInterval; +/// The time of last setDefaults timestamp. +@property(nonatomic, readwrite, assign) NSTimeInterval lastSetDefaultsTimeInterval; +/// The latest eTag value stored from the last successful response. +@property(nonatomic, readwrite, assign) NSString *lastETag; +/// The timestamp of the last eTag update. +@property(nonatomic, readwrite, assign) NSTimeInterval lastETagUpdateTime; +/// Last fetched template version. +@property(nonatomic, readwrite, assign) NSString *lastFetchedTemplateVersion; +/// Last active template version. +@property(nonatomic, readwrite, assign) NSString *lastActiveTemplateVersion; + +#pragma mark Throttling properties + +/// Throttling intervals are based on https://cloud.google.com/storage/docs/exponential-backoff +/// Returns true if client has fetched config and has not got back from server. This is used to +/// determine whether there is another config task infight when fetching. +@property(atomic, readwrite, assign) BOOL isFetchInProgress; +/// Returns the current retry interval in seconds set for exponential backoff. +@property(nonatomic, readwrite, assign) double exponentialBackoffRetryInterval; +/// Returns the time in seconds until the next request is allowed while in exponential backoff mode. +@property(nonatomic, readonly, assign) NSTimeInterval exponentialBackoffThrottleEndTime; +/// Returns the current retry interval in seconds set for exponential backoff for the Realtime +/// service. +@property(nonatomic, readwrite, assign) double realtimeExponentialBackoffRetryInterval; +/// Returns the time in seconds until the next request is allowed while in exponential backoff mode +/// for the Realtime service. +@property(nonatomic, readonly, assign) NSTimeInterval realtimeExponentialBackoffThrottleEndTime; +/// Realtime connection attempts. +@property(nonatomic, readwrite, assign) int realtimeRetryCount; + +#pragma mark Throttling Methods + +/// Designated initializer. +- (instancetype)initWithDatabaseManager:(RCNConfigDBManager *)manager + namespace:(NSString *)FIRNamespace + firebaseAppName:(NSString *)appName + googleAppID:(NSString *)googleAppID; + +/// Returns a fetch request with the latest device and config change. +/// Whenever user issues a fetch api call, collect the latest request. +/// @param userProperties User properties to set to config request. +/// @return Config fetch request string +- (NSString *)nextRequestWithUserProperties:(NSDictionary *)userProperties; + +/// Returns metadata from metadata table. +- (NSDictionary *)loadConfigFromMetadataTable; + +/// Updates internal content with the latest successful config response. +- (void)updateInternalContentWithResponse:(NSDictionary *)response; + +/// Updates the metadata table with the current fetch status. +/// @param fetchSuccess True if fetch was successful. +- (void)updateMetadataWithFetchSuccessStatus:(BOOL)fetchSuccess + templateVersion:(NSString *)templateVersion; + +/// Increases the throttling time. Should only be called if the fetch error indicates a server +/// issue. +- (void)updateExponentialBackoffTime; + +/// Increases the throttling time for Realtime. Should only be called if the Realtime error +/// indicates a server issue. +- (void)updateRealtimeExponentialBackoffTime; + +/// Update last active template version from last fetched template version. +- (void)updateLastActiveTemplateVersion; + +/// Returns the difference between the Realtime backoff end time and the current time in a +/// NSTimeInterval format. +- (NSTimeInterval)getRealtimeBackoffInterval; + +/// Returns true if we are in exponential backoff mode and it is not yet the next request time. +- (BOOL)shouldThrottle; + +/// Returns true if the last fetch is outside the minimum fetch interval supplied. +- (BOOL)hasMinimumFetchIntervalElapsed:(NSTimeInterval)minimumFetchInterval; + +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h new file mode 100644 index 0000000..29cd12a --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h @@ -0,0 +1,360 @@ +/* + * 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 + +@class FIRApp; + +/// The Firebase Remote Config service default namespace, to be used if the API method does not +/// specify a different namespace. Use the default namespace if configuring from the Google Firebase +/// service. +extern NSString *const _Nonnull FIRNamespaceGoogleMobilePlatform NS_SWIFT_NAME( + NamespaceGoogleMobilePlatform); + +/// Key used to manage throttling in NSError user info when the refreshing of Remote Config +/// parameter values (data) is throttled. The value of this key is the elapsed time since 1970, +/// measured in seconds. +extern NSString *const _Nonnull FIRRemoteConfigThrottledEndTimeInSecondsKey NS_SWIFT_NAME( + RemoteConfigThrottledEndTimeInSecondsKey); + +/** + * Listener registration returned by `addOnConfigUpdateListener`. Calling its method `remove` stops + * the associated listener from receiving config updates and unregisters itself. + * + * If remove is called and no other listener registrations remain, the connection to the real-time + * RC backend is closed. Subsequently calling `addOnConfigUpdateListener` will re-open the + * connection. + */ +NS_SWIFT_NAME(ConfigUpdateListenerRegistration) +@interface FIRConfigUpdateListenerRegistration : NSObject +/** + * Removes the listener associated with this `ConfigUpdateListenerRegistration`. After the + * initial call, subsequent calls have no effect. + */ +- (void)remove; +@end + +/// Indicates whether updated data was successfully fetched. +typedef NS_ENUM(NSInteger, FIRRemoteConfigFetchStatus) { + /// Config has never been fetched. + FIRRemoteConfigFetchStatusNoFetchYet, + /// Config fetch succeeded. + FIRRemoteConfigFetchStatusSuccess, + /// Config fetch failed. + FIRRemoteConfigFetchStatusFailure, + /// Config fetch was throttled. + FIRRemoteConfigFetchStatusThrottled, +} NS_SWIFT_NAME(RemoteConfigFetchStatus); + +/// Indicates whether updated data was successfully fetched and activated. +typedef NS_ENUM(NSInteger, FIRRemoteConfigFetchAndActivateStatus) { + /// The remote fetch succeeded and fetched data was activated. + FIRRemoteConfigFetchAndActivateStatusSuccessFetchedFromRemote, + /// The fetch and activate succeeded from already fetched but yet unexpired config data. You can + /// control this using minimumFetchInterval property in FIRRemoteConfigSettings. + FIRRemoteConfigFetchAndActivateStatusSuccessUsingPreFetchedData, + /// The fetch and activate failed. + FIRRemoteConfigFetchAndActivateStatusError +} NS_SWIFT_NAME(RemoteConfigFetchAndActivateStatus); + +/// Remote Config error domain that handles errors when fetching data from the service. +extern NSString *const _Nonnull FIRRemoteConfigErrorDomain NS_SWIFT_NAME(RemoteConfigErrorDomain); +/// Firebase Remote Config service fetch error. +typedef NS_ERROR_ENUM(FIRRemoteConfigErrorDomain, FIRRemoteConfigError){ + /// Unknown or no error. + FIRRemoteConfigErrorUnknown = 8001, + /// Frequency of fetch requests exceeds throttled limit. + FIRRemoteConfigErrorThrottled = 8002, + /// Internal error that covers all internal HTTP errors. + FIRRemoteConfigErrorInternalError = 8003, +} NS_SWIFT_NAME(RemoteConfigError); + +/// Remote Config error domain that handles errors for the real-time config update service. +extern NSString *const _Nonnull FIRRemoteConfigUpdateErrorDomain NS_SWIFT_NAME(RemoteConfigUpdateErrorDomain); +/// Firebase Remote Config real-time config update service error. +typedef NS_ERROR_ENUM(FIRRemoteConfigUpdateErrorDomain, FIRRemoteConfigUpdateError){ + /// Unable to make a connection to the Remote Config backend. + FIRRemoteConfigUpdateErrorStreamError = 8001, + /// Unable to fetch the latest version of the config. + FIRRemoteConfigUpdateErrorNotFetched = 8002, + /// The ConfigUpdate message was unparsable. + FIRRemoteConfigUpdateErrorMessageInvalid = 8003, + /// The Remote Config real-time config update service is unavailable. + FIRRemoteConfigUpdateErrorUnavailable = 8004, +} NS_SWIFT_NAME(RemoteConfigUpdateError); + +/// Enumerated value that indicates the source of Remote Config data. Data can come from +/// the Remote Config service, the DefaultConfig that is available when the app is first installed, +/// or a static initialized value if data is not available from the service or DefaultConfig. +typedef NS_ENUM(NSInteger, FIRRemoteConfigSource) { + FIRRemoteConfigSourceRemote, ///< The data source is the Remote Config service. + FIRRemoteConfigSourceDefault, ///< The data source is the DefaultConfig defined for this app. + FIRRemoteConfigSourceStatic, ///< The data doesn't exist, return a static initialized value. +} NS_SWIFT_NAME(RemoteConfigSource); + +/// Completion handler invoked by fetch methods when they get a response from the server. +/// +/// @param status Config fetching status. +/// @param error Error message on failure. +typedef void (^FIRRemoteConfigFetchCompletion)(FIRRemoteConfigFetchStatus status, + NSError *_Nullable error) + NS_SWIFT_UNAVAILABLE("Use Swift's closure syntax instead."); + +/// Completion handler invoked by activate method upon completion. +/// @param error Error message on failure. Nil if activation was successful. +typedef void (^FIRRemoteConfigActivateCompletion)(NSError *_Nullable error) + NS_SWIFT_UNAVAILABLE("Use Swift's closure syntax instead."); + +/// Completion handler invoked upon completion of Remote Config initialization. +/// +/// @param initializationError nil if initialization succeeded. +typedef void (^FIRRemoteConfigInitializationCompletion)(NSError *_Nullable initializationError) + NS_SWIFT_UNAVAILABLE("Use Swift's closure syntax instead."); + +/// Completion handler invoked by the fetchAndActivate method. Used to convey status of fetch and, +/// if successful, resultant activate call +/// @param status Config fetching status. +/// @param error Error message on failure of config fetch +typedef void (^FIRRemoteConfigFetchAndActivateCompletion)( + FIRRemoteConfigFetchAndActivateStatus status, NSError *_Nullable error) + NS_SWIFT_UNAVAILABLE("Use Swift's closure syntax instead."); + +#pragma mark - FIRRemoteConfigValue +/// This class provides a wrapper for Remote Config parameter values, with methods to get parameter +/// values as different data types. +NS_SWIFT_NAME(RemoteConfigValue) +@interface FIRRemoteConfigValue : NSObject +/// Gets the value as a string. +@property(nonatomic, readonly, nullable) NSString *stringValue; +/// Gets the value as a number value. +@property(nonatomic, readonly, nonnull) NSNumber *numberValue; +/// Gets the value as a NSData object. +@property(nonatomic, readonly, nonnull) NSData *dataValue; +/// Gets the value as a boolean. +@property(nonatomic, readonly) BOOL boolValue; +/// Gets a foundation object (NSDictionary / NSArray) by parsing the value as JSON. This method uses +/// NSJSONSerialization's JSONObjectWithData method with an options value of 0. +@property(nonatomic, readonly, nullable) id JSONValue NS_SWIFT_NAME(jsonValue); +/// Identifies the source of the fetched value. +@property(nonatomic, readonly) FIRRemoteConfigSource source; +@end + +#pragma mark - FIRRemoteConfigSettings +/// Firebase Remote Config settings. +NS_SWIFT_NAME(RemoteConfigSettings) +@interface FIRRemoteConfigSettings : NSObject +/// Indicates the default value in seconds to set for the minimum interval that needs to elapse +/// before a fetch request can again be made to the Remote Config backend. After a fetch request to +/// the backend has succeeded, no additional fetch requests to the backend will be allowed until the +/// minimum fetch interval expires. Note that you can override this default on a per-fetch request +/// basis using `RemoteConfig.fetch(withExpirationDuration:)`. For example, setting +/// the expiration duration to 0 in the fetch request will override the `minimumFetchInterval` and +/// allow the request to proceed. +@property(nonatomic, assign) NSTimeInterval minimumFetchInterval; +/// Indicates the default value in seconds to abandon a pending fetch request made to the backend. +/// This value is set for outgoing requests as the `timeoutIntervalForRequest` as well as the +/// `timeoutIntervalForResource` on the `NSURLSession`'s configuration. +@property(nonatomic, assign) NSTimeInterval fetchTimeout; +@end + +#pragma mark - FIRRemoteConfigUpdate +/// Used by Remote Config real-time config update service, this class represents changes between the +/// newly fetched config and the current one. An instance of this class is passed to +/// `FIRRemoteConfigUpdateCompletion` when a new config version has been automatically fetched. +NS_SWIFT_NAME(RemoteConfigUpdate) +@interface FIRRemoteConfigUpdate : NSObject + +/// Parameter keys whose values have been updated from the currently activated values. Includes +/// keys that are added, deleted, and whose value, value source, or metadata has changed. +@property(nonatomic, readonly, nonnull) NSSet *updatedKeys; + +@end + +#pragma mark - FIRRemoteConfig +/// Firebase Remote Config class. The class method `remoteConfig()` can be used +/// to fetch, activate and read config results and set default config results on the default +/// Remote Config instance. +NS_SWIFT_NAME(RemoteConfig) +@interface FIRRemoteConfig : NSObject +/// Last successful fetch completion time. +@property(nonatomic, readonly, strong, nullable) NSDate *lastFetchTime; +/// Last fetch status. The status can be any enumerated value from `RemoteConfigFetchStatus`. +@property(nonatomic, readonly, assign) FIRRemoteConfigFetchStatus lastFetchStatus; +/// Config settings are custom settings. +@property(nonatomic, readwrite, strong, nonnull) FIRRemoteConfigSettings *configSettings; + +/// Returns the `RemoteConfig` instance configured for the default Firebase app. This singleton +/// object contains the complete set of Remote Config parameter values available to the app, +/// including the Active Config and Default Config. This object also caches values fetched from the +/// Remote Config server until they are copied to the Active Config by calling `activate()`. When +/// you fetch values from the Remote Config server using the default Firebase app, you should use +/// this class method to create and reuse a shared instance of `RemoteConfig`. ++ (nonnull FIRRemoteConfig *)remoteConfig NS_SWIFT_NAME(remoteConfig()); + +/// Returns the `RemoteConfig` instance for your (non-default) Firebase appID. Note that Firebase +/// analytics does not work for non-default app instances. This singleton object contains the +/// complete set of Remote Config parameter values available to the app, including the Active Config +/// and Default Config. This object also caches values fetched from the Remote Config Server until +/// they are copied to the Active Config by calling `activate())`. When you fetch values +/// from the Remote Config Server using the non-default Firebase app, you should use this +/// class method to create and reuse shared instance of `RemoteConfig`. ++ (nonnull FIRRemoteConfig *)remoteConfigWithApp:(nonnull FIRApp *)app + NS_SWIFT_NAME(remoteConfig(app:)); + +/// Unavailable. Use +remoteConfig instead. +- (nonnull instancetype)init __attribute__((unavailable("Use +remoteConfig instead."))); + +/// Ensures initialization is complete and clients can begin querying for Remote Config values. +/// @param completionHandler Initialization complete callback with error parameter. +- (void)ensureInitializedWithCompletionHandler: + (void (^_Nonnull)(NSError *_Nullable initializationError))completionHandler; +#pragma mark - Fetch +/// Fetches Remote Config data with a callback. Call `activate()` to make fetched data +/// available to your app. +/// +/// Note: This method uses a Firebase Installations token to identify the app instance, and once +/// it's called, it periodically sends data to the Firebase backend. (see +/// `Installations.authToken(completion:)`). +/// To stop the periodic sync, call `Installations.delete(completion:)` +/// and avoid calling this method again. +/// +/// @param completionHandler Fetch operation callback with status and error parameters. +- (void)fetchWithCompletionHandler:(void (^_Nullable)(FIRRemoteConfigFetchStatus status, + NSError *_Nullable error))completionHandler; + +/// Fetches Remote Config data and sets a duration that specifies how long config data lasts. +/// Call `activateWithCompletion:` to make fetched data available to your app. +/// +/// Note: This method uses a Firebase Installations token to identify the app instance, and once +/// it's called, it periodically sends data to the Firebase backend. (see +/// `Installations.authToken(completion:)`). +/// To stop the periodic sync, call `Installations.delete(completion:)` +/// and avoid calling this method again. +/// +/// @param expirationDuration Override the (default or optionally set `minimumFetchInterval` +/// property in RemoteConfigSettings) `minimumFetchInterval` for only the current request, in +/// seconds. Setting a value of 0 seconds will force a fetch to the backend. +/// @param completionHandler Fetch operation callback with status and error parameters. +- (void)fetchWithExpirationDuration:(NSTimeInterval)expirationDuration + completionHandler:(void (^_Nullable)(FIRRemoteConfigFetchStatus status, + NSError *_Nullable error))completionHandler; + +/// Fetches Remote Config data and if successful, activates fetched data. Optional completion +/// handler callback is invoked after the attempted activation of data, if the fetch call succeeded. +/// +/// Note: This method uses a Firebase Installations token to identify the app instance, and once +/// it's called, it periodically sends data to the Firebase backend. (see +/// `Installations.authToken(completion:)`). +/// To stop the periodic sync, call `Installations.delete(completion:)` +/// and avoid calling this method again. +/// +/// @param completionHandler Fetch operation callback with status and error parameters. +- (void)fetchAndActivateWithCompletionHandler: + (void (^_Nullable)(FIRRemoteConfigFetchAndActivateStatus status, + NSError *_Nullable error))completionHandler; + +#pragma mark - Apply + +/// Applies Fetched Config data to the Active Config, causing updates to the behavior and appearance +/// of the app to take effect (depending on how config data is used in the app). +/// @param completion Activate operation callback with changed and error parameters. +- (void)activateWithCompletion:(void (^_Nullable)(BOOL changed, + NSError *_Nullable error))completion; + +#pragma mark - Get Config +/// Enables access to configuration values by using object subscripting syntax. +/// For example: +/// let config = RemoteConfig.remoteConfig() +/// let value = config["yourKey"] +/// let boolValue = value.boolValue +/// let number = config["yourKey"].numberValue +- (nonnull FIRRemoteConfigValue *)objectForKeyedSubscript:(nonnull NSString *)key; + +/// Gets the config value. +/// @param key Config key. +- (nonnull FIRRemoteConfigValue *)configValueForKey:(nullable NSString *)key; + +/// Gets the config value of a given source from the default namespace. +/// @param key Config key. +/// @param source Config value source. +- (nonnull FIRRemoteConfigValue *)configValueForKey:(nullable NSString *)key + source:(FIRRemoteConfigSource)source; + +/// Gets all the parameter keys of a given source from the default namespace. +/// +/// @param source The config data source. +/// @return An array of keys under the given source. +- (nonnull NSArray *)allKeysFromSource:(FIRRemoteConfigSource)source; + +/// Returns the set of parameter keys that start with the given prefix, from the default namespace +/// in the active config. +/// +/// @param prefix The key prefix to look for. If prefix is nil or empty, returns all the +/// keys. +/// @return The set of parameter keys that start with the specified prefix. +- (nonnull NSSet *)keysWithPrefix:(nullable NSString *)prefix; + +#pragma mark - Defaults +/// Sets config defaults for parameter keys and values in the default namespace config. +/// @param defaults A dictionary mapping a NSString * key to a NSObject * value. +- (void)setDefaults:(nullable NSDictionary *)defaults; + +/// Sets default configs from plist for default namespace. +/// +/// @param fileName The plist file name, with no file name extension. For example, if the plist file +/// is named `defaultSamples.plist`: +/// `RemoteConfig.remoteConfig().setDefaults(fromPlist: "defaultSamples")` +- (void)setDefaultsFromPlistFileName:(nullable NSString *)fileName + NS_SWIFT_NAME(setDefaults(fromPlist:)); + +/// Returns the default value of a given key from the default config. +/// +/// @param key The parameter key of default config. +/// @return Returns the default value of the specified key. Returns +/// nil if the key doesn't exist in the default config. +- (nullable FIRRemoteConfigValue *)defaultValueForKey:(nullable NSString *)key; + +#pragma mark - Real-time Config Updates + +/// Completion handler invoked by `addOnConfigUpdateListener` when there is an update to +/// the config from the backend. +/// +/// @param configUpdate An instance of `FIRRemoteConfigUpdate` that contains information on which +/// key's values have changed. +/// @param error Error message on failure. +typedef void (^FIRRemoteConfigUpdateCompletion)(FIRRemoteConfigUpdate *_Nullable configUpdate, + NSError *_Nullable error) + NS_SWIFT_UNAVAILABLE("Use Swift's closure syntax instead."); + +/// Start listening for real-time config updates from the Remote Config backend and automatically +/// fetch updates when they're available. +/// +/// If a connection to the Remote Config backend is not already open, calling this method will +/// open it. Multiple listeners can be added by calling this method again, but subsequent calls +/// re-use the same connection to the backend. +/// +/// Note: Real-time Remote Config requires the Firebase Remote Config Realtime API. See Get started +/// with Firebase Remote Config at https://firebase.google.com/docs/remote-config/get-started for +/// more information. +/// +/// @param listener The configured listener that is called for every config update. +/// @return Returns a registration representing the listener. The registration contains +/// a remove method, which can be used to stop receiving updates for the provided listener. +- (FIRConfigUpdateListenerRegistration *_Nonnull)addOnConfigUpdateListener: + (FIRRemoteConfigUpdateCompletion _Nonnull)listener + NS_SWIFT_NAME(addOnConfigUpdateListener(remoteConfigUpdateCompletion:)); + +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FirebaseRemoteConfig.h b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FirebaseRemoteConfig.h new file mode 100644 index 0000000..9ae8cea --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FirebaseRemoteConfig.h @@ -0,0 +1,17 @@ +/* + * 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 "FIRRemoteConfig.h" diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigConstants.h b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigConstants.h new file mode 100644 index 0000000..51d248c --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigConstants.h @@ -0,0 +1,72 @@ +/* + * 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 + +#define RCN_SEC_PER_MIN 60 +#define RCN_MSEC_PER_SEC 1000 + +/// Key prefix applied to all the packages (bundle IDs) in internal metadata. +static NSString *const RCNInternalMetadataAllPackagesPrefix = @"all_packages"; + +/// HTTP connection default timeout in seconds. +static const NSTimeInterval RCNHTTPDefaultConnectionTimeout = 60; +/// Default duration of how long config data lasts to stay fresh. +static const NSTimeInterval RCNDefaultMinimumFetchInterval = 43200; + +/// Label for serial queue for read/write lock on ivars. +static const char *RCNRemoteConfigQueueLabel = "com.google.GoogleConfigService.FIRRemoteConfig"; + +/// Constants for key names in the fetch response. +/// Key that includes an array of template entries. +static NSString *const RCNFetchResponseKeyEntries = @"entries"; +/// Key that includes data for experiment descriptions in ABT. +static NSString *const RCNFetchResponseKeyExperimentDescriptions = @"experimentDescriptions"; +/// Key that includes data for Personalization metadata. +static NSString *const RCNFetchResponseKeyPersonalizationMetadata = @"personalizationMetadata"; +/// Key that includes data for Rollout metadata. +static NSString *const RCNFetchResponseKeyRolloutMetadata = @"rolloutMetadata"; +/// Key that indicates rollout id in Rollout metadata. +static NSString *const RCNFetchResponseKeyRolloutID = @"rolloutId"; +/// Key that indicates variant id in Rollout metadata. +static NSString *const RCNFetchResponseKeyVariantID = @"variantId"; +/// Key that indicates affected parameter keys in Rollout Metadata. +static NSString *const RCNFetchResponseKeyAffectedParameterKeys = @"affectedParameterKeys"; +/// Error key. +static NSString *const RCNFetchResponseKeyError = @"error"; +/// Error code. +static NSString *const RCNFetchResponseKeyErrorCode = @"code"; +/// Error status. +static NSString *const RCNFetchResponseKeyErrorStatus = @"status"; +/// Error message. +static NSString *const RCNFetchResponseKeyErrorMessage = @"message"; +/// The current state of the backend template. +static NSString *const RCNFetchResponseKeyState = @"state"; +/// Default state (when not set). +static NSString *const RCNFetchResponseKeyStateUnspecified = @"INSTANCE_STATE_UNSPECIFIED"; +/// Config key/value map and/or ABT experiment list differs from last fetch. +/// TODO: Migrate to the new HTTP error codes once available in the backend. b/117182055 +static NSString *const RCNFetchResponseKeyStateUpdate = @"UPDATE"; +/// No template fetched. +static NSString *const RCNFetchResponseKeyStateNoTemplate = @"NO_TEMPLATE"; +/// Config key/value map and ABT experiment list both match last fetch. +static NSString *const RCNFetchResponseKeyStateNoChange = @"NO_CHANGE"; +/// Template found, but evaluates to empty (e.g. all keys omitted). +static NSString *const RCNFetchResponseKeyStateEmptyConfig = @"EMPTY_CONFIG"; +/// Fetched Template Version key +static NSString *const RCNFetchResponseKeyTemplateVersion = @"templateVersion"; +/// Active Template Version key +static NSString *const RCNActiveKeyTemplateVersion = @"activeTemplateVersion"; diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigContent.h b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigContent.h new file mode 100644 index 0000000..e841007 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigContent.h @@ -0,0 +1,76 @@ +/* + * 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 + +#import "FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h" + +typedef NS_ENUM(NSInteger, RCNDBSource) { + RCNDBSourceActive, + RCNDBSourceDefault, + RCNDBSourceFetched, +}; + +@class RCNConfigDBManager; + +/// This class handles all the config content that is fetched from the server, cached in local +/// config or persisted in database. +@interface RCNConfigContent : NSObject +/// Shared Singleton Instance ++ (instancetype)sharedInstance; + +/// Fetched config (aka pending config) data that is latest data from server that might or might +/// not be applied. +@property(nonatomic, readonly, copy) NSDictionary *fetchedConfig; +/// Active config that is available to external users; +@property(nonatomic, readonly, copy) NSDictionary *activeConfig; +/// Local default config that is provided by external users; +@property(nonatomic, readonly, copy) NSDictionary *defaultConfig; +/// Active Rollout metadata that is currently used. +@property(nonatomic, readonly, copy) NSArray *activeRolloutMetadata; + +- (instancetype)init NS_UNAVAILABLE; + +/// Designated initializer; +- (instancetype)initWithDBManager:(RCNConfigDBManager *)DBManager NS_DESIGNATED_INITIALIZER; + +/// Returns true if initialization succeeded. +- (BOOL)initializationSuccessful; + +/// Update config content from fetch response in JSON format. +- (void)updateConfigContentWithResponse:(NSDictionary *)response + forNamespace:(NSString *)FIRNamespace; + +/// Copy from a given dictionary to one of the data source. +/// @param fromDictionary The data to copy from. +/// @param source The data source to copy to(pending/active/default). +- (void)copyFromDictionary:(NSDictionary *)fromDictionary + toSource:(RCNDBSource)source + forNamespace:(NSString *)FIRNamespace; + +/// Sets the fetched Personalization metadata to active. +- (void)activatePersonalization; + +/// Gets the active config and Personalization metadata. +- (NSDictionary *)getConfigAndMetadataForNamespace:(NSString *)FIRNamespace; + +/// Sets the fetched rollout metadata to active with a success completion handler. +- (void)activateRolloutMetadata:(void (^)(BOOL success))completionHandler; + +/// Returns the updated parameters between fetched and active config. +- (FIRRemoteConfigUpdate *)getConfigUpdateForNamespace:(NSString *)FIRNamespace; + +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigContent.m b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigContent.m new file mode 100644 index 0000000..1c26673 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigContent.m @@ -0,0 +1,526 @@ +/* + * 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 "FirebaseRemoteConfig/Sources/RCNConfigContent.h" + +#import "FirebaseRemoteConfig/Sources/Private/FIRRemoteConfig_Private.h" +#import "FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigConstants.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigDBManager.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigDefines.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h" + +#import "FirebaseCore/Extension/FirebaseCoreInternal.h" + +@implementation RCNConfigContent { + /// Active config data that is currently used. + NSMutableDictionary *_activeConfig; + /// Pending config (aka Fetched config) data that is latest data from server that might or might + /// not be applied. + NSMutableDictionary *_fetchedConfig; + /// Default config provided by user. + NSMutableDictionary *_defaultConfig; + /// Active Personalization metadata that is currently used. + NSDictionary *_activePersonalization; + /// Pending Personalization metadata that is latest data from server that might or might not be + /// applied. + NSDictionary *_fetchedPersonalization; + /// Active Rollout metadata that is currently used. + NSArray *_activeRolloutMetadata; + /// Pending Rollout metadata that is latest data from server that might or might not be applied. + NSArray *_fetchedRolloutMetadata; + /// DBManager + RCNConfigDBManager *_DBManager; + /// Current bundle identifier; + NSString *_bundleIdentifier; + /// Blocks all config reads until we have read from the database. This only + /// potentially blocks on the first read. Should be a no-wait for all subsequent reads once we + /// have data read into memory from the database. + dispatch_group_t _dispatch_group; + /// Boolean indicating if initial DB load of fetched,active and default config has succeeded. + BOOL _isConfigLoadFromDBCompleted; + /// Boolean indicating that the load from database has initiated at least once. + BOOL _isDatabaseLoadAlreadyInitiated; +} + +/// Default timeout when waiting to read data from database. +const NSTimeInterval kDatabaseLoadTimeoutSecs = 30.0; + +/// Singleton instance of RCNConfigContent. ++ (instancetype)sharedInstance { + static dispatch_once_t onceToken; + static RCNConfigContent *sharedInstance; + dispatch_once(&onceToken, ^{ + sharedInstance = + [[RCNConfigContent alloc] initWithDBManager:[RCNConfigDBManager sharedInstance]]; + }); + return sharedInstance; +} + +- (instancetype)init { + NSAssert(NO, @"Invalid initializer."); + return nil; +} + +/// Designated initializer +- (instancetype)initWithDBManager:(RCNConfigDBManager *)DBManager { + self = [super init]; + if (self) { + _activeConfig = [[NSMutableDictionary alloc] init]; + _fetchedConfig = [[NSMutableDictionary alloc] init]; + _defaultConfig = [[NSMutableDictionary alloc] init]; + _activePersonalization = [[NSDictionary alloc] init]; + _fetchedPersonalization = [[NSDictionary alloc] init]; + _activeRolloutMetadata = [[NSArray alloc] init]; + _fetchedRolloutMetadata = [[NSArray alloc] init]; + _bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier]; + if (!_bundleIdentifier) { + FIRLogNotice(kFIRLoggerRemoteConfig, @"I-RCN000038", + @"Main bundle identifier is missing. Remote Config might not work properly."); + _bundleIdentifier = @""; + } + _DBManager = DBManager; + // Waits for both config and Personalization data to load. + _dispatch_group = dispatch_group_create(); + [self loadConfigFromMainTable]; + } + return self; +} + +// Blocking call that returns true/false once database load completes / times out. +// @return Initialization status. +- (BOOL)initializationSuccessful { + RCN_MUST_NOT_BE_MAIN_THREAD(); + BOOL isDatabaseLoadSuccessful = [self checkAndWaitForInitialDatabaseLoad]; + return isDatabaseLoadSuccessful; +} + +#pragma mark - database + +/// This method is only meant to be called at init time. The underlying logic will need to be +/// revaluated if the assumption changes at a later time. +- (void)loadConfigFromMainTable { + if (!_DBManager) { + return; + } + + NSAssert(!_isDatabaseLoadAlreadyInitiated, @"Database load has already been initiated"); + _isDatabaseLoadAlreadyInitiated = true; + + dispatch_group_enter(_dispatch_group); + [_DBManager loadMainWithBundleIdentifier:_bundleIdentifier + completionHandler:^( + BOOL success, NSDictionary *fetchedConfig, NSDictionary *activeConfig, + NSDictionary *defaultConfig, NSDictionary *rolloutMetadata) { + self->_fetchedConfig = [fetchedConfig mutableCopy]; + self->_activeConfig = [activeConfig mutableCopy]; + self->_defaultConfig = [defaultConfig mutableCopy]; + self->_fetchedRolloutMetadata = + [rolloutMetadata[@RCNRolloutTableKeyFetchedMetadata] copy]; + self->_activeRolloutMetadata = + [rolloutMetadata[@RCNRolloutTableKeyActiveMetadata] copy]; + dispatch_group_leave(self->_dispatch_group); + }]; + + // TODO(karenzeng): Refactor personalization to be returned in loadMainWithBundleIdentifier above + dispatch_group_enter(_dispatch_group); + [_DBManager + loadPersonalizationWithCompletionHandler:^( + BOOL success, NSDictionary *fetchedPersonalization, NSDictionary *activePersonalization, + NSDictionary *defaultConfig, NSDictionary *rolloutMetadata) { + self->_fetchedPersonalization = [fetchedPersonalization copy]; + self->_activePersonalization = [activePersonalization copy]; + dispatch_group_leave(self->_dispatch_group); + }]; +} + +/// Update the current config result to main table. +/// @param values Values in a row to write to the table. +/// @param source The source the config data is coming from. It determines which table to write to. +- (void)updateMainTableWithValues:(NSArray *)values fromSource:(RCNDBSource)source { + [_DBManager insertMainTableWithValues:values fromSource:source completionHandler:nil]; +} + +#pragma mark - update +/// This function is for copying dictionary when user set up a default config or when user clicks +/// activate. For now the DBSource can only be Active or Default. +- (void)copyFromDictionary:(NSDictionary *)fromDict + toSource:(RCNDBSource)DBSource + forNamespace:(NSString *)FIRNamespace { + // Make sure database load has completed. + [self checkAndWaitForInitialDatabaseLoad]; + NSMutableDictionary *toDict; + if (!fromDict) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000007", + @"The source dictionary to copy from does not exist."); + return; + } + FIRRemoteConfigSource source = FIRRemoteConfigSourceRemote; + switch (DBSource) { + case RCNDBSourceDefault: + toDict = _defaultConfig; + source = FIRRemoteConfigSourceDefault; + break; + case RCNDBSourceFetched: + FIRLogWarning(kFIRLoggerRemoteConfig, @"I-RCN000008", + @"This shouldn't happen. Destination dictionary should never be pending type."); + return; + case RCNDBSourceActive: + toDict = _activeConfig; + source = FIRRemoteConfigSourceRemote; + [toDict removeObjectForKey:FIRNamespace]; + break; + default: + toDict = _activeConfig; + source = FIRRemoteConfigSourceRemote; + [toDict removeObjectForKey:FIRNamespace]; + break; + } + + // Completely wipe out DB first. + [_DBManager deleteRecordFromMainTableWithNamespace:FIRNamespace + bundleIdentifier:_bundleIdentifier + fromSource:DBSource]; + + toDict[FIRNamespace] = [[NSMutableDictionary alloc] init]; + NSDictionary *config = fromDict[FIRNamespace]; + for (NSString *key in config) { + if (DBSource == FIRRemoteConfigSourceDefault) { + NSObject *value = config[key]; + NSData *valueData; + if ([value isKindOfClass:[NSData class]]) { + valueData = (NSData *)value; + } else if ([value isKindOfClass:[NSString class]]) { + valueData = [(NSString *)value dataUsingEncoding:NSUTF8StringEncoding]; + } else if ([value isKindOfClass:[NSNumber class]]) { + NSString *strValue = [(NSNumber *)value stringValue]; + valueData = [(NSString *)strValue dataUsingEncoding:NSUTF8StringEncoding]; + } else if ([value isKindOfClass:[NSDate class]]) { + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; + NSString *strValue = [dateFormatter stringFromDate:(NSDate *)value]; + valueData = [(NSString *)strValue dataUsingEncoding:NSUTF8StringEncoding]; + } else if ([value isKindOfClass:[NSArray class]]) { + NSError *error; + valueData = [NSJSONSerialization dataWithJSONObject:value options:0 error:&error]; + if (error) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000076", @"Invalid array value for key '%@'", + key); + } + } else if ([value isKindOfClass:[NSDictionary class]]) { + NSError *error; + valueData = [NSJSONSerialization dataWithJSONObject:value options:0 error:&error]; + if (error) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000077", + @"Invalid dictionary value for key '%@'", key); + } + } else { + continue; + } + toDict[FIRNamespace][key] = [[FIRRemoteConfigValue alloc] initWithData:valueData + source:source]; + NSArray *values = @[ _bundleIdentifier, FIRNamespace, key, valueData ]; + [self updateMainTableWithValues:values fromSource:DBSource]; + } else { + FIRRemoteConfigValue *value = config[key]; + toDict[FIRNamespace][key] = [[FIRRemoteConfigValue alloc] initWithData:value.dataValue + source:source]; + NSArray *values = @[ _bundleIdentifier, FIRNamespace, key, value.dataValue ]; + [self updateMainTableWithValues:values fromSource:DBSource]; + } + } +} + +- (void)updateConfigContentWithResponse:(NSDictionary *)response + forNamespace:(NSString *)currentNamespace { + // Make sure database load has completed. + [self checkAndWaitForInitialDatabaseLoad]; + NSString *state = response[RCNFetchResponseKeyState]; + + if (!state) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000049", @"State field in fetch response is nil."); + return; + } + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000059", + @"Updating config content from Response for namespace:%@ with state: %@", + currentNamespace, response[RCNFetchResponseKeyState]); + + if ([state isEqualToString:RCNFetchResponseKeyStateNoChange]) { + [self handleNoChangeStateForConfigNamespace:currentNamespace]; + return; + } + + /// Handle empty config state + if ([state isEqualToString:RCNFetchResponseKeyStateEmptyConfig]) { + [self handleEmptyConfigStateForConfigNamespace:currentNamespace]; + return; + } + + /// Handle no template state. + if ([state isEqualToString:RCNFetchResponseKeyStateNoTemplate]) { + [self handleNoTemplateStateForConfigNamespace:currentNamespace]; + return; + } + + /// Handle update state + if ([state isEqualToString:RCNFetchResponseKeyStateUpdate]) { + [self handleUpdateStateForConfigNamespace:currentNamespace + withEntries:response[RCNFetchResponseKeyEntries]]; + [self handleUpdatePersonalization:response[RCNFetchResponseKeyPersonalizationMetadata]]; + [self handleUpdateRolloutFetchedMetadata:response[RCNFetchResponseKeyRolloutMetadata]]; + return; + } +} + +- (void)activatePersonalization { + _activePersonalization = _fetchedPersonalization; + [_DBManager insertOrUpdatePersonalizationConfig:_activePersonalization + fromSource:RCNDBSourceActive]; +} + +- (void)activateRolloutMetadata:(void (^)(BOOL success))completionHandler { + _activeRolloutMetadata = _fetchedRolloutMetadata; + [_DBManager insertOrUpdateRolloutTableWithKey:@RCNRolloutTableKeyActiveMetadata + value:_activeRolloutMetadata + completionHandler:^(BOOL success, NSDictionary *result) { + completionHandler(success); + }]; +} + +#pragma mark State handling +- (void)handleNoChangeStateForConfigNamespace:(NSString *)currentNamespace { + if (!_fetchedConfig[currentNamespace]) { + _fetchedConfig[currentNamespace] = [[NSMutableDictionary alloc] init]; + } +} + +- (void)handleEmptyConfigStateForConfigNamespace:(NSString *)currentNamespace { + if (_fetchedConfig[currentNamespace]) { + [_fetchedConfig[currentNamespace] removeAllObjects]; + } else { + // If namespace has empty status and it doesn't exist in _fetchedConfig, we will + // still add an entry for that namespace. Even if it will not be persisted in database. + // TODO: Add generics for all collection types. + _fetchedConfig[currentNamespace] = [[NSMutableDictionary alloc] init]; + } + [_DBManager deleteRecordFromMainTableWithNamespace:currentNamespace + bundleIdentifier:_bundleIdentifier + fromSource:RCNDBSourceFetched]; +} + +- (void)handleNoTemplateStateForConfigNamespace:(NSString *)currentNamespace { + // Remove the namespace. + [_fetchedConfig removeObjectForKey:currentNamespace]; + [_DBManager deleteRecordFromMainTableWithNamespace:currentNamespace + bundleIdentifier:_bundleIdentifier + fromSource:RCNDBSourceFetched]; +} +- (void)handleUpdateStateForConfigNamespace:(NSString *)currentNamespace + withEntries:(NSDictionary *)entries { + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000058", @"Update config in DB for namespace:%@", + currentNamespace); + // Clear before updating + [_DBManager deleteRecordFromMainTableWithNamespace:currentNamespace + bundleIdentifier:_bundleIdentifier + fromSource:RCNDBSourceFetched]; + if ([_fetchedConfig objectForKey:currentNamespace]) { + [_fetchedConfig[currentNamespace] removeAllObjects]; + } else { + _fetchedConfig[currentNamespace] = [[NSMutableDictionary alloc] init]; + } + + // Store the fetched config values. + for (NSString *key in entries) { + NSData *valueData = [entries[key] dataUsingEncoding:NSUTF8StringEncoding]; + if (!valueData) { + continue; + } + _fetchedConfig[currentNamespace][key] = + [[FIRRemoteConfigValue alloc] initWithData:valueData source:FIRRemoteConfigSourceRemote]; + NSArray *values = @[ _bundleIdentifier, currentNamespace, key, valueData ]; + [self updateMainTableWithValues:values fromSource:RCNDBSourceFetched]; + } +} + +- (void)handleUpdatePersonalization:(NSDictionary *)metadata { + if (!metadata) { + return; + } + _fetchedPersonalization = metadata; + [_DBManager insertOrUpdatePersonalizationConfig:metadata fromSource:RCNDBSourceFetched]; +} + +- (void)handleUpdateRolloutFetchedMetadata:(NSArray *)metadata { + if (!metadata) { + metadata = [[NSArray alloc] init]; + } + _fetchedRolloutMetadata = metadata; + [_DBManager insertOrUpdateRolloutTableWithKey:@RCNRolloutTableKeyFetchedMetadata + value:metadata + completionHandler:nil]; +} + +#pragma mark - getter/setter +- (NSDictionary *)fetchedConfig { + /// If this is the first time reading the fetchedConfig, we might still be reading it from the + /// database. + [self checkAndWaitForInitialDatabaseLoad]; + return _fetchedConfig; +} + +- (NSDictionary *)activeConfig { + /// If this is the first time reading the activeConfig, we might still be reading it from the + /// database. + [self checkAndWaitForInitialDatabaseLoad]; + return _activeConfig; +} + +- (NSDictionary *)defaultConfig { + /// If this is the first time reading the fetchedConfig, we might still be reading it from the + /// database. + [self checkAndWaitForInitialDatabaseLoad]; + return _defaultConfig; +} + +- (NSDictionary *)activePersonalization { + [self checkAndWaitForInitialDatabaseLoad]; + return _activePersonalization; +} + +- (NSArray *)activeRolloutMetadata { + [self checkAndWaitForInitialDatabaseLoad]; + return _activeRolloutMetadata; +} + +- (NSDictionary *)getConfigAndMetadataForNamespace:(NSString *)FIRNamespace { + /// If this is the first time reading the active metadata, we might still be reading it from the + /// database. + [self checkAndWaitForInitialDatabaseLoad]; + return @{ + RCNFetchResponseKeyEntries : _activeConfig[FIRNamespace], + RCNFetchResponseKeyPersonalizationMetadata : _activePersonalization + }; +} + +/// We load the database async at init time. Block all further calls to active/fetched/default +/// configs until load is done. +/// @return Database load completion status. +- (BOOL)checkAndWaitForInitialDatabaseLoad { + /// Wait until load is done. This should be a no-op for subsequent calls. + if (!_isConfigLoadFromDBCompleted) { + intptr_t isErrorOrTimeout = dispatch_group_wait( + _dispatch_group, + dispatch_time(DISPATCH_TIME_NOW, (int64_t)(kDatabaseLoadTimeoutSecs * NSEC_PER_SEC))); + if (isErrorOrTimeout) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000048", + @"Timed out waiting for fetched config to be loaded from DB"); + return false; + } + _isConfigLoadFromDBCompleted = true; + } + return true; +} + +// Compare fetched config with active config and output what has changed +- (FIRRemoteConfigUpdate *)getConfigUpdateForNamespace:(NSString *)FIRNamespace { + // TODO: handle diff in experiment metadata + + FIRRemoteConfigUpdate *configUpdate; + NSMutableSet *updatedKeys = [[NSMutableSet alloc] init]; + + NSDictionary *fetchedConfig = + _fetchedConfig[FIRNamespace] ? _fetchedConfig[FIRNamespace] : [[NSDictionary alloc] init]; + NSDictionary *activeConfig = + _activeConfig[FIRNamespace] ? _activeConfig[FIRNamespace] : [[NSDictionary alloc] init]; + NSDictionary *fetchedP13n = _fetchedPersonalization; + NSDictionary *activeP13n = _activePersonalization; + NSArray *fetchedRolloutMetadata = _fetchedRolloutMetadata; + NSArray *activeRolloutMetadata = _activeRolloutMetadata; + + // add new/updated params + for (NSString *key in [fetchedConfig allKeys]) { + if (activeConfig[key] == nil || + ![[activeConfig[key] stringValue] isEqualToString:[fetchedConfig[key] stringValue]]) { + [updatedKeys addObject:key]; + } + } + // add deleted params + for (NSString *key in [activeConfig allKeys]) { + if (fetchedConfig[key] == nil) { + [updatedKeys addObject:key]; + } + } + + // add params with new/updated p13n metadata + for (NSString *key in [fetchedP13n allKeys]) { + if (activeP13n[key] == nil || ![activeP13n[key] isEqualToDictionary:fetchedP13n[key]]) { + [updatedKeys addObject:key]; + } + } + // add params with deleted p13n metadata + for (NSString *key in [activeP13n allKeys]) { + if (fetchedP13n[key] == nil) { + [updatedKeys addObject:key]; + } + } + + NSDictionary *fetchedRollouts = + [self getParameterKeyToRolloutMetadata:fetchedRolloutMetadata]; + NSDictionary *activeRollouts = + [self getParameterKeyToRolloutMetadata:activeRolloutMetadata]; + + // add params with new/updated rollout metadata + for (NSString *key in [fetchedRollouts allKeys]) { + if (activeRollouts[key] == nil || + ![activeRollouts[key] isEqualToDictionary:fetchedRollouts[key]]) { + [updatedKeys addObject:key]; + } + } + // add params with deleted rollout metadata + for (NSString *key in [activeRollouts allKeys]) { + if (fetchedRollouts[key] == nil) { + [updatedKeys addObject:key]; + } + } + + configUpdate = [[FIRRemoteConfigUpdate alloc] initWithUpdatedKeys:updatedKeys]; + return configUpdate; +} + +- (NSDictionary *)getParameterKeyToRolloutMetadata: + (NSArray *)rolloutMetadata { + NSMutableDictionary *result = + [[NSMutableDictionary alloc] init]; + for (NSDictionary *metadata in rolloutMetadata) { + NSString *rolloutId = metadata[RCNFetchResponseKeyRolloutID]; + NSString *variantId = metadata[RCNFetchResponseKeyVariantID]; + NSArray *affectedKeys = metadata[RCNFetchResponseKeyAffectedParameterKeys]; + if (rolloutId && variantId && affectedKeys) { + for (NSString *key in affectedKeys) { + if (result[key]) { + NSMutableDictionary *rolloutIdToVariantId = result[key]; + [rolloutIdToVariantId setValue:variantId forKey:rolloutId]; + } else { + NSMutableDictionary *rolloutIdToVariantId = [@{rolloutId : variantId} mutableCopy]; + [result setValue:rolloutIdToVariantId forKey:key]; + } + } + } + } + return [result copy]; +} + +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigDBManager.h b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigDBManager.h new file mode 100644 index 0000000..fba0946 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigDBManager.h @@ -0,0 +1,142 @@ +/* + * 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 + +#import "FirebaseRemoteConfig/Sources/RCNConfigContent.h" + +typedef NS_ENUM(NSInteger, RCNUpdateOption) { + RCNUpdateOptionApplyTime, + RCNUpdateOptionDefaultTime, + RCNUpdateOptionFetchStatus, +}; + +/// Column names in metadata table +static NSString *const RCNKeyBundleIdentifier = @"bundle_identifier"; +static NSString *const RCNKeyNamespace = @"namespace"; +static NSString *const RCNKeyFetchTime = @"fetch_time"; +static NSString *const RCNKeyDigestPerNamespace = @"digest_per_ns"; +static NSString *const RCNKeyDeviceContext = @"device_context"; +static NSString *const RCNKeyAppContext = @"app_context"; +static NSString *const RCNKeySuccessFetchTime = @"success_fetch_time"; +static NSString *const RCNKeyFailureFetchTime = @"failure_fetch_time"; +static NSString *const RCNKeyLastFetchStatus = @"last_fetch_status"; +static NSString *const RCNKeyLastFetchError = @"last_fetch_error"; +static NSString *const RCNKeyLastApplyTime = @"last_apply_time"; +static NSString *const RCNKeyLastSetDefaultsTime = @"last_set_defaults_time"; + +/// Persist config data in sqlite database on device. Managing data read/write from/to database. +@interface RCNConfigDBManager : NSObject +/// Shared Singleton Instance ++ (instancetype)sharedInstance; + +/// Database Operation Completion callback. +/// @param success Decide whether the DB operation succeeds. +/// @param result Return operation result data. +typedef void (^RCNDBCompletion)(BOOL success, NSDictionary *result); + +/// Database Load Operation Completion callback. +/// @param success Decide whether the DB operation succeeds. +/// @param fetchedConfig Return fetchedConfig loaded from DB +/// @param activeConfig Return activeConfig loaded from DB +/// @param defaultConfig Return defaultConfig loaded from DB +/// @param rolloutMetadata Return fetched and active RolloutMetadata loaded from DB +typedef void (^RCNDBLoadCompletion)(BOOL success, + NSDictionary *fetchedConfig, + NSDictionary *activeConfig, + NSDictionary *defaultConfig, + NSDictionary *rolloutMetadata); + +/// Returns the current version of the Remote Config database. ++ (NSString *)remoteConfigPathForDatabase; + +/// Load config content from main table to cached memory during app start. +- (void)loadMainWithBundleIdentifier:(NSString *)bundleIdentifier + completionHandler:(RCNDBLoadCompletion)handler; +/// Load config settings for a given namespace from metadata table to cached memory during app +/// start. Config settings include success/failure fetch times, device contenxt, app context, etc. +- (NSDictionary *)loadMetadataWithBundleIdentifier:(NSString *)bundleIdentifier + namespace:(NSString *)namespace; +/// Load internal metadata from internal metadata table, such as customized HTTP connection/read +/// timeout, throttling time interval and number limit of throttling, etc. +/// This call needs to be blocking to ensure throttling works during apps starts. +- (NSDictionary *)loadInternalMetadataTable; +/// Load experiment from experiment table. +/// @param handler The callback when reading from DB is complete. +- (void)loadExperimentWithCompletionHandler:(RCNDBCompletion)handler; +/// Load Personalization from table. +/// @param handler The callback when reading from DB is complete. +- (void)loadPersonalizationWithCompletionHandler:(RCNDBLoadCompletion)handler; +/// Insert a record in metadata table. +/// @param columnNameToValue The column name and its value to be inserted in metadata table. +/// @param handler The callback. +- (void)insertMetadataTableWithValues:(NSDictionary *)columnNameToValue + completionHandler:(RCNDBCompletion)handler; +/// Insert a record in main table. +/// @param values Values to be inserted. +- (void)insertMainTableWithValues:(NSArray *)values + fromSource:(RCNDBSource)source + completionHandler:(RCNDBCompletion)handler; +/// Insert a record in internal metadata table. +/// @param values Values to be inserted. +- (void)insertInternalMetadataTableWithValues:(NSArray *)values + completionHandler:(RCNDBCompletion)handler; +/// Insert exepriment data in experiment table. +/// @param key The key of experiment data belongs to, which are defined in +/// RCNConfigDefines.h. +/// @param value The value that experiment. +/// @param handler The callback. +- (void)insertExperimentTableWithKey:(NSString *)key + value:(NSData *)value + completionHandler:(RCNDBCompletion)handler; + +- (void)updateMetadataWithOption:(RCNUpdateOption)option + namespace:(NSString *)namespace + values:(NSArray *)values + completionHandler:(RCNDBCompletion)handler; + +/// Insert or update the data in Personalization config. +- (BOOL)insertOrUpdatePersonalizationConfig:(NSDictionary *)metadata fromSource:(RCNDBSource)source; + +/// Insert rollout metadata in rollout table. +/// @param key Key indicating whether rollout metadata is fetched or active and defined in +/// RCNConfigDefines.h. +/// @param metadataList The metadata info for each rollout entry . +/// @param handler The callback. +- (void)insertOrUpdateRolloutTableWithKey:(NSString *)key + value:(NSArray *)metadataList + completionHandler:(RCNDBCompletion)handler; + +/// Clear the record of given namespace and package name +/// before updating the table. +- (void)deleteRecordFromMainTableWithNamespace:(NSString *)namespace_p + bundleIdentifier:(NSString *)bundleIdentifier + fromSource:(RCNDBSource)source; +/// Remove all the records of given package name and namespace from metadata/internal metadata DB +/// before updating new values from response. +- (void)deleteRecordWithBundleIdentifier:(NSString *)bundlerIdentifier + namespace:(NSString *)namespace + isInternalDB:(BOOL)isInternalDB; +/// Remove all the records from a config content table. +- (void)deleteAllRecordsFromTableWithSource:(RCNDBSource)source; + +/// Remove all the records from experiment table with given key. +/// @param key The key of experiment data belongs to, which are defined in RCNConfigDefines.h. +- (void)deleteExperimentTableForKey:(NSString *)key; + +/// Returns true if this a new install of the Config database. +- (BOOL)isNewDatabase; +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigDBManager.m b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigDBManager.m new file mode 100644 index 0000000..4bbefd3 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigDBManager.m @@ -0,0 +1,1305 @@ +/* + * 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 + +#import "FirebaseRemoteConfig/Sources/RCNConfigDBManager.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigDefines.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h" + +#import "FirebaseCore/Extension/FirebaseCoreInternal.h" + +/// Using macro for securely preprocessing string concatenation in query before runtime. +#define RCNTableNameMain "main" +#define RCNTableNameMainActive "main_active" +#define RCNTableNameMainDefault "main_default" +#define RCNTableNameMetadataDeprecated "fetch_metadata" +#define RCNTableNameMetadata "fetch_metadata_v2" +#define RCNTableNameInternalMetadata "internal_metadata" +#define RCNTableNameExperiment "experiment" +#define RCNTableNamePersonalization "personalization" +#define RCNTableNameRollout "rollout" + +static BOOL gIsNewDatabase; +/// SQLite file name in versions 0, 1 and 2. +static NSString *const RCNDatabaseName = @"RemoteConfig.sqlite3"; +/// The storage sub-directory that the Remote Config database resides in. +static NSString *const RCNRemoteConfigStorageSubDirectory = @"Google/RemoteConfig"; + +/// Remote Config database path for deprecated V0 version. +static NSString *RemoteConfigPathForOldDatabaseV0(void) { + NSArray *dirPaths = + NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *docPath = dirPaths.firstObject; + return [docPath stringByAppendingPathComponent:RCNDatabaseName]; +} + +/// Remote Config database path for current database. +static NSString *RemoteConfigPathForDatabase(void) { +#if TARGET_OS_TV + NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); +#else + NSArray *dirPaths = + NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); +#endif + NSString *storageDirPath = dirPaths.firstObject; + NSArray *components = @[ storageDirPath, RCNRemoteConfigStorageSubDirectory, RCNDatabaseName ]; + return [NSString pathWithComponents:components]; +} + +static BOOL RemoteConfigAddSkipBackupAttributeToItemAtPath(NSString *filePathString) { + NSURL *URL = [NSURL fileURLWithPath:filePathString]; + assert([[NSFileManager defaultManager] fileExistsAtPath:[URL path]]); + + NSError *error = nil; + BOOL success = [URL setResourceValue:[NSNumber numberWithBool:YES] + forKey:NSURLIsExcludedFromBackupKey + error:&error]; + if (!success) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000017", @"Error excluding %@ from backup %@.", + [URL lastPathComponent], error); + } + return success; +} + +static BOOL RemoteConfigCreateFilePathIfNotExist(NSString *filePath) { + if (!filePath || !filePath.length) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000018", + @"Failed to create subdirectory for an empty file path."); + return NO; + } + NSFileManager *fileManager = [NSFileManager defaultManager]; + if (![fileManager fileExistsAtPath:filePath]) { + gIsNewDatabase = YES; + NSError *error; + [fileManager createDirectoryAtPath:[filePath stringByDeletingLastPathComponent] + withIntermediateDirectories:YES + attributes:nil + error:&error]; + if (error) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000019", + @"Failed to create subdirectory for database file: %@.", error); + return NO; + } + } + return YES; +} + +static NSArray *RemoteConfigMetadataTableColumnsInOrder(void) { + return @[ + RCNKeyBundleIdentifier, RCNKeyNamespace, RCNKeyFetchTime, RCNKeyDigestPerNamespace, + RCNKeyDeviceContext, RCNKeyAppContext, RCNKeySuccessFetchTime, RCNKeyFailureFetchTime, + RCNKeyLastFetchStatus, RCNKeyLastFetchError, RCNKeyLastApplyTime, RCNKeyLastSetDefaultsTime + ]; +} + +@interface RCNConfigDBManager () { + /// Database storing all the config information. + sqlite3 *_database; + /// Serial queue for database read/write operations. + dispatch_queue_t _databaseOperationQueue; +} +@end + +@implementation RCNConfigDBManager + ++ (instancetype)sharedInstance { + static dispatch_once_t onceToken; + static RCNConfigDBManager *sharedInstance; + dispatch_once(&onceToken, ^{ + sharedInstance = [[RCNConfigDBManager alloc] init]; + }); + return sharedInstance; +} + +/// Returns the current version of the Remote Config database. ++ (NSString *)remoteConfigPathForDatabase { + return RemoteConfigPathForDatabase(); +} + +- (instancetype)init { + self = [super init]; + if (self) { + _databaseOperationQueue = + dispatch_queue_create("com.google.GoogleConfigService.database", DISPATCH_QUEUE_SERIAL); + [self createOrOpenDatabase]; + } + return self; +} + +#pragma mark - database +- (void)migrateV1NamespaceToV2Namespace { + for (int table = 0; table < 3; table++) { + NSString *tableName = @"" RCNTableNameMain; + switch (table) { + case 1: + tableName = @"" RCNTableNameMainActive; + break; + case 2: + tableName = @"" RCNTableNameMainDefault; + break; + default: + break; + } + NSString *SQLString = [NSString + stringWithFormat:@"SELECT namespace FROM %@ WHERE namespace NOT LIKE '%%:%%'", tableName]; + const char *SQL = [SQLString UTF8String]; + sqlite3_stmt *statement = [self prepareSQL:SQL]; + if (!statement) { + return; + } + NSMutableArray *namespaceArray = [[NSMutableArray alloc] init]; + while (sqlite3_step(statement) == SQLITE_ROW) { + NSString *configNamespace = + [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statement, 0)]; + [namespaceArray addObject:configNamespace]; + } + sqlite3_finalize(statement); + + // Update. + for (NSString *namespaceToUpdate in namespaceArray) { + NSString *newNamespace = + [NSString stringWithFormat:@"%@:%@", namespaceToUpdate, kFIRDefaultAppName]; + NSString *updateSQLString = + [NSString stringWithFormat:@"UPDATE %@ SET namespace = ? WHERE namespace = ?", tableName]; + const char *updateSQL = [updateSQLString UTF8String]; + sqlite3_stmt *updateStatement = [self prepareSQL:updateSQL]; + if (!updateStatement) { + return; + } + NSArray *updateParams = @[ newNamespace, namespaceToUpdate ]; + [self bindStringsToStatement:updateStatement stringArray:updateParams]; + + int result = sqlite3_step(updateStatement); + if (result != SQLITE_DONE) { + [self logErrorWithSQL:SQL finalizeStatement:updateStatement returnValue:NO]; + return; + } + sqlite3_finalize(updateStatement); + } + } +} + +- (void)createOrOpenDatabase { + __weak RCNConfigDBManager *weakSelf = self; + dispatch_async(_databaseOperationQueue, ^{ + RCNConfigDBManager *strongSelf = weakSelf; + if (!strongSelf) { + return; + } + NSString *oldV0DBPath = RemoteConfigPathForOldDatabaseV0(); + // Backward Compatibility + if ([[NSFileManager defaultManager] fileExistsAtPath:oldV0DBPath]) { + FIRLogInfo(kFIRLoggerRemoteConfig, @"I-RCN000009", + @"Old database V0 exists, removed it and replace with the new one."); + [strongSelf removeDatabase:oldV0DBPath]; + } + NSString *dbPath = [RCNConfigDBManager remoteConfigPathForDatabase]; + FIRLogInfo(kFIRLoggerRemoteConfig, @"I-RCN000062", @"Loading database at path %@", dbPath); + const char *databasePath = dbPath.UTF8String; + + // Create or open database path. + if (!RemoteConfigCreateFilePathIfNotExist(dbPath)) { + return; + } + + int flags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_FULLMUTEX; +#ifdef SQLITE_OPEN_FILEPROTECTION_COMPLETEUNTILFIRSTUSERAUTHENTICATION + flags |= SQLITE_OPEN_FILEPROTECTION_COMPLETEUNTILFIRSTUSERAUTHENTICATION; +#endif + + if (sqlite3_open_v2(databasePath, &strongSelf->_database, flags, NULL) == SQLITE_OK) { + // Always try to create table if not exists for backward compatibility. + if (![strongSelf createTableSchema]) { + // Remove database before fail. + [strongSelf removeDatabase:dbPath]; + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000010", @"Failed to create table."); + // Create a new database if existing database file is corrupted. + if (!RemoteConfigCreateFilePathIfNotExist(dbPath)) { + return; + } + if (sqlite3_open_v2(databasePath, &strongSelf->_database, flags, NULL) == SQLITE_OK) { + if (![strongSelf createTableSchema]) { + // Remove database before fail. + [strongSelf removeDatabase:dbPath]; + // If it failed again, there's nothing we can do here. + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000010", @"Failed to create table."); + } else { + // Exclude the app data used from iCloud backup. + RemoteConfigAddSkipBackupAttributeToItemAtPath(dbPath); + } + } else { + [strongSelf logDatabaseError]; + } + } else { + // DB file already exists. Migrate any V1 namespace column entries to V2 fully qualified + // 'namespace:FIRApp' entries. + [self migrateV1NamespaceToV2Namespace]; + // Exclude the app data used from iCloud backup. + RemoteConfigAddSkipBackupAttributeToItemAtPath(dbPath); + } + } else { + [strongSelf logDatabaseError]; + } + }); +} + +- (BOOL)createTableSchema { + RCN_MUST_NOT_BE_MAIN_THREAD(); + static const char *createTableMain = + "create TABLE IF NOT EXISTS " RCNTableNameMain + " (_id INTEGER PRIMARY KEY, bundle_identifier TEXT, namespace TEXT, key TEXT, value BLOB)"; + + static const char *createTableMainActive = + "create TABLE IF NOT EXISTS " RCNTableNameMainActive + " (_id INTEGER PRIMARY KEY, bundle_identifier TEXT, namespace TEXT, key TEXT, value BLOB)"; + + static const char *createTableMainDefault = + "create TABLE IF NOT EXISTS " RCNTableNameMainDefault + " (_id INTEGER PRIMARY KEY, bundle_identifier TEXT, namespace TEXT, key TEXT, value BLOB)"; + + static const char *createTableMetadata = + "create TABLE IF NOT EXISTS " RCNTableNameMetadata + " (_id INTEGER PRIMARY KEY, bundle_identifier TEXT, namespace TEXT," + " fetch_time INTEGER, digest_per_ns BLOB, device_context BLOB, app_context BLOB, " + "success_fetch_time BLOB, failure_fetch_time BLOB, last_fetch_status INTEGER, " + "last_fetch_error INTEGER, last_apply_time INTEGER, last_set_defaults_time INTEGER)"; + + static const char *createTableInternalMetadata = + "create TABLE IF NOT EXISTS " RCNTableNameInternalMetadata + " (_id INTEGER PRIMARY KEY, key TEXT, value BLOB)"; + + static const char *createTableExperiment = "create TABLE IF NOT EXISTS " RCNTableNameExperiment + " (_id INTEGER PRIMARY KEY, key TEXT, value BLOB)"; + static const char *createTablePersonalization = + "create TABLE IF NOT EXISTS " RCNTableNamePersonalization + " (_id INTEGER PRIMARY KEY, key INTEGER, value BLOB)"; + + static const char *createTableRollout = "create TABLE IF NOT EXISTS " RCNTableNameRollout + " (_id INTEGER PRIMARY KEY, key TEXT, value BLOB)"; + + return [self executeQuery:createTableMain] && [self executeQuery:createTableMainActive] && + [self executeQuery:createTableMainDefault] && [self executeQuery:createTableMetadata] && + [self executeQuery:createTableInternalMetadata] && + [self executeQuery:createTableExperiment] && + [self executeQuery:createTablePersonalization] && [self executeQuery:createTableRollout]; +} + +- (void)removeDatabaseOnDatabaseQueueAtPath:(NSString *)path { + __weak RCNConfigDBManager *weakSelf = self; + dispatch_sync(_databaseOperationQueue, ^{ + RCNConfigDBManager *strongSelf = weakSelf; + if (!strongSelf) { + return; + } + if (sqlite3_close(strongSelf->_database) != SQLITE_OK) { + [self logDatabaseError]; + } + strongSelf->_database = nil; + + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSError *error; + if (![fileManager removeItemAtPath:path error:&error]) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000011", + @"Failed to remove database at path %@ for error %@.", path, error); + } + }); +} + +- (void)removeDatabase:(NSString *)path { + if (sqlite3_close(_database) != SQLITE_OK) { + [self logDatabaseError]; + } + _database = nil; + + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSError *error; + if (![fileManager removeItemAtPath:path error:&error]) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000011", + @"Failed to remove database at path %@ for error %@.", path, error); + } +} + +#pragma mark - execute +- (BOOL)executeQuery:(const char *)SQL { + RCN_MUST_NOT_BE_MAIN_THREAD(); + char *error; + if (sqlite3_exec(_database, SQL, nil, nil, &error) != SQLITE_OK) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000012", @"Failed to execute query with error %s.", + error); + return NO; + } + return YES; +} + +#pragma mark - insert +- (void)insertMetadataTableWithValues:(NSDictionary *)columnNameToValue + completionHandler:(RCNDBCompletion)handler { + __weak RCNConfigDBManager *weakSelf = self; + dispatch_async(_databaseOperationQueue, ^{ + BOOL success = [weakSelf insertMetadataTableWithValues:columnNameToValue]; + if (handler) { + dispatch_async(dispatch_get_main_queue(), ^{ + handler(success, nil); + }); + } + }); +} + +- (BOOL)insertMetadataTableWithValues:(NSDictionary *)columnNameToValue { + RCN_MUST_NOT_BE_MAIN_THREAD(); + static const char *SQL = + "INSERT INTO " RCNTableNameMetadata + " (bundle_identifier, namespace, fetch_time, digest_per_ns, device_context, " + "app_context, success_fetch_time, failure_fetch_time, last_fetch_status, " + "last_fetch_error, last_apply_time, last_set_defaults_time) values (?, ?, ?, ?, ?, ?, " + "?, ?, ?, ?, ?, ?)"; + + sqlite3_stmt *statement = [self prepareSQL:SQL]; + if (!statement) { + [self logErrorWithSQL:SQL finalizeStatement:nil returnValue:NO]; + return NO; + } + + NSArray *columns = RemoteConfigMetadataTableColumnsInOrder(); + int index = 0; + for (NSString *columnName in columns) { + if ([columnName isEqualToString:RCNKeyBundleIdentifier] || + [columnName isEqualToString:RCNKeyNamespace]) { + NSString *value = columnNameToValue[columnName]; + if (![self bindStringToStatement:statement index:++index string:value]) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + } else if ([columnName isEqualToString:RCNKeyFetchTime] || + [columnName isEqualToString:RCNKeyLastApplyTime] || + [columnName isEqualToString:RCNKeyLastSetDefaultsTime]) { + double value = [columnNameToValue[columnName] doubleValue]; + if (sqlite3_bind_double(statement, ++index, value) != SQLITE_OK) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + } else if ([columnName isEqualToString:RCNKeyLastFetchStatus] || + [columnName isEqualToString:RCNKeyLastFetchError]) { + int value = [columnNameToValue[columnName] intValue]; + if (sqlite3_bind_int(statement, ++index, value) != SQLITE_OK) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + } else { + NSData *data = columnNameToValue[columnName]; + if (sqlite3_bind_blob(statement, ++index, data.bytes, (int)data.length, NULL) != SQLITE_OK) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + } + } + if (sqlite3_step(statement) != SQLITE_DONE) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + sqlite3_finalize(statement); + return YES; +} + +- (void)insertMainTableWithValues:(NSArray *)values + fromSource:(RCNDBSource)source + completionHandler:(RCNDBCompletion)handler { + __weak RCNConfigDBManager *weakSelf = self; + dispatch_async(_databaseOperationQueue, ^{ + BOOL success = [weakSelf insertMainTableWithValues:values fromSource:source]; + if (handler) { + dispatch_async(dispatch_get_main_queue(), ^{ + handler(success, nil); + }); + } + }); +} + +- (BOOL)insertMainTableWithValues:(NSArray *)values fromSource:(RCNDBSource)source { + RCN_MUST_NOT_BE_MAIN_THREAD(); + if (values.count != 4) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000013", + @"Failed to insert config record. Wrong number of give parameters, current " + @"number is %ld, correct number is 4.", + (long)values.count); + return NO; + } + const char *SQL = "INSERT INTO " RCNTableNameMain + " (bundle_identifier, namespace, key, value) values (?, ?, ?, ?)"; + if (source == RCNDBSourceDefault) { + SQL = "INSERT INTO " RCNTableNameMainDefault + " (bundle_identifier, namespace, key, value) values (?, ?, ?, ?)"; + } else if (source == RCNDBSourceActive) { + SQL = "INSERT INTO " RCNTableNameMainActive + " (bundle_identifier, namespace, key, value) values (?, ?, ?, ?)"; + } + + sqlite3_stmt *statement = [self prepareSQL:SQL]; + if (!statement) { + return NO; + } + + NSString *aString = values[0]; + if (![self bindStringToStatement:statement index:1 string:aString]) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + aString = values[1]; + if (![self bindStringToStatement:statement index:2 string:aString]) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + aString = values[2]; + if (![self bindStringToStatement:statement index:3 string:aString]) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + NSData *blobData = values[3]; + if (sqlite3_bind_blob(statement, 4, blobData.bytes, (int)blobData.length, NULL) != SQLITE_OK) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + if (sqlite3_step(statement) != SQLITE_DONE) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + sqlite3_finalize(statement); + return YES; +} + +- (void)insertInternalMetadataTableWithValues:(NSArray *)values + completionHandler:(RCNDBCompletion)handler { + __weak RCNConfigDBManager *weakSelf = self; + dispatch_async(_databaseOperationQueue, ^{ + BOOL success = [weakSelf insertInternalMetadataWithValues:values]; + if (handler) { + dispatch_async(dispatch_get_main_queue(), ^{ + handler(success, nil); + }); + } + }); +} + +- (BOOL)insertInternalMetadataWithValues:(NSArray *)values { + RCN_MUST_NOT_BE_MAIN_THREAD(); + if (values.count != 2) { + return NO; + } + const char *SQL = + "INSERT OR REPLACE INTO " RCNTableNameInternalMetadata " (key, value) values (?, ?)"; + sqlite3_stmt *statement = [self prepareSQL:SQL]; + if (!statement) { + return NO; + } + NSString *aString = values[0]; + if (![self bindStringToStatement:statement index:1 string:aString]) { + [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + return NO; + } + NSData *blobData = values[1]; + if (sqlite3_bind_blob(statement, 2, blobData.bytes, (int)blobData.length, NULL) != SQLITE_OK) { + [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + return NO; + } + if (sqlite3_step(statement) != SQLITE_DONE) { + [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + return NO; + } + sqlite3_finalize(statement); + return YES; +} + +- (void)insertExperimentTableWithKey:(NSString *)key + value:(NSData *)serializedValue + completionHandler:(RCNDBCompletion)handler { + dispatch_async(_databaseOperationQueue, ^{ + BOOL success = [self insertExperimentTableWithKey:key value:serializedValue]; + if (handler) { + dispatch_async(dispatch_get_main_queue(), ^{ + handler(success, nil); + }); + } + }); +} + +- (BOOL)insertExperimentTableWithKey:(NSString *)key value:(NSData *)dataValue { + if ([key isEqualToString:@RCNExperimentTableKeyMetadata]) { + return [self updateExperimentMetadata:dataValue]; + } + + RCN_MUST_NOT_BE_MAIN_THREAD(); + const char *SQL = "INSERT INTO " RCNTableNameExperiment " (key, value) values (?, ?)"; + + sqlite3_stmt *statement = [self prepareSQL:SQL]; + if (!statement) { + return NO; + } + + if (![self bindStringToStatement:statement index:1 string:key]) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + + if (sqlite3_bind_blob(statement, 2, dataValue.bytes, (int)dataValue.length, NULL) != SQLITE_OK) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + + if (sqlite3_step(statement) != SQLITE_DONE) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + sqlite3_finalize(statement); + return YES; +} + +- (BOOL)updateExperimentMetadata:(NSData *)dataValue { + RCN_MUST_NOT_BE_MAIN_THREAD(); + const char *SQL = "INSERT OR REPLACE INTO " RCNTableNameExperiment + " (_id, key, value) values ((SELECT _id from " RCNTableNameExperiment + " WHERE key = ?), ?, ?)"; + + sqlite3_stmt *statement = [self prepareSQL:SQL]; + if (!statement) { + return NO; + } + + if (![self bindStringToStatement:statement index:1 string:@RCNExperimentTableKeyMetadata]) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + + if (![self bindStringToStatement:statement index:2 string:@RCNExperimentTableKeyMetadata]) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + if (sqlite3_bind_blob(statement, 3, dataValue.bytes, (int)dataValue.length, NULL) != SQLITE_OK) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + + if (sqlite3_step(statement) != SQLITE_DONE) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + sqlite3_finalize(statement); + return YES; +} + +- (BOOL)insertOrUpdatePersonalizationConfig:(NSDictionary *)dataValue + fromSource:(RCNDBSource)source { + RCN_MUST_NOT_BE_MAIN_THREAD(); + + NSError *error; + NSData *JSONPayload = [NSJSONSerialization dataWithJSONObject:dataValue + options:NSJSONWritingPrettyPrinted + error:&error]; + + if (!JSONPayload || error) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000075", + @"Invalid Personalization payload to be serialized."); + } + + const char *SQL = "INSERT OR REPLACE INTO " RCNTableNamePersonalization + " (_id, key, value) values ((SELECT _id from " RCNTableNamePersonalization + " WHERE key = ?), ?, ?)"; + + sqlite3_stmt *statement = [self prepareSQL:SQL]; + if (!statement) { + return NO; + } + + if (sqlite3_bind_int(statement, 1, (int)source) != SQLITE_OK) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + + if (sqlite3_bind_int(statement, 2, (int)source) != SQLITE_OK) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + if (sqlite3_bind_blob(statement, 3, JSONPayload.bytes, (int)JSONPayload.length, NULL) != + SQLITE_OK) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + + if (sqlite3_step(statement) != SQLITE_DONE) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + sqlite3_finalize(statement); + return YES; +} + +- (void)insertOrUpdateRolloutTableWithKey:(NSString *)key + value:(NSArray *)metadataList + completionHandler:(RCNDBCompletion)handler { + dispatch_async(_databaseOperationQueue, ^{ + BOOL success = [self insertOrUpdateRolloutTableWithKey:key value:metadataList]; + if (handler) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + handler(success, nil); + }); + } + }); +} + +- (BOOL)insertOrUpdateRolloutTableWithKey:(NSString *)key + value:(NSArray *)arrayValue { + RCN_MUST_NOT_BE_MAIN_THREAD(); + NSError *error; + NSData *dataValue = [NSJSONSerialization dataWithJSONObject:arrayValue + options:NSJSONWritingPrettyPrinted + error:&error]; + const char *SQL = + "INSERT OR REPLACE INTO " RCNTableNameRollout + " (_id, key, value) values ((SELECT _id from " RCNTableNameRollout " WHERE key = ?), ?, ?)"; + sqlite3_stmt *statement = [self prepareSQL:SQL]; + if (!statement) { + return NO; + } + if (![self bindStringToStatement:statement index:1 string:key]) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + + if (![self bindStringToStatement:statement index:2 string:key]) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + + if (sqlite3_bind_blob(statement, 3, dataValue.bytes, (int)dataValue.length, NULL) != SQLITE_OK) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + + if (sqlite3_step(statement) != SQLITE_DONE) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + sqlite3_finalize(statement); + return YES; +} + +#pragma mark - update + +- (void)updateMetadataWithOption:(RCNUpdateOption)option + namespace:(NSString *)namespace + values:(NSArray *)values + completionHandler:(RCNDBCompletion)handler { + dispatch_async(_databaseOperationQueue, ^{ + BOOL success = [self updateMetadataTableWithOption:option namespace:namespace andValues:values]; + if (handler) { + dispatch_async(dispatch_get_main_queue(), ^{ + handler(success, nil); + }); + } + }); +} + +- (BOOL)updateMetadataTableWithOption:(RCNUpdateOption)option + namespace:(NSString *)namespace + andValues:(NSArray *)values { + RCN_MUST_NOT_BE_MAIN_THREAD(); + static const char *SQL = + "UPDATE " RCNTableNameMetadata " (last_fetch_status, last_fetch_error, last_apply_time, " + "last_set_defaults_time) values (?, ?, ?, ?) WHERE namespace = ?"; + if (option == RCNUpdateOptionFetchStatus) { + SQL = "UPDATE " RCNTableNameMetadata + " SET last_fetch_status = ?, last_fetch_error = ? WHERE namespace = ?"; + } else if (option == RCNUpdateOptionApplyTime) { + SQL = "UPDATE " RCNTableNameMetadata " SET last_apply_time = ? WHERE namespace = ?"; + } else if (option == RCNUpdateOptionDefaultTime) { + SQL = "UPDATE " RCNTableNameMetadata " SET last_set_defaults_time = ? WHERE namespace = ?"; + } else { + return NO; + } + sqlite3_stmt *statement = [self prepareSQL:SQL]; + if (!statement) { + return NO; + } + + int index = 0; + if ((option == RCNUpdateOptionApplyTime || option == RCNUpdateOptionDefaultTime) && + values.count == 1) { + double value = [values[0] doubleValue]; + if (sqlite3_bind_double(statement, ++index, value) != SQLITE_OK) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + } else if (option == RCNUpdateOptionFetchStatus && values.count == 2) { + int value = [values[0] intValue]; + if (sqlite3_bind_int(statement, ++index, value) != SQLITE_OK) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + value = [values[1] intValue]; + if (sqlite3_bind_int(statement, ++index, value) != SQLITE_OK) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + } + // bind namespace to query + if (sqlite3_bind_text(statement, ++index, [namespace UTF8String], -1, SQLITE_TRANSIENT) != + SQLITE_OK) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + + if (sqlite3_step(statement) != SQLITE_DONE) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + sqlite3_finalize(statement); + return YES; +} +#pragma mark - read from DB + +- (NSDictionary *)loadMetadataWithBundleIdentifier:(NSString *)bundleIdentifier + namespace:(NSString *)namespace { + __block NSDictionary *metadataTableResult; + __weak RCNConfigDBManager *weakSelf = self; + dispatch_sync(_databaseOperationQueue, ^{ + metadataTableResult = [weakSelf loadMetadataTableWithBundleIdentifier:bundleIdentifier + namespace:namespace]; + }); + if (metadataTableResult) { + return metadataTableResult; + } + return [[NSDictionary alloc] init]; +} + +- (NSMutableDictionary *)loadMetadataTableWithBundleIdentifier:(NSString *)bundleIdentifier + namespace:(NSString *)namespace { + NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; + const char *SQL = + "SELECT bundle_identifier, fetch_time, digest_per_ns, device_context, app_context, " + "success_fetch_time, failure_fetch_time , last_fetch_status, " + "last_fetch_error, last_apply_time, last_set_defaults_time FROM " RCNTableNameMetadata + " WHERE bundle_identifier = ? and namespace = ?"; + sqlite3_stmt *statement = [self prepareSQL:SQL]; + if (!statement) { + return nil; + } + + NSArray *params = @[ bundleIdentifier, namespace ]; + [self bindStringsToStatement:statement stringArray:params]; + + while (sqlite3_step(statement) == SQLITE_ROW) { + NSString *dbBundleIdentifier = + [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statement, 0)]; + + if (dbBundleIdentifier && ![dbBundleIdentifier isEqualToString:bundleIdentifier]) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000014", + @"Load Metadata from table error: Wrong package name %@, should be %@.", + dbBundleIdentifier, bundleIdentifier); + return nil; + } + + double fetchTime = sqlite3_column_double(statement, 1); + NSData *digestPerNamespace = [NSData dataWithBytes:(char *)sqlite3_column_blob(statement, 2) + length:sqlite3_column_bytes(statement, 2)]; + NSData *deviceContext = [NSData dataWithBytes:(char *)sqlite3_column_blob(statement, 3) + length:sqlite3_column_bytes(statement, 3)]; + NSData *appContext = [NSData dataWithBytes:(char *)sqlite3_column_blob(statement, 4) + length:sqlite3_column_bytes(statement, 4)]; + NSData *successTimeDigest = [NSData dataWithBytes:(char *)sqlite3_column_blob(statement, 5) + length:sqlite3_column_bytes(statement, 5)]; + NSData *failureTimeDigest = [NSData dataWithBytes:(char *)sqlite3_column_blob(statement, 6) + length:sqlite3_column_bytes(statement, 6)]; + + int lastFetchStatus = sqlite3_column_int(statement, 7); + int lastFetchFailReason = sqlite3_column_int(statement, 8); + double lastApplyTimestamp = sqlite3_column_double(statement, 9); + double lastSetDefaultsTimestamp = sqlite3_column_double(statement, 10); + + NSError *error; + NSMutableDictionary *deviceContextDict = nil; + if (deviceContext) { + deviceContextDict = [NSJSONSerialization JSONObjectWithData:deviceContext + options:NSJSONReadingMutableContainers + error:&error]; + } + + NSMutableDictionary *appContextDict = nil; + if (appContext) { + appContextDict = [NSJSONSerialization JSONObjectWithData:appContext + options:NSJSONReadingMutableContainers + error:&error]; + } + + NSMutableDictionary *digestPerNamespaceDictionary = nil; + if (digestPerNamespace) { + digestPerNamespaceDictionary = + [NSJSONSerialization JSONObjectWithData:digestPerNamespace + options:NSJSONReadingMutableContainers + error:&error]; + } + + NSMutableArray *successTimes = nil; + if (successTimeDigest) { + successTimes = [NSJSONSerialization JSONObjectWithData:successTimeDigest + options:NSJSONReadingMutableContainers + error:&error]; + } + + NSMutableArray *failureTimes = nil; + if (failureTimeDigest) { + failureTimes = [NSJSONSerialization JSONObjectWithData:failureTimeDigest + options:NSJSONReadingMutableContainers + error:&error]; + } + + dict[RCNKeyBundleIdentifier] = bundleIdentifier; + dict[RCNKeyFetchTime] = @(fetchTime); + dict[RCNKeyDigestPerNamespace] = digestPerNamespaceDictionary; + dict[RCNKeyDeviceContext] = deviceContextDict; + dict[RCNKeyAppContext] = appContextDict; + dict[RCNKeySuccessFetchTime] = successTimes; + dict[RCNKeyFailureFetchTime] = failureTimes; + dict[RCNKeyLastFetchStatus] = @(lastFetchStatus); + dict[RCNKeyLastFetchError] = @(lastFetchFailReason); + dict[RCNKeyLastApplyTime] = @(lastApplyTimestamp); + dict[RCNKeyLastSetDefaultsTime] = @(lastSetDefaultsTimestamp); + + break; + } + sqlite3_finalize(statement); + return dict; +} + +- (void)loadExperimentWithCompletionHandler:(RCNDBCompletion)handler { + __weak RCNConfigDBManager *weakSelf = self; + dispatch_async(_databaseOperationQueue, ^{ + RCNConfigDBManager *strongSelf = weakSelf; + if (!strongSelf) { + return; + } + NSMutableArray *experimentPayloads = + [strongSelf loadExperimentTableFromKey:@RCNExperimentTableKeyPayload]; + if (!experimentPayloads) { + experimentPayloads = [[NSMutableArray alloc] init]; + } + + NSMutableDictionary *experimentMetadata; + NSMutableArray *experiments = + [strongSelf loadExperimentTableFromKey:@RCNExperimentTableKeyMetadata]; + // There should be only one entry for experiment metadata. + if (experiments.count > 0) { + NSError *error; + experimentMetadata = [NSJSONSerialization JSONObjectWithData:experiments[0] + options:NSJSONReadingMutableContainers + error:&error]; + } + if (!experimentMetadata) { + experimentMetadata = [[NSMutableDictionary alloc] init]; + } + + /// Load activated experiments payload. + NSMutableArray *activeExperimentPayloads = + [strongSelf loadExperimentTableFromKey:@RCNExperimentTableKeyActivePayload]; + if (!activeExperimentPayloads) { + activeExperimentPayloads = [[NSMutableArray alloc] init]; + } + + if (handler) { + dispatch_async(dispatch_get_main_queue(), ^{ + handler( + YES, @{ + @RCNExperimentTableKeyPayload : [experimentPayloads copy], + @RCNExperimentTableKeyMetadata : [experimentMetadata copy], + /// Activated experiments only need ExperimentsDescriptions data, which + /// experimentPayloads contains. + @RCNExperimentTableKeyActivePayload : [activeExperimentPayloads copy] + }); + }); + } + }); +} + +- (NSMutableArray *)loadExperimentTableFromKey:(NSString *)key { + RCN_MUST_NOT_BE_MAIN_THREAD(); + + const char *SQL = "SELECT value FROM " RCNTableNameExperiment " WHERE key = ?"; + sqlite3_stmt *statement = [self prepareSQL:SQL]; + if (!statement) { + return nil; + } + + NSArray *params = @[ key ]; + [self bindStringsToStatement:statement stringArray:params]; + NSMutableArray *results = [self loadValuesFromStatement:statement]; + return results; +} + +- (NSArray *)loadRolloutTableFromKey:(NSString *)key { + RCN_MUST_NOT_BE_MAIN_THREAD(); + const char *SQL = "SELECT value FROM " RCNTableNameRollout " WHERE key = ?"; + sqlite3_stmt *statement = [self prepareSQL:SQL]; + if (!statement) { + return nil; + } + NSArray *params = @[ key ]; + [self bindStringsToStatement:statement stringArray:params]; + NSMutableArray *results = [self loadValuesFromStatement:statement]; + // There should be only one entry in this table. + if (results.count != 1) { + return nil; + } + NSArray *rollout; + // Convert from NSData to NSArray + if (results[0]) { + NSError *error; + rollout = [NSJSONSerialization JSONObjectWithData:results[0] options:0 error:&error]; + if (!rollout) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000011", + @"Failed to convert NSData to NSAarry for Rollout Metadata with error %@.", + error); + } + } + if (!rollout) { + rollout = [[NSArray alloc] init]; + } + return rollout; +} + +- (NSMutableArray *)loadValuesFromStatement:(sqlite3_stmt *)statement { + NSMutableArray *results = [[NSMutableArray alloc] init]; + NSData *value; + while (sqlite3_step(statement) == SQLITE_ROW) { + value = [NSData dataWithBytes:(char *)sqlite3_column_blob(statement, 0) + length:sqlite3_column_bytes(statement, 0)]; + if (value) { + [results addObject:value]; + } + } + + sqlite3_finalize(statement); + return results; +} + +- (void)loadPersonalizationWithCompletionHandler:(RCNDBLoadCompletion)handler { + __weak RCNConfigDBManager *weakSelf = self; + dispatch_async(_databaseOperationQueue, ^{ + RCNConfigDBManager *strongSelf = weakSelf; + if (!strongSelf) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + handler(NO, [NSMutableDictionary new], [NSMutableDictionary new], nil, nil); + }); + return; + } + + NSDictionary *activePersonalization; + NSData *personalizationResult = [strongSelf loadPersonalizationTableFromKey:RCNDBSourceActive]; + // There should be only one entry for Personalization metadata. + if (personalizationResult) { + NSError *error; + activePersonalization = [NSJSONSerialization JSONObjectWithData:personalizationResult + options:0 + error:&error]; + } + if (!activePersonalization) { + activePersonalization = [[NSMutableDictionary alloc] init]; + } + + NSDictionary *fetchedPersonalization; + personalizationResult = [strongSelf loadPersonalizationTableFromKey:RCNDBSourceFetched]; + // There should be only one entry for Personalization metadata. + if (personalizationResult) { + NSError *error; + fetchedPersonalization = [NSJSONSerialization JSONObjectWithData:personalizationResult + options:0 + error:&error]; + } + if (!fetchedPersonalization) { + fetchedPersonalization = [[NSMutableDictionary alloc] init]; + } + + if (handler) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + handler(YES, fetchedPersonalization, activePersonalization, nil, nil); + }); + } + }); +} + +- (NSData *)loadPersonalizationTableFromKey:(int)key { + RCN_MUST_NOT_BE_MAIN_THREAD(); + + NSMutableArray *results = [[NSMutableArray alloc] init]; + const char *SQL = "SELECT value FROM " RCNTableNamePersonalization " WHERE key = ?"; + sqlite3_stmt *statement = [self prepareSQL:SQL]; + if (!statement) { + return nil; + } + + if (sqlite3_bind_int(statement, 1, key) != SQLITE_OK) { + [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + return nil; + } + NSData *personalizationData; + while (sqlite3_step(statement) == SQLITE_ROW) { + personalizationData = [NSData dataWithBytes:(char *)sqlite3_column_blob(statement, 0) + length:sqlite3_column_bytes(statement, 0)]; + if (personalizationData) { + [results addObject:personalizationData]; + } + } + + sqlite3_finalize(statement); + // There should be only one entry in this table. + if (results.count != 1) { + return nil; + } + return results[0]; +} + +- (NSDictionary *)loadInternalMetadataTable { + __block NSMutableDictionary *internalMetadataTableResult; + __weak RCNConfigDBManager *weakSelf = self; + dispatch_sync(_databaseOperationQueue, ^{ + internalMetadataTableResult = [weakSelf loadInternalMetadataTableInternal]; + }); + return internalMetadataTableResult; +} + +- (NSMutableDictionary *)loadInternalMetadataTableInternal { + NSMutableDictionary *internalMetadata = [[NSMutableDictionary alloc] init]; + const char *SQL = "SELECT key, value FROM " RCNTableNameInternalMetadata; + sqlite3_stmt *statement = [self prepareSQL:SQL]; + if (!statement) { + return nil; + } + + while (sqlite3_step(statement) == SQLITE_ROW) { + NSString *key = [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statement, 0)]; + + NSData *dataValue = [NSData dataWithBytes:(char *)sqlite3_column_blob(statement, 1) + length:sqlite3_column_bytes(statement, 1)]; + internalMetadata[key] = dataValue; + } + sqlite3_finalize(statement); + return internalMetadata; +} + +/// This method is only meant to be called at init time. The underlying logic will need to be +/// revaluated if the assumption changes at a later time. +- (void)loadMainWithBundleIdentifier:(NSString *)bundleIdentifier + completionHandler:(RCNDBLoadCompletion)handler { + __weak RCNConfigDBManager *weakSelf = self; + dispatch_async(_databaseOperationQueue, ^{ + RCNConfigDBManager *strongSelf = weakSelf; + if (!strongSelf) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + handler(NO, [NSDictionary new], [NSDictionary new], [NSDictionary new], [NSDictionary new]); + }); + return; + } + __block NSDictionary *fetchedConfig = + [strongSelf loadMainTableWithBundleIdentifier:bundleIdentifier + fromSource:RCNDBSourceFetched]; + __block NSDictionary *activeConfig = + [strongSelf loadMainTableWithBundleIdentifier:bundleIdentifier + fromSource:RCNDBSourceActive]; + __block NSDictionary *defaultConfig = + [strongSelf loadMainTableWithBundleIdentifier:bundleIdentifier + fromSource:RCNDBSourceDefault]; + + __block NSArray *fetchedRolloutMetadata = + [strongSelf loadRolloutTableFromKey:@RCNRolloutTableKeyFetchedMetadata]; + __block NSArray *activeRolloutMetadata = + [strongSelf loadRolloutTableFromKey:@RCNRolloutTableKeyActiveMetadata]; + + if (handler) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + fetchedConfig = fetchedConfig ? fetchedConfig : [[NSDictionary alloc] init]; + activeConfig = activeConfig ? activeConfig : [[NSDictionary alloc] init]; + defaultConfig = defaultConfig ? defaultConfig : [[NSDictionary alloc] init]; + fetchedRolloutMetadata = + fetchedRolloutMetadata ? fetchedRolloutMetadata : [[NSArray alloc] init]; + activeRolloutMetadata = + activeRolloutMetadata ? activeRolloutMetadata : [[NSArray alloc] init]; + NSDictionary *rolloutMetadata = @{ + @RCNRolloutTableKeyActiveMetadata : [activeRolloutMetadata copy], + @RCNRolloutTableKeyFetchedMetadata : [fetchedRolloutMetadata copy] + }; + handler(YES, fetchedConfig, activeConfig, defaultConfig, rolloutMetadata); + }); + } + }); +} + +- (NSMutableDictionary *)loadMainTableWithBundleIdentifier:(NSString *)bundleIdentifier + fromSource:(RCNDBSource)source { + NSMutableDictionary *namespaceToConfig = [[NSMutableDictionary alloc] init]; + const char *SQL = "SELECT bundle_identifier, namespace, key, value FROM " RCNTableNameMain + " WHERE bundle_identifier = ?"; + if (source == RCNDBSourceDefault) { + SQL = "SELECT bundle_identifier, namespace, key, value FROM " RCNTableNameMainDefault + " WHERE bundle_identifier = ?"; + } else if (source == RCNDBSourceActive) { + SQL = "SELECT bundle_identifier, namespace, key, value FROM " RCNTableNameMainActive + " WHERE bundle_identifier = ?"; + } + NSArray *params = @[ bundleIdentifier ]; + sqlite3_stmt *statement = [self prepareSQL:SQL]; + if (!statement) { + return nil; + } + [self bindStringsToStatement:statement stringArray:params]; + + while (sqlite3_step(statement) == SQLITE_ROW) { + NSString *configNamespace = + [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statement, 1)]; + NSString *key = [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statement, 2)]; + NSData *value = [NSData dataWithBytes:(char *)sqlite3_column_blob(statement, 3) + length:sqlite3_column_bytes(statement, 3)]; + if (!namespaceToConfig[configNamespace]) { + namespaceToConfig[configNamespace] = [[NSMutableDictionary alloc] init]; + } + + if (source == RCNDBSourceDefault) { + namespaceToConfig[configNamespace][key] = + [[FIRRemoteConfigValue alloc] initWithData:value source:FIRRemoteConfigSourceDefault]; + } else { + namespaceToConfig[configNamespace][key] = + [[FIRRemoteConfigValue alloc] initWithData:value source:FIRRemoteConfigSourceRemote]; + } + } + sqlite3_finalize(statement); + return namespaceToConfig; +} + +#pragma mark - delete +- (void)deleteRecordFromMainTableWithNamespace:(NSString *)namespace_p + bundleIdentifier:(NSString *)bundleIdentifier + fromSource:(RCNDBSource)source { + __weak RCNConfigDBManager *weakSelf = self; + dispatch_async(_databaseOperationQueue, ^{ + RCNConfigDBManager *strongSelf = weakSelf; + if (!strongSelf) { + return; + } + NSArray *params = @[ bundleIdentifier, namespace_p ]; + const char *SQL = + "DELETE FROM " RCNTableNameMain " WHERE bundle_identifier = ? and namespace = ?"; + if (source == RCNDBSourceDefault) { + SQL = "DELETE FROM " RCNTableNameMainDefault " WHERE bundle_identifier = ? and namespace = ?"; + } else if (source == RCNDBSourceActive) { + SQL = "DELETE FROM " RCNTableNameMainActive " WHERE bundle_identifier = ? and namespace = ?"; + } + [strongSelf executeQuery:SQL withParams:params]; + }); +} + +- (void)deleteRecordWithBundleIdentifier:(NSString *)bundleIdentifier + namespace:(NSString *)namespace + isInternalDB:(BOOL)isInternalDB { + __weak RCNConfigDBManager *weakSelf = self; + dispatch_async(_databaseOperationQueue, ^{ + RCNConfigDBManager *strongSelf = weakSelf; + if (!strongSelf) { + return; + } + const char *SQL = "DELETE FROM " RCNTableNameInternalMetadata " WHERE key LIKE ?"; + NSArray *params = @[ bundleIdentifier ]; + if (!isInternalDB) { + SQL = "DELETE FROM " RCNTableNameMetadata " WHERE bundle_identifier = ? and namespace = ?"; + params = @[ bundleIdentifier, namespace ]; + } + [strongSelf executeQuery:SQL withParams:params]; + }); +} + +- (void)deleteAllRecordsFromTableWithSource:(RCNDBSource)source { + __weak RCNConfigDBManager *weakSelf = self; + dispatch_async(_databaseOperationQueue, ^{ + RCNConfigDBManager *strongSelf = weakSelf; + if (!strongSelf) { + return; + } + const char *SQL = "DELETE FROM " RCNTableNameMain; + if (source == RCNDBSourceDefault) { + SQL = "DELETE FROM " RCNTableNameMainDefault; + } else if (source == RCNDBSourceActive) { + SQL = "DELETE FROM " RCNTableNameMainActive; + } + [strongSelf executeQuery:SQL]; + }); +} + +- (void)deleteExperimentTableForKey:(NSString *)key { + __weak RCNConfigDBManager *weakSelf = self; + dispatch_async(_databaseOperationQueue, ^{ + RCNConfigDBManager *strongSelf = weakSelf; + if (!strongSelf) { + return; + } + NSArray *params = @[ key ]; + const char *SQL = "DELETE FROM " RCNTableNameExperiment " WHERE key = ?"; + [strongSelf executeQuery:SQL withParams:params]; + }); +} + +#pragma mark - helper +- (BOOL)executeQuery:(const char *)SQL withParams:(NSArray *)params { + RCN_MUST_NOT_BE_MAIN_THREAD(); + sqlite3_stmt *statement = [self prepareSQL:SQL]; + if (!statement) { + return NO; + } + + [self bindStringsToStatement:statement stringArray:params]; + if (sqlite3_step(statement) != SQLITE_DONE) { + return [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + } + sqlite3_finalize(statement); + return YES; +} + +/// Params only accept TEXT format string. +- (BOOL)bindStringsToStatement:(sqlite3_stmt *)statement stringArray:(NSArray *)array { + int index = 1; + for (NSString *param in array) { + if (![self bindStringToStatement:statement index:index string:param]) { + return [self logErrorWithSQL:nil finalizeStatement:statement returnValue:NO]; + } + index++; + } + return YES; +} + +- (BOOL)bindStringToStatement:(sqlite3_stmt *)statement index:(int)index string:(NSString *)value { + if (sqlite3_bind_text(statement, index, [value UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK) { + return [self logErrorWithSQL:nil finalizeStatement:statement returnValue:NO]; + } + return YES; +} + +- (sqlite3_stmt *)prepareSQL:(const char *)SQL { + sqlite3_stmt *statement = nil; + if (sqlite3_prepare_v2(_database, SQL, -1, &statement, NULL) != SQLITE_OK) { + [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; + return nil; + } + return statement; +} + +- (NSString *)errorMessage { + return [NSString stringWithFormat:@"%s", sqlite3_errmsg(_database)]; +} + +- (int)errorCode { + return sqlite3_errcode(_database); +} + +- (void)logDatabaseError { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000015", @"Error message: %@. Error code: %d.", + [self errorMessage], [self errorCode]); +} + +- (BOOL)logErrorWithSQL:(const char *)SQL + finalizeStatement:(sqlite3_stmt *)statement + returnValue:(BOOL)returnValue { + if (SQL) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000016", @"Failed with SQL: %s.", SQL); + } + [self logDatabaseError]; + + if (statement) { + sqlite3_finalize(statement); + } + + return returnValue; +} + +- (BOOL)isNewDatabase { + return gIsNewDatabase; +} + +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigDefines.h b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigDefines.h new file mode 100644 index 0000000..1e95373 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigDefines.h @@ -0,0 +1,37 @@ +/* + * 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. + */ + +#ifndef RCNConfigDefines_h +#define RCNConfigDefines_h + +#if defined(DEBUG) +#define RCN_MUST_NOT_BE_MAIN_THREAD() \ + do { \ + NSAssert(![NSThread isMainThread], @"Must not be executing on the main thread."); \ + } while (0); +#else +#define RCN_MUST_NOT_BE_MAIN_THREAD() \ + do { \ + } while (0); +#endif + +#define RCNExperimentTableKeyPayload "experiment_payload" +#define RCNExperimentTableKeyMetadata "experiment_metadata" +#define RCNExperimentTableKeyActivePayload "experiment_active_payload" +#define RCNRolloutTableKeyActiveMetadata "active_rollout_metadata" +#define RCNRolloutTableKeyFetchedMetadata "fetched_rollout_metadata" + +#endif diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigExperiment.h b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigExperiment.h new file mode 100644 index 0000000..79051fa --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigExperiment.h @@ -0,0 +1,38 @@ +/* + * 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 + +@class FIRExperimentController; +@class RCNConfigDBManager; + +/// Handles experiment information update and persistence. +@interface RCNConfigExperiment : NSObject + +/// Designated initializer; +- (nonnull instancetype)initWithDBManager:(RCNConfigDBManager *_Nullable)DBManager + experimentController:(FIRExperimentController *_Nullable)controller + NS_DESIGNATED_INITIALIZER; + +/// Use `initWithDBManager:` instead. +- (nonnull instancetype)init NS_UNAVAILABLE; + +/// Update/Persist experiment information from config fetch response. +- (void)updateExperimentsWithResponse:(NSArray *> *_Nullable)response; + +/// Update experiments to Firebase Analytics when `activateWithCompletion:` happens. +- (void)updateExperimentsWithHandler:(nullable void (^)(NSError *_Nullable error))handler; +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigExperiment.m b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigExperiment.m new file mode 100644 index 0000000..f5d09ea --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigExperiment.m @@ -0,0 +1,200 @@ +/* + * 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 "FirebaseRemoteConfig/Sources/RCNConfigExperiment.h" + +#import "FirebaseABTesting/Sources/Private/FirebaseABTestingInternal.h" +#import "FirebaseCore/Extension/FirebaseCoreInternal.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigDBManager.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigDefines.h" + +static NSString *const kExperimentMetadataKeyLastStartTime = @"last_experiment_start_time"; + +static NSString *const kServiceOrigin = @"frc"; +static NSString *const kMethodNameLatestStartTime = + @"latestExperimentStartTimestampBetweenTimestamp:andPayloads:"; + +@interface RCNConfigExperiment () +@property(nonatomic, strong) + NSMutableArray *experimentPayloads; ///< Experiment payloads. +@property(nonatomic, strong) + NSMutableDictionary *experimentMetadata; ///< Experiment metadata +@property(nonatomic, strong) + NSMutableArray *activeExperimentPayloads; ///< Activated experiment payloads. +@property(nonatomic, strong) RCNConfigDBManager *DBManager; ///< Database Manager. +@property(nonatomic, strong) FIRExperimentController *experimentController; +@property(nonatomic, strong) NSDateFormatter *experimentStartTimeDateFormatter; +@end + +@implementation RCNConfigExperiment +/// Designated initializer +- (instancetype)initWithDBManager:(RCNConfigDBManager *)DBManager + experimentController:(FIRExperimentController *)controller { + self = [super init]; + if (self) { + _experimentPayloads = [[NSMutableArray alloc] init]; + _experimentMetadata = [[NSMutableDictionary alloc] init]; + _activeExperimentPayloads = [[NSMutableArray alloc] init]; + _experimentStartTimeDateFormatter = [[NSDateFormatter alloc] init]; + [_experimentStartTimeDateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"]; + [_experimentStartTimeDateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; + // Locale needs to be hardcoded. See + // https://developer.apple.com/library/ios/#qa/qa1480/_index.html for more details. + [_experimentStartTimeDateFormatter + setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]]; + [_experimentStartTimeDateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]; + + _DBManager = DBManager; + _experimentController = controller; + [self loadExperimentFromTable]; + } + return self; +} + +- (void)loadExperimentFromTable { + if (!_DBManager) { + return; + } + __weak RCNConfigExperiment *weakSelf = self; + RCNDBCompletion completionHandler = ^(BOOL success, NSDictionary *result) { + RCNConfigExperiment *strongSelf = weakSelf; + if (strongSelf == nil) { + return; + } + if (result[@RCNExperimentTableKeyPayload]) { + [strongSelf->_experimentPayloads removeAllObjects]; + for (NSData *experiment in result[@RCNExperimentTableKeyPayload]) { + NSError *error; + id experimentPayloadJSON = [NSJSONSerialization JSONObjectWithData:experiment + options:kNilOptions + error:&error]; + if (!experimentPayloadJSON || error) { + FIRLogWarning(kFIRLoggerRemoteConfig, @"I-RCN000031", + @"Experiment payload could not be parsed as JSON."); + } else { + [strongSelf->_experimentPayloads addObject:experiment]; + } + } + } + if (result[@RCNExperimentTableKeyMetadata]) { + strongSelf->_experimentMetadata = [result[@RCNExperimentTableKeyMetadata] mutableCopy]; + } + + /// Load activated experiments payload and metadata. + if (result[@RCNExperimentTableKeyActivePayload]) { + [strongSelf->_activeExperimentPayloads removeAllObjects]; + for (NSData *experiment in result[@RCNExperimentTableKeyActivePayload]) { + NSError *error; + id experimentPayloadJSON = [NSJSONSerialization JSONObjectWithData:experiment + options:kNilOptions + error:&error]; + if (!experimentPayloadJSON || error) { + FIRLogWarning(kFIRLoggerRemoteConfig, @"I-RCN000031", + @"Activated experiment payload could not be parsed as JSON."); + } else { + [strongSelf->_activeExperimentPayloads addObject:experiment]; + } + } + } + }; + [_DBManager loadExperimentWithCompletionHandler:completionHandler]; +} + +- (void)updateExperimentsWithResponse:(NSArray *> *)response { + // cache fetched experiment payloads. + [_experimentPayloads removeAllObjects]; + [_DBManager deleteExperimentTableForKey:@RCNExperimentTableKeyPayload]; + + for (NSDictionary *experiment in response) { + NSError *error; + NSData *JSONPayload = [NSJSONSerialization dataWithJSONObject:experiment + options:kNilOptions + error:&error]; + if (!JSONPayload || error) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000030", + @"Invalid experiment payload to be serialized."); + } else { + [_experimentPayloads addObject:JSONPayload]; + [_DBManager insertExperimentTableWithKey:@RCNExperimentTableKeyPayload + value:JSONPayload + completionHandler:nil]; + } + } +} + +- (void)updateExperimentsWithHandler:(void (^)(NSError *_Nullable))handler { + FIRLifecycleEvents *lifecycleEvent = [[FIRLifecycleEvents alloc] init]; + + // Get the last experiment start time prior to the latest payload. + NSTimeInterval lastStartTime = + [_experimentMetadata[kExperimentMetadataKeyLastStartTime] doubleValue]; + + // Update the last experiment start time with the latest payload. + [self updateExperimentStartTime]; + [self.experimentController + updateExperimentsWithServiceOrigin:kServiceOrigin + events:lifecycleEvent + policy:ABTExperimentPayloadExperimentOverflowPolicyDiscardOldest + lastStartTime:lastStartTime + payloads:_experimentPayloads + completionHandler:handler]; + + /// Update activated experiments payload and metadata in DB. + [self updateActiveExperimentsInDB]; +} + +- (void)updateExperimentStartTime { + NSTimeInterval existingLastStartTime = + [_experimentMetadata[kExperimentMetadataKeyLastStartTime] doubleValue]; + + NSTimeInterval latestStartTime = + [self latestStartTimeWithExistingLastStartTime:existingLastStartTime]; + + _experimentMetadata[kExperimentMetadataKeyLastStartTime] = @(latestStartTime); + + if (![NSJSONSerialization isValidJSONObject:_experimentMetadata]) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000028", + @"Invalid fetched experiment metadata to be serialized."); + return; + } + NSError *error; + NSData *serializedExperimentMetadata = + [NSJSONSerialization dataWithJSONObject:_experimentMetadata + options:NSJSONWritingPrettyPrinted + error:&error]; + [_DBManager insertExperimentTableWithKey:@RCNExperimentTableKeyMetadata + value:serializedExperimentMetadata + completionHandler:nil]; +} + +- (void)updateActiveExperimentsInDB { + /// Put current fetched experiment payloads into activated experiment DB. + [_activeExperimentPayloads removeAllObjects]; + [_DBManager deleteExperimentTableForKey:@RCNExperimentTableKeyActivePayload]; + for (NSData *experiment in _experimentPayloads) { + [_activeExperimentPayloads addObject:experiment]; + [_DBManager insertExperimentTableWithKey:@RCNExperimentTableKeyActivePayload + value:experiment + completionHandler:nil]; + } +} + +- (NSTimeInterval)latestStartTimeWithExistingLastStartTime:(NSTimeInterval)existingLastStartTime { + return [self.experimentController + latestExperimentStartTimestampBetweenTimestamp:existingLastStartTime + andPayloads:_experimentPayloads]; +} +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigFetch.m b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigFetch.m new file mode 100644 index 0000000..dbc4b9b --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigFetch.m @@ -0,0 +1,691 @@ +/* + * 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 "FirebaseRemoteConfig/Sources/Private/RCNConfigFetch.h" +#import "FirebaseRemoteConfig/Sources/Private/FIRRemoteConfig_Private.h" + +#import +#import "FirebaseCore/Extension/FirebaseCoreInternal.h" +#import "FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h" +#import "FirebaseRemoteConfig/Sources/Private/RCNConfigSettings.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigConstants.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigContent.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigExperiment.h" +#import "FirebaseRemoteConfig/Sources/RCNDevice.h" +@import FirebaseRemoteConfigInterop; + +#ifdef RCN_STAGING_SERVER +static NSString *const kServerURLDomain = + @"https://staging-firebaseremoteconfig.sandbox.googleapis.com"; +#else +static NSString *const kServerURLDomain = @"https://firebaseremoteconfig.googleapis.com"; +#endif + +static NSString *const kServerURLVersion = @"/v1"; +static NSString *const kServerURLProjects = @"/projects/"; +static NSString *const kServerURLNamespaces = @"/namespaces/"; +static NSString *const kServerURLQuery = @":fetch?"; +static NSString *const kServerURLKey = @"key="; +static NSString *const kRequestJSONKeyAppID = @"app_id"; + +static NSString *const kHTTPMethodPost = @"POST"; ///< HTTP request method config fetch using +static NSString *const kContentTypeHeaderName = @"Content-Type"; ///< HTTP Header Field Name +static NSString *const kContentEncodingHeaderName = + @"Content-Encoding"; ///< HTTP Header Field Name +static NSString *const kAcceptEncodingHeaderName = @"Accept-Encoding"; ///< HTTP Header Field Name +static NSString *const kETagHeaderName = @"etag"; ///< HTTP Header Field Name +static NSString *const kIfNoneMatchETagHeaderName = @"if-none-match"; ///< HTTP Header Field Name +static NSString *const kInstallationsAuthTokenHeaderName = @"x-goog-firebase-installations-auth"; +// Sends the bundle ID. Refer to b/130301479 for details. +static NSString *const kiOSBundleIdentifierHeaderName = + @"X-Ios-Bundle-Identifier"; ///< HTTP Header Field Name + +static NSString *const kFetchTypeHeaderName = + @"X-Firebase-RC-Fetch-Type"; ///< Custom Http header key to identify the fetch type +static NSString *const kBaseFetchType = @"BASE"; ///< Fetch identifier for Base Fetch +static NSString *const kRealtimeFetchType = @"REALTIME"; ///< Fetch identifier for Realtime Fetch + +/// Config HTTP request content type proto buffer +static NSString *const kContentTypeValueJSON = @"application/json"; + +/// HTTP status codes. Ref: https://cloud.google.com/apis/design/errors#error_retries +static NSInteger const kRCNFetchResponseHTTPStatusCodeOK = 200; +static NSInteger const kRCNFetchResponseHTTPStatusTooManyRequests = 429; +static NSInteger const kRCNFetchResponseHTTPStatusCodeInternalError = 500; +static NSInteger const kRCNFetchResponseHTTPStatusCodeServiceUnavailable = 503; +static NSInteger const kRCNFetchResponseHTTPStatusCodeGatewayTimeout = 504; + +#pragma mark - RCNConfig + +@implementation RCNConfigFetch { + RCNConfigContent *_content; + RCNConfigSettings *_settings; + id _analytics; + RCNConfigExperiment *_experiment; + dispatch_queue_t _lockQueue; /// Guard the read/write operation. + NSURLSession *_fetchSession; /// Managed internally by the fetch instance. + NSString *_FIRNamespace; + FIROptions *_options; + NSString *_templateVersionNumber; +} + +- (instancetype)init { + NSAssert(NO, @"Invalid initializer."); + return nil; +} + +/// Designated initializer +- (instancetype)initWithContent:(RCNConfigContent *)content + DBManager:(RCNConfigDBManager *)DBManager + settings:(RCNConfigSettings *)settings + analytics:(nullable id)analytics + experiment:(RCNConfigExperiment *)experiment + queue:(dispatch_queue_t)queue + namespace:(NSString *)FIRNamespace + options:(FIROptions *)options { + self = [super init]; + if (self) { + _FIRNamespace = FIRNamespace; + _settings = settings; + _analytics = analytics; + _experiment = experiment; + _lockQueue = queue; + _content = content; + _fetchSession = [self newFetchSession]; + _options = options; + _templateVersionNumber = [self->_settings lastFetchedTemplateVersion]; + } + return self; +} + +/// Force a new NSURLSession creation for updated config. +- (void)recreateNetworkSession { + if (_fetchSession) { + [_fetchSession invalidateAndCancel]; + } + _fetchSession = [self newFetchSession]; +} + +/// Return the current session. (Tests). +- (NSURLSession *)currentNetworkSession { + return _fetchSession; +} + +- (void)dealloc { + [_fetchSession invalidateAndCancel]; +} + +#pragma mark - Fetch Config API + +- (void)fetchConfigWithExpirationDuration:(NSTimeInterval)expirationDuration + completionHandler:(FIRRemoteConfigFetchCompletion)completionHandler { + // Note: We expect the googleAppID to always be available. + BOOL hasDeviceContextChanged = + FIRRemoteConfigHasDeviceContextChanged(_settings.deviceContext, _options.googleAppID); + + __weak RCNConfigFetch *weakSelf = self; + dispatch_async(_lockQueue, ^{ + RCNConfigFetch *strongSelf = weakSelf; + if (strongSelf == nil) { + return; + } + + // Check whether we are outside of the minimum fetch interval. + if (![strongSelf->_settings hasMinimumFetchIntervalElapsed:expirationDuration] && + !hasDeviceContextChanged) { + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000051", @"Returning cached data."); + return [strongSelf reportCompletionOnHandler:completionHandler + withStatus:FIRRemoteConfigFetchStatusSuccess + withError:nil]; + } + + // Check if a fetch is already in progress. + if (strongSelf->_settings.isFetchInProgress) { + // Check if we have some fetched data. + if (strongSelf->_settings.lastFetchTimeInterval > 0) { + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000052", + @"A fetch is already in progress. Using previous fetch results."); + return [strongSelf reportCompletionOnHandler:completionHandler + withStatus:strongSelf->_settings.lastFetchStatus + withError:nil]; + } else { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000053", + @"A fetch is already in progress. Ignoring duplicate request."); + return [strongSelf reportCompletionOnHandler:completionHandler + withStatus:FIRRemoteConfigFetchStatusFailure + withError:nil]; + } + } + + // Check whether cache data is within throttle limit. + if ([strongSelf->_settings shouldThrottle] && !hasDeviceContextChanged) { + // Must set lastFetchStatus before FailReason. + strongSelf->_settings.lastFetchStatus = FIRRemoteConfigFetchStatusThrottled; + strongSelf->_settings.lastFetchError = FIRRemoteConfigErrorThrottled; + NSTimeInterval throttledEndTime = strongSelf->_settings.exponentialBackoffThrottleEndTime; + + NSError *error = + [NSError errorWithDomain:FIRRemoteConfigErrorDomain + code:FIRRemoteConfigErrorThrottled + userInfo:@{ + FIRRemoteConfigThrottledEndTimeInSecondsKey : @(throttledEndTime) + }]; + return [strongSelf reportCompletionOnHandler:completionHandler + withStatus:strongSelf->_settings.lastFetchStatus + withError:error]; + } + strongSelf->_settings.isFetchInProgress = YES; + NSString *fetchTypeHeader = [NSString stringWithFormat:@"%@/1", kBaseFetchType]; + [strongSelf refreshInstallationsTokenWithFetchHeader:fetchTypeHeader + completionHandler:completionHandler + updateCompletionHandler:nil]; + }); +} + +#pragma mark - Fetch helpers + +- (void)realtimeFetchConfigWithNoExpirationDuration:(NSInteger)fetchAttemptNumber + completionHandler:(RCNConfigFetchCompletion)completionHandler { + // Note: We expect the googleAppID to always be available. + BOOL hasDeviceContextChanged = + FIRRemoteConfigHasDeviceContextChanged(_settings.deviceContext, _options.googleAppID); + + __weak RCNConfigFetch *weakSelf = self; + dispatch_async(_lockQueue, ^{ + RCNConfigFetch *strongSelf = weakSelf; + if (strongSelf == nil) { + return; + } + // Check whether cache data is within throttle limit. + if ([strongSelf->_settings shouldThrottle] && !hasDeviceContextChanged) { + // Must set lastFetchStatus before FailReason. + strongSelf->_settings.lastFetchStatus = FIRRemoteConfigFetchStatusThrottled; + strongSelf->_settings.lastFetchError = FIRRemoteConfigErrorThrottled; + NSTimeInterval throttledEndTime = strongSelf->_settings.exponentialBackoffThrottleEndTime; + + NSError *error = + [NSError errorWithDomain:FIRRemoteConfigErrorDomain + code:FIRRemoteConfigErrorThrottled + userInfo:@{ + FIRRemoteConfigThrottledEndTimeInSecondsKey : @(throttledEndTime) + }]; + return [strongSelf reportCompletionWithStatus:FIRRemoteConfigFetchStatusFailure + withUpdate:nil + withError:error + completionHandler:nil + updateCompletionHandler:completionHandler]; + } + strongSelf->_settings.isFetchInProgress = YES; + + NSString *fetchTypeHeader = + [NSString stringWithFormat:@"%@/%ld", kRealtimeFetchType, (long)fetchAttemptNumber]; + [strongSelf refreshInstallationsTokenWithFetchHeader:fetchTypeHeader + completionHandler:nil + updateCompletionHandler:completionHandler]; + }); +} + +- (NSString *)FIRAppNameFromFullyQualifiedNamespace { + return [[_FIRNamespace componentsSeparatedByString:@":"] lastObject]; +} +/// Refresh installation ID token before fetching config. installation ID is now mandatory for fetch +/// requests to work.(b/14751422). +- (void)refreshInstallationsTokenWithFetchHeader:(NSString *)fetchTypeHeader + completionHandler:(FIRRemoteConfigFetchCompletion)completionHandler + updateCompletionHandler:(RCNConfigFetchCompletion)updateCompletionHandler { + FIRInstallations *installations = [FIRInstallations + installationsWithApp:[FIRApp appNamed:[self FIRAppNameFromFullyQualifiedNamespace]]]; + if (!installations || !_options.GCMSenderID) { + NSString *errorDescription = @"Failed to get GCMSenderID"; + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000074", @"%@", + [NSString stringWithFormat:@"%@", errorDescription]); + self->_settings.isFetchInProgress = NO; + return [self + reportCompletionOnHandler:completionHandler + withStatus:FIRRemoteConfigFetchStatusFailure + withError:[NSError errorWithDomain:FIRRemoteConfigErrorDomain + code:FIRRemoteConfigErrorInternalError + userInfo:@{ + NSLocalizedDescriptionKey : errorDescription + }]]; + } + + __weak RCNConfigFetch *weakSelf = self; + FIRInstallationsTokenHandler installationsTokenHandler = ^( + FIRInstallationsAuthTokenResult *tokenResult, NSError *error) { + RCNConfigFetch *strongSelf = weakSelf; + if (strongSelf == nil) { + return; + } + + if (!tokenResult || !tokenResult.authToken || error) { + NSString *errorDescription = + [NSString stringWithFormat:@"Failed to get installations token. Error : %@.", error]; + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000073", @"%@", + [NSString stringWithFormat:@"%@", errorDescription]); + strongSelf->_settings.isFetchInProgress = NO; + + NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; + userInfo[NSLocalizedDescriptionKey] = errorDescription; + userInfo[NSUnderlyingErrorKey] = error.userInfo[NSUnderlyingErrorKey]; + + return [strongSelf + reportCompletionOnHandler:completionHandler + withStatus:FIRRemoteConfigFetchStatusFailure + withError:[NSError errorWithDomain:FIRRemoteConfigErrorDomain + code:FIRRemoteConfigErrorInternalError + userInfo:userInfo]]; + } + + // We have a valid token. Get the backing installationID. + [installations installationIDWithCompletion:^(NSString *_Nullable identifier, + NSError *_Nullable error) { + RCNConfigFetch *strongSelf = weakSelf; + if (strongSelf == nil) { + return; + } + + // Dispatch to the RC serial queue to update settings on the queue. + dispatch_async(strongSelf->_lockQueue, ^{ + RCNConfigFetch *strongSelfQueue = weakSelf; + if (strongSelfQueue == nil) { + return; + } + + // Update config settings with the IID and token. + strongSelfQueue->_settings.configInstallationsToken = tokenResult.authToken; + strongSelfQueue->_settings.configInstallationsIdentifier = identifier; + + if (!identifier || error) { + NSString *errorDescription = + [NSString stringWithFormat:@"Error getting iid : %@.", error]; + + NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; + userInfo[NSLocalizedDescriptionKey] = errorDescription; + userInfo[NSUnderlyingErrorKey] = error.userInfo[NSUnderlyingErrorKey]; + + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000055", @"%@", + [NSString stringWithFormat:@"%@", errorDescription]); + strongSelfQueue->_settings.isFetchInProgress = NO; + return [strongSelfQueue + reportCompletionOnHandler:completionHandler + withStatus:FIRRemoteConfigFetchStatusFailure + withError:[NSError errorWithDomain:FIRRemoteConfigErrorDomain + code:FIRRemoteConfigErrorInternalError + userInfo:userInfo]]; + } + + FIRLogInfo(kFIRLoggerRemoteConfig, @"I-RCN000022", @"Success to get iid : %@.", + strongSelfQueue->_settings.configInstallationsIdentifier); + [strongSelf doFetchCall:fetchTypeHeader + completionHandler:completionHandler + updateCompletionHandler:updateCompletionHandler]; + }); + }]; + }; + + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000039", @"Starting requesting token."); + [installations authTokenWithCompletion:installationsTokenHandler]; +} + +- (void)doFetchCall:(NSString *)fetchTypeHeader + completionHandler:(FIRRemoteConfigFetchCompletion)completionHandler + updateCompletionHandler:(RCNConfigFetchCompletion)updateCompletionHandler { + [self getAnalyticsUserPropertiesWithCompletionHandler:^(NSDictionary *userProperties) { + dispatch_async(self->_lockQueue, ^{ + [self fetchWithUserProperties:userProperties + fetchTypeHeader:fetchTypeHeader + completionHandler:completionHandler + updateCompletionHandler:updateCompletionHandler]; + }); + }]; +} + +- (void)getAnalyticsUserPropertiesWithCompletionHandler: + (FIRAInteropUserPropertiesCallback)completionHandler { + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000060", @"Fetch with user properties completed."); + id analytics = self->_analytics; + if (analytics == nil) { + completionHandler(@{}); + } else { + [analytics getUserPropertiesWithCallback:completionHandler]; + } +} + +- (void)reportCompletionOnHandler:(FIRRemoteConfigFetchCompletion)completionHandler + withStatus:(FIRRemoteConfigFetchStatus)status + withError:(NSError *)error { + [self reportCompletionWithStatus:status + withUpdate:nil + withError:error + completionHandler:completionHandler + updateCompletionHandler:nil]; +} + +- (void)reportCompletionWithStatus:(FIRRemoteConfigFetchStatus)status + withUpdate:(FIRRemoteConfigUpdate *)update + withError:(NSError *)error + completionHandler:(FIRRemoteConfigFetchCompletion)completionHandler + updateCompletionHandler:(RCNConfigFetchCompletion)updateCompletionHandler { + if (completionHandler) { + dispatch_async(dispatch_get_main_queue(), ^{ + completionHandler(status, error); + }); + } + // if completion handler expects a config update response + if (updateCompletionHandler) { + dispatch_async(dispatch_get_main_queue(), ^{ + updateCompletionHandler(status, update, error); + }); + } +} + +- (void)fetchWithUserProperties:(NSDictionary *)userProperties + fetchTypeHeader:(NSString *)fetchTypeHeader + completionHandler:(FIRRemoteConfigFetchCompletion)completionHandler + updateCompletionHandler:(RCNConfigFetchCompletion)updateCompletionHandler { + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000061", @"Fetch with user properties initiated."); + + NSString *postRequestString = [_settings nextRequestWithUserProperties:userProperties]; + + // Get POST request content. + NSData *content = [postRequestString dataUsingEncoding:NSUTF8StringEncoding]; + NSError *compressionError; + NSData *compressedContent = [NSData gul_dataByGzippingData:content error:&compressionError]; + if (compressionError) { + NSString *errString = [NSString stringWithFormat:@"Failed to compress the config request."]; + FIRLogWarning(kFIRLoggerRemoteConfig, @"I-RCN000033", @"%@", errString); + NSError *error = [NSError errorWithDomain:FIRRemoteConfigErrorDomain + code:FIRRemoteConfigErrorInternalError + userInfo:@{NSLocalizedDescriptionKey : errString}]; + + self->_settings.isFetchInProgress = NO; + return [self reportCompletionWithStatus:FIRRemoteConfigFetchStatusFailure + withUpdate:nil + withError:error + completionHandler:completionHandler + updateCompletionHandler:updateCompletionHandler]; + } + + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000040", @"Start config fetch."); + __weak RCNConfigFetch *weakSelf = self; + RCNConfigFetcherCompletion fetcherCompletion = ^(NSData *data, NSURLResponse *response, + NSError *error) { + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000050", + @"config fetch completed. Error: %@ StatusCode: %ld", (error ? error : @"nil"), + (long)[((NSHTTPURLResponse *)response) statusCode]); + + RCNConfigFetch *fetcherCompletionSelf = weakSelf; + if (fetcherCompletionSelf == nil) { + return; + } + + // The fetch has completed. + fetcherCompletionSelf->_settings.isFetchInProgress = NO; + + dispatch_async(fetcherCompletionSelf->_lockQueue, ^{ + RCNConfigFetch *strongSelf = weakSelf; + if (strongSelf == nil) { + return; + } + + NSInteger statusCode = [((NSHTTPURLResponse *)response) statusCode]; + + if (error || (statusCode != kRCNFetchResponseHTTPStatusCodeOK)) { + // Update metadata about fetch failure. + [strongSelf->_settings updateMetadataWithFetchSuccessStatus:NO templateVersion:nil]; + if (error) { + if (strongSelf->_settings.lastFetchStatus == FIRRemoteConfigFetchStatusSuccess) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000025", + @"RCN Fetch failure: %@. Using cached config result.", error); + } else { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000026", + @"RCN Fetch failure: %@. No cached config result.", error); + } + } + if (statusCode != kRCNFetchResponseHTTPStatusCodeOK) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000026", + @"RCN Fetch failure. Response http error code: %ld", (long)statusCode); + // Response error code 429, 500, 503 will trigger exponential backoff mode. + // TODO: check error code in helper + if (statusCode == kRCNFetchResponseHTTPStatusTooManyRequests || + statusCode == kRCNFetchResponseHTTPStatusCodeInternalError || + statusCode == kRCNFetchResponseHTTPStatusCodeServiceUnavailable || + statusCode == kRCNFetchResponseHTTPStatusCodeGatewayTimeout) { + [strongSelf->_settings updateExponentialBackoffTime]; + if ([strongSelf->_settings shouldThrottle]) { + // Must set lastFetchStatus before FailReason. + strongSelf->_settings.lastFetchStatus = FIRRemoteConfigFetchStatusThrottled; + strongSelf->_settings.lastFetchError = FIRRemoteConfigErrorThrottled; + NSTimeInterval throttledEndTime = + strongSelf->_settings.exponentialBackoffThrottleEndTime; + + NSError *error = [NSError + errorWithDomain:FIRRemoteConfigErrorDomain + code:FIRRemoteConfigErrorThrottled + userInfo:@{ + FIRRemoteConfigThrottledEndTimeInSecondsKey : @(throttledEndTime) + }]; + return [strongSelf reportCompletionWithStatus:strongSelf->_settings.lastFetchStatus + withUpdate:nil + withError:error + completionHandler:completionHandler + updateCompletionHandler:updateCompletionHandler]; + } + } + } + // Return back the received error. + // Must set lastFetchStatus before setting Fetch Error. + strongSelf->_settings.lastFetchStatus = FIRRemoteConfigFetchStatusFailure; + strongSelf->_settings.lastFetchError = FIRRemoteConfigErrorInternalError; + NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; + userInfo[NSUnderlyingErrorKey] = error; + userInfo[NSLocalizedDescriptionKey] = + error.localizedDescription + ?: [NSString + stringWithFormat:@"Internal Error. Status code: %ld", (long)statusCode]; + + return [strongSelf + reportCompletionWithStatus:FIRRemoteConfigFetchStatusFailure + withUpdate:nil + withError:[NSError errorWithDomain:FIRRemoteConfigErrorDomain + code:FIRRemoteConfigErrorInternalError + userInfo:userInfo] + completionHandler:completionHandler + updateCompletionHandler:updateCompletionHandler]; + } + + // Fetch was successful. Check if we have data. + NSError *retError; + if (!data) { + FIRLogInfo(kFIRLoggerRemoteConfig, @"I-RCN000043", @"RCN Fetch: No data in fetch response"); + // There may still be a difference between fetched and active config + FIRRemoteConfigUpdate *update = + [strongSelf->_content getConfigUpdateForNamespace:strongSelf->_FIRNamespace]; + return [strongSelf reportCompletionWithStatus:FIRRemoteConfigFetchStatusSuccess + withUpdate:update + withError:nil + completionHandler:completionHandler + updateCompletionHandler:updateCompletionHandler]; + } + + // Config fetch succeeded. + // JSONObjectWithData is always expected to return an NSDictionary in our case + NSMutableDictionary *fetchedConfig = + [NSJSONSerialization JSONObjectWithData:data + options:NSJSONReadingMutableContainers + error:&retError]; + if (retError) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000042", + @"RCN Fetch failure: %@. Could not parse response data as JSON", error); + } + + // Check and log if we received an error from the server + if (fetchedConfig && fetchedConfig.count == 1 && fetchedConfig[RCNFetchResponseKeyError]) { + NSString *errStr = [NSString stringWithFormat:@"RCN Fetch Failure: Server returned error:"]; + NSDictionary *errDict = fetchedConfig[RCNFetchResponseKeyError]; + if (errDict[RCNFetchResponseKeyErrorCode]) { + errStr = [errStr + stringByAppendingString:[NSString + stringWithFormat:@"code: %@", + errDict[RCNFetchResponseKeyErrorCode]]]; + } + if (errDict[RCNFetchResponseKeyErrorStatus]) { + errStr = [errStr stringByAppendingString: + [NSString stringWithFormat:@". Status: %@", + errDict[RCNFetchResponseKeyErrorStatus]]]; + } + if (errDict[RCNFetchResponseKeyErrorMessage]) { + errStr = + [errStr stringByAppendingString: + [NSString stringWithFormat:@". Message: %@", + errDict[RCNFetchResponseKeyErrorMessage]]]; + } + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000044", @"%@.", errStr); + NSError *error = [NSError errorWithDomain:FIRRemoteConfigErrorDomain + code:FIRRemoteConfigErrorInternalError + userInfo:@{NSLocalizedDescriptionKey : errStr}]; + return [strongSelf reportCompletionWithStatus:FIRRemoteConfigFetchStatusFailure + withUpdate:nil + withError:error + completionHandler:completionHandler + updateCompletionHandler:updateCompletionHandler]; + } + + // Add the fetched config to the database. + if (fetchedConfig) { + // Update config content to cache and DB. + [strongSelf->_content updateConfigContentWithResponse:fetchedConfig + forNamespace:strongSelf->_FIRNamespace]; + // Update experiments only for 3p namespace + NSString *namespace = [strongSelf->_FIRNamespace + substringToIndex:[strongSelf->_FIRNamespace rangeOfString:@":"].location]; + if ([namespace isEqualToString:FIRRemoteConfigConstants.FIRNamespaceGoogleMobilePlatform]) { + [strongSelf->_experiment updateExperimentsWithResponse: + fetchedConfig[RCNFetchResponseKeyExperimentDescriptions]]; + } + + strongSelf->_templateVersionNumber = [strongSelf getTemplateVersionNumber:fetchedConfig]; + } else { + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000063", + @"Empty response with no fetched config."); + } + + // We had a successful fetch. Update the current eTag in settings if different. + NSString *latestETag = ((NSHTTPURLResponse *)response).allHeaderFields[kETagHeaderName]; + if (!strongSelf->_settings.lastETag || + !([strongSelf->_settings.lastETag isEqualToString:latestETag])) { + strongSelf->_settings.lastETag = latestETag; + } + // Compute config update after successful fetch + FIRRemoteConfigUpdate *update = + [strongSelf->_content getConfigUpdateForNamespace:strongSelf->_FIRNamespace]; + + [strongSelf->_settings + updateMetadataWithFetchSuccessStatus:YES + templateVersion:strongSelf->_templateVersionNumber]; + return [strongSelf reportCompletionWithStatus:FIRRemoteConfigFetchStatusSuccess + withUpdate:update + withError:nil + completionHandler:completionHandler + updateCompletionHandler:updateCompletionHandler]; + }); + }; + + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000061", @"Making remote config fetch."); + + NSURLSessionDataTask *dataTask = [self URLSessionDataTaskWithContent:compressedContent + fetchTypeHeader:fetchTypeHeader + completionHandler:fetcherCompletion]; + [dataTask resume]; +} + +- (NSString *)constructServerURL { + NSString *serverURLStr = [[NSString alloc] initWithString:kServerURLDomain]; + serverURLStr = [serverURLStr stringByAppendingString:kServerURLVersion]; + serverURLStr = [serverURLStr stringByAppendingString:kServerURLProjects]; + serverURLStr = [serverURLStr stringByAppendingString:_options.projectID]; + serverURLStr = [serverURLStr stringByAppendingString:kServerURLNamespaces]; + + // Get the namespace from the fully qualified namespace string of "namespace:FIRAppName". + NSString *namespace = + [_FIRNamespace substringToIndex:[_FIRNamespace rangeOfString:@":"].location]; + serverURLStr = [serverURLStr stringByAppendingString:namespace]; + serverURLStr = [serverURLStr stringByAppendingString:kServerURLQuery]; + + if (_options.APIKey) { + serverURLStr = [serverURLStr stringByAppendingString:kServerURLKey]; + serverURLStr = [serverURLStr stringByAppendingString:_options.APIKey]; + } else { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000071", + @"Missing `APIKey` from `FirebaseOptions`, please ensure the configured " + @"`FirebaseApp` is configured with `FirebaseOptions` that contains an `APIKey`."); + } + + return serverURLStr; +} + +- (NSURLSession *)newFetchSession { + NSURLSessionConfiguration *config = + [[NSURLSessionConfiguration defaultSessionConfiguration] copy]; + config.timeoutIntervalForRequest = _settings.fetchTimeout; + config.timeoutIntervalForResource = _settings.fetchTimeout; + NSURLSession *session = [NSURLSession sessionWithConfiguration:config]; + return session; +} + +- (NSURLSessionDataTask *)URLSessionDataTaskWithContent:(NSData *)content + fetchTypeHeader:(NSString *)fetchTypeHeader + completionHandler: + (RCNConfigFetcherCompletion)fetcherCompletion { + NSURL *URL = [NSURL URLWithString:[self constructServerURL]]; + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000046", @"%@", + [NSString stringWithFormat:@"Making config request: %@", [URL absoluteString]]); + + NSTimeInterval timeoutInterval = _fetchSession.configuration.timeoutIntervalForResource; + NSMutableURLRequest *URLRequest = + [[NSMutableURLRequest alloc] initWithURL:URL + cachePolicy:NSURLRequestReloadIgnoringLocalCacheData + timeoutInterval:timeoutInterval]; + URLRequest.HTTPMethod = kHTTPMethodPost; + [URLRequest setValue:kContentTypeValueJSON forHTTPHeaderField:kContentTypeHeaderName]; + [URLRequest setValue:_settings.configInstallationsToken + forHTTPHeaderField:kInstallationsAuthTokenHeaderName]; + [URLRequest setValue:[[NSBundle mainBundle] bundleIdentifier] + forHTTPHeaderField:kiOSBundleIdentifierHeaderName]; + [URLRequest setValue:@"gzip" forHTTPHeaderField:kContentEncodingHeaderName]; + [URLRequest setValue:@"gzip" forHTTPHeaderField:kAcceptEncodingHeaderName]; + [URLRequest setValue:fetchTypeHeader forHTTPHeaderField:kFetchTypeHeaderName]; + // Set the eTag from the last successful fetch, if available. + if (_settings.lastETag) { + [URLRequest setValue:_settings.lastETag forHTTPHeaderField:kIfNoneMatchETagHeaderName]; + } + [URLRequest setHTTPBody:content]; + + return [_fetchSession dataTaskWithRequest:URLRequest completionHandler:fetcherCompletion]; +} + +- (NSString *)getTemplateVersionNumber:(NSDictionary *)fetchedConfig { + if (fetchedConfig != nil && [fetchedConfig objectForKey:RCNFetchResponseKeyTemplateVersion] && + [[fetchedConfig objectForKey:RCNFetchResponseKeyTemplateVersion] + isKindOfClass:[NSString class]]) { + return (NSString *)[fetchedConfig objectForKey:RCNFetchResponseKeyTemplateVersion]; + } + + return @"0"; +} + +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigRealtime.h b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigRealtime.h new file mode 100644 index 0000000..56b6ad1 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigRealtime.h @@ -0,0 +1,40 @@ +/* + * Copyright 2022 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 +#import "FirebaseRemoteConfig/Sources/Private/RCNConfigFetch.h" +#import "FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h" + +@class RCNConfigSettings; + +@interface RCNConfigRealtime : NSObject + +/// Completion handler invoked by config update methods when they get a response from the server. +/// +/// @param error Error message on failure. +typedef void (^RCNConfigUpdateCompletion)(FIRRemoteConfigUpdate *_Nullable configUpdate, + NSError *_Nullable error); + +- (instancetype _Nonnull)init:(RCNConfigFetch *_Nonnull)configFetch + settings:(RCNConfigSettings *_Nonnull)settings + namespace:(NSString *_Nonnull)namespace + options:(FIROptions *_Nonnull)options; + +- (FIRConfigUpdateListenerRegistration *_Nonnull)addConfigUpdateListener: + (RCNConfigUpdateCompletion _Nonnull)listener; +- (void)removeConfigUpdateListener:(RCNConfigUpdateCompletion _Nonnull)listener; + +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigRealtime.m b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigRealtime.m new file mode 100644 index 0000000..2fb2b98 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigRealtime.m @@ -0,0 +1,716 @@ +/* + * Copyright 2022 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 "FirebaseRemoteConfig/Sources/RCNConfigRealtime.h" +#import +#import +#import "FirebaseCore/Extension/FirebaseCoreInternal.h" +#import "FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h" +#import "FirebaseRemoteConfig/Sources/Private/RCNConfigFetch.h" +#import "FirebaseRemoteConfig/Sources/Private/RCNConfigSettings.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigConstants.h" +#import "FirebaseRemoteConfig/Sources/RCNDevice.h" + +/// URL params +static NSString *const kServerURLDomain = @"https://firebaseremoteconfigrealtime.googleapis.com"; +static NSString *const kServerURLVersion = @"/v1"; +static NSString *const kServerURLProjects = @"/projects/"; +static NSString *const kServerURLNamespaces = @"/namespaces/"; +static NSString *const kServerURLQuery = @":streamFetchInvalidations?"; +static NSString *const kServerURLKey = @"key="; + +/// Realtime API enablement +static NSString *const kServerForbiddenStatusCode = @"\"code\": 403"; + +/// Header names +static NSString *const kHTTPMethodPost = @"POST"; ///< HTTP request method config fetch using +static NSString *const kContentTypeHeaderName = @"Content-Type"; ///< HTTP Header Field Name +static NSString *const kContentEncodingHeaderName = + @"Content-Encoding"; ///< HTTP Header Field Name +static NSString *const kAcceptEncodingHeaderName = @"Accept"; ///< HTTP Header Field Name +static NSString *const kETagHeaderName = @"etag"; ///< HTTP Header Field Name +static NSString *const kIfNoneMatchETagHeaderName = @"if-none-match"; ///< HTTP Header Field Name +static NSString *const kInstallationsAuthTokenHeaderName = @"x-goog-firebase-installations-auth"; +// Sends the bundle ID. Refer to b/130301479 for details. +static NSString *const kiOSBundleIdentifierHeaderName = + @"X-Ios-Bundle-Identifier"; ///< HTTP Header Field Name + +/// Retryable HTTP status code. +static NSInteger const kRCNFetchResponseHTTPStatusOk = 200; +static NSInteger const kRCNFetchResponseHTTPStatusClientTimeout = 429; +static NSInteger const kRCNFetchResponseHTTPStatusTooManyRequests = 429; +static NSInteger const kRCNFetchResponseHTTPStatusCodeBadGateway = 502; +static NSInteger const kRCNFetchResponseHTTPStatusCodeServiceUnavailable = 503; +static NSInteger const kRCNFetchResponseHTTPStatusCodeGatewayTimeout = 504; + +/// Invalidation message field names. +static NSString *const kTemplateVersionNumberKey = @"latestTemplateVersionNumber"; +static NSString *const kIsFeatureDisabled = @"featureDisabled"; + +static NSTimeInterval gTimeoutSeconds = 330; +static NSInteger const gFetchAttempts = 3; + +// Retry parameters +static NSInteger const gMaxRetries = 7; + +@interface FIRConfigUpdateListenerRegistration () +@property(strong, atomic, nonnull) RCNConfigUpdateCompletion completionHandler; +@end + +@implementation FIRConfigUpdateListenerRegistration { + RCNConfigRealtime *_realtimeClient; +} + +- (instancetype)initWithClient:(RCNConfigRealtime *)realtimeClient + completionHandler:(RCNConfigUpdateCompletion)completionHandler { + self = [super init]; + if (self) { + _realtimeClient = realtimeClient; + _completionHandler = completionHandler; + } + return self; +} + +- (void)remove { + [self->_realtimeClient removeConfigUpdateListener:_completionHandler]; +} + +@end + +@interface RCNConfigRealtime () + +@property(strong, atomic, nonnull) NSMutableSet *listeners; +@property(strong, atomic, nonnull) dispatch_queue_t realtimeLockQueue; +@property(strong, atomic, nonnull) NSNotificationCenter *notificationCenter; + +@property(strong, atomic) NSURLSession *session; +@property(strong, atomic) NSURLSessionDataTask *dataTask; +@property(strong, atomic) NSMutableURLRequest *request; + +@end + +@implementation RCNConfigRealtime { + RCNConfigFetch *_configFetch; + RCNConfigSettings *_settings; + FIROptions *_options; + NSString *_namespace; + NSInteger _remainingRetryCount; + bool _isRequestInProgress; + bool _isInBackground; + bool _isRealtimeDisabled; +} + +- (instancetype)init:(RCNConfigFetch *)configFetch + settings:(RCNConfigSettings *)settings + namespace:(NSString *)namespace + options:(FIROptions *)options { + self = [super init]; + if (self) { + _listeners = [[NSMutableSet alloc] init]; + _realtimeLockQueue = [RCNConfigRealtime realtimeRemoteConfigSerialQueue]; + _notificationCenter = [NSNotificationCenter defaultCenter]; + + _configFetch = configFetch; + _settings = settings; + _options = options; + _namespace = namespace; + + _remainingRetryCount = MAX(gMaxRetries - [_settings realtimeRetryCount], 1); + _isRequestInProgress = false; + _isRealtimeDisabled = false; + _isInBackground = false; + + [self setUpHttpRequest]; + [self setUpHttpSession]; + [self backgroundChangeListener]; + } + + return self; +} + +/// Singleton instance of serial queue for queuing all incoming RC calls. ++ (dispatch_queue_t)realtimeRemoteConfigSerialQueue { + static dispatch_once_t onceToken; + static dispatch_queue_t realtimeRemoteConfigQueue; + dispatch_once(&onceToken, ^{ + realtimeRemoteConfigQueue = + dispatch_queue_create(RCNRemoteConfigQueueLabel, DISPATCH_QUEUE_SERIAL); + }); + return realtimeRemoteConfigQueue; +} + +- (void)propogateErrors:(NSError *)error { + __weak RCNConfigRealtime *weakSelf = self; + dispatch_async(_realtimeLockQueue, ^{ + __strong RCNConfigRealtime *strongSelf = weakSelf; + for (RCNConfigUpdateCompletion listener in strongSelf->_listeners) { + listener(nil, error); + } + }); +} + +#pragma mark - Test Only Helpers + +// TESTING ONLY +- (void)triggerListenerForTesting:(void (^_Nonnull)(FIRRemoteConfigUpdate *configUpdate, + NSError *_Nullable error))listener { + listener([[FIRRemoteConfigUpdate alloc] init], nil); +} + +#pragma mark - Http Helpers + +- (NSString *)constructServerURL { + NSString *serverURLStr = [[NSString alloc] initWithString:kServerURLDomain]; + serverURLStr = [serverURLStr stringByAppendingString:kServerURLVersion]; + serverURLStr = [serverURLStr stringByAppendingString:kServerURLProjects]; + serverURLStr = [serverURLStr stringByAppendingString:_options.GCMSenderID]; + serverURLStr = [serverURLStr stringByAppendingString:kServerURLNamespaces]; + + /// Get the namespace from the fully qualified namespace string of "namespace:FIRAppName". + NSString *namespace = [_namespace substringToIndex:[_namespace rangeOfString:@":"].location]; + serverURLStr = [serverURLStr stringByAppendingString:namespace]; + serverURLStr = [serverURLStr stringByAppendingString:kServerURLQuery]; + if (_options.APIKey) { + serverURLStr = [serverURLStr stringByAppendingString:kServerURLKey]; + serverURLStr = [serverURLStr stringByAppendingString:_options.APIKey]; + } else { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000071", + @"Missing `APIKey` from `FirebaseOptions`, please ensure the configured " + @"`FirebaseApp` is configured with `FirebaseOptions` that contains an `APIKey`."); + } + + return serverURLStr; +} + +- (NSString *)FIRAppNameFromFullyQualifiedNamespace { + return [[_namespace componentsSeparatedByString:@":"] lastObject]; +} + +- (void)reportCompletionOnHandler:(FIRRemoteConfigFetchCompletion)completionHandler + withStatus:(FIRRemoteConfigFetchStatus)status + withError:(NSError *)error { + if (completionHandler) { + dispatch_async(_realtimeLockQueue, ^{ + completionHandler(status, error); + }); + } +} + +/// Refresh installation ID token before fetching config. installation ID is now mandatory for fetch +/// requests to work.(b/14751422). +- (void)refreshInstallationsTokenWithCompletionHandler: + (FIRRemoteConfigFetchCompletion)completionHandler { + FIRInstallations *installations = [FIRInstallations + installationsWithApp:[FIRApp appNamed:[self FIRAppNameFromFullyQualifiedNamespace]]]; + if (!installations || !_options.GCMSenderID) { + NSString *errorDescription = @"Failed to get GCMSenderID"; + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000074", @"%@", + [NSString stringWithFormat:@"%@", errorDescription]); + return [self + reportCompletionOnHandler:completionHandler + withStatus:FIRRemoteConfigFetchStatusFailure + withError:[NSError errorWithDomain:FIRRemoteConfigErrorDomain + code:FIRRemoteConfigErrorInternalError + userInfo:@{ + NSLocalizedDescriptionKey : errorDescription + }]]; + } + + __weak RCNConfigRealtime *weakSelf = self; + FIRInstallationsTokenHandler installationsTokenHandler = ^( + FIRInstallationsAuthTokenResult *tokenResult, NSError *error) { + RCNConfigRealtime *strongSelf = weakSelf; + if (strongSelf == nil) { + return; + } + + if (!tokenResult || !tokenResult.authToken || error) { + NSString *errorDescription = + [NSString stringWithFormat:@"Failed to get installations token. Error : %@.", error]; + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000073", @"%@", + [NSString stringWithFormat:@"%@", errorDescription]); + return [strongSelf + reportCompletionOnHandler:completionHandler + withStatus:FIRRemoteConfigFetchStatusFailure + withError:[NSError errorWithDomain:FIRRemoteConfigErrorDomain + code:FIRRemoteConfigErrorInternalError + userInfo:@{ + NSLocalizedDescriptionKey : errorDescription + }]]; + } + + /// We have a valid token. Get the backing installationID. + [installations installationIDWithCompletion:^(NSString *_Nullable identifier, + NSError *_Nullable error) { + RCNConfigRealtime *strongSelf = weakSelf; + if (strongSelf == nil) { + return; + } + + // Dispatch to the RC serial queue to update settings on the queue. + dispatch_async(strongSelf->_realtimeLockQueue, ^{ + RCNConfigRealtime *strongSelfQueue = weakSelf; + if (strongSelfQueue == nil) { + return; + } + + /// Update config settings with the IID and token. + strongSelfQueue->_settings.configInstallationsToken = tokenResult.authToken; + strongSelfQueue->_settings.configInstallationsIdentifier = identifier; + + if (!identifier || error) { + NSString *errorDescription = + [NSString stringWithFormat:@"Error getting iid : %@.", error]; + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000055", @"%@", + [NSString stringWithFormat:@"%@", errorDescription]); + strongSelfQueue->_settings.isFetchInProgress = NO; + return [strongSelfQueue + reportCompletionOnHandler:completionHandler + withStatus:FIRRemoteConfigFetchStatusFailure + withError:[NSError + errorWithDomain:FIRRemoteConfigErrorDomain + code:FIRRemoteConfigErrorInternalError + userInfo:@{ + NSLocalizedDescriptionKey : errorDescription + }]]; + } + + FIRLogInfo(kFIRLoggerRemoteConfig, @"I-RCN000022", @"Success to get iid : %@.", + strongSelfQueue->_settings.configInstallationsIdentifier); + }); + }]; + }; + + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000039", @"Starting requesting token."); + [installations authTokenWithCompletion:installationsTokenHandler]; +} + +- (NSData *)createRequestBody { + [self refreshInstallationsTokenWithCompletionHandler:^(FIRRemoteConfigFetchStatus status, + NSError *_Nullable error) { + if (status != FIRRemoteConfigFetchStatusSuccess) { + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000013", @"Installation token retrival failed."); + } + }]; + + [_request setValue:_settings.configInstallationsToken + forHTTPHeaderField:kInstallationsAuthTokenHeaderName]; + if (_settings.lastETag) { + [_request setValue:_settings.lastETag forHTTPHeaderField:kIfNoneMatchETagHeaderName]; + } + + NSString *namespace = [_namespace substringToIndex:[_namespace rangeOfString:@":"].location]; + NSString *postBody = [NSString + stringWithFormat:@"{project:'%@', namespace:'%@', lastKnownVersionNumber:'%@', appId:'%@', " + @"sdkVersion:'%@', appInstanceId:'%@'}", + [self->_options GCMSenderID], namespace, _configFetch.templateVersionNumber, + _options.googleAppID, FIRRemoteConfigPodVersion(), + _settings.configInstallationsIdentifier]; + NSData *postData = [postBody dataUsingEncoding:NSUTF8StringEncoding]; + NSError *compressionError; + return [NSData gul_dataByGzippingData:postData error:&compressionError]; +} + +/// Creates request. +- (void)setUpHttpRequest { + NSString *address = [self constructServerURL]; + _request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:address] + cachePolicy:NSURLRequestReloadIgnoringLocalCacheData + timeoutInterval:gTimeoutSeconds]; + [_request setHTTPMethod:kHTTPMethodPost]; + [_request setValue:@"application/json" forHTTPHeaderField:kContentTypeHeaderName]; + [_request setValue:@"application/json" forHTTPHeaderField:kAcceptEncodingHeaderName]; + [_request setValue:@"gzip" forHTTPHeaderField:kContentEncodingHeaderName]; + [_request setValue:@"true" forHTTPHeaderField:@"X-Google-GFE-Can-Retry"]; + [_request setValue:[_options APIKey] forHTTPHeaderField:@"X-Goog-Api-Key"]; + [_request setValue:[[NSBundle mainBundle] bundleIdentifier] + forHTTPHeaderField:kiOSBundleIdentifierHeaderName]; +} + +/// Makes call to create session. +- (void)setUpHttpSession { + NSURLSessionConfiguration *sessionConfig = + [[NSURLSessionConfiguration defaultSessionConfiguration] copy]; + [sessionConfig setTimeoutIntervalForResource:gTimeoutSeconds]; + [sessionConfig setTimeoutIntervalForRequest:gTimeoutSeconds]; + _session = [NSURLSession sessionWithConfiguration:sessionConfig + delegate:self + delegateQueue:[NSOperationQueue mainQueue]]; +} + +#pragma mark - Retry Helpers + +// Retry mechanism for HTTP connections +- (void)retryHTTPConnection { + __weak RCNConfigRealtime *weakSelf = self; + dispatch_async(_realtimeLockQueue, ^{ + __strong RCNConfigRealtime *strongSelf = weakSelf; + if (strongSelf->_isInBackground) { + return; + } + + bool noRunningConnection = + strongSelf->_dataTask == nil || strongSelf->_dataTask.state != NSURLSessionTaskStateRunning; + bool canMakeConnection = noRunningConnection && [strongSelf->_listeners count] > 0 && + !strongSelf->_isRealtimeDisabled; + if (canMakeConnection && strongSelf->_remainingRetryCount > 0) { + NSTimeInterval backOffInterval = self->_settings.getRealtimeBackoffInterval; + + strongSelf->_remainingRetryCount--; + [strongSelf->_settings setRealtimeRetryCount:[strongSelf->_settings realtimeRetryCount] + 1]; + dispatch_time_t executionDelay = + dispatch_time(DISPATCH_TIME_NOW, (backOffInterval * NSEC_PER_SEC)); + dispatch_after(executionDelay, strongSelf->_realtimeLockQueue, ^{ + [strongSelf beginRealtimeStream]; + }); + } else { + NSError *error = [NSError + errorWithDomain:FIRRemoteConfigUpdateErrorDomain + code:FIRRemoteConfigUpdateErrorStreamError + userInfo:@{ + NSLocalizedDescriptionKey : + @"Unable to connect to the server. Check your connection and try again." + }]; + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000014", @"Cannot establish connection. Error: %@", + error); + [self propogateErrors:error]; + } + }); +} + +- (void)backgroundChangeListener { + [_notificationCenter addObserver:self + selector:@selector(isInForeground) + name:@"UIApplicationWillEnterForegroundNotification" + object:nil]; + + [_notificationCenter addObserver:self + selector:@selector(isInBackground) + name:@"UIApplicationDidEnterBackgroundNotification" + object:nil]; +} + +- (void)isInForeground { + __weak RCNConfigRealtime *weakSelf = self; + dispatch_async(_realtimeLockQueue, ^{ + __strong RCNConfigRealtime *strongSelf = weakSelf; + strongSelf->_isInBackground = false; + [strongSelf beginRealtimeStream]; + }); +} + +- (void)isInBackground { + __weak RCNConfigRealtime *weakSelf = self; + dispatch_async(_realtimeLockQueue, ^{ + __strong RCNConfigRealtime *strongSelf = weakSelf; + [strongSelf pauseRealtimeStream]; + strongSelf->_isInBackground = true; + }); +} + +#pragma mark - Autofetch Helpers + +- (void)fetchLatestConfig:(NSInteger)remainingAttempts targetVersion:(NSInteger)targetVersion { + __weak RCNConfigRealtime *weakSelf = self; + dispatch_async(_realtimeLockQueue, ^{ + __strong RCNConfigRealtime *strongSelf = weakSelf; + NSInteger attempts = remainingAttempts - 1; + + [strongSelf->_configFetch + realtimeFetchConfigWithNoExpirationDuration:gFetchAttempts - attempts + completionHandler:^(FIRRemoteConfigFetchStatus status, + FIRRemoteConfigUpdate *update, + NSError *error) { + if (error != nil) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000010", + @"Failed to retrive config due to fetch error. " + @"Error: %@", + error); + return [self propogateErrors:error]; + } + if (status == FIRRemoteConfigFetchStatusSuccess) { + if ([strongSelf->_configFetch.templateVersionNumber + integerValue] >= targetVersion) { + // only notify listeners if there is a change + if ([update updatedKeys].count > 0) { + for (RCNConfigUpdateCompletion listener in strongSelf + ->_listeners) { + listener(update, nil); + } + } + } else { + FIRLogDebug( + kFIRLoggerRemoteConfig, @"I-RCN000016", + @"Fetched config's template version is outdated, " + @"re-fetching"); + [strongSelf autoFetch:attempts targetVersion:targetVersion]; + } + } else { + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000016", + @"Fetched config's template version is " + @"outdated, re-fetching"); + [strongSelf autoFetch:attempts targetVersion:targetVersion]; + } + }]; + }); +} + +- (void)scheduleFetch:(NSInteger)remainingAttempts targetVersion:(NSInteger)targetVersion { + /// Needs fetch to occur between 0 - 3 seconds. Randomize to not cause DDoS alerts in backend + dispatch_time_t executionDelay = + dispatch_time(DISPATCH_TIME_NOW, arc4random_uniform(4) * NSEC_PER_SEC); + dispatch_after(executionDelay, _realtimeLockQueue, ^{ + [self fetchLatestConfig:remainingAttempts targetVersion:targetVersion]; + }); +} + +/// Perform fetch and handle developers callbacks +- (void)autoFetch:(NSInteger)remainingAttempts targetVersion:(NSInteger)targetVersion { + __weak RCNConfigRealtime *weakSelf = self; + dispatch_async(_realtimeLockQueue, ^{ + __strong RCNConfigRealtime *strongSelf = weakSelf; + if (remainingAttempts == 0) { + NSError *error = [NSError errorWithDomain:FIRRemoteConfigUpdateErrorDomain + code:FIRRemoteConfigUpdateErrorNotFetched + userInfo:@{ + NSLocalizedDescriptionKey : + @"Unable to fetch the latest version of the template." + }]; + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000011", + @"Ran out of fetch attempts, cannot find target config version."); + [self propogateErrors:error]; + return; + } + + [strongSelf scheduleFetch:remainingAttempts targetVersion:targetVersion]; + }); +} + +#pragma mark - NSURLSession Delegates + +- (void)evaluateStreamResponse:(NSDictionary *)response error:(NSError *)dataError { + NSInteger updateTemplateVersion = 1; + if (dataError == nil) { + if ([response objectForKey:kTemplateVersionNumberKey]) { + updateTemplateVersion = [[response objectForKey:kTemplateVersionNumberKey] integerValue]; + } + if ([response objectForKey:kIsFeatureDisabled]) { + self->_isRealtimeDisabled = [response objectForKey:kIsFeatureDisabled]; + } + + if (self->_isRealtimeDisabled) { + [self pauseRealtimeStream]; + NSError *error = [NSError + errorWithDomain:FIRRemoteConfigUpdateErrorDomain + code:FIRRemoteConfigUpdateErrorUnavailable + userInfo:@{ + NSLocalizedDescriptionKey : + @"The server is temporarily unavailable. Try again in a few minutes." + }]; + [self propogateErrors:error]; + } else { + NSInteger clientTemplateVersion = [_configFetch.templateVersionNumber integerValue]; + if (updateTemplateVersion > clientTemplateVersion) { + [self autoFetch:gFetchAttempts targetVersion:updateTemplateVersion]; + } + } + } else { + NSError *error = + [NSError errorWithDomain:FIRRemoteConfigUpdateErrorDomain + code:FIRRemoteConfigUpdateErrorMessageInvalid + userInfo:@{NSLocalizedDescriptionKey : @"Unable to parse ConfigUpdate."}]; + [self propogateErrors:error]; + } +} + +/// Delegate to asynchronously handle every new notification that comes over the wire. Auto-fetches +/// and runs callback for each new notification +- (void)URLSession:(NSURLSession *)session + dataTask:(NSURLSessionDataTask *)dataTask + didReceiveData:(NSData *)data { + NSError *dataError; + NSString *strData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + + /// If response data contains the API enablement link, return the entire message to the user in + /// the form of a error. + if ([strData containsString:kServerForbiddenStatusCode]) { + NSError *error = [NSError errorWithDomain:FIRRemoteConfigUpdateErrorDomain + code:FIRRemoteConfigUpdateErrorStreamError + userInfo:@{NSLocalizedDescriptionKey : strData}]; + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000021", @"Cannot establish connection. %@", error); + [self propogateErrors:error]; + return; + } + + NSRange endRange = [strData rangeOfString:@"}"]; + NSRange beginRange = [strData rangeOfString:@"{"]; + if (beginRange.location != NSNotFound && endRange.location != NSNotFound) { + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000015", + @"Received config update message on stream."); + NSRange msgRange = + NSMakeRange(beginRange.location, endRange.location - beginRange.location + 1); + strData = [strData substringWithRange:msgRange]; + data = [strData dataUsingEncoding:NSUTF8StringEncoding]; + NSDictionary *response = [NSJSONSerialization JSONObjectWithData:data + options:NSJSONReadingMutableContainers + error:&dataError]; + + [self evaluateStreamResponse:response error:dataError]; + } +} + +/// Check if response code is retryable +- (bool)isStatusCodeRetryable:(NSInteger)statusCode { + return statusCode == kRCNFetchResponseHTTPStatusClientTimeout || + statusCode == kRCNFetchResponseHTTPStatusTooManyRequests || + statusCode == kRCNFetchResponseHTTPStatusCodeServiceUnavailable || + statusCode == kRCNFetchResponseHTTPStatusCodeBadGateway || + statusCode == kRCNFetchResponseHTTPStatusCodeGatewayTimeout; +} + +/// Delegate to handle initial reply from the server +- (void)URLSession:(NSURLSession *)session + dataTask:(NSURLSessionDataTask *)dataTask + didReceiveResponse:(NSURLResponse *)response + completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler { + _isRequestInProgress = false; + NSHTTPURLResponse *_httpURLResponse = (NSHTTPURLResponse *)response; + NSInteger statusCode = [_httpURLResponse statusCode]; + + if (statusCode == 403) { + completionHandler(NSURLSessionResponseAllow); + return; + } + + if (statusCode != kRCNFetchResponseHTTPStatusOk) { + [self->_settings updateRealtimeExponentialBackoffTime]; + [self pauseRealtimeStream]; + + if ([self isStatusCodeRetryable:statusCode]) { + [self retryHTTPConnection]; + } else { + NSError *error = [NSError + errorWithDomain:FIRRemoteConfigUpdateErrorDomain + code:FIRRemoteConfigUpdateErrorStreamError + userInfo:@{ + NSLocalizedDescriptionKey : + [NSString stringWithFormat:@"Unable to connect to the server. Try again in " + @"a few minutes. Http Status code: %@", + [@(statusCode) stringValue]] + }]; + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000021", @"Cannot establish connection. Error: %@", + error); + } + } else { + /// on success reset retry parameters + _remainingRetryCount = gMaxRetries; + [self->_settings setRealtimeRetryCount:0]; + } + + completionHandler(NSURLSessionResponseAllow); +} + +/// Delegate to handle data task completion +- (void)URLSession:(NSURLSession *)session + task:(NSURLSessionTask *)task + didCompleteWithError:(NSError *)error { + _isRequestInProgress = false; + if (error != nil && [error code] != NSURLErrorCancelled) { + [self->_settings updateRealtimeExponentialBackoffTime]; + } + [self pauseRealtimeStream]; + [self retryHTTPConnection]; +} + +/// Delegate to handle session invalidation +- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(NSError *)error { + if (!_isRequestInProgress) { + if (error != nil) { + [self->_settings updateRealtimeExponentialBackoffTime]; + } + [self pauseRealtimeStream]; + [self retryHTTPConnection]; + } +} + +#pragma mark - Top level methods + +- (void)beginRealtimeStream { + __weak RCNConfigRealtime *weakSelf = self; + dispatch_async(_realtimeLockQueue, ^{ + __strong RCNConfigRealtime *strongSelf = weakSelf; + bool noRunningConnection = + strongSelf->_dataTask == nil || strongSelf->_dataTask.state != NSURLSessionTaskStateRunning; + bool canMakeConnection = noRunningConnection && [strongSelf->_listeners count] > 0 && + !strongSelf->_isInBackground && !strongSelf->_isRealtimeDisabled; + + if (self->_settings.getRealtimeBackoffInterval > 0) { + [self retryHTTPConnection]; + return; + } + + if (canMakeConnection) { + strongSelf->_isRequestInProgress = true; + NSData *compressedContent = [strongSelf createRequestBody]; + [strongSelf->_request setHTTPBody:compressedContent]; + strongSelf->_dataTask = [strongSelf->_session dataTaskWithRequest:strongSelf->_request]; + [strongSelf->_dataTask resume]; + } + }); +} + +- (void)pauseRealtimeStream { + __weak RCNConfigRealtime *weakSelf = self; + dispatch_async(_realtimeLockQueue, ^{ + __strong RCNConfigRealtime *strongSelf = weakSelf; + if (strongSelf->_dataTask != nil) { + [strongSelf->_dataTask cancel]; + strongSelf->_dataTask = nil; + } + }); +} + +- (FIRConfigUpdateListenerRegistration *)addConfigUpdateListener: + (void (^_Nonnull)(FIRRemoteConfigUpdate *configUpdate, NSError *_Nullable error))listener { + if (listener == nil) { + return nil; + } + __block id listenerCopy = listener; + + __weak RCNConfigRealtime *weakSelf = self; + dispatch_async(_realtimeLockQueue, ^{ + __strong RCNConfigRealtime *strongSelf = weakSelf; + [strongSelf->_listeners addObject:listenerCopy]; + [strongSelf beginRealtimeStream]; + }); + + return [[FIRConfigUpdateListenerRegistration alloc] initWithClient:self + completionHandler:listenerCopy]; +} + +- (void)removeConfigUpdateListener:(void (^_Nonnull)(FIRRemoteConfigUpdate *configUpdate, + NSError *_Nullable error))listener { + __weak RCNConfigRealtime *weakSelf = self; + dispatch_async(_realtimeLockQueue, ^{ + __strong RCNConfigRealtime *strongSelf = weakSelf; + [strongSelf->_listeners removeObject:listener]; + if (strongSelf->_listeners.count == 0) { + [strongSelf pauseRealtimeStream]; + } + }); +} + +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigSettings.m b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigSettings.m new file mode 100644 index 0000000..e85a63f --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigSettings.m @@ -0,0 +1,537 @@ +/* + * 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 "FirebaseRemoteConfig/Sources/Private/RCNConfigSettings.h" + +#import "FirebaseRemoteConfig/Sources/RCNConfigConstants.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigDBManager.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h" +#import "FirebaseRemoteConfig/Sources/RCNDevice.h" +#import "FirebaseRemoteConfig/Sources/RCNUserDefaultsManager.h" + +#import +#import "FirebaseCore/Extension/FirebaseCoreInternal.h" + +static NSString *const kRCNGroupPrefix = @"frc.group."; +static NSString *const kRCNUserDefaultsKeyNamelastETag = @"lastETag"; +static NSString *const kRCNUserDefaultsKeyNameLastSuccessfulFetchTime = @"lastSuccessfulFetchTime"; +static NSString *const kRCNAnalyticsFirstOpenTimePropertyName = @"_fot"; +static const int kRCNExponentialBackoffMinimumInterval = 60 * 2; // 2 mins. +static const int kRCNExponentialBackoffMaximumInterval = 60 * 60 * 4; // 4 hours. + +@interface RCNConfigSettings () { + /// A list of successful fetch timestamps in seconds. + NSMutableArray *_successFetchTimes; + /// A list of failed fetch timestamps in seconds. + NSMutableArray *_failureFetchTimes; + /// Device conditions since last successful fetch from the backend. Device conditions including + /// app + /// version, iOS version, device localte, language, GMP project ID and Game project ID. Used for + /// determing whether to throttle. + NSMutableDictionary *_deviceContext; + /// Custom variables (aka App context digest). This is the pending custom variables request before + /// fetching. + NSMutableDictionary *_customVariables; + /// Cached internal metadata from internal metadata table. It contains customized information such + /// as HTTP connection timeout, HTTP read timeout, success/failure throttling rate and time + /// interval. Client has the default value of each parameters, they are only saved in + /// internalMetadata if they have been customize by developers. + NSMutableDictionary *_internalMetadata; + /// Last fetch status. + FIRRemoteConfigFetchStatus _lastFetchStatus; + /// Last fetch Error. + FIRRemoteConfigError _lastFetchError; + /// The time of last apply timestamp. + NSTimeInterval _lastApplyTimeInterval; + /// The time of last setDefaults timestamp. + NSTimeInterval _lastSetDefaultsTimeInterval; + /// The database manager. + RCNConfigDBManager *_DBManager; + // The namespace for this instance. + NSString *_FIRNamespace; + // The Google App ID of the configured FIRApp. + NSString *_googleAppID; + /// The user defaults manager scoped to this RC instance of FIRApp and namespace. + RCNUserDefaultsManager *_userDefaultsManager; + /// The timestamp of last eTag update. + NSTimeInterval _lastETagUpdateTime; +} +@end + +@implementation RCNConfigSettings + +- (instancetype)initWithDatabaseManager:(RCNConfigDBManager *)manager + namespace:(NSString *)FIRNamespace + firebaseAppName:(NSString *)appName + googleAppID:(NSString *)googleAppID { + self = [super init]; + if (self) { + _FIRNamespace = FIRNamespace; + _googleAppID = googleAppID; + _bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier]; + if (!_bundleIdentifier) { + FIRLogNotice(kFIRLoggerRemoteConfig, @"I-RCN000038", + @"Main bundle identifier is missing. Remote Config might not work properly."); + _bundleIdentifier = @""; + } + _minimumFetchInterval = RCNDefaultMinimumFetchInterval; + _deviceContext = [[NSMutableDictionary alloc] init]; + _customVariables = [[NSMutableDictionary alloc] init]; + _successFetchTimes = [[NSMutableArray alloc] init]; + _failureFetchTimes = [[NSMutableArray alloc] init]; + _DBManager = manager; + + _internalMetadata = [[_DBManager loadInternalMetadataTable] mutableCopy]; + if (!_internalMetadata) { + _internalMetadata = [[NSMutableDictionary alloc] init]; + } + _userDefaultsManager = [[RCNUserDefaultsManager alloc] initWithAppName:appName + bundleID:_bundleIdentifier + namespace:_FIRNamespace]; + + // Check if the config database is new. If so, clear the configs saved in userDefaults. + if ([_DBManager isNewDatabase]) { + FIRLogNotice(kFIRLoggerRemoteConfig, @"I-RCN000072", + @"New config database created. Resetting user defaults."); + [_userDefaultsManager resetUserDefaults]; + } + + _isFetchInProgress = NO; + _lastFetchedTemplateVersion = [_userDefaultsManager lastFetchedTemplateVersion]; + _lastActiveTemplateVersion = [_userDefaultsManager lastActiveTemplateVersion]; + _realtimeExponentialBackoffRetryInterval = + [_userDefaultsManager currentRealtimeThrottlingRetryIntervalSeconds]; + _realtimeExponentialBackoffThrottleEndTime = [_userDefaultsManager realtimeThrottleEndTime]; + _realtimeRetryCount = [_userDefaultsManager realtimeRetryCount]; + } + return self; +} + +#pragma mark - read from / update userDefaults +- (NSString *)lastETag { + return [_userDefaultsManager lastETag]; +} + +- (void)setLastETag:(NSString *)lastETag { + [self setLastETagUpdateTime:[[NSDate date] timeIntervalSince1970]]; + [_userDefaultsManager setLastETag:lastETag]; +} + +- (void)setLastETagUpdateTime:(NSTimeInterval)lastETagUpdateTime { + [_userDefaultsManager setLastETagUpdateTime:lastETagUpdateTime]; +} + +- (NSTimeInterval)lastFetchTimeInterval { + return _userDefaultsManager.lastFetchTime; +} + +- (NSTimeInterval)lastETagUpdateTime { + return _userDefaultsManager.lastETagUpdateTime; +} + +// TODO: Update logic for app extensions as required. +- (void)updateLastFetchTimeInterval:(NSTimeInterval)lastFetchTimeInterval { + _userDefaultsManager.lastFetchTime = lastFetchTimeInterval; +} + +#pragma mark - load from DB +- (NSDictionary *)loadConfigFromMetadataTable { + NSDictionary *metadata = [[_DBManager loadMetadataWithBundleIdentifier:_bundleIdentifier + namespace:_FIRNamespace] copy]; + if (metadata) { + // TODO: Remove (all metadata in general) once ready to + // migrate to user defaults completely. + if (metadata[RCNKeyDeviceContext]) { + self->_deviceContext = [metadata[RCNKeyDeviceContext] mutableCopy]; + } + if (metadata[RCNKeyAppContext]) { + self->_customVariables = [metadata[RCNKeyAppContext] mutableCopy]; + } + if (metadata[RCNKeySuccessFetchTime]) { + self->_successFetchTimes = [metadata[RCNKeySuccessFetchTime] mutableCopy]; + } + if (metadata[RCNKeyFailureFetchTime]) { + self->_failureFetchTimes = [metadata[RCNKeyFailureFetchTime] mutableCopy]; + } + if (metadata[RCNKeyLastFetchStatus]) { + self->_lastFetchStatus = + (FIRRemoteConfigFetchStatus)[metadata[RCNKeyLastFetchStatus] intValue]; + } + if (metadata[RCNKeyLastFetchError]) { + self->_lastFetchError = (FIRRemoteConfigError)[metadata[RCNKeyLastFetchError] intValue]; + } + if (metadata[RCNKeyLastApplyTime]) { + self->_lastApplyTimeInterval = [metadata[RCNKeyLastApplyTime] doubleValue]; + } + if (metadata[RCNKeyLastFetchStatus]) { + self->_lastSetDefaultsTimeInterval = [metadata[RCNKeyLastSetDefaultsTime] doubleValue]; + } + } + return metadata; +} + +#pragma mark - update DB/cached + +// Update internal metadata content to cache and DB. +- (void)updateInternalContentWithResponse:(NSDictionary *)response { + // Remove all the keys with current pakcage name. + [_DBManager deleteRecordWithBundleIdentifier:_bundleIdentifier + namespace:_FIRNamespace + isInternalDB:YES]; + + for (NSString *key in _internalMetadata.allKeys) { + if ([key hasPrefix:_bundleIdentifier]) { + [_internalMetadata removeObjectForKey:key]; + } + } + + for (NSString *entry in response) { + NSData *val = [response[entry] dataUsingEncoding:NSUTF8StringEncoding]; + NSArray *values = @[ entry, val ]; + _internalMetadata[entry] = response[entry]; + [self updateInternalMetadataTableWithValues:values]; + } +} + +- (void)updateInternalMetadataTableWithValues:(NSArray *)values { + [_DBManager insertInternalMetadataTableWithValues:values completionHandler:nil]; +} + +/// If the last fetch was not successful, update the (exponential backoff) period that we wait until +/// fetching again. Any subsequent fetch requests will be checked and allowed only if past this +/// throttle end time. +- (void)updateExponentialBackoffTime { + // If not in exponential backoff mode, reset the retry interval. + if (_lastFetchStatus == FIRRemoteConfigFetchStatusSuccess) { + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000057", + @"Throttling: Entering exponential backoff mode."); + _exponentialBackoffRetryInterval = kRCNExponentialBackoffMinimumInterval; + } else { + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000057", + @"Throttling: Updating throttling interval."); + // Double the retry interval until we hit the truncated exponential backoff. More info here: + // https://cloud.google.com/storage/docs/exponential-backoff + _exponentialBackoffRetryInterval = + ((_exponentialBackoffRetryInterval * 2) < kRCNExponentialBackoffMaximumInterval) + ? _exponentialBackoffRetryInterval * 2 + : _exponentialBackoffRetryInterval; + } + + // Randomize the next retry interval. + int randomPlusMinusInterval = ((arc4random() % 2) == 0) ? -1 : 1; + NSTimeInterval randomizedRetryInterval = + _exponentialBackoffRetryInterval + + (0.5 * _exponentialBackoffRetryInterval * randomPlusMinusInterval); + _exponentialBackoffThrottleEndTime = + [[NSDate date] timeIntervalSince1970] + randomizedRetryInterval; +} + +/// If the last Realtime stream attempt was not successful, update the (exponential backoff) period +/// that we wait until trying again. Any subsequent Realtime requests will be checked and allowed +/// only if past this throttle end time. +- (void)updateRealtimeExponentialBackoffTime { + // If there was only one stream attempt before, reset the retry interval. + if (_realtimeRetryCount == 0) { + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000058", + @"Throttling: Entering exponential Realtime backoff mode."); + _realtimeExponentialBackoffRetryInterval = kRCNExponentialBackoffMinimumInterval; + } else { + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000058", + @"Throttling: Updating Realtime throttling interval."); + // Double the retry interval until we hit the truncated exponential backoff. More info here: + // https://cloud.google.com/storage/docs/exponential-backoff + _realtimeExponentialBackoffRetryInterval = + ((_realtimeExponentialBackoffRetryInterval * 2) < kRCNExponentialBackoffMaximumInterval) + ? _realtimeExponentialBackoffRetryInterval * 2 + : _realtimeExponentialBackoffRetryInterval; + } + + // Randomize the next retry interval. + int randomPlusMinusInterval = ((arc4random() % 2) == 0) ? -1 : 1; + NSTimeInterval randomizedRetryInterval = + _realtimeExponentialBackoffRetryInterval + + (0.5 * _realtimeExponentialBackoffRetryInterval * randomPlusMinusInterval); + _realtimeExponentialBackoffThrottleEndTime = + [[NSDate date] timeIntervalSince1970] + randomizedRetryInterval; + + [_userDefaultsManager setRealtimeThrottleEndTime:_realtimeExponentialBackoffThrottleEndTime]; + [_userDefaultsManager + setCurrentRealtimeThrottlingRetryIntervalSeconds:_realtimeExponentialBackoffRetryInterval]; +} + +- (void)setRealtimeRetryCount:(int)realtimeRetryCount { + _realtimeRetryCount = realtimeRetryCount; + [_userDefaultsManager setRealtimeRetryCount:_realtimeRetryCount]; +} + +- (NSTimeInterval)getRealtimeBackoffInterval { + NSTimeInterval now = [[NSDate date] timeIntervalSince1970]; + return _realtimeExponentialBackoffThrottleEndTime - now; +} + +- (void)updateMetadataWithFetchSuccessStatus:(BOOL)fetchSuccess + templateVersion:(NSString *)templateVersion { + FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000056", @"Updating metadata with fetch result."); + [self updateFetchTimeWithSuccessFetch:fetchSuccess]; + _lastFetchStatus = + fetchSuccess ? FIRRemoteConfigFetchStatusSuccess : FIRRemoteConfigFetchStatusFailure; + _lastFetchError = fetchSuccess ? FIRRemoteConfigErrorUnknown : FIRRemoteConfigErrorInternalError; + if (fetchSuccess) { + [self updateLastFetchTimeInterval:[[NSDate date] timeIntervalSince1970]]; + // Note: We expect the googleAppID to always be available. + _deviceContext = FIRRemoteConfigDeviceContextWithProjectIdentifier(_googleAppID); + _lastFetchedTemplateVersion = templateVersion; + [_userDefaultsManager setLastFetchedTemplateVersion:templateVersion]; + } + + [self updateMetadataTable]; +} + +- (void)updateFetchTimeWithSuccessFetch:(BOOL)isSuccessfulFetch { + NSTimeInterval epochTimeInterval = [[NSDate date] timeIntervalSince1970]; + if (isSuccessfulFetch) { + [_successFetchTimes addObject:@(epochTimeInterval)]; + } else { + [_failureFetchTimes addObject:@(epochTimeInterval)]; + } +} + +- (void)updateMetadataTable { + [_DBManager deleteRecordWithBundleIdentifier:_bundleIdentifier + namespace:_FIRNamespace + isInternalDB:NO]; + NSError *error; + // Objects to be serialized cannot be invalid. + if (!_bundleIdentifier) { + return; + } + if (![NSJSONSerialization isValidJSONObject:_customVariables]) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000028", + @"Invalid custom variables to be serialized."); + return; + } + if (![NSJSONSerialization isValidJSONObject:_deviceContext]) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000029", + @"Invalid device context to be serialized."); + return; + } + + if (![NSJSONSerialization isValidJSONObject:_successFetchTimes]) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000031", + @"Invalid success fetch times to be serialized."); + return; + } + if (![NSJSONSerialization isValidJSONObject:_failureFetchTimes]) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000032", + @"Invalid failure fetch times to be serialized."); + return; + } + NSData *serializedAppContext = [NSJSONSerialization dataWithJSONObject:_customVariables + options:NSJSONWritingPrettyPrinted + error:&error]; + NSData *serializedDeviceContext = + [NSJSONSerialization dataWithJSONObject:_deviceContext + options:NSJSONWritingPrettyPrinted + error:&error]; + // The digestPerNamespace is not used and only meant for backwards DB compatibility. + NSData *serializedDigestPerNamespace = + [NSJSONSerialization dataWithJSONObject:@{} options:NSJSONWritingPrettyPrinted error:&error]; + NSData *serializedSuccessTime = [NSJSONSerialization dataWithJSONObject:_successFetchTimes + options:NSJSONWritingPrettyPrinted + error:&error]; + NSData *serializedFailureTime = [NSJSONSerialization dataWithJSONObject:_failureFetchTimes + options:NSJSONWritingPrettyPrinted + error:&error]; + + if (!serializedDigestPerNamespace || !serializedDeviceContext || !serializedAppContext || + !serializedSuccessTime || !serializedFailureTime) { + return; + } + + NSDictionary *columnNameToValue = @{ + RCNKeyBundleIdentifier : _bundleIdentifier, + RCNKeyNamespace : _FIRNamespace, + RCNKeyFetchTime : @(self.lastFetchTimeInterval), + RCNKeyDigestPerNamespace : serializedDigestPerNamespace, + RCNKeyDeviceContext : serializedDeviceContext, + RCNKeyAppContext : serializedAppContext, + RCNKeySuccessFetchTime : serializedSuccessTime, + RCNKeyFailureFetchTime : serializedFailureTime, + RCNKeyLastFetchStatus : [NSString stringWithFormat:@"%ld", (long)_lastFetchStatus], + RCNKeyLastFetchError : [NSString stringWithFormat:@"%ld", (long)_lastFetchError], + RCNKeyLastApplyTime : @(_lastApplyTimeInterval), + RCNKeyLastSetDefaultsTime : @(_lastSetDefaultsTimeInterval) + }; + + [_DBManager insertMetadataTableWithValues:columnNameToValue completionHandler:nil]; +} + +- (void)updateLastActiveTemplateVersion { + _lastActiveTemplateVersion = _lastFetchedTemplateVersion; + [_userDefaultsManager setLastActiveTemplateVersion:_lastActiveTemplateVersion]; +} + +#pragma mark - fetch request + +/// Returns a fetch request with the latest device and config change. +/// Whenever user issues a fetch api call, collect the latest request. +- (NSString *)nextRequestWithUserProperties:(NSDictionary *)userProperties { + // Note: We only set user properties as mentioned in the new REST API Design doc + NSString *ret = [NSString stringWithFormat:@"{"]; + ret = [ret stringByAppendingString:[NSString stringWithFormat:@"app_instance_id:'%@'", + _configInstallationsIdentifier]]; + ret = [ret stringByAppendingString:[NSString stringWithFormat:@", app_instance_id_token:'%@'", + _configInstallationsToken]]; + ret = [ret stringByAppendingString:[NSString stringWithFormat:@", app_id:'%@'", _googleAppID]]; + + ret = [ret stringByAppendingString:[NSString stringWithFormat:@", country_code:'%@'", + FIRRemoteConfigDeviceCountry()]]; + ret = [ret stringByAppendingString:[NSString stringWithFormat:@", language_code:'%@'", + FIRRemoteConfigDeviceLocale()]]; + ret = [ret + stringByAppendingString:[NSString stringWithFormat:@", platform_version:'%@'", + [GULAppEnvironmentUtil systemVersion]]]; + ret = [ret stringByAppendingString:[NSString stringWithFormat:@", time_zone:'%@'", + FIRRemoteConfigTimezone()]]; + ret = [ret stringByAppendingString:[NSString stringWithFormat:@", package_name:'%@'", + _bundleIdentifier]]; + ret = [ret stringByAppendingString:[NSString stringWithFormat:@", app_version:'%@'", + FIRRemoteConfigAppVersion()]]; + ret = [ret stringByAppendingString:[NSString stringWithFormat:@", app_build:'%@'", + FIRRemoteConfigAppBuildVersion()]]; + ret = [ret stringByAppendingString:[NSString stringWithFormat:@", sdk_version:'%@'", + FIRRemoteConfigPodVersion()]]; + + if (userProperties && userProperties.count > 0) { + NSError *error; + + // Extract first open time from user properties and send as a separate field + NSNumber *firstOpenTime = userProperties[kRCNAnalyticsFirstOpenTimePropertyName]; + NSMutableDictionary *remainingUserProperties = [userProperties mutableCopy]; + if (firstOpenTime != nil) { + NSDate *date = [NSDate dateWithTimeIntervalSince1970:([firstOpenTime longValue] / 1000)]; + NSISO8601DateFormatter *formatter = [[NSISO8601DateFormatter alloc] init]; + NSString *firstOpenTimeISOString = [formatter stringFromDate:date]; + ret = [ret stringByAppendingString:[NSString stringWithFormat:@", first_open_time:'%@'", + firstOpenTimeISOString]]; + + [remainingUserProperties removeObjectForKey:kRCNAnalyticsFirstOpenTimePropertyName]; + } + if (remainingUserProperties.count > 0) { + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:remainingUserProperties + options:0 + error:&error]; + if (!error) { + ret = [ret + stringByAppendingString:[NSString + stringWithFormat:@", analytics_user_properties:%@", + [[NSString alloc] + initWithData:jsonData + encoding:NSUTF8StringEncoding]]]; + } + } + } + ret = [ret stringByAppendingString:@"}"]; + return ret; +} + +#pragma mark - getter/setter + +- (void)setLastFetchError:(FIRRemoteConfigError)lastFetchError { + if (_lastFetchError != lastFetchError) { + _lastFetchError = lastFetchError; + [_DBManager updateMetadataWithOption:RCNUpdateOptionFetchStatus + namespace:_FIRNamespace + values:@[ @(_lastFetchStatus), @(_lastFetchError) ] + completionHandler:nil]; + } +} + +- (NSArray *)successFetchTimes { + return [_successFetchTimes copy]; +} + +- (NSArray *)failureFetchTimes { + return [_failureFetchTimes copy]; +} + +- (NSDictionary *)customVariables { + return [_customVariables copy]; +} + +- (NSDictionary *)internalMetadata { + return [_internalMetadata copy]; +} + +- (NSDictionary *)deviceContext { + return [_deviceContext copy]; +} + +- (void)setCustomVariables:(NSDictionary *)customVariables { + _customVariables = [[NSMutableDictionary alloc] initWithDictionary:customVariables]; + [self updateMetadataTable]; +} + +- (void)setMinimumFetchInterval:(NSTimeInterval)minimumFetchInterval { + if (minimumFetchInterval < 0) { + _minimumFetchInterval = 0; + } else { + _minimumFetchInterval = minimumFetchInterval; + } +} + +- (void)setFetchTimeout:(NSTimeInterval)fetchTimeout { + if (fetchTimeout <= 0) { + _fetchTimeout = RCNHTTPDefaultConnectionTimeout; + } else { + _fetchTimeout = fetchTimeout; + } +} + +- (void)setLastApplyTimeInterval:(NSTimeInterval)lastApplyTimestamp { + _lastApplyTimeInterval = lastApplyTimestamp; + [_DBManager updateMetadataWithOption:RCNUpdateOptionApplyTime + namespace:_FIRNamespace + values:@[ @(lastApplyTimestamp) ] + completionHandler:nil]; +} + +- (void)setLastSetDefaultsTimeInterval:(NSTimeInterval)lastSetDefaultsTimestamp { + _lastSetDefaultsTimeInterval = lastSetDefaultsTimestamp; + [_DBManager updateMetadataWithOption:RCNUpdateOptionDefaultTime + namespace:_FIRNamespace + values:@[ @(lastSetDefaultsTimestamp) ] + completionHandler:nil]; +} + +#pragma mark Throttling + +- (BOOL)hasMinimumFetchIntervalElapsed:(NSTimeInterval)minimumFetchInterval { + if (self.lastFetchTimeInterval == 0) return YES; + + // Check if last config fetch is within minimum fetch interval in seconds. + NSTimeInterval diffInSeconds = [[NSDate date] timeIntervalSince1970] - self.lastFetchTimeInterval; + return diffInSeconds > minimumFetchInterval; +} + +- (BOOL)shouldThrottle { + NSTimeInterval now = [[NSDate date] timeIntervalSince1970]; + return ((self.lastFetchTimeInterval > 0) && + (_lastFetchStatus != FIRRemoteConfigFetchStatusSuccess) && + (_exponentialBackoffThrottleEndTime - now > 0)); +} + +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h new file mode 100644 index 0000000..5c9ef0c --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h @@ -0,0 +1,25 @@ +/* + * 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 "FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h" + +@interface FIRRemoteConfigValue () +@property(nonatomic, readwrite, assign) FIRRemoteConfigSource source; + +/// Designated initializer. +- (instancetype)initWithData:(NSData *)data + source:(FIRRemoteConfigSource)source NS_DESIGNATED_INITIALIZER; +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConstants3P.m b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConstants3P.m new file mode 100644 index 0000000..e64295b --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNConstants3P.m @@ -0,0 +1,21 @@ +/* + * 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 "FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h" + +/// Firebase Remote Config service default namespace. +/// TODO(doudounan): Change to use this namespace defined in RemoteConfigInterop. +NSString *const FIRNamespaceGoogleMobilePlatform = @"firebase"; diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNDevice.h b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNDevice.h new file mode 100644 index 0000000..15697e3 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNDevice.h @@ -0,0 +1,57 @@ +/* + * 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 + +typedef NS_ENUM(NSInteger, RCNDeviceModel) { + RCNDeviceModelOther, + RCNDeviceModelPhone, + RCNDeviceModelTablet, + RCNDeviceModelTV, + RCNDeviceModelGlass, + RCNDeviceModelCar, + RCNDeviceModelWearable, +}; + +/// CocoaPods SDK version +NSString *FIRRemoteConfigPodVersion(void); + +/// App version. +NSString *FIRRemoteConfigAppVersion(void); + +/// App build version +NSString *FIRRemoteConfigAppBuildVersion(void); + +/// Device country, in lowercase. +NSString *FIRRemoteConfigDeviceCountry(void); + +/// Device locale, in language_country format, e.g. en_US. +NSString *FIRRemoteConfigDeviceLocale(void); + +/// Device subtype. +RCNDeviceModel FIRRemoteConfigDeviceSubtype(void); + +/// Device timezone. +NSString *FIRRemoteConfigTimezone(void); + +/// Update device context to the given dictionary. +NSMutableDictionary *FIRRemoteConfigDeviceContextWithProjectIdentifier( + NSString *GMPProjectIdentifier); + +/// Check whether client has changed device context, including app version, +/// iOS version, device country etc. This is used to determine whether to throttle. +BOOL FIRRemoteConfigHasDeviceContextChanged(NSDictionary *deviceContext, + NSString *GMPProjectIdentifier); diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNDevice.m b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNDevice.m new file mode 100644 index 0000000..48cda11 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNDevice.m @@ -0,0 +1,241 @@ +/* + * 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 "FirebaseRemoteConfig/Sources/RCNDevice.h" + +#import + +#import +#import "FirebaseCore/Extension/FirebaseCoreInternal.h" +#import "FirebaseRemoteConfig/Sources/Private/RCNConfigSettings.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigConstants.h" + +#define STR(x) STR_EXPAND(x) +#define STR_EXPAND(x) #x + +static NSString *const RCNDeviceContextKeyVersion = @"app_version"; +static NSString *const RCNDeviceContextKeyBuild = @"app_build"; +static NSString *const RCNDeviceContextKeyOSVersion = @"os_version"; +static NSString *const RCNDeviceContextKeyDeviceLocale = @"device_locale"; +static NSString *const RCNDeviceContextKeyLocaleLanguage = @"locale_language"; +static NSString *const RCNDeviceContextKeyGMPProjectIdentifier = @"GMP_project_Identifier"; + +NSString *FIRRemoteConfigAppVersion(void) { + return [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"]; +} + +NSString *FIRRemoteConfigAppBuildVersion(void) { + return [[NSBundle mainBundle] infoDictionary][@"CFBundleVersion"]; +} + +NSString *FIRRemoteConfigPodVersion(void) { + return FIRFirebaseVersion(); +} + +RCNDeviceModel FIRRemoteConfigDeviceSubtype(void) { + NSString *model = [GULAppEnvironmentUtil deviceModel]; + if ([model hasPrefix:@"iPhone"]) { + return RCNDeviceModelPhone; + } + if ([model isEqualToString:@"iPad"]) { + return RCNDeviceModelTablet; + } + return RCNDeviceModelOther; +} + +NSString *FIRRemoteConfigDeviceCountry(void) { + return [[[NSLocale currentLocale] objectForKey:NSLocaleCountryCode] lowercaseString]; +} + +NSDictionary *FIRRemoteConfigFirebaseLocaleMap(void) { + return @{ + // Albanian + @"sq" : @[ @"sq_AL" ], + // Belarusian + @"be" : @[ @"be_BY" ], + // Bulgarian + @"bg" : @[ @"bg_BG" ], + // Catalan + @"ca" : @[ @"ca", @"ca_ES" ], + // Croatian + @"hr" : @[ @"hr", @"hr_HR" ], + // Czech + @"cs" : @[ @"cs", @"cs_CZ" ], + // Danish + @"da" : @[ @"da", @"da_DK" ], + // Estonian + @"et" : @[ @"et_EE" ], + // Finnish + @"fi" : @[ @"fi", @"fi_FI" ], + // Hebrew + @"he" : @[ @"he", @"iw_IL" ], + // Hindi + @"hi" : @[ @"hi_IN" ], + // Hungarian + @"hu" : @[ @"hu", @"hu_HU" ], + // Icelandic + @"is" : @[ @"is_IS" ], + // Indonesian + @"id" : @[ @"id", @"in_ID", @"id_ID" ], + // Irish + @"ga" : @[ @"ga_IE" ], + // Korean + @"ko" : @[ @"ko", @"ko_KR", @"ko-KR" ], + // Latvian + @"lv" : @[ @"lv_LV" ], + // Lithuanian + @"lt" : @[ @"lt_LT" ], + // Macedonian + @"mk" : @[ @"mk_MK" ], + // Malay + @"ms" : @[ @"ms_MY" ], + // Maltese + @"mt" : @[ @"mt_MT" ], + // Polish + @"pl" : @[ @"pl", @"pl_PL", @"pl-PL" ], + // Romanian + @"ro" : @[ @"ro", @"ro_RO" ], + // Russian + @"ru" : @[ @"ru_RU", @"ru", @"ru_BY", @"ru_KZ", @"ru-RU" ], + // Slovak + @"sk" : @[ @"sk", @"sk_SK" ], + // Slovenian + @"sl" : @[ @"sl_SI" ], + // Swedish + @"sv" : @[ @"sv", @"sv_SE", @"sv-SE" ], + // Turkish + @"tr" : @[ @"tr", @"tr-TR", @"tr_TR" ], + // Ukrainian + @"uk" : @[ @"uk", @"uk_UA" ], + // Vietnamese + @"vi" : @[ @"vi", @"vi_VN" ], + // The following are groups of locales or locales that sub-divide a + // language). + // Arabic + @"ar" : @[ + @"ar", @"ar_DZ", @"ar_BH", @"ar_EG", @"ar_IQ", @"ar_JO", @"ar_KW", + @"ar_LB", @"ar_LY", @"ar_MA", @"ar_OM", @"ar_QA", @"ar_SA", @"ar_SD", + @"ar_SY", @"ar_TN", @"ar_AE", @"ar_YE", @"ar_GB", @"ar-IQ", @"ar_US" + ], + // Simplified Chinese + @"zh_Hans" : @[ @"zh_CN", @"zh_SG", @"zh-Hans" ], + // Traditional Chinese + // Remove zh_HK until console added to the list. Otherwise client sends + // zh_HK and server/console falls back to zh. + // @"zh_Hant" : @[ @"zh_HK", @"zh_TW", @"zh-Hant", @"zh-HK", @"zh-TW" ], + @"zh_Hant" : @[ @"zh_TW", @"zh-Hant", @"zh-TW" ], + // Dutch + @"nl" : @[ @"nl", @"nl_BE", @"nl_NL", @"nl-NL" ], + // English + @"en" : @[ + @"en", @"en_AU", @"en_CA", @"en_IN", @"en_IE", @"en_MT", @"en_NZ", @"en_PH", + @"en_SG", @"en_ZA", @"en_GB", @"en_US", @"en_AE", @"en-AE", @"en_AS", @"en-AU", + @"en_BD", @"en-CA", @"en_EG", @"en_ES", @"en_GB", @"en-GB", @"en_HK", @"en_ID", + @"en-IN", @"en_NG", @"en-PH", @"en_PK", @"en-SG", @"en-US" + ], + // French + @"fr" : + @[ @"fr", @"fr_BE", @"fr_CA", @"fr_FR", @"fr_LU", @"fr_CH", @"fr-CA", @"fr-FR", @"fr_MA" ], + // German + @"de" : @[ @"de", @"de_AT", @"de_DE", @"de_LU", @"de_CH", @"de-DE" ], + // Greek + @"el" : @[ @"el", @"el_CY", @"el_GR" ], + // Italian + @"it" : @[ @"it", @"it_IT", @"it_CH", @"it-IT" ], + // Japanese + @"ja" : @[ @"ja", @"ja_JP", @"ja_JP_JP", @"ja-JP" ], + // Norwegian + @"no" : @[ @"nb", @"no_NO", @"no_NO_NY", @"nb_NO" ], + // Brazilian Portuguese + @"pt_BR" : @[ @"pt_BR", @"pt-BR" ], + // European Portuguese + @"pt_PT" : @[ @"pt", @"pt_PT", @"pt-PT" ], + // Serbian + @"sr" : @[ @"sr_BA", @"sr_ME", @"sr_RS", @"sr_Latn_BA", @"sr_Latn_ME", @"sr_Latn_RS" ], + // European Spanish + @"es_ES" : @[ @"es", @"es_ES", @"es-ES" ], + // Mexican Spanish + @"es_MX" : @[ @"es-MX", @"es_MX", @"es_US", @"es-US" ], + // Latin American Spanish + @"es_419" : @[ + @"es_AR", @"es_BO", @"es_CL", @"es_CO", @"es_CR", @"es_DO", @"es_EC", + @"es_SV", @"es_GT", @"es_HN", @"es_NI", @"es_PA", @"es_PY", @"es_PE", + @"es_PR", @"es_UY", @"es_VE", @"es-AR", @"es-CL", @"es-CO" + ], + // Thai + @"th" : @[ @"th", @"th_TH", @"th_TH_TH" ], + }; +} + +NSArray *FIRRemoteConfigAppManagerLocales(void) { + NSMutableArray *locales = [NSMutableArray array]; + NSDictionary *localesMap = FIRRemoteConfigFirebaseLocaleMap(); + for (NSString *key in localesMap) { + [locales addObjectsFromArray:localesMap[key]]; + } + return locales; +} +NSString *FIRRemoteConfigDeviceLocale(void) { + NSArray *locales = FIRRemoteConfigAppManagerLocales(); + NSArray *preferredLocalizations = + [NSBundle preferredLocalizationsFromArray:locales + forPreferences:[NSLocale preferredLanguages]]; + NSString *legalDocsLanguage = [preferredLocalizations firstObject]; + // Use en as the default language + return legalDocsLanguage ? legalDocsLanguage : @"en"; +} + +NSString *FIRRemoteConfigTimezone(void) { + NSTimeZone *timezone = [NSTimeZone systemTimeZone]; + return timezone.name; +} + +NSMutableDictionary *FIRRemoteConfigDeviceContextWithProjectIdentifier( + NSString *GMPProjectIdentifier) { + NSMutableDictionary *deviceContext = [[NSMutableDictionary alloc] init]; + deviceContext[RCNDeviceContextKeyVersion] = FIRRemoteConfigAppVersion(); + deviceContext[RCNDeviceContextKeyBuild] = FIRRemoteConfigAppBuildVersion(); + deviceContext[RCNDeviceContextKeyOSVersion] = [GULAppEnvironmentUtil systemVersion]; + deviceContext[RCNDeviceContextKeyDeviceLocale] = FIRRemoteConfigDeviceLocale(); + // NSDictionary setObjectForKey will fail if there's no GMP project ID, must check ahead. + if (GMPProjectIdentifier) { + deviceContext[RCNDeviceContextKeyGMPProjectIdentifier] = GMPProjectIdentifier; + } + return deviceContext; +} + +BOOL FIRRemoteConfigHasDeviceContextChanged(NSDictionary *deviceContext, + NSString *GMPProjectIdentifier) { + if (![deviceContext[RCNDeviceContextKeyVersion] isEqual:FIRRemoteConfigAppVersion()]) { + return YES; + } + if (![deviceContext[RCNDeviceContextKeyBuild] isEqual:FIRRemoteConfigAppBuildVersion()]) { + return YES; + } + if (![deviceContext[RCNDeviceContextKeyOSVersion] + isEqual:[GULAppEnvironmentUtil systemVersion]]) { + return YES; + } + if (![deviceContext[RCNDeviceContextKeyDeviceLocale] isEqual:FIRRemoteConfigDeviceLocale()]) { + return YES; + } + // GMP project id is optional. + if (deviceContext[RCNDeviceContextKeyGMPProjectIdentifier] && + ![deviceContext[RCNDeviceContextKeyGMPProjectIdentifier] isEqual:GMPProjectIdentifier]) { + return YES; + } + return NO; +} diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNPersonalization.h b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNPersonalization.h new file mode 100644 index 0000000..556eb0f --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNPersonalization.h @@ -0,0 +1,56 @@ +/* + * 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 "Interop/Analytics/Public/FIRAnalyticsInterop.h" + +NS_ASSUME_NONNULL_BEGIN + +static NSString *const kAnalyticsOriginPersonalization = @"fp"; + +static NSString *const kExternalEvent = @"personalization_assignment"; +static NSString *const kExternalRcParameterParam = @"arm_key"; +static NSString *const kExternalArmValueParam = @"arm_value"; +static NSString *const kPersonalizationId = @"personalizationId"; +static NSString *const kExternalPersonalizationIdParam = @"personalization_id"; +static NSString *const kArmIndex = @"armIndex"; +static NSString *const kExternalArmIndexParam = @"arm_index"; +static NSString *const kGroup = @"group"; +static NSString *const kExternalGroupParam = @"group"; + +static NSString *const kInternalEvent = @"_fpc"; +static NSString *const kChoiceId = @"choiceId"; +static NSString *const kInternalChoiceIdParam = @"_fpid"; + +@interface RCNPersonalization : NSObject + +/// Analytics connector +@property(nonatomic, strong) id _Nullable analytics; + +@property(atomic, strong) NSMutableDictionary *loggedChoiceIds; + +- (instancetype)init NS_UNAVAILABLE; + +/// Designated initializer. +- (instancetype)initWithAnalytics:(id _Nullable)analytics + NS_DESIGNATED_INITIALIZER; + +/// Called when an arm is pulled from Remote Config. If the arm is personalized, log information to +/// Google in another thread. +- (void)logArmActive:(NSString *)rcParameter config:(NSDictionary *)config; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNPersonalization.m b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNPersonalization.m new file mode 100644 index 0000000..0bcb411 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNPersonalization.m @@ -0,0 +1,72 @@ +/* + * 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 "FirebaseRemoteConfig/Sources/RCNPersonalization.h" + +#import "FirebaseRemoteConfig/Sources/RCNConfigConstants.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h" + +@implementation RCNPersonalization + +- (instancetype)initWithAnalytics:(id _Nullable)analytics { + self = [super init]; + if (self) { + self->_analytics = analytics; + self->_loggedChoiceIds = [[NSMutableDictionary alloc] init]; + } + return self; +} + +- (void)logArmActive:(NSString *)rcParameter config:(NSDictionary *)config { + NSDictionary *ids = config[RCNFetchResponseKeyPersonalizationMetadata]; + NSDictionary *values = config[RCNFetchResponseKeyEntries]; + if (ids.count < 1 || values.count < 1 || !values[rcParameter]) { + return; + } + + NSDictionary *metadata = ids[rcParameter]; + if (!metadata) { + return; + } + + NSString *choiceId = metadata[kChoiceId]; + if (choiceId == nil) { + return; + } + + // Listeners like logArmActive() are dispatched to a serial queue, so loggedChoiceIds should + // contain any previously logged RC parameter / choice ID pairs. + if (self->_loggedChoiceIds[rcParameter] == choiceId) { + return; + } + self->_loggedChoiceIds[rcParameter] = choiceId; + + [self->_analytics logEventWithOrigin:kAnalyticsOriginPersonalization + name:kExternalEvent + parameters:@{ + kExternalRcParameterParam : rcParameter, + kExternalArmValueParam : values[rcParameter].stringValue, + kExternalPersonalizationIdParam : metadata[kPersonalizationId], + kExternalArmIndexParam : metadata[kArmIndex], + kExternalGroupParam : metadata[kGroup] + }]; + + [self->_analytics logEventWithOrigin:kAnalyticsOriginPersonalization + name:kInternalEvent + parameters:@{kInternalChoiceIdParam : choiceId}]; +} + +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNUserDefaultsManager.h b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNUserDefaultsManager.h new file mode 100644 index 0000000..b235f21 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNUserDefaultsManager.h @@ -0,0 +1,66 @@ +/* + * 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 + +NS_ASSUME_NONNULL_BEGIN + +@interface RCNUserDefaultsManager : NSObject + +/// The last eTag received from the backend. +@property(nonatomic, assign) NSString *lastETag; +/// The time of the last eTag update. +@property(nonatomic, assign) NSTimeInterval lastETagUpdateTime; +/// The time of the last successful fetch. +@property(nonatomic, assign) NSTimeInterval lastFetchTime; +/// The time of the last successful fetch. +@property(nonatomic, assign) NSString *lastFetchStatus; +/// Boolean indicating if the last (one or more) fetch(es) was/were unsuccessful, in which case we +/// are in an exponential backoff mode. +@property(nonatomic, assign) BOOL isClientThrottledWithExponentialBackoff; +/// Time when the next request can be made while being throttled. +@property(nonatomic, assign) NSTimeInterval throttleEndTime; +/// The retry interval increases exponentially for cumulative fetch failures. Refer to +/// go/rc-client-throttling for details. +@property(nonatomic, assign) NSTimeInterval currentThrottlingRetryIntervalSeconds; +/// Time when the next request can be made while being throttled. +@property(nonatomic, assign) NSTimeInterval realtimeThrottleEndTime; +/// The retry interval increases exponentially for cumulative Realtime failures. Refer to +/// go/rc-client-throttling for details. +@property(nonatomic, assign) NSTimeInterval currentRealtimeThrottlingRetryIntervalSeconds; +/// Realtime retry count. +@property(nonatomic, assign) int realtimeRetryCount; +/// Last fetched template version. +@property(nonatomic, assign) NSString *lastFetchedTemplateVersion; +/// Last active template version. +@property(nonatomic, assign) NSString *lastActiveTemplateVersion; + +/// Designated initializer. +- (instancetype)initWithAppName:(NSString *)appName + bundleID:(NSString *)bundleIdentifier + namespace:(NSString *)firebaseNamespace NS_DESIGNATED_INITIALIZER; + +// NOLINTBEGIN +/// Use `initWithAppName:bundleID:namespace:` instead. +- (instancetype)init + __attribute__((unavailable("Use `initWithAppName:bundleID:namespace:` instead."))); +// NOLINTEND + +/// Delete all saved userdefaults for this instance. +- (void)resetUserDefaults; +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNUserDefaultsManager.m b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNUserDefaultsManager.m new file mode 100644 index 0000000..880a215 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Sources/RCNUserDefaultsManager.m @@ -0,0 +1,313 @@ +/* + * 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 "FirebaseRemoteConfig/Sources/RCNUserDefaultsManager.h" +#import "FirebaseCore/Extension/FirebaseCoreInternal.h" +#import "FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h" +#import "FirebaseRemoteConfig/Sources/RCNConfigConstants.h" + +static NSString *const kRCNGroupPrefix = @"group"; +static NSString *const kRCNGroupSuffix = @"firebase"; +static NSString *const kRCNUserDefaultsKeyNamelastETag = @"lastETag"; +static NSString *const kRCNUserDefaultsKeyNamelastETagUpdateTime = @"lastETagUpdateTime"; +static NSString *const kRCNUserDefaultsKeyNameLastSuccessfulFetchTime = @"lastSuccessfulFetchTime"; +static NSString *const kRCNUserDefaultsKeyNamelastFetchStatus = @"lastFetchStatus"; +static NSString *const kRCNUserDefaultsKeyNameIsClientThrottled = + @"isClientThrottledWithExponentialBackoff"; +static NSString *const kRCNUserDefaultsKeyNameThrottleEndTime = @"throttleEndTime"; +static NSString *const kRCNUserDefaultsKeyNamecurrentThrottlingRetryInterval = + @"currentThrottlingRetryInterval"; +static NSString *const kRCNUserDefaultsKeyNameRealtimeThrottleEndTime = @"throttleRealtimeEndTime"; +static NSString *const kRCNUserDefaultsKeyNameCurrentRealtimeThrottlingRetryInterval = + @"currentRealtimeThrottlingRetryInterval"; +static NSString *const kRCNUserDefaultsKeyNameRealtimeRetryCount = @"realtimeRetryCount"; + +@interface RCNUserDefaultsManager () { + /// User Defaults instance for this bundleID. NSUserDefaults is guaranteed to be thread-safe. + NSUserDefaults *_userDefaults; + /// The suite name for this user defaults instance. It is a combination of a prefix and the + /// bundleID. This is because you cannot use just the bundleID of the current app as the suite + /// name when initializing user defaults. + NSString *_userDefaultsSuiteName; + /// The FIRApp that this instance is scoped within. + NSString *_firebaseAppName; + /// The Firebase Namespace that this instance is scoped within. + NSString *_firebaseNamespace; + /// The bundleID of the app. In case of an extension, this will be the bundleID of the parent app. + NSString *_bundleIdentifier; +} + +@end + +@implementation RCNUserDefaultsManager + +#pragma mark Initializers. + +/// Designated initializer. +- (instancetype)initWithAppName:(NSString *)appName + bundleID:(NSString *)bundleIdentifier + namespace:(NSString *)firebaseNamespace { + self = [super init]; + if (self) { + _firebaseAppName = appName; + _bundleIdentifier = bundleIdentifier; + NSInteger location = [firebaseNamespace rangeOfString:@":"].location; + if (location == NSNotFound) { + FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000064", + @"Error: Namespace %@ is not fully qualified app:namespace.", firebaseNamespace); + _firebaseNamespace = firebaseNamespace; + } else { + _firebaseNamespace = [firebaseNamespace substringToIndex:location]; + } + + // Initialize the user defaults with a prefix and the bundleID. For app extensions, this will be + // the bundleID of the app extension. + _userDefaults = + [RCNUserDefaultsManager sharedUserDefaultsForBundleIdentifier:_bundleIdentifier]; + } + + return self; +} + ++ (NSUserDefaults *)sharedUserDefaultsForBundleIdentifier:(NSString *)bundleIdentifier { + static dispatch_once_t onceToken; + static NSUserDefaults *sharedInstance; + dispatch_once(&onceToken, ^{ + NSString *userDefaultsSuiteName = + [RCNUserDefaultsManager userDefaultsSuiteNameForBundleIdentifier:bundleIdentifier]; + sharedInstance = [[NSUserDefaults alloc] initWithSuiteName:userDefaultsSuiteName]; + }); + return sharedInstance; +} + ++ (NSString *)userDefaultsSuiteNameForBundleIdentifier:(NSString *)bundleIdentifier { + NSString *suiteName = + [NSString stringWithFormat:@"%@.%@.%@", kRCNGroupPrefix, bundleIdentifier, kRCNGroupSuffix]; + return suiteName; +} + +#pragma mark Public properties. + +- (NSString *)lastETag { + return [[self instanceUserDefaults] objectForKey:kRCNUserDefaultsKeyNamelastETag]; +} + +- (void)setLastETag:(NSString *)lastETag { + if (lastETag) { + [self setInstanceUserDefaultsValue:lastETag forKey:kRCNUserDefaultsKeyNamelastETag]; + } +} + +- (NSString *)lastFetchedTemplateVersion { + NSDictionary *userDefaults = [self instanceUserDefaults]; + if ([userDefaults objectForKey:RCNFetchResponseKeyTemplateVersion]) { + return [userDefaults objectForKey:RCNFetchResponseKeyTemplateVersion]; + } + + return @"0"; +} + +- (void)setLastFetchedTemplateVersion:(NSString *)templateVersion { + if (templateVersion) { + [self setInstanceUserDefaultsValue:templateVersion forKey:RCNFetchResponseKeyTemplateVersion]; + } +} + +- (NSString *)lastActiveTemplateVersion { + NSDictionary *userDefaults = [self instanceUserDefaults]; + if ([userDefaults objectForKey:RCNActiveKeyTemplateVersion]) { + return [userDefaults objectForKey:RCNActiveKeyTemplateVersion]; + } + + return @"0"; +} + +- (void)setLastActiveTemplateVersion:(NSString *)templateVersion { + if (templateVersion) { + [self setInstanceUserDefaultsValue:templateVersion forKey:RCNActiveKeyTemplateVersion]; + } +} + +- (NSTimeInterval)lastETagUpdateTime { + NSNumber *lastETagUpdateTime = + [[self instanceUserDefaults] objectForKey:kRCNUserDefaultsKeyNamelastETagUpdateTime]; + return lastETagUpdateTime.doubleValue; +} + +- (void)setLastETagUpdateTime:(NSTimeInterval)lastETagUpdateTime { + if (lastETagUpdateTime) { + [self setInstanceUserDefaultsValue:@(lastETagUpdateTime) + forKey:kRCNUserDefaultsKeyNamelastETagUpdateTime]; + } +} + +- (NSTimeInterval)lastFetchTime { + NSNumber *lastFetchTime = + [[self instanceUserDefaults] objectForKey:kRCNUserDefaultsKeyNameLastSuccessfulFetchTime]; + return lastFetchTime.doubleValue; +} + +- (void)setLastFetchTime:(NSTimeInterval)lastFetchTime { + [self setInstanceUserDefaultsValue:@(lastFetchTime) + forKey:kRCNUserDefaultsKeyNameLastSuccessfulFetchTime]; +} + +- (NSString *)lastFetchStatus { + return [[self instanceUserDefaults] objectForKey:kRCNUserDefaultsKeyNamelastFetchStatus]; +} + +- (void)setLastFetchStatus:(NSString *)lastFetchStatus { + if (lastFetchStatus) { + [self setInstanceUserDefaultsValue:lastFetchStatus + forKey:kRCNUserDefaultsKeyNamelastFetchStatus]; + } +} + +- (BOOL)isClientThrottledWithExponentialBackoff { + NSNumber *isClientThrottled = + [[self instanceUserDefaults] objectForKey:kRCNUserDefaultsKeyNameIsClientThrottled]; + return isClientThrottled.boolValue; +} + +- (void)setIsClientThrottledWithExponentialBackoff:(BOOL)isClientThrottled { + [self setInstanceUserDefaultsValue:@(isClientThrottled) + forKey:kRCNUserDefaultsKeyNameIsClientThrottled]; +} + +- (NSTimeInterval)throttleEndTime { + NSNumber *throttleEndTime = + [[self instanceUserDefaults] objectForKey:kRCNUserDefaultsKeyNameThrottleEndTime]; + return throttleEndTime.doubleValue; +} + +- (void)setThrottleEndTime:(NSTimeInterval)throttleEndTime { + [self setInstanceUserDefaultsValue:@(throttleEndTime) + forKey:kRCNUserDefaultsKeyNameThrottleEndTime]; +} + +- (NSTimeInterval)currentThrottlingRetryIntervalSeconds { + NSNumber *throttleEndTime = [[self instanceUserDefaults] + objectForKey:kRCNUserDefaultsKeyNamecurrentThrottlingRetryInterval]; + return throttleEndTime.doubleValue; +} + +- (void)setCurrentThrottlingRetryIntervalSeconds:(NSTimeInterval)throttlingRetryIntervalSeconds { + [self setInstanceUserDefaultsValue:@(throttlingRetryIntervalSeconds) + forKey:kRCNUserDefaultsKeyNamecurrentThrottlingRetryInterval]; +} + +- (int)realtimeRetryCount { + int realtimeRetryCount = 0; + if ([[self instanceUserDefaults] objectForKey:kRCNUserDefaultsKeyNameRealtimeRetryCount]) { + realtimeRetryCount = [[[self instanceUserDefaults] + objectForKey:kRCNUserDefaultsKeyNameRealtimeRetryCount] intValue]; + } + + return realtimeRetryCount; +} + +- (void)setRealtimeRetryCount:(int)realtimeRetryCount { + [self setInstanceUserDefaultsValue:[NSNumber numberWithInt:realtimeRetryCount] + forKey:kRCNUserDefaultsKeyNameRealtimeRetryCount]; +} + +- (NSTimeInterval)realtimeThrottleEndTime { + NSNumber *realtimeThrottleEndTime = 0; + if ([[self instanceUserDefaults] objectForKey:kRCNUserDefaultsKeyNameRealtimeThrottleEndTime]) { + realtimeThrottleEndTime = + [[self instanceUserDefaults] objectForKey:kRCNUserDefaultsKeyNameRealtimeThrottleEndTime]; + } + return realtimeThrottleEndTime.doubleValue; +} + +- (void)setRealtimeThrottleEndTime:(NSTimeInterval)throttleEndTime { + [self setInstanceUserDefaultsValue:@(throttleEndTime) + forKey:kRCNUserDefaultsKeyNameRealtimeThrottleEndTime]; +} + +- (NSTimeInterval)currentRealtimeThrottlingRetryIntervalSeconds { + NSNumber *realtimeThrottleEndTime = 0; + if ([[self instanceUserDefaults] + objectForKey:kRCNUserDefaultsKeyNameCurrentRealtimeThrottlingRetryInterval]) { + realtimeThrottleEndTime = [[self instanceUserDefaults] + objectForKey:kRCNUserDefaultsKeyNameCurrentRealtimeThrottlingRetryInterval]; + } + return realtimeThrottleEndTime.doubleValue; +} + +- (void)setCurrentRealtimeThrottlingRetryIntervalSeconds: + (NSTimeInterval)throttlingRetryIntervalSeconds { + [self setInstanceUserDefaultsValue:@(throttlingRetryIntervalSeconds) + forKey:kRCNUserDefaultsKeyNameCurrentRealtimeThrottlingRetryInterval]; +} + +#pragma mark Public methods. +- (void)resetUserDefaults { + [self resetInstanceUserDefaults]; +} + +#pragma mark Private methods. + +// There is a nested hierarchy for the userdefaults as follows: +// [FIRAppName][FIRNamespaceName][Key] +- (nonnull NSDictionary *)appUserDefaults { + NSString *appPath = _firebaseAppName; + NSDictionary *appDict = [_userDefaults valueForKeyPath:appPath]; + if (!appDict) { + appDict = [[NSDictionary alloc] init]; + } + return appDict; +} + +// Search for the user defaults for this (app, namespace) instance using the valueForKeyPath method. +- (nonnull NSDictionary *)instanceUserDefaults { + NSString *appNamespacePath = + [NSString stringWithFormat:@"%@.%@", _firebaseAppName, _firebaseNamespace]; + NSDictionary *appNamespaceDict = [_userDefaults valueForKeyPath:appNamespacePath]; + + if (!appNamespaceDict) { + appNamespaceDict = [[NSMutableDictionary alloc] init]; + } + return appNamespaceDict; +} + +// Update users defaults for just this (app, namespace) instance. +- (void)setInstanceUserDefaultsValue:(NSObject *)value forKey:(NSString *)key { + @synchronized(_userDefaults) { + NSMutableDictionary *appUserDefaults = [[self appUserDefaults] mutableCopy]; + NSMutableDictionary *appNamespaceUserDefaults = [[self instanceUserDefaults] mutableCopy]; + [appNamespaceUserDefaults setObject:value forKey:key]; + [appUserDefaults setObject:appNamespaceUserDefaults forKey:_firebaseNamespace]; + [_userDefaults setObject:appUserDefaults forKey:_firebaseAppName]; + // We need to synchronize to have this value updated for the extension. + [_userDefaults synchronize]; + } +} + +// Delete any existing userdefaults for this instance. +- (void)resetInstanceUserDefaults { + @synchronized(_userDefaults) { + NSMutableDictionary *appUserDefaults = [[self appUserDefaults] mutableCopy]; + NSMutableDictionary *appNamespaceUserDefaults = [[self instanceUserDefaults] mutableCopy]; + [appNamespaceUserDefaults removeAllObjects]; + [appUserDefaults setObject:appNamespaceUserDefaults forKey:_firebaseNamespace]; + [_userDefaults setObject:appUserDefaults forKey:_firebaseAppName]; + // We need to synchronize to have this value updated for the extension. + [_userDefaults synchronize]; + } +} + +@end diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/Codable.swift b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/Codable.swift new file mode 100644 index 0000000..d2df8a9 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/Codable.swift @@ -0,0 +1,69 @@ +/* + * Copyright 2021 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 +#if SWIFT_PACKAGE + @_exported import FirebaseRemoteConfigInternal +#endif // SWIFT_PACKAGE +import FirebaseSharedSwift + +public enum RemoteConfigValueCodableError: Error { + case unsupportedType(String) +} + +public extension RemoteConfigValue { + /// Extracts a RemoteConfigValue JSON-encoded object and decodes it to the requested type. + /// + /// - Parameter asType: The type to decode the JSON-object to + func decoded(asType: Value.Type = Value.self) throws -> Value { + if asType == Date.self { + throw RemoteConfigValueCodableError + .unsupportedType("Date type is not currently supported for " + + " Remote Config Value decoding. Please file a feature request") + } + return try FirebaseDataDecoder() + .decode(Value.self, from: FirebaseRemoteConfigValueDecoderHelper(value: self)) + } +} + +public enum RemoteConfigCodableError: Error { + case invalidSetDefaultsInput(String) +} + +public extension RemoteConfig { + /// Decodes a struct from the respective Remote Config values. + /// + /// - Parameter asType: The type to decode to. + func decoded(asType: Value.Type = Value.self) throws -> Value { + let keys = allKeys(from: RemoteConfigSource.default) + allKeys(from: RemoteConfigSource.remote) + let config = keys.reduce(into: [String: FirebaseRemoteConfigValueDecoderHelper]()) { + $0[$1] = FirebaseRemoteConfigValueDecoderHelper(value: configValue(forKey: $1)) + } + return try FirebaseDataDecoder().decode(Value.self, from: config) + } + + /// Sets config defaults from an encodable struct. + /// + /// - Parameter value: The object to use to set the defaults. + func setDefaults(from value: Value) throws { + guard let encoded = try FirebaseDataEncoder().encode(value) as? [String: NSObject] else { + throw RemoteConfigCodableError.invalidSetDefaultsInput( + "The setDefaults input: \(value), must be a Struct that encodes to a Dictionary" + ) + } + setDefaults(encoded) + } +} diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/FirebaseRemoteConfigValueDecoderHelper.swift b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/FirebaseRemoteConfigValueDecoderHelper.swift new file mode 100644 index 0000000..d0cea37 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/FirebaseRemoteConfigValueDecoderHelper.swift @@ -0,0 +1,58 @@ +/* + * Copyright 2021 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 +#if SWIFT_PACKAGE + @_exported import FirebaseRemoteConfigInternal +#endif // SWIFT_PACKAGE +import FirebaseSharedSwift + +/// Implement the FirebaseRemoteConfigValueDecoding protocol for the shared Firebase decoder to +/// decode Remote Config Values. It returns the four different kinds of values from +/// a RemoteConfigValue object. +struct FirebaseRemoteConfigValueDecoderHelper: FirebaseRemoteConfigValueDecoding { + let value: RemoteConfigValue + + func numberValue() -> NSNumber { + return value.numberValue + } + + func boolValue() -> Bool { + return value.boolValue + } + + func stringValue() -> String { + return value.stringValue ?? "" + } + + func dataValue() -> Data { + return value.dataValue + } + + func arrayValue() -> [AnyHashable]? { + guard let value = value.jsonValue as? [AnyHashable] else { + return nil + } + return value + } + + func dictionaryValue() -> [String: AnyHashable]? { + guard let value = value.jsonValue as? [String: AnyHashable] else { + return nil + } + return value + } +} diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/PropertyWrapper/RemoteConfigProperty.swift b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/PropertyWrapper/RemoteConfigProperty.swift new file mode 100644 index 0000000..05d1df5 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/PropertyWrapper/RemoteConfigProperty.swift @@ -0,0 +1,51 @@ +/* + * Copyright 2022 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. + */ + +#if SWIFT_PACKAGE + @_exported import FirebaseRemoteConfigInternal +#endif // SWIFT_PACKAGE + +import SwiftUI + +/// A property wrapper that listens to a Remote Config value. +@available(iOS 14.0, macOS 11.0, macCatalyst 14.0, tvOS 14.0, watchOS 7.0, *) +@propertyWrapper +public struct RemoteConfigProperty: DynamicProperty { + @StateObject private var configValueObserver: RemoteConfigValueObservable + + /// Remote Config key name for this property + public let key: String + + public var wrappedValue: T { + configValueObserver.configValue + } + + /// Creates an instance by providing a config key. + /// + /// - Parameter key: key name + /// - Parameter fallback: The value to fall back to if the key doesn't exist in remote or default + /// configs + public init(key: String, fallback: T) { + self.key = key + + _configValueObserver = StateObject( + wrappedValue: RemoteConfigValueObservable( + key: key, + fallbackValue: fallback + ) + ) + } +} diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/PropertyWrapper/RemoteConfigValueObservable.swift b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/PropertyWrapper/RemoteConfigValueObservable.swift new file mode 100644 index 0000000..69e521b --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/PropertyWrapper/RemoteConfigValueObservable.swift @@ -0,0 +1,75 @@ +/* + * Copyright 2022 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. + */ + +#if SWIFT_PACKAGE + @_exported import FirebaseRemoteConfigInternal +#endif // SWIFT_PACKAGE +import FirebaseCore +import SwiftUI + +extension Notification.Name { + // Listens to FirebaseRemoteConfig SDK if new configs are activated. + static let onRemoteConfigActivated = Notification.Name("FIRRemoteConfigActivateNotification") +} + +// Make sure this key is consistent with kFIRGoogleAppIDKey in FirebaseCore SDK +let FirebaseRemoteConfigAppNameKey = "FIRAppNameKey" + +@available(iOS 14.0, macOS 11.0, macCatalyst 14.0, tvOS 14.0, watchOS 7.0, *) +class RemoteConfigValueObservable: ObservableObject { + @Published var configValue: T + private let key: String + private let remoteConfig: RemoteConfig + private let fallbackValue: T + + init(key: String, fallbackValue: T) { + self.key = key + remoteConfig = RemoteConfig.remoteConfig() + self.fallbackValue = fallbackValue + // Initialize with fallback value + configValue = fallbackValue + // Check cached remote config value + do { + let configValue: RemoteConfigValue = remoteConfig[key] + if configValue.source == .remote || configValue.source == .default { + self.configValue = try remoteConfig[key].decoded() + } else { + self.configValue = fallbackValue + } + } catch { + configValue = fallbackValue + } + NotificationCenter.default.addObserver( + self, selector: #selector(configDidActivate), name: .onRemoteConfigActivated, object: nil + ) + } + + @objc func configDidActivate(notification: NSNotification) { + // This feature is only available in the default app. + let appName = notification.userInfo?[FirebaseRemoteConfigAppNameKey] as? String + if FirebaseApp.app()?.name != appName { + return + } + do { + let configValue: RemoteConfigValue = remoteConfig[key] + if configValue.source == .remote { + self.configValue = try remoteConfig[key].decoded() + } + } catch { + // Suppresses a hard failure if decoding failed. + } + } +} diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/Resources/PrivacyInfo.xcprivacy b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/Resources/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..719a06f --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/Resources/PrivacyInfo.xcprivacy @@ -0,0 +1,38 @@ + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + + NSPrivacyCollectedDataTypes + + + NSPrivacyCollectedDataType + NSPrivacyCollectedDataTypeOtherDiagnosticData + NSPrivacyCollectedDataTypeLinked + + NSPrivacyCollectedDataTypeTracking + + NSPrivacyCollectedDataTypePurposes + + NSPrivacyCollectedDataTypePurposeAnalytics + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPITypeReasons + + 1C8F.1 + + + + + + diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/SPMSwiftHeaderWorkaround.swift b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/SPMSwiftHeaderWorkaround.swift new file mode 100644 index 0000000..b83a981 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/SPMSwiftHeaderWorkaround.swift @@ -0,0 +1,30 @@ +// Copyright 2023 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. + +#if SWIFT_PACKAGE + @_exported import FirebaseRemoteConfigInternal + + // This is a trick to force generate a `FirebaseRemoteConfig-Swift.h` header + // that re-exports `FirebaseRemoteConfigInternal` for Objective-C clients. It + // is important for the below code to reference a Remote Config symbol defined + // in Objective-C as that will import the symbol's module + // (`FirebaseRemoteConfigInternal`) in the generated header. This allows + // Objective-C clients to import Remote Config's Objective-C API using + // `@import FirebaseRemoteConfig;`. This API is not needed for Swift clients + // and is therefore unavailable in a Swift context. + @available(*, unavailable) + @objc public extension RemoteConfig { + static var __no_op: () -> Void { {} } + } +#endif // SWIFT_PACKAGE diff --git a/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/Value.swift b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/Value.swift new file mode 100644 index 0000000..8a66eda --- /dev/null +++ b/Pods/FirebaseRemoteConfig/FirebaseRemoteConfig/Swift/Value.swift @@ -0,0 +1,42 @@ +/* + * Copyright 2021 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 +#if SWIFT_PACKAGE + @_exported import FirebaseRemoteConfigInternal +#endif // SWIFT_PACKAGE + +/// Implements subscript overloads to enable Remote Config values to be accessed +/// in a type-safe way directly from the current config. +public extension RemoteConfig { + /// Return a typed RemoteConfigValue for a key. + /// - Parameter key: A Remote Config key. + /// - Returns: A typed RemoteConfigValue. + subscript(decodedValue key: String) -> T? { + return try? configValue(forKey: key).decoded() + } + + /// Return a Dictionary for a RemoteConfig JSON key. + /// - Parameter key: A Remote Config key. + /// - Returns: A Dictionary representing a RemoteConfig JSON value. + subscript(jsonValue key: String) -> [String: AnyHashable]? { + guard let value = configValue(forKey: key).jsonValue as? [String: AnyHashable] else { + // nil is the historical behavior for failing to extract JSON. + return nil + } + return value + } +} diff --git a/Pods/FirebaseRemoteConfig/Interop/Analytics/Public/FIRAnalyticsInterop.h b/Pods/FirebaseRemoteConfig/Interop/Analytics/Public/FIRAnalyticsInterop.h new file mode 100644 index 0000000..3b49733 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/Interop/Analytics/Public/FIRAnalyticsInterop.h @@ -0,0 +1,68 @@ +/* + * 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 + +@protocol FIRAnalyticsInteropListener; + +NS_ASSUME_NONNULL_BEGIN + +/// Block typedef callback parameter to `getUserProperties(with:)`. +typedef void (^FIRAInteropUserPropertiesCallback)(NSDictionary *userProperties) + NS_SWIFT_UNAVAILABLE("Use Swift's closure syntax instead."); + +/// Connector for bridging communication between Firebase SDKs and FirebaseAnalytics APIs. +@protocol FIRAnalyticsInterop + +/// Sets user property when trigger event is logged. This API is only available in the SDK. +- (void)setConditionalUserProperty:(NSDictionary *)conditionalUserProperty; + +/// Clears user property if set. +- (void)clearConditionalUserProperty:(NSString *)userPropertyName + forOrigin:(NSString *)origin + clearEventName:(NSString *)clearEventName + clearEventParameters:(NSDictionary *)clearEventParameters; + +/// Returns currently set user properties. +- (NSArray *> *)conditionalUserProperties:(NSString *)origin + propertyNamePrefix: + (NSString *)propertyNamePrefix; + +/// Returns the maximum number of user properties. +- (NSInteger)maxUserProperties:(NSString *)origin; + +/// Returns the user properties to a callback function. +- (void)getUserPropertiesWithCallback: + (void (^)(NSDictionary *userProperties))callback; + +/// Logs events. +- (void)logEventWithOrigin:(NSString *)origin + name:(NSString *)name + parameters:(nullable NSDictionary *)parameters; + +/// Sets user property. +- (void)setUserPropertyWithOrigin:(NSString *)origin name:(NSString *)name value:(id)value; + +/// Registers an Analytics listener for the given origin. +- (void)registerAnalyticsListener:(id)listener + withOrigin:(NSString *)origin; + +/// Unregisters an Analytics listener for the given origin. +- (void)unregisterAnalyticsListenerWithOrigin:(NSString *)origin; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FirebaseRemoteConfig/Interop/Analytics/Public/FIRAnalyticsInteropListener.h b/Pods/FirebaseRemoteConfig/Interop/Analytics/Public/FIRAnalyticsInteropListener.h new file mode 100644 index 0000000..327aefd --- /dev/null +++ b/Pods/FirebaseRemoteConfig/Interop/Analytics/Public/FIRAnalyticsInteropListener.h @@ -0,0 +1,24 @@ +/* + * 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. + */ + +/// Handles events and messages from Analytics. +@protocol FIRAnalyticsInteropListener + +/// Triggers when an Analytics event happens for the registered origin with +/// FirebaseAnalyticsInterop`s `registerAnalyticsListener(_:withOrigin:)`. +- (void)messageTriggered:(NSString *)name parameters:(NSDictionary *)parameters; + +@end diff --git a/Pods/FirebaseRemoteConfig/Interop/Analytics/Public/FIRInteropEventNames.h b/Pods/FirebaseRemoteConfig/Interop/Analytics/Public/FIRInteropEventNames.h new file mode 100644 index 0000000..efc54ab --- /dev/null +++ b/Pods/FirebaseRemoteConfig/Interop/Analytics/Public/FIRInteropEventNames.h @@ -0,0 +1,28 @@ +/* + * 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. + */ + +/// @file FIRInteropEventNames.h + +#import + +/// Notification open event name. +static NSString *const kFIRIEventNotificationOpen = @"_no"; + +/// Notification foreground event name. +static NSString *const kFIRIEventNotificationForeground = @"_nf"; + +/// Campaign event name. +static NSString *const kFIRIEventFirebaseCampaign = @"_cmp"; diff --git a/Pods/FirebaseRemoteConfig/Interop/Analytics/Public/FIRInteropParameterNames.h b/Pods/FirebaseRemoteConfig/Interop/Analytics/Public/FIRInteropParameterNames.h new file mode 100644 index 0000000..f640702 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/Interop/Analytics/Public/FIRInteropParameterNames.h @@ -0,0 +1,73 @@ +/* + * 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 + +/// @file FIRInteropParameterNames.h +/// +/// Predefined event parameter names used by Firebase. This file is a subset of the +/// FirebaseAnalytics FIRParameterNames.h public header. +/// +/// The origin of your traffic, such as an Ad network (for example, google) or partner (urban +/// airship). Identify the advertiser, site, publication, etc. that is sending traffic to your +/// property. Highly recommended (String). +///
+///     let params = [
+///       kFIRParameterSource : "InMobi",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRIParameterSource NS_SWIFT_NAME(AnalyticsParameterSource) = @"source"; + +/// The advertising or marketing medium, for example: cpc, banner, email, push. Highly recommended +/// (String). +///
+///     let params = [
+///       kFIRParameterMedium : "email",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRIParameterMedium NS_SWIFT_NAME(AnalyticsParameterMedium) = @"medium"; + +/// The individual campaign name, slogan, promo code, etc. Some networks have pre-defined macro to +/// capture campaign information, otherwise can be populated by developer. Highly Recommended +/// (String). +///
+///     let params = [
+///       kFIRParameterCampaign : "winter_promotion",
+///       // ...
+///     ]
+/// 
+static NSString *const kFIRIParameterCampaign NS_SWIFT_NAME(AnalyticsParameterCampaign) = + @"campaign"; + +/// Message identifier. +static NSString *const kFIRIParameterMessageIdentifier = @"_nmid"; + +/// Message name. +static NSString *const kFIRIParameterMessageName = @"_nmn"; + +/// Message send time. +static NSString *const kFIRIParameterMessageTime = @"_nmt"; + +/// Message device time. +static NSString *const kFIRIParameterMessageDeviceTime = @"_ndt"; + +/// Topic message. +static NSString *const kFIRIParameterTopic = @"_nt"; + +/// Stores the message_id of the last notification opened by the app. +static NSString *const kFIRIUserPropertyLastNotification = @"_ln"; diff --git a/Pods/FirebaseRemoteConfig/LICENSE b/Pods/FirebaseRemoteConfig/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/Pods/FirebaseRemoteConfig/LICENSE @@ -0,0 +1,202 @@ + + 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. diff --git a/Pods/FirebaseRemoteConfig/README.md b/Pods/FirebaseRemoteConfig/README.md new file mode 100644 index 0000000..4c915ab --- /dev/null +++ b/Pods/FirebaseRemoteConfig/README.md @@ -0,0 +1,297 @@ +

+ + + + + + + + +
+ + + + + + +

+ +# Firebase Apple Open Source Development + +This repository contains the source code for all Apple platform Firebase SDKs except FirebaseAnalytics. + +Firebase is an app development platform with tools to help you build, grow, and +monetize your app. More information about Firebase can be found on the +[official Firebase website](https://firebase.google.com). + +## Installation + +See the subsections below for details about the different installation methods. Where +available, it's recommended to install any libraries with a `Swift` suffix to get the +best experience when writing your app in Swift. + +1. [Standard pod install](#standard-pod-install) +2. [Swift Package Manager](#swift-package-manager) +3. [Installing from the GitHub repo](#installing-from-github) +4. [Experimental Carthage](#carthage-ios-only) + +### Standard pod install + +For instructions on the standard pod install, visit: +[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup). + +### Swift Package Manager + +Instructions for [Swift Package Manager](https://swift.org/package-manager/) support can be +found in the [SwiftPackageManager.md](SwiftPackageManager.md) Markdown file. + +### Installing from GitHub + +These instructions can be used to access the Firebase repo at other branches, +tags, or commits. + +#### Background + +See [the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod) +for instructions and options about overriding pod source locations. + +#### Accessing Firebase Source Snapshots + +All official releases are tagged in this repo and available via CocoaPods. To access a local +source snapshot or unreleased branch, use Podfile directives like the following: + +To access FirebaseFirestore via a branch: +```ruby +pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'main' +pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'main' +``` + +To access FirebaseMessaging via a checked-out version of the firebase-ios-sdk repo: +```ruby +pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk' +pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk' +``` + +### Carthage (iOS only) + +Instructions for the experimental Carthage distribution can be found at +[Carthage.md](Carthage.md). + +### Using Firebase from a Framework or a library + +For details on using Firebase from a Framework or a library, refer to [firebase_in_libraries.md](docs/firebase_in_libraries.md). + +## Development + +To develop Firebase software in this repository, ensure that you have at least +the following software: + +* Xcode 15.2 (or later) + +CocoaPods is still the canonical way to develop, but much of the repo now supports +development with Swift Package Manager. + +### CocoaPods + +Install the following: +* CocoaPods 1.12.0 (or later) +* [CocoaPods generate](https://github.com/square/cocoapods-generate) + +For the pod that you want to develop: + +```ruby +pod gen Firebase{name here}.podspec --local-sources=./ --auto-open --platforms=ios +``` + +Note: If the CocoaPods cache is out of date, you may need to run +`pod repo update` before the `pod gen` command. + +Note: Set the `--platforms` option to `macos` or `tvos` to develop/test for +those platforms. Since 10.2, Xcode does not properly handle multi-platform +CocoaPods workspaces. + +Firestore has a self-contained Xcode project. See +[Firestore/README](Firestore/README.md) Markdown file. + +#### Development for Catalyst +* `pod gen {name here}.podspec --local-sources=./ --auto-open --platforms=ios` +* Check the Mac box in the App-iOS Build Settings +* Sign the App in the Settings Signing & Capabilities tab +* Click Pods in the Project Manager +* Add Signing to the iOS host app and unit test targets +* Select the Unit-unit scheme +* Run it to build and test + +Alternatively, disable signing in each target: +* Go to Build Settings tab +* Click `+` +* Select `Add User-Defined Setting` +* Add `CODE_SIGNING_REQUIRED` setting with a value of `NO` + +### Swift Package Manager +* To enable test schemes: `./scripts/setup_spm_tests.sh` +* `open Package.swift` or double click `Package.swift` in Finder. +* Xcode will open the project + * Choose a scheme for a library to build or test suite to run + * Choose a target platform by selecting the run destination along with the scheme + +### Adding a New Firebase Pod + +Refer to [AddNewPod](AddNewPod.md) Markdown file for details. + +### Managing Headers and Imports + +For information about managing headers and imports, see [HeadersImports](HeadersImports.md) Markdown file. + +### Code Formatting + +To ensure that the code is formatted consistently, run the script +[./scripts/check.sh](https://github.com/firebase/firebase-ios-sdk/blob/main/scripts/check.sh) +before creating a pull request (PR). + +GitHub Actions will verify that any code changes are done in a style-compliant +way. Install `clang-format` and `mint`: + +```console +brew install clang-format@18 +brew install mint +``` + +### Running Unit Tests + +Select a scheme and press Command-u to build a component and run its unit tests. + +### Running Sample Apps +To run the sample apps and integration tests, you'll need a valid +`GoogleService-Info.plist +` file. The Firebase Xcode project contains dummy plist +files without real values, but they can be replaced with real plist files. To get your own +`GoogleService-Info.plist` files: + +1. Go to the [Firebase Console](https://console.firebase.google.com/) +2. Create a new Firebase project, if you don't already have one +3. For each sample app you want to test, create a new Firebase app with the sample app's bundle +identifier (e.g., `com.google.Database-Example`) +4. Download the resulting `GoogleService-Info.plist` and add it to the Xcode project. + +### Coverage Report Generation + +For coverage report generation instructions, see [scripts/code_coverage_report/README](scripts/code_coverage_report/README.md) Markdown file. + +## Specific Component Instructions +See the sections below for any special instructions for those components. + +### Firebase Auth + +For specific Firebase Auth development, refer to the [Auth Sample README](FirebaseAuth/Tests/Sample/README.md) for instructions about +building and running the FirebaseAuth pod along with various samples and tests. + +### Firebase Database + +The Firebase Database Integration tests can be run against a locally running Database Emulator +or against a production instance. + +To run against a local emulator instance, invoke `./scripts/run_database_emulator.sh start` before +running the integration test. + +To run against a production instance, provide a valid `GoogleServices-Info.plist` and copy it to +`FirebaseDatabase/Tests/Resources/GoogleService-Info.plist`. Your Security Rule must be set to +[public](https://firebase.google.com/docs/database/security/quickstart) while your tests are +running. + +### Firebase Dynamic Links + +Firebase Dynamic Links is **deprecated** and should not be used in new projects. The service will shut down on August 25, 2025. + +Please see our [Dynamic Links Deprecation FAQ documentation](https://firebase.google.com/support/dynamic-links-faq) for more guidance. + +### Firebase Performance Monitoring + +For specific Firebase Performance Monitoring development, see +[the Performance README](FirebasePerformance/README.md) for instructions about building the SDK +and [the Performance TestApp README](FirebasePerformance/Tests/TestApp/README.md) for instructions about +integrating Performance with the dev test App. + +### Firebase Storage + +To run the Storage Integration tests, follow the instructions in +[StorageIntegration.swift](FirebaseStorage/Tests/Integration/StorageIntegration.swift). + +#### Push Notifications + +Push notifications can only be delivered to specially provisioned App IDs in the developer portal. +In order to test receiving push notifications, you will need to: + +1. Change the bundle identifier of the sample app to something you own in your Apple Developer +account and enable that App ID for push notifications. +2. You'll also need to +[upload your APNs Provider Authentication Key or certificate to the +Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs) +at **Project Settings > Cloud Messaging > [Your Firebase App]**. +3. Ensure your iOS device is added to your Apple Developer portal as a test device. + +#### iOS Simulator + +The iOS Simulator cannot register for remote notifications and will not receive push notifications. +To receive push notifications, follow the steps above and run the app on a physical device. + +## Building with Firebase on Apple platforms + +Firebase provides official beta support for macOS, Catalyst, and tvOS. visionOS and watchOS +are community supported. Thanks to community contributions for many of the multi-platform PRs. + +At this time, most of Firebase's products are available across Apple platforms. There are still +a few gaps, especially on visionOS and watchOS. For details about the current support matrix, see +[this chart](https://firebase.google.com/docs/ios/learn-more#firebase_library_support_by_platform) +in Firebase's documentation. + +### visionOS + +Where supported, visionOS works as expected with the exception of Firestore via Swift Package +Manager where it is required to use the source distribution. + +To enable the Firestore source distribution, quit Xcode and open the desired +project from the command line with the `FIREBASE_SOURCE_FIRESTORE` environment +variable: `open --env FIREBASE_SOURCE_FIRESTORE /path/to/project.xcodeproj`. +To go back to using the binary distribution of Firestore, quit Xcode and open +Xcode like normal, without the environment variable. + +### watchOS +Thanks to contributions from the community, many of Firebase SDKs now compile, run unit tests, and +work on watchOS. See the [Independent Watch App Sample](Example/watchOSSample). + +Keep in mind that watchOS is not officially supported by Firebase. While we can catch basic unit +test issues with GitHub Actions, there may be some changes where the SDK no longer works as expected +on watchOS. If you encounter this, please +[file an issue](https://github.com/firebase/firebase-ios-sdk/issues). + +During app setup in the console, you may get to a step that mentions something like "Checking if the +app has communicated with our servers". This relies on Analytics and will not work on watchOS. +**It's safe to ignore the message and continue**, the rest of the SDKs will work as expected. + +#### Additional Crashlytics Notes +* watchOS has limited support. Due to watchOS restrictions, mach exceptions and signal crashes are +not recorded. (Crashes in SwiftUI are generated as mach exceptions, so will not be recorded) + +## Combine +Thanks to contributions from the community, _FirebaseCombineSwift_ contains support for Apple's Combine +framework. This module is currently under development and not yet supported for use in production +environments. For more details, please refer to the [docs](FirebaseCombineSwift/README.md). + +## Roadmap + +See [Roadmap](ROADMAP.md) for more about the Firebase Apple SDK Open Source +plans and directions. + +## Contributing + +See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase +Apple SDK. + +## License + +The contents of this repository are licensed under the +[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +Your use of Firebase is governed by the +[Terms of Service for Firebase Services](https://firebase.google.com/terms/). diff --git a/Pods/FirebaseRemoteConfigInterop/FirebaseRemoteConfig/Interop/RemoteConfigConstants.swift b/Pods/FirebaseRemoteConfigInterop/FirebaseRemoteConfig/Interop/RemoteConfigConstants.swift new file mode 100644 index 0000000..f9a10e4 --- /dev/null +++ b/Pods/FirebaseRemoteConfigInterop/FirebaseRemoteConfig/Interop/RemoteConfigConstants.swift @@ -0,0 +1,21 @@ +// Copyright 2024 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 + +@objc(FIRRemoteConfigConstants) +public final class RemoteConfigConstants: NSObject { + @objc(FIRNamespaceGoogleMobilePlatform) public static let NamespaceGoogleMobilePlatform = + "firebase" +} diff --git a/Pods/FirebaseRemoteConfigInterop/FirebaseRemoteConfig/Interop/RemoteConfigInterop.swift b/Pods/FirebaseRemoteConfigInterop/FirebaseRemoteConfig/Interop/RemoteConfigInterop.swift new file mode 100644 index 0000000..b7988ef --- /dev/null +++ b/Pods/FirebaseRemoteConfigInterop/FirebaseRemoteConfig/Interop/RemoteConfigInterop.swift @@ -0,0 +1,21 @@ +// Copyright 2023 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 + +@objc(FIRRemoteConfigInterop) +public protocol RemoteConfigInterop { + func registerRolloutsStateSubscriber(_ subscriber: RolloutsStateSubscriber, + for namespace: String) +} diff --git a/Pods/FirebaseRemoteConfigInterop/FirebaseRemoteConfig/Interop/RolloutAssignment.swift b/Pods/FirebaseRemoteConfigInterop/FirebaseRemoteConfig/Interop/RolloutAssignment.swift new file mode 100644 index 0000000..715412b --- /dev/null +++ b/Pods/FirebaseRemoteConfigInterop/FirebaseRemoteConfig/Interop/RolloutAssignment.swift @@ -0,0 +1,47 @@ +// Copyright 2023 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 + +@objc(FIRRolloutAssignment) +public class RolloutAssignment: NSObject { + @objc public var rolloutId: String + @objc public var variantId: String + @objc public var templateVersion: Int64 + @objc public var parameterKey: String + @objc public var parameterValue: String + + @objc public init(rolloutId: String, variantId: String, templateVersion: Int64, + parameterKey: String, + parameterValue: String) { + self.rolloutId = rolloutId + self.variantId = variantId + self.templateVersion = templateVersion + self.parameterKey = parameterKey + self.parameterValue = parameterValue + super.init() + } +} + +@objc(FIRRolloutsState) +public class RolloutsState: NSObject { + @objc public var assignments: Set = Set() + + @objc public init(assignmentList: [RolloutAssignment]) { + for assignment in assignmentList { + assignments.insert(assignment) + } + super.init() + } +} diff --git a/Pods/FirebaseRemoteConfigInterop/FirebaseRemoteConfig/Interop/RolloutsStateSubscriber.swift b/Pods/FirebaseRemoteConfigInterop/FirebaseRemoteConfig/Interop/RolloutsStateSubscriber.swift new file mode 100644 index 0000000..88e5ba8 --- /dev/null +++ b/Pods/FirebaseRemoteConfigInterop/FirebaseRemoteConfig/Interop/RolloutsStateSubscriber.swift @@ -0,0 +1,20 @@ +// Copyright 2023 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 + +@objc(FIRRolloutsStateSubscriber) +public protocol RolloutsStateSubscriber { + func rolloutsStateDidChange(_ rolloutsState: RolloutsState) +} diff --git a/Pods/FirebaseRemoteConfigInterop/LICENSE b/Pods/FirebaseRemoteConfigInterop/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/Pods/FirebaseRemoteConfigInterop/LICENSE @@ -0,0 +1,202 @@ + + 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. diff --git a/Pods/FirebaseRemoteConfigInterop/README.md b/Pods/FirebaseRemoteConfigInterop/README.md new file mode 100644 index 0000000..4c915ab --- /dev/null +++ b/Pods/FirebaseRemoteConfigInterop/README.md @@ -0,0 +1,297 @@ +

+ + + + + + + + +
+ + + + + + +

+ +# Firebase Apple Open Source Development + +This repository contains the source code for all Apple platform Firebase SDKs except FirebaseAnalytics. + +Firebase is an app development platform with tools to help you build, grow, and +monetize your app. More information about Firebase can be found on the +[official Firebase website](https://firebase.google.com). + +## Installation + +See the subsections below for details about the different installation methods. Where +available, it's recommended to install any libraries with a `Swift` suffix to get the +best experience when writing your app in Swift. + +1. [Standard pod install](#standard-pod-install) +2. [Swift Package Manager](#swift-package-manager) +3. [Installing from the GitHub repo](#installing-from-github) +4. [Experimental Carthage](#carthage-ios-only) + +### Standard pod install + +For instructions on the standard pod install, visit: +[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup). + +### Swift Package Manager + +Instructions for [Swift Package Manager](https://swift.org/package-manager/) support can be +found in the [SwiftPackageManager.md](SwiftPackageManager.md) Markdown file. + +### Installing from GitHub + +These instructions can be used to access the Firebase repo at other branches, +tags, or commits. + +#### Background + +See [the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod) +for instructions and options about overriding pod source locations. + +#### Accessing Firebase Source Snapshots + +All official releases are tagged in this repo and available via CocoaPods. To access a local +source snapshot or unreleased branch, use Podfile directives like the following: + +To access FirebaseFirestore via a branch: +```ruby +pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'main' +pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'main' +``` + +To access FirebaseMessaging via a checked-out version of the firebase-ios-sdk repo: +```ruby +pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk' +pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk' +``` + +### Carthage (iOS only) + +Instructions for the experimental Carthage distribution can be found at +[Carthage.md](Carthage.md). + +### Using Firebase from a Framework or a library + +For details on using Firebase from a Framework or a library, refer to [firebase_in_libraries.md](docs/firebase_in_libraries.md). + +## Development + +To develop Firebase software in this repository, ensure that you have at least +the following software: + +* Xcode 15.2 (or later) + +CocoaPods is still the canonical way to develop, but much of the repo now supports +development with Swift Package Manager. + +### CocoaPods + +Install the following: +* CocoaPods 1.12.0 (or later) +* [CocoaPods generate](https://github.com/square/cocoapods-generate) + +For the pod that you want to develop: + +```ruby +pod gen Firebase{name here}.podspec --local-sources=./ --auto-open --platforms=ios +``` + +Note: If the CocoaPods cache is out of date, you may need to run +`pod repo update` before the `pod gen` command. + +Note: Set the `--platforms` option to `macos` or `tvos` to develop/test for +those platforms. Since 10.2, Xcode does not properly handle multi-platform +CocoaPods workspaces. + +Firestore has a self-contained Xcode project. See +[Firestore/README](Firestore/README.md) Markdown file. + +#### Development for Catalyst +* `pod gen {name here}.podspec --local-sources=./ --auto-open --platforms=ios` +* Check the Mac box in the App-iOS Build Settings +* Sign the App in the Settings Signing & Capabilities tab +* Click Pods in the Project Manager +* Add Signing to the iOS host app and unit test targets +* Select the Unit-unit scheme +* Run it to build and test + +Alternatively, disable signing in each target: +* Go to Build Settings tab +* Click `+` +* Select `Add User-Defined Setting` +* Add `CODE_SIGNING_REQUIRED` setting with a value of `NO` + +### Swift Package Manager +* To enable test schemes: `./scripts/setup_spm_tests.sh` +* `open Package.swift` or double click `Package.swift` in Finder. +* Xcode will open the project + * Choose a scheme for a library to build or test suite to run + * Choose a target platform by selecting the run destination along with the scheme + +### Adding a New Firebase Pod + +Refer to [AddNewPod](AddNewPod.md) Markdown file for details. + +### Managing Headers and Imports + +For information about managing headers and imports, see [HeadersImports](HeadersImports.md) Markdown file. + +### Code Formatting + +To ensure that the code is formatted consistently, run the script +[./scripts/check.sh](https://github.com/firebase/firebase-ios-sdk/blob/main/scripts/check.sh) +before creating a pull request (PR). + +GitHub Actions will verify that any code changes are done in a style-compliant +way. Install `clang-format` and `mint`: + +```console +brew install clang-format@18 +brew install mint +``` + +### Running Unit Tests + +Select a scheme and press Command-u to build a component and run its unit tests. + +### Running Sample Apps +To run the sample apps and integration tests, you'll need a valid +`GoogleService-Info.plist +` file. The Firebase Xcode project contains dummy plist +files without real values, but they can be replaced with real plist files. To get your own +`GoogleService-Info.plist` files: + +1. Go to the [Firebase Console](https://console.firebase.google.com/) +2. Create a new Firebase project, if you don't already have one +3. For each sample app you want to test, create a new Firebase app with the sample app's bundle +identifier (e.g., `com.google.Database-Example`) +4. Download the resulting `GoogleService-Info.plist` and add it to the Xcode project. + +### Coverage Report Generation + +For coverage report generation instructions, see [scripts/code_coverage_report/README](scripts/code_coverage_report/README.md) Markdown file. + +## Specific Component Instructions +See the sections below for any special instructions for those components. + +### Firebase Auth + +For specific Firebase Auth development, refer to the [Auth Sample README](FirebaseAuth/Tests/Sample/README.md) for instructions about +building and running the FirebaseAuth pod along with various samples and tests. + +### Firebase Database + +The Firebase Database Integration tests can be run against a locally running Database Emulator +or against a production instance. + +To run against a local emulator instance, invoke `./scripts/run_database_emulator.sh start` before +running the integration test. + +To run against a production instance, provide a valid `GoogleServices-Info.plist` and copy it to +`FirebaseDatabase/Tests/Resources/GoogleService-Info.plist`. Your Security Rule must be set to +[public](https://firebase.google.com/docs/database/security/quickstart) while your tests are +running. + +### Firebase Dynamic Links + +Firebase Dynamic Links is **deprecated** and should not be used in new projects. The service will shut down on August 25, 2025. + +Please see our [Dynamic Links Deprecation FAQ documentation](https://firebase.google.com/support/dynamic-links-faq) for more guidance. + +### Firebase Performance Monitoring + +For specific Firebase Performance Monitoring development, see +[the Performance README](FirebasePerformance/README.md) for instructions about building the SDK +and [the Performance TestApp README](FirebasePerformance/Tests/TestApp/README.md) for instructions about +integrating Performance with the dev test App. + +### Firebase Storage + +To run the Storage Integration tests, follow the instructions in +[StorageIntegration.swift](FirebaseStorage/Tests/Integration/StorageIntegration.swift). + +#### Push Notifications + +Push notifications can only be delivered to specially provisioned App IDs in the developer portal. +In order to test receiving push notifications, you will need to: + +1. Change the bundle identifier of the sample app to something you own in your Apple Developer +account and enable that App ID for push notifications. +2. You'll also need to +[upload your APNs Provider Authentication Key or certificate to the +Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs) +at **Project Settings > Cloud Messaging > [Your Firebase App]**. +3. Ensure your iOS device is added to your Apple Developer portal as a test device. + +#### iOS Simulator + +The iOS Simulator cannot register for remote notifications and will not receive push notifications. +To receive push notifications, follow the steps above and run the app on a physical device. + +## Building with Firebase on Apple platforms + +Firebase provides official beta support for macOS, Catalyst, and tvOS. visionOS and watchOS +are community supported. Thanks to community contributions for many of the multi-platform PRs. + +At this time, most of Firebase's products are available across Apple platforms. There are still +a few gaps, especially on visionOS and watchOS. For details about the current support matrix, see +[this chart](https://firebase.google.com/docs/ios/learn-more#firebase_library_support_by_platform) +in Firebase's documentation. + +### visionOS + +Where supported, visionOS works as expected with the exception of Firestore via Swift Package +Manager where it is required to use the source distribution. + +To enable the Firestore source distribution, quit Xcode and open the desired +project from the command line with the `FIREBASE_SOURCE_FIRESTORE` environment +variable: `open --env FIREBASE_SOURCE_FIRESTORE /path/to/project.xcodeproj`. +To go back to using the binary distribution of Firestore, quit Xcode and open +Xcode like normal, without the environment variable. + +### watchOS +Thanks to contributions from the community, many of Firebase SDKs now compile, run unit tests, and +work on watchOS. See the [Independent Watch App Sample](Example/watchOSSample). + +Keep in mind that watchOS is not officially supported by Firebase. While we can catch basic unit +test issues with GitHub Actions, there may be some changes where the SDK no longer works as expected +on watchOS. If you encounter this, please +[file an issue](https://github.com/firebase/firebase-ios-sdk/issues). + +During app setup in the console, you may get to a step that mentions something like "Checking if the +app has communicated with our servers". This relies on Analytics and will not work on watchOS. +**It's safe to ignore the message and continue**, the rest of the SDKs will work as expected. + +#### Additional Crashlytics Notes +* watchOS has limited support. Due to watchOS restrictions, mach exceptions and signal crashes are +not recorded. (Crashes in SwiftUI are generated as mach exceptions, so will not be recorded) + +## Combine +Thanks to contributions from the community, _FirebaseCombineSwift_ contains support for Apple's Combine +framework. This module is currently under development and not yet supported for use in production +environments. For more details, please refer to the [docs](FirebaseCombineSwift/README.md). + +## Roadmap + +See [Roadmap](ROADMAP.md) for more about the Firebase Apple SDK Open Source +plans and directions. + +## Contributing + +See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase +Apple SDK. + +## License + +The contents of this repository are licensed under the +[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +Your use of Firebase is governed by the +[Terms of Service for Firebase Services](https://firebase.google.com/terms/). diff --git a/Pods/FirebaseSharedSwift/FirebaseSharedSwift/LICENSE b/Pods/FirebaseSharedSwift/FirebaseSharedSwift/LICENSE new file mode 100644 index 0000000..a1c8b37 --- /dev/null +++ b/Pods/FirebaseSharedSwift/FirebaseSharedSwift/LICENSE @@ -0,0 +1,412 @@ + + 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. + + ## Runtime Library Exception to the Apache 2.0 License: ## + + + As an exception, if you use this Software to compile your source code and + portions of this Software are embedded into the binary product as a result, + you may redistribute such product without providing attribution as would + otherwise be required by Sections 4(a), 4(b) and 4(d) of the License. + + 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. diff --git a/Pods/FirebaseSharedSwift/FirebaseSharedSwift/Sources/FirebaseRemoteConfigValueDecoding.swift b/Pods/FirebaseSharedSwift/FirebaseSharedSwift/Sources/FirebaseRemoteConfigValueDecoding.swift new file mode 100644 index 0000000..39482c0 --- /dev/null +++ b/Pods/FirebaseSharedSwift/FirebaseSharedSwift/Sources/FirebaseRemoteConfigValueDecoding.swift @@ -0,0 +1,26 @@ +// Copyright 2021 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 + +/// Conform to this protocol for the Firebase Decoder to extract values as from a RemoteConfigValue +/// object. +public protocol FirebaseRemoteConfigValueDecoding { + func numberValue() -> NSNumber + func boolValue() -> Bool + func stringValue() -> String + func dataValue() -> Data + func arrayValue() -> [AnyHashable]? + func dictionaryValue() -> [String: AnyHashable]? +} diff --git a/Pods/FirebaseSharedSwift/FirebaseSharedSwift/Sources/third_party/FirebaseDataEncoder/FirebaseDataEncoder.swift b/Pods/FirebaseSharedSwift/FirebaseSharedSwift/Sources/third_party/FirebaseDataEncoder/FirebaseDataEncoder.swift new file mode 100644 index 0000000..76bea35 --- /dev/null +++ b/Pods/FirebaseSharedSwift/FirebaseSharedSwift/Sources/third_party/FirebaseDataEncoder/FirebaseDataEncoder.swift @@ -0,0 +1,2644 @@ +// This file is derived from swift/stdlib/public/Darwin/Foundation/JSONEncoder.swift + +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +import Foundation + +public protocol StructureCodingPassthroughTypeResolver { + static func isPassthroughType(_ t: T) -> Bool +} + +private struct NoPassthroughTypes: StructureCodingPassthroughTypeResolver { + static func isPassthroughType(_ t: T) -> Bool { + return false + } +} + +public protocol StructureCodingUncodedUnkeyed {} + +extension DecodingError { + /// Returns a `.typeMismatch` error describing the expected type. + /// + /// - parameter path: The path of `CodingKey`s taken to decode a value of this type. + /// - parameter expectation: The type expected to be encountered. + /// - parameter reality: The value that was encountered instead of the expected type. + /// - returns: A `DecodingError` with the appropriate path and debug description. + internal static func _typeMismatch(at path: [CodingKey], expectation: Any.Type, reality: Any) -> DecodingError { + let description = "Expected to decode \(expectation) but found \(_typeDescription(of: reality)) instead." + return .typeMismatch(expectation, Context(codingPath: path, debugDescription: description)) + } + + /// Returns a description of the type of `value` appropriate for an error message. + /// + /// - parameter value: The value whose type to describe. + /// - returns: A string describing `value`. + /// - precondition: `value` is one of the types below. + fileprivate static func _typeDescription(of value: Any) -> String { + if value is NSNull { + return "a null value" + } else if value is NSNumber /* FIXME: If swift-corelibs-foundation isn't updated to use NSNumber, this check will be necessary: || value is Int || value is Double */ { + return "a number" + } else if value is String { + return "a string/data" + } else if value is [Any] { + return "an array" + } else if value is [String : Any] { + return "a dictionary" + } else { + return "\(type(of: value))" + } + } +} + + +/// A marker protocol used to determine whether a value is a `String`-keyed `Dictionary` +/// containing `Encodable` values (in which case it should be exempt from key conversion strategies). +/// +/// NOTE: The architecture and environment check is due to a bug in the current (2018-08-08) Swift 4.2 +/// runtime when running on i386 simulator. The issue is tracked in https://bugs.swift.org/browse/SR-8276 +/// Making the protocol `internal` instead of `fileprivate` works around this issue. +/// Once SR-8276 is fixed, this check can be removed and the protocol always be made fileprivate. +#if arch(i386) || arch(arm) +internal protocol _JSONStringDictionaryEncodableMarker { } +#else +fileprivate protocol _JSONStringDictionaryEncodableMarker { } +#endif + +extension Dictionary : _JSONStringDictionaryEncodableMarker where Key == String, Value: Encodable { } + +/// A marker protocol used to determine whether a value is a `String`-keyed `Dictionary` +/// containing `Decodable` values (in which case it should be exempt from key conversion strategies). +/// +/// The marker protocol also provides access to the type of the `Decodable` values, +/// which is needed for the implementation of the key conversion strategy exemption. +/// +/// NOTE: Please see comment above regarding SR-8276 +#if arch(i386) || arch(arm) +internal protocol _JSONStringDictionaryDecodableMarker { + static var elementType: Decodable.Type { get } +} +#else +fileprivate protocol _JSONStringDictionaryDecodableMarker { + static var elementType: Decodable.Type { get } +} +#endif + +extension Dictionary : _JSONStringDictionaryDecodableMarker where Key == String, Value: Decodable { + static var elementType: Decodable.Type { return Value.self } +} + +//===----------------------------------------------------------------------===// +// JSON Encoder +//===----------------------------------------------------------------------===// + +/// `JSONEncoder` facilitates the encoding of `Encodable` values into JSON. +// NOTE: older overlays had Foundation.JSONEncoder as the ObjC name. +// The two must coexist, so it was renamed. The old name must not be +// used in the new runtime. _TtC10Foundation13__JSONEncoder is the +// mangled name for Foundation.__JSONEncoder. + +public class FirebaseDataEncoder { + // MARK: Options + + /// The strategy to use for encoding `Date` values. + public enum DateEncodingStrategy { + /// Defer to `Date` for choosing an encoding. This is the default strategy. + case deferredToDate + + /// Encode the `Date` as a UNIX timestamp (as a JSON number). + case secondsSince1970 + + /// Encode the `Date` as UNIX millisecond timestamp (as a JSON number). + case millisecondsSince1970 + + /// Encode the `Date` as an ISO-8601-formatted string (in RFC 3339 format). + case iso8601 + + /// Encode the `Date` as a string formatted by the given formatter. + case formatted(DateFormatter) + + /// Encode the `Date` as a custom value encoded by the given closure. + /// + /// If the closure fails to encode a value into the given encoder, the encoder will encode an empty automatic container in its place. + case custom((Date, Swift.Encoder) throws -> Void) + } + + /// The strategy to use for encoding `Data` values. + public enum DataEncodingStrategy { + /// Defer to `Data` for choosing an encoding. + case deferredToData + + /// Encode the `Data` as a Base64-encoded string. This is the default strategy. + case base64 + + /// Encode the `Data` as an `NSData` blob. + case blob + + /// Encode the `Data` as a custom value encoded by the given closure. + /// + /// If the closure fails to encode a value into the given encoder, the encoder will encode an empty automatic container in its place. + case custom((Data, Swift.Encoder) throws -> Void) + } + + /// The strategy to use for non-JSON-conforming floating-point values (IEEE 754 infinity and NaN). + public enum NonConformingFloatEncodingStrategy { + /// Throw upon encountering non-conforming values. This is the default strategy. + case `throw` + + /// Encode the values using the given representation strings. + case convertToString(positiveInfinity: String, negativeInfinity: String, nan: String) + } + + /// The strategy to use for automatically changing the value of keys before encoding. + public enum KeyEncodingStrategy { + /// Use the keys specified by each type. This is the default strategy. + case useDefaultKeys + + /// Convert from "camelCaseKeys" to "snake_case_keys" before writing a key to JSON payload. + /// + /// Capital characters are determined by testing membership in `CharacterSet.uppercaseLetters` and `CharacterSet.lowercaseLetters` (Unicode General Categories Lu and Lt). + /// The conversion to lower case uses `Locale.system`, also known as the ICU "root" locale. This means the result is consistent regardless of the current user's locale and language preferences. + /// + /// Converting from camel case to snake case: + /// 1. Splits words at the boundary of lower-case to upper-case + /// 2. Inserts `_` between words + /// 3. Lowercases the entire string + /// 4. Preserves starting and ending `_`. + /// + /// For example, `oneTwoThree` becomes `one_two_three`. `_oneTwoThree_` becomes `_one_two_three_`. + /// + /// - Note: Using a key encoding strategy has a nominal performance cost, as each string key has to be converted. + case convertToSnakeCase + + /// Provide a custom conversion to the key in the encoded JSON from the keys specified by the encoded types. + /// The full path to the current encoding position is provided for context (in case you need to locate this key within the payload). The returned key is used in place of the last component in the coding path before encoding. + /// If the result of the conversion is a duplicate key, then only one value will be present in the result. + case custom((_ codingPath: [CodingKey]) -> CodingKey) + + fileprivate static func _convertToSnakeCase(_ stringKey: String) -> String { + guard !stringKey.isEmpty else { return stringKey } + + var words : [Range] = [] + // The general idea of this algorithm is to split words on transition from lower to upper case, then on transition of >1 upper case characters to lowercase + // + // myProperty -> my_property + // myURLProperty -> my_url_property + // + // We assume, per Swift naming conventions, that the first character of the key is lowercase. + var wordStart = stringKey.startIndex + var searchRange = stringKey.index(after: wordStart)..1 capital letters. Turn those into a word, stopping at the capital before the lower case character. + let beforeLowerIndex = stringKey.index(before: lowerCaseRange.lowerBound) + words.append(upperCaseRange.lowerBound..(_ value: T) throws -> Any { + let encoder = __JSONEncoder(options: self.options) + + guard let topLevel = try encoder.box_(value) else { + throw Swift.EncodingError.invalidValue(value, + Swift.EncodingError.Context(codingPath: [], debugDescription: "Top-level \(T.self) did not encode any values.")) + } + return topLevel + } +} + +// MARK: - __JSONEncoder + +// NOTE: older overlays called this class _JSONEncoder. +// The two must coexist without a conflicting ObjC class name, so it +// was renamed. The old name must not be used in the new runtime. +fileprivate class __JSONEncoder : Encoder { + // MARK: Properties + + /// The encoder's storage. + fileprivate var storage: _JSONEncodingStorage + + /// Options set on the top-level encoder. + fileprivate let options: FirebaseDataEncoder._Options + + /// The path to the current point in encoding. + public var codingPath: [CodingKey] + + /// Contextual user-provided information for use during encoding. + public var userInfo: [CodingUserInfoKey : Any] { + return self.options.userInfo + } + + // MARK: - Initialization + + /// Initializes `self` with the given top-level encoder options. + fileprivate init(options: FirebaseDataEncoder._Options, codingPath: [CodingKey] = []) { + self.options = options + self.storage = _JSONEncodingStorage() + self.codingPath = codingPath + } + + /// Returns whether a new element can be encoded at this coding path. + /// + /// `true` if an element has not yet been encoded at this coding path; `false` otherwise. + fileprivate var canEncodeNewValue: Bool { + // Every time a new value gets encoded, the key it's encoded for is pushed onto the coding path (even if it's a nil key from an unkeyed container). + // At the same time, every time a container is requested, a new value gets pushed onto the storage stack. + // If there are more values on the storage stack than on the coding path, it means the value is requesting more than one container, which violates the precondition. + // + // This means that anytime something that can request a new container goes onto the stack, we MUST push a key onto the coding path. + // Things which will not request containers do not need to have the coding path extended for them (but it doesn't matter if it is, because they will not reach here). + return self.storage.count == self.codingPath.count + } + + // MARK: - Encoder Methods + public func container(keyedBy: Key.Type) -> KeyedEncodingContainer { + // If an existing keyed container was already requested, return that one. + let topContainer: NSMutableDictionary + if self.canEncodeNewValue { + // We haven't yet pushed a container at this level; do so here. + topContainer = self.storage.pushKeyedContainer() + } else { + guard let container = self.storage.containers.last as? NSMutableDictionary else { + preconditionFailure("Attempt to push new keyed encoding container when already previously encoded at this path.") + } + + topContainer = container + } + + let container = _JSONKeyedEncodingContainer(referencing: self, codingPath: self.codingPath, wrapping: topContainer) + return KeyedEncodingContainer(container) + } + + public func unkeyedContainer() -> UnkeyedEncodingContainer { + // If an existing unkeyed container was already requested, return that one. + let topContainer: NSMutableArray + if self.canEncodeNewValue { + // We haven't yet pushed a container at this level; do so here. + topContainer = self.storage.pushUnkeyedContainer() + } else { + guard let container = self.storage.containers.last as? NSMutableArray else { + preconditionFailure("Attempt to push new unkeyed encoding container when already previously encoded at this path.") + } + + topContainer = container + } + + return _JSONUnkeyedEncodingContainer(referencing: self, codingPath: self.codingPath, wrapping: topContainer) + } + + public func singleValueContainer() -> SingleValueEncodingContainer { + return self + } +} + +// MARK: - Encoding Storage and Containers + +fileprivate struct _JSONEncodingStorage { + // MARK: Properties + + /// The container stack. + /// Elements may be any one of the JSON types (NSNull, NSNumber, NSString, NSArray, NSDictionary). + private(set) fileprivate var containers: [NSObject] = [] + + // MARK: - Initialization + + /// Initializes `self` with no containers. + fileprivate init() {} + + // MARK: - Modifying the Stack + + fileprivate var count: Int { + return self.containers.count + } + + fileprivate mutating func pushKeyedContainer() -> NSMutableDictionary { + let dictionary = NSMutableDictionary() + self.containers.append(dictionary) + return dictionary + } + + fileprivate mutating func pushUnkeyedContainer() -> NSMutableArray { + let array = NSMutableArray() + self.containers.append(array) + return array + } + + fileprivate mutating func push(container: __owned NSObject) { + self.containers.append(container) + } + + fileprivate mutating func popContainer() -> NSObject { + precondition(!self.containers.isEmpty, "Empty container stack.") + return self.containers.popLast()! + } +} + +// MARK: - Encoding Containers + +fileprivate struct _JSONKeyedEncodingContainer : KeyedEncodingContainerProtocol { + typealias Key = K + + // MARK: Properties + + /// A reference to the encoder we're writing to. + private let encoder: __JSONEncoder + + /// A reference to the container we're writing to. + private let container: NSMutableDictionary + + /// The path of coding keys taken to get to this point in encoding. + private(set) public var codingPath: [CodingKey] + + // MARK: - Initialization + + /// Initializes `self` with the given references. + fileprivate init(referencing encoder: __JSONEncoder, codingPath: [CodingKey], wrapping container: NSMutableDictionary) { + self.encoder = encoder + self.codingPath = codingPath + self.container = container + } + + // MARK: - Coding Path Operations + + private func _converted(_ key: CodingKey) -> CodingKey { + switch encoder.options.keyEncodingStrategy { + case .useDefaultKeys: + return key + case .convertToSnakeCase: + let newKeyString = FirebaseDataEncoder.KeyEncodingStrategy._convertToSnakeCase(key.stringValue) + return _JSONKey(stringValue: newKeyString, intValue: key.intValue) + case .custom(let converter): + return converter(codingPath + [key]) + } + } + + // MARK: - KeyedEncodingContainerProtocol Methods + + public mutating func encodeNil(forKey key: Key) throws { + self.container[_converted(key).stringValue] = NSNull() + } + public mutating func encode(_ value: Bool, forKey key: Key) throws { + self.container[_converted(key).stringValue] = self.encoder.box(value) + } + public mutating func encode(_ value: Int, forKey key: Key) throws { + self.container[_converted(key).stringValue] = self.encoder.box(value) + } + public mutating func encode(_ value: Int8, forKey key: Key) throws { + self.container[_converted(key).stringValue] = self.encoder.box(value) + } + public mutating func encode(_ value: Int16, forKey key: Key) throws { + self.container[_converted(key).stringValue] = self.encoder.box(value) + } + public mutating func encode(_ value: Int32, forKey key: Key) throws { + self.container[_converted(key).stringValue] = self.encoder.box(value) + } + public mutating func encode(_ value: Int64, forKey key: Key) throws { + self.container[_converted(key).stringValue] = self.encoder.box(value) + } + public mutating func encode(_ value: UInt, forKey key: Key) throws { + self.container[_converted(key).stringValue] = self.encoder.box(value) + } + public mutating func encode(_ value: UInt8, forKey key: Key) throws { + self.container[_converted(key).stringValue] = self.encoder.box(value) + } + public mutating func encode(_ value: UInt16, forKey key: Key) throws { + self.container[_converted(key).stringValue] = self.encoder.box(value) + } + public mutating func encode(_ value: UInt32, forKey key: Key) throws { + self.container[_converted(key).stringValue] = self.encoder.box(value) + } + public mutating func encode(_ value: UInt64, forKey key: Key) throws { + self.container[_converted(key).stringValue] = self.encoder.box(value) + } + public mutating func encode(_ value: String, forKey key: Key) throws { + self.container[_converted(key).stringValue] = self.encoder.box(value) + } + + public mutating func encode(_ value: Float, forKey key: Key) throws { + // Since the float may be invalid and throw, the coding path needs to contain this key. + self.encoder.codingPath.append(key) + defer { self.encoder.codingPath.removeLast() } + self.container[_converted(key).stringValue] = try self.encoder.box(value) + } + + public mutating func encode(_ value: Double, forKey key: Key) throws { + // Since the double may be invalid and throw, the coding path needs to contain this key. + self.encoder.codingPath.append(key) + defer { self.encoder.codingPath.removeLast() } + self.container[_converted(key).stringValue] = try self.encoder.box(value) + } + + public mutating func encode(_ value: T, forKey key: Key) throws { + if T.self is StructureCodingUncodedUnkeyed.Type { return } + self.encoder.codingPath.append(key) + defer { self.encoder.codingPath.removeLast() } + self.container[_converted(key).stringValue] = try self.encoder.box(value) + } + + public mutating func nestedContainer(keyedBy keyType: NestedKey.Type, forKey key: Key) -> KeyedEncodingContainer { + let containerKey = _converted(key).stringValue + let dictionary: NSMutableDictionary + if let existingContainer = self.container[containerKey] { + precondition( + existingContainer is NSMutableDictionary, + "Attempt to re-encode into nested KeyedEncodingContainer<\(Key.self)> for key \"\(containerKey)\" is invalid: non-keyed container already encoded for this key" + ) + dictionary = existingContainer as! NSMutableDictionary + } else { + dictionary = NSMutableDictionary() + self.container[containerKey] = dictionary + } + + self.codingPath.append(key) + defer { self.codingPath.removeLast() } + + let container = _JSONKeyedEncodingContainer(referencing: self.encoder, codingPath: self.codingPath, wrapping: dictionary) + return KeyedEncodingContainer(container) + } + + public mutating func nestedUnkeyedContainer(forKey key: Key) -> UnkeyedEncodingContainer { + let containerKey = _converted(key).stringValue + let array: NSMutableArray + if let existingContainer = self.container[containerKey] { + precondition( + existingContainer is NSMutableArray, + "Attempt to re-encode into nested UnkeyedEncodingContainer for key \"\(containerKey)\" is invalid: keyed container/single value already encoded for this key" + ) + array = existingContainer as! NSMutableArray + } else { + array = NSMutableArray() + self.container[containerKey] = array + } + + self.codingPath.append(key) + defer { self.codingPath.removeLast() } + return _JSONUnkeyedEncodingContainer(referencing: self.encoder, codingPath: self.codingPath, wrapping: array) + } + + public mutating func superEncoder() -> Encoder { + return __JSONReferencingEncoder(referencing: self.encoder, key: _JSONKey.super, convertedKey: _converted(_JSONKey.super), wrapping: self.container) + } + + public mutating func superEncoder(forKey key: Key) -> Encoder { + return __JSONReferencingEncoder(referencing: self.encoder, key: key, convertedKey: _converted(key), wrapping: self.container) + } +} + +fileprivate struct _JSONUnkeyedEncodingContainer : UnkeyedEncodingContainer { + // MARK: Properties + + /// A reference to the encoder we're writing to. + private let encoder: __JSONEncoder + + /// A reference to the container we're writing to. + private let container: NSMutableArray + + /// The path of coding keys taken to get to this point in encoding. + private(set) public var codingPath: [CodingKey] + + /// The number of elements encoded into the container. + public var count: Int { + return self.container.count + } + + // MARK: - Initialization + + /// Initializes `self` with the given references. + fileprivate init(referencing encoder: __JSONEncoder, codingPath: [CodingKey], wrapping container: NSMutableArray) { + self.encoder = encoder + self.codingPath = codingPath + self.container = container + } + + // MARK: - UnkeyedEncodingContainer Methods + + public mutating func encodeNil() throws { self.container.add(NSNull()) } + public mutating func encode(_ value: Bool) throws { self.container.add(self.encoder.box(value)) } + public mutating func encode(_ value: Int) throws { self.container.add(self.encoder.box(value)) } + public mutating func encode(_ value: Int8) throws { self.container.add(self.encoder.box(value)) } + public mutating func encode(_ value: Int16) throws { self.container.add(self.encoder.box(value)) } + public mutating func encode(_ value: Int32) throws { self.container.add(self.encoder.box(value)) } + public mutating func encode(_ value: Int64) throws { self.container.add(self.encoder.box(value)) } + public mutating func encode(_ value: UInt) throws { self.container.add(self.encoder.box(value)) } + public mutating func encode(_ value: UInt8) throws { self.container.add(self.encoder.box(value)) } + public mutating func encode(_ value: UInt16) throws { self.container.add(self.encoder.box(value)) } + public mutating func encode(_ value: UInt32) throws { self.container.add(self.encoder.box(value)) } + public mutating func encode(_ value: UInt64) throws { self.container.add(self.encoder.box(value)) } + public mutating func encode(_ value: String) throws { self.container.add(self.encoder.box(value)) } + + public mutating func encode(_ value: Float) throws { + // Since the float may be invalid and throw, the coding path needs to contain this key. + self.encoder.codingPath.append(_JSONKey(index: self.count)) + defer { self.encoder.codingPath.removeLast() } + self.container.add(try self.encoder.box(value)) + } + + public mutating func encode(_ value: Double) throws { + // Since the double may be invalid and throw, the coding path needs to contain this key. + self.encoder.codingPath.append(_JSONKey(index: self.count)) + defer { self.encoder.codingPath.removeLast() } + self.container.add(try self.encoder.box(value)) + } + + public mutating func encode(_ value: T) throws { + self.encoder.codingPath.append(_JSONKey(index: self.count)) + defer { self.encoder.codingPath.removeLast() } + self.container.add(try self.encoder.box(value)) + } + + public mutating func nestedContainer(keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer { + self.codingPath.append(_JSONKey(index: self.count)) + defer { self.codingPath.removeLast() } + + let dictionary = NSMutableDictionary() + self.container.add(dictionary) + + let container = _JSONKeyedEncodingContainer(referencing: self.encoder, codingPath: self.codingPath, wrapping: dictionary) + return KeyedEncodingContainer(container) + } + + public mutating func nestedUnkeyedContainer() -> UnkeyedEncodingContainer { + self.codingPath.append(_JSONKey(index: self.count)) + defer { self.codingPath.removeLast() } + + let array = NSMutableArray() + self.container.add(array) + return _JSONUnkeyedEncodingContainer(referencing: self.encoder, codingPath: self.codingPath, wrapping: array) + } + + public mutating func superEncoder() -> Encoder { + return __JSONReferencingEncoder(referencing: self.encoder, at: self.container.count, wrapping: self.container) + } +} + +extension __JSONEncoder : SingleValueEncodingContainer { + // MARK: - SingleValueEncodingContainer Methods + + fileprivate func assertCanEncodeNewValue() { + precondition(self.canEncodeNewValue, "Attempt to encode value through single value container when previously value already encoded.") + } + + public func encodeNil() throws { + assertCanEncodeNewValue() + self.storage.push(container: NSNull()) + } + + public func encode(_ value: Bool) throws { + assertCanEncodeNewValue() + self.storage.push(container: self.box(value)) + } + + public func encode(_ value: Int) throws { + assertCanEncodeNewValue() + self.storage.push(container: self.box(value)) + } + + public func encode(_ value: Int8) throws { + assertCanEncodeNewValue() + self.storage.push(container: self.box(value)) + } + + public func encode(_ value: Int16) throws { + assertCanEncodeNewValue() + self.storage.push(container: self.box(value)) + } + + public func encode(_ value: Int32) throws { + assertCanEncodeNewValue() + self.storage.push(container: self.box(value)) + } + + public func encode(_ value: Int64) throws { + assertCanEncodeNewValue() + self.storage.push(container: self.box(value)) + } + + public func encode(_ value: UInt) throws { + assertCanEncodeNewValue() + self.storage.push(container: self.box(value)) + } + + public func encode(_ value: UInt8) throws { + assertCanEncodeNewValue() + self.storage.push(container: self.box(value)) + } + + public func encode(_ value: UInt16) throws { + assertCanEncodeNewValue() + self.storage.push(container: self.box(value)) + } + + public func encode(_ value: UInt32) throws { + assertCanEncodeNewValue() + self.storage.push(container: self.box(value)) + } + + public func encode(_ value: UInt64) throws { + assertCanEncodeNewValue() + self.storage.push(container: self.box(value)) + } + + public func encode(_ value: String) throws { + assertCanEncodeNewValue() + self.storage.push(container: self.box(value)) + } + + public func encode(_ value: Float) throws { + assertCanEncodeNewValue() + try self.storage.push(container: self.box(value)) + } + + public func encode(_ value: Double) throws { + assertCanEncodeNewValue() + try self.storage.push(container: self.box(value)) + } + + public func encode(_ value: T) throws { + assertCanEncodeNewValue() + try self.storage.push(container: self.box(value)) + } +} + +// MARK: - Concrete Value Representations + +extension __JSONEncoder { + /// Returns the given value boxed in a container appropriate for pushing onto the container stack. + fileprivate func box(_ value: Bool) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: Int) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: Int8) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: Int16) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: Int32) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: Int64) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: UInt) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: UInt8) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: UInt16) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: UInt32) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: UInt64) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: String) -> NSObject { return NSString(string: value) } + + fileprivate func box(_ float: Float) throws -> NSObject { + guard !float.isInfinite && !float.isNaN else { + guard case let .convertToString(positiveInfinity: posInfString, + negativeInfinity: negInfString, + nan: nanString) = self.options.nonConformingFloatEncodingStrategy else { + throw EncodingError._invalidFloatingPointValue(float, at: codingPath) + } + + if float == Float.infinity { + return NSString(string: posInfString) + } else if float == -Float.infinity { + return NSString(string: negInfString) + } else { + return NSString(string: nanString) + } + } + + return NSNumber(value: float) + } + + fileprivate func box(_ double: Double) throws -> NSObject { + guard !double.isInfinite && !double.isNaN else { + guard case let .convertToString(positiveInfinity: posInfString, + negativeInfinity: negInfString, + nan: nanString) = self.options.nonConformingFloatEncodingStrategy else { + throw EncodingError._invalidFloatingPointValue(double, at: codingPath) + } + + if double == Double.infinity { + return NSString(string: posInfString) + } else if double == -Double.infinity { + return NSString(string: negInfString) + } else { + return NSString(string: nanString) + } + } + + return NSNumber(value: double) + } + + fileprivate func box(_ date: Date) throws -> NSObject { + switch self.options.dateEncodingStrategy { + case .deferredToDate: + // Must be called with a surrounding with(pushedKey:) call. + // Dates encode as single-value objects; this can't both throw and push a container, so no need to catch the error. + try date.encode(to: self) + return self.storage.popContainer() + + case .secondsSince1970: + return NSNumber(value: date.timeIntervalSince1970) + + case .millisecondsSince1970: + return NSNumber(value: 1000.0 * date.timeIntervalSince1970) + + case .iso8601: + return NSString(string: _iso8601Formatter.string(from: date)) + + case .formatted(let formatter): + return NSString(string: formatter.string(from: date)) + + case .custom(let closure): + let depth = self.storage.count + do { + try closure(date, self) + } catch { + // If the value pushed a container before throwing, pop it back off to restore state. + if self.storage.count > depth { + let _ = self.storage.popContainer() + } + + throw error + } + + guard self.storage.count > depth else { + // The closure didn't encode anything. Return the default keyed container. + return NSDictionary() + } + + // We can pop because the closure encoded something. + return self.storage.popContainer() + } + } + + fileprivate func box(_ data: Data) throws -> NSObject { + switch self.options.dataEncodingStrategy { + case .deferredToData: + // Must be called with a surrounding with(pushedKey:) call. + let depth = self.storage.count + do { + try data.encode(to: self) + } catch { + // If the value pushed a container before throwing, pop it back off to restore state. + // This shouldn't be possible for Data (which encodes as an array of bytes), but it can't hurt to catch a failure. + if self.storage.count > depth { + let _ = self.storage.popContainer() + } + + throw error + } + + return self.storage.popContainer() + + case .base64: + return NSString(string: data.base64EncodedString()) + + case .blob: + return data as NSData + + case .custom(let closure): + let depth = self.storage.count + do { + try closure(data, self) + } catch { + // If the value pushed a container before throwing, pop it back off to restore state. + if self.storage.count > depth { + let _ = self.storage.popContainer() + } + + throw error + } + + guard self.storage.count > depth else { + // The closure didn't encode anything. Return the default keyed container. + return NSDictionary() + } + + // We can pop because the closure encoded something. + return self.storage.popContainer() + } + } + + fileprivate func box(_ dict: [String : Encodable]) throws -> NSObject? { + let depth = self.storage.count + let result = self.storage.pushKeyedContainer() + do { + for (key, value) in dict { + self.codingPath.append(_JSONKey(stringValue: key, intValue: nil)) + defer { self.codingPath.removeLast() } + result[key] = try box(value) + } + } catch { + // If the value pushed a container before throwing, pop it back off to restore state. + if self.storage.count > depth { + let _ = self.storage.popContainer() + } + + throw error + } + + // The top container should be a new container. + guard self.storage.count > depth else { + return nil + } + + return self.storage.popContainer() + } + + fileprivate func box(_ value: Encodable) throws -> NSObject { + return try self.box_(value) ?? NSDictionary() + } + + // This method is called "box_" instead of "box" to disambiguate it from the overloads. Because the return type here is different from all of the "box" overloads (and is more general), any "box" calls in here would call back into "box" recursively instead of calling the appropriate overload, which is not what we want. + fileprivate func box_(_ value: Encodable) throws -> NSObject? { + // Disambiguation between variable and function is required due to + // issue tracked at: https://bugs.swift.org/browse/SR-1846 + let type = Swift.type(of: value) + if type == Date.self || type == NSDate.self { + // Respect Date encoding strategy + return try self.box((value as! Date)) + } else if type == Data.self || type == NSData.self { + // Respect Data encoding strategy + return try self.box((value as! Data)) + } else if type == URL.self || type == NSURL.self { + // Encode URLs as single strings. + return self.box((value as! URL).absoluteString) + } else if type == Decimal.self || type == NSDecimalNumber.self { + // JSONSerialization can natively handle NSDecimalNumber. + return (value as! NSDecimalNumber) + } else if value is _JSONStringDictionaryEncodableMarker { + return try self.box(value as! [String : Encodable]) + } else if let object = value as? NSObject, self.options.passthroughTypeResolver.isPassthroughType(value) { + return object + } + + // The value should request a container from the __JSONEncoder. + let depth = self.storage.count + do { + try value.encode(to: self) + } catch { + // If the value pushed a container before throwing, pop it back off to restore state. + if self.storage.count > depth { + let _ = self.storage.popContainer() + } + + throw error + } + + // The top container should be a new container. + guard self.storage.count > depth else { + return nil + } + + return self.storage.popContainer() + } +} + +// MARK: - __JSONReferencingEncoder + +/// __JSONReferencingEncoder is a special subclass of __JSONEncoder which has its own storage, but references the contents of a different encoder. +/// It's used in superEncoder(), which returns a new encoder for encoding a superclass -- the lifetime of the encoder should not escape the scope it's created in, but it doesn't necessarily know when it's done being used (to write to the original container). +// NOTE: older overlays called this class _JSONReferencingEncoder. +// The two must coexist without a conflicting ObjC class name, so it +// was renamed. The old name must not be used in the new runtime. +fileprivate class __JSONReferencingEncoder : __JSONEncoder { + // MARK: Reference types. + + /// The type of container we're referencing. + private enum Reference { + /// Referencing a specific index in an array container. + case array(NSMutableArray, Int) + + /// Referencing a specific key in a dictionary container. + case dictionary(NSMutableDictionary, String) + } + + // MARK: - Properties + + /// The encoder we're referencing. + fileprivate let encoder: __JSONEncoder + + /// The container reference itself. + private let reference: Reference + + // MARK: - Initialization + + /// Initializes `self` by referencing the given array container in the given encoder. + fileprivate init(referencing encoder: __JSONEncoder, at index: Int, wrapping array: NSMutableArray) { + self.encoder = encoder + self.reference = .array(array, index) + super.init(options: encoder.options, codingPath: encoder.codingPath) + + self.codingPath.append(_JSONKey(index: index)) + } + + /// Initializes `self` by referencing the given dictionary container in the given encoder. + fileprivate init(referencing encoder: __JSONEncoder, + key: CodingKey, convertedKey: __shared CodingKey, wrapping dictionary: NSMutableDictionary) { + self.encoder = encoder + self.reference = .dictionary(dictionary, convertedKey.stringValue) + super.init(options: encoder.options, codingPath: encoder.codingPath) + + self.codingPath.append(key) + } + + // MARK: - Coding Path Operations + + fileprivate override var canEncodeNewValue: Bool { + // With a regular encoder, the storage and coding path grow together. + // A referencing encoder, however, inherits its parents coding path, as well as the key it was created for. + // We have to take this into account. + return self.storage.count == self.codingPath.count - self.encoder.codingPath.count - 1 + } + + // MARK: - Deinitialization + + // Finalizes `self` by writing the contents of our storage to the referenced encoder's storage. + deinit { + let value: Any + switch self.storage.count { + case 0: value = NSDictionary() + case 1: value = self.storage.popContainer() + default: fatalError("Referencing encoder deallocated with multiple containers on stack.") + } + + switch self.reference { + case .array(let array, let index): + array.insert(value, at: index) + + case .dictionary(let dictionary, let key): + dictionary[NSString(string: key)] = value + } + } +} + +//===----------------------------------------------------------------------===// +// JSON Decoder +//===----------------------------------------------------------------------===// + +/// `JSONDecoder` facilitates the decoding of JSON into semantic `Decodable` types. +// NOTE: older overlays had Foundation.JSONDecoder as the ObjC name. +// The two must coexist, so it was renamed. The old name must not be +// used in the new runtime. _TtC10Foundation13__JSONDecoder is the +// mangled name for Foundation.__JSONDecoder. +public class FirebaseDataDecoder { + // MARK: Options + + /// The strategy to use for decoding `Date` values. + public enum DateDecodingStrategy { + /// Defer to `Date` for decoding. This is the default strategy. + case deferredToDate + + /// Decode the `Date` as a UNIX timestamp from a JSON number. + case secondsSince1970 + + /// Decode the `Date` as UNIX millisecond timestamp from a JSON number. + case millisecondsSince1970 + + /// Decode the `Date` as an ISO-8601-formatted string (in RFC 3339 format). + case iso8601 + + /// Decode the `Date` as a string parsed by the given formatter. + case formatted(DateFormatter) + + /// Decode the `Date` as a custom value decoded by the given closure. + case custom((_ decoder: Swift.Decoder) throws -> Date) + } + + /// The strategy to use for decoding `Data` values. + public enum DataDecodingStrategy { + /// Defer to `Data` for decoding. + case deferredToData + + /// Decode the `Data` from a Base64-encoded string. This is the default strategy. + case base64 + + /// Decode the `Data` as an `NSData` blob. + case blob + + /// Decode the `Data` as a custom value decoded by the given closure. + case custom((_ decoder: Swift.Decoder) throws -> Data) + } + + /// The strategy to use for non-JSON-conforming floating-point values (IEEE 754 infinity and NaN). + public enum NonConformingFloatDecodingStrategy { + /// Throw upon encountering non-conforming values. This is the default strategy. + case `throw` + + /// Decode the values from the given representation strings. + case convertFromString(positiveInfinity: String, negativeInfinity: String, nan: String) + } + + /// The strategy to use for automatically changing the value of keys before decoding. + public enum KeyDecodingStrategy { + /// Use the keys specified by each type. This is the default strategy. + case useDefaultKeys + + /// Convert from "snake_case_keys" to "camelCaseKeys" before attempting to match a key with the one specified by each type. + /// + /// The conversion to upper case uses `Locale.system`, also known as the ICU "root" locale. This means the result is consistent regardless of the current user's locale and language preferences. + /// + /// Converting from snake case to camel case: + /// 1. Capitalizes the word starting after each `_` + /// 2. Removes all `_` + /// 3. Preserves starting and ending `_` (as these are often used to indicate private variables or other metadata). + /// For example, `one_two_three` becomes `oneTwoThree`. `_one_two_three_` becomes `_oneTwoThree_`. + /// + /// - Note: Using a key decoding strategy has a nominal performance cost, as each string key has to be inspected for the `_` character. + case convertFromSnakeCase + + /// Provide a custom conversion from the key in the encoded JSON to the keys specified by the decoded types. + /// The full path to the current decoding position is provided for context (in case you need to locate this key within the payload). The returned key is used in place of the last component in the coding path before decoding. + /// If the result of the conversion is a duplicate key, then only one value will be present in the container for the type to decode from. + case custom((_ codingPath: [CodingKey]) -> CodingKey) + + fileprivate static func _convertFromSnakeCase(_ stringKey: String) -> String { + guard !stringKey.isEmpty else { return stringKey } + + // Find the first non-underscore character + guard let firstNonUnderscore = stringKey.firstIndex(where: { $0 != "_" }) else { + // Reached the end without finding an _ + return stringKey + } + + // Find the last non-underscore character + var lastNonUnderscore = stringKey.index(before: stringKey.endIndex) + while lastNonUnderscore > firstNonUnderscore && stringKey[lastNonUnderscore] == "_" { + stringKey.formIndex(before: &lastNonUnderscore) + } + + let keyRange = firstNonUnderscore...lastNonUnderscore + let leadingUnderscoreRange = stringKey.startIndex..(_ type: T.Type, from structure: Any) throws -> T { + let decoder = __JSONDecoder(referencing: structure, options: self.options) + guard let value = try decoder.unbox(structure, as: type) else { + throw Swift.DecodingError.valueNotFound(type, Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data did not contain a top-level value.")) + } + + return value + } +} + +// MARK: - __JSONDecoder + +// NOTE: older overlays called this class _JSONDecoder. The two must +// coexist without a conflicting ObjC class name, so it was renamed. +// The old name must not be used in the new runtime. +fileprivate class __JSONDecoder : Decoder { + // MARK: Properties + + /// The decoder's storage. + fileprivate var storage: _JSONDecodingStorage + + /// Options set on the top-level decoder. + fileprivate let options: FirebaseDataDecoder._Options + + /// The path to the current point in encoding. + fileprivate(set) public var codingPath: [CodingKey] + + /// Contextual user-provided information for use during encoding. + public var userInfo: [CodingUserInfoKey : Any] { + return self.options.userInfo + } + + // MARK: - Initialization + + /// Initializes `self` with the given top-level container and options. + fileprivate init(referencing container: Any, at codingPath: [CodingKey] = [], options: FirebaseDataDecoder._Options) { + self.storage = _JSONDecodingStorage() + self.storage.push(container: container) + self.codingPath = codingPath + self.options = options + } + + // MARK: - Decoder Methods + + public func container(keyedBy type: Key.Type) throws -> KeyedDecodingContainer { + guard !(self.storage.topContainer is NSNull) else { + throw DecodingError.valueNotFound(KeyedDecodingContainer.self, + DecodingError.Context(codingPath: self.codingPath, + debugDescription: "Cannot get keyed decoding container -- found null value instead.")) + } + var topContainer : [String : Any] + if let rcValue = self.storage.topContainer as? FirebaseRemoteConfigValueDecoding { + guard let top = rcValue.dictionaryValue() else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: [String : Any].self, + reality: rcValue) + } + topContainer = top + } else { + guard let top = self.storage.topContainer as? [String : Any] else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: [String : Any].self, reality: self.storage.topContainer) + } + topContainer = top + } + + let container = _JSONKeyedDecodingContainer(referencing: self, wrapping: topContainer) + return KeyedDecodingContainer(container) + } + + public func unkeyedContainer() throws -> UnkeyedDecodingContainer { + guard !(self.storage.topContainer is NSNull) else { + throw DecodingError.valueNotFound(UnkeyedDecodingContainer.self, + DecodingError.Context(codingPath: self.codingPath, + debugDescription: "Cannot get unkeyed decoding container -- found null value instead.")) + } + + if let rcValue = self.storage.topContainer as? FirebaseRemoteConfigValueDecoding { + guard let arrayValue = rcValue.arrayValue() else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: [Any].self, reality: rcValue) + } + return _JSONUnkeyedDecodingContainer(referencing: self, wrapping: arrayValue ) + } + + guard let topContainer = self.storage.topContainer as? [Any] else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: [Any].self, reality: self.storage.topContainer) + } + + return _JSONUnkeyedDecodingContainer(referencing: self, wrapping: topContainer) + } + + public func singleValueContainer() throws -> SingleValueDecodingContainer { + return self + } +} + +// MARK: - Decoding Storage + +fileprivate struct _JSONDecodingStorage { + // MARK: Properties + + /// The container stack. + /// Elements may be any one of the JSON types (NSNull, NSNumber, String, Array, [String : Any]). + private(set) fileprivate var containers: [Any] = [] + + // MARK: - Initialization + + /// Initializes `self` with no containers. + fileprivate init() {} + + // MARK: - Modifying the Stack + + fileprivate var count: Int { + return self.containers.count + } + + fileprivate var topContainer: Any { + precondition(!self.containers.isEmpty, "Empty container stack.") + return self.containers.last! + } + + fileprivate mutating func push(container: __owned Any) { + self.containers.append(container) + } + + fileprivate mutating func popContainer() { + precondition(!self.containers.isEmpty, "Empty container stack.") + self.containers.removeLast() + } +} + +// MARK: Decoding Containers + +fileprivate struct _JSONKeyedDecodingContainer : KeyedDecodingContainerProtocol { + typealias Key = K + + // MARK: Properties + + /// A reference to the decoder we're reading from. + private let decoder: __JSONDecoder + + /// A reference to the container we're reading from. + private let container: [String : Any] + + /// The path of coding keys taken to get to this point in decoding. + private(set) public var codingPath: [CodingKey] + + // MARK: - Initialization + + /// Initializes `self` by referencing the given decoder and container. + fileprivate init(referencing decoder: __JSONDecoder, wrapping container: [String : Any]) { + self.decoder = decoder + switch decoder.options.keyDecodingStrategy { + case .useDefaultKeys: + self.container = container + case .convertFromSnakeCase: + // Convert the snake case keys in the container to camel case. + // If we hit a duplicate key after conversion, then we'll use the first one we saw. Effectively an undefined behavior with JSON dictionaries. + self.container = Dictionary(container.map { + key, value in (FirebaseDataDecoder.KeyDecodingStrategy._convertFromSnakeCase(key), value) + }, uniquingKeysWith: { (first, _) in first }) + case .custom(let converter): + self.container = Dictionary(container.map { + key, value in (converter(decoder.codingPath + [_JSONKey(stringValue: key, intValue: nil)]).stringValue, value) + }, uniquingKeysWith: { (first, _) in first }) + } + self.codingPath = decoder.codingPath + } + + // MARK: - KeyedDecodingContainerProtocol Methods + + public var allKeys: [Key] { + return self.container.keys.compactMap { Key(stringValue: $0) } + } + + public func contains(_ key: Key) -> Bool { + return self.container[key.stringValue] != nil + } + + private func _errorDescription(of key: CodingKey) -> String { + switch decoder.options.keyDecodingStrategy { + case .convertFromSnakeCase: + // In this case we can attempt to recover the original value by reversing the transform + let original = key.stringValue + let converted = FirebaseDataEncoder.KeyEncodingStrategy._convertToSnakeCase(original) + let roundtrip = FirebaseDataDecoder.KeyDecodingStrategy._convertFromSnakeCase(converted) + if converted == original { + return "\(key) (\"\(original)\")" + } else if roundtrip == original { + return "\(key) (\"\(original)\"), converted to \(converted)" + } else { + return "\(key) (\"\(original)\"), with divergent representation \(roundtrip), converted to \(converted)" + } + default: + // Otherwise, just report the converted string + return "\(key) (\"\(key.stringValue)\")" + } + } + + public func decodeNil(forKey key: Key) throws -> Bool { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(_errorDescription(of: key)).")) + } + + return entry is NSNull + } + + public func decode(_ type: Bool.Type, forKey key: Key) throws -> Bool { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(_errorDescription(of: key)).")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: Bool.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: Int.Type, forKey key: Key) throws -> Int { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(_errorDescription(of: key)).")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: Int.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: Int8.Type, forKey key: Key) throws -> Int8 { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(_errorDescription(of: key)).")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: Int8.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: Int16.Type, forKey key: Key) throws -> Int16 { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(_errorDescription(of: key)).")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: Int16.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: Int32.Type, forKey key: Key) throws -> Int32 { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(_errorDescription(of: key)).")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: Int32.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: Int64.Type, forKey key: Key) throws -> Int64 { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(_errorDescription(of: key)).")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: Int64.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: UInt.Type, forKey key: Key) throws -> UInt { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(_errorDescription(of: key)).")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: UInt.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: UInt8.Type, forKey key: Key) throws -> UInt8 { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(_errorDescription(of: key)).")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: UInt8.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: UInt16.Type, forKey key: Key) throws -> UInt16 { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(_errorDescription(of: key)).")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: UInt16.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: UInt32.Type, forKey key: Key) throws -> UInt32 { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(_errorDescription(of: key)).")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: UInt32.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: UInt64.Type, forKey key: Key) throws -> UInt64 { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(_errorDescription(of: key)).")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: UInt64.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: Float.Type, forKey key: Key) throws -> Float { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(_errorDescription(of: key)).")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: Float.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: Double.Type, forKey key: Key) throws -> Double { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(_errorDescription(of: key)).")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: Double.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: String.Type, forKey key: Key) throws -> String { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(_errorDescription(of: key)).")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: String.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: T.Type, forKey key: Key) throws -> T { + if type is StructureCodingUncodedUnkeyed.Type { + // Note: not pushing and popping key to codingPath since the key is + // not part of the decoded structure. + return try T.init(from: self.decoder) + } + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(_errorDescription(of: key)).")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: type) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func nestedContainer(keyedBy type: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer { + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, + DecodingError.Context(codingPath: self.codingPath, + debugDescription: "Cannot get \(KeyedDecodingContainer.self) -- no value found for key \(_errorDescription(of: key))")) + } + + guard let dictionary = value as? [String : Any] else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: [String : Any].self, reality: value) + } + + let container = _JSONKeyedDecodingContainer(referencing: self.decoder, wrapping: dictionary) + return KeyedDecodingContainer(container) + } + + public func nestedUnkeyedContainer(forKey key: Key) throws -> UnkeyedDecodingContainer { + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, + DecodingError.Context(codingPath: self.codingPath, + debugDescription: "Cannot get UnkeyedDecodingContainer -- no value found for key \(_errorDescription(of: key))")) + } + + guard let array = value as? [Any] else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: [Any].self, reality: value) + } + + return _JSONUnkeyedDecodingContainer(referencing: self.decoder, wrapping: array) + } + + private func _superDecoder(forKey key: __owned CodingKey) throws -> Decoder { + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + let value: Any = self.container[key.stringValue] ?? NSNull() + return __JSONDecoder(referencing: value, at: self.decoder.codingPath, options: self.decoder.options) + } + + public func superDecoder() throws -> Decoder { + return try _superDecoder(forKey: _JSONKey.super) + } + + public func superDecoder(forKey key: Key) throws -> Decoder { + return try _superDecoder(forKey: key) + } +} + +fileprivate struct _JSONUnkeyedDecodingContainer : UnkeyedDecodingContainer { + // MARK: Properties + + /// A reference to the decoder we're reading from. + private let decoder: __JSONDecoder + + /// A reference to the container we're reading from. + private let container: [Any] + + /// The path of coding keys taken to get to this point in decoding. + private(set) public var codingPath: [CodingKey] + + /// The index of the element we're about to decode. + private(set) public var currentIndex: Int + + // MARK: - Initialization + + /// Initializes `self` by referencing the given decoder and container. + fileprivate init(referencing decoder: __JSONDecoder, wrapping container: [Any]) { + self.decoder = decoder + self.container = container + self.codingPath = decoder.codingPath + self.currentIndex = 0 + } + + // MARK: - UnkeyedDecodingContainer Methods + + public var count: Int? { + return self.container.count + } + + public var isAtEnd: Bool { + return self.currentIndex >= self.count! + } + + public mutating func decodeNil() throws -> Bool { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(Any?.self, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + if self.container[self.currentIndex] is NSNull { + self.currentIndex += 1 + return true + } else { + return false + } + } + + public mutating func decode(_ type: Bool.Type) throws -> Bool { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + self.decoder.codingPath.append(_JSONKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Bool.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + self.currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: Int.Type) throws -> Int { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + self.decoder.codingPath.append(_JSONKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Int.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + self.currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: Int8.Type) throws -> Int8 { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + self.decoder.codingPath.append(_JSONKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Int8.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + self.currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: Int16.Type) throws -> Int16 { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + self.decoder.codingPath.append(_JSONKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Int16.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + self.currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: Int32.Type) throws -> Int32 { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + self.decoder.codingPath.append(_JSONKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Int32.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + self.currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: Int64.Type) throws -> Int64 { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + self.decoder.codingPath.append(_JSONKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Int64.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + self.currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: UInt.Type) throws -> UInt { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + self.decoder.codingPath.append(_JSONKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: UInt.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + self.currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: UInt8.Type) throws -> UInt8 { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + self.decoder.codingPath.append(_JSONKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: UInt8.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + self.currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: UInt16.Type) throws -> UInt16 { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + self.decoder.codingPath.append(_JSONKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: UInt16.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + self.currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: UInt32.Type) throws -> UInt32 { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + self.decoder.codingPath.append(_JSONKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: UInt32.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + self.currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: UInt64.Type) throws -> UInt64 { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + self.decoder.codingPath.append(_JSONKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: UInt64.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + self.currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: Float.Type) throws -> Float { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + self.decoder.codingPath.append(_JSONKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Float.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + self.currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: Double.Type) throws -> Double { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + self.decoder.codingPath.append(_JSONKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Double.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + self.currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: String.Type) throws -> String { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + self.decoder.codingPath.append(_JSONKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: String.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + self.currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: T.Type) throws -> T { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + self.decoder.codingPath.append(_JSONKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: type) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_JSONKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + self.currentIndex += 1 + return decoded + } + + public mutating func nestedContainer(keyedBy type: NestedKey.Type) throws -> KeyedDecodingContainer { + self.decoder.codingPath.append(_JSONKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(KeyedDecodingContainer.self, + DecodingError.Context(codingPath: self.codingPath, + debugDescription: "Cannot get nested keyed container -- unkeyed container is at end.")) + } + + let value = self.container[self.currentIndex] + guard !(value is NSNull) else { + throw DecodingError.valueNotFound(KeyedDecodingContainer.self, + DecodingError.Context(codingPath: self.codingPath, + debugDescription: "Cannot get keyed decoding container -- found null value instead.")) + } + + guard let dictionary = value as? [String : Any] else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: [String : Any].self, reality: value) + } + + self.currentIndex += 1 + let container = _JSONKeyedDecodingContainer(referencing: self.decoder, wrapping: dictionary) + return KeyedDecodingContainer(container) + } + + public mutating func nestedUnkeyedContainer() throws -> UnkeyedDecodingContainer { + self.decoder.codingPath.append(_JSONKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(UnkeyedDecodingContainer.self, + DecodingError.Context(codingPath: self.codingPath, + debugDescription: "Cannot get nested keyed container -- unkeyed container is at end.")) + } + + let value = self.container[self.currentIndex] + guard !(value is NSNull) else { + throw DecodingError.valueNotFound(UnkeyedDecodingContainer.self, + DecodingError.Context(codingPath: self.codingPath, + debugDescription: "Cannot get keyed decoding container -- found null value instead.")) + } + + guard let array = value as? [Any] else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: [Any].self, reality: value) + } + + self.currentIndex += 1 + return _JSONUnkeyedDecodingContainer(referencing: self.decoder, wrapping: array) + } + + public mutating func superDecoder() throws -> Decoder { + self.decoder.codingPath.append(_JSONKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(Decoder.self, + DecodingError.Context(codingPath: self.codingPath, + debugDescription: "Cannot get superDecoder() -- unkeyed container is at end.")) + } + + let value = self.container[self.currentIndex] + self.currentIndex += 1 + return __JSONDecoder(referencing: value, at: self.decoder.codingPath, options: self.decoder.options) + } +} + +extension __JSONDecoder : SingleValueDecodingContainer { + // MARK: SingleValueDecodingContainer Methods + + private func expectNonNull(_ type: T.Type) throws { + guard !self.decodeNil() else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.codingPath, debugDescription: "Expected \(type) but found null value instead.")) + } + } + + public func decodeNil() -> Bool { + return self.storage.topContainer is NSNull + } + + public func decode(_ type: Bool.Type) throws -> Bool { + try expectNonNull(Bool.self) + return try self.unbox(self.storage.topContainer, as: Bool.self)! + } + + public func decode(_ type: Int.Type) throws -> Int { + try expectNonNull(Int.self) + return try self.unbox(self.storage.topContainer, as: Int.self)! + } + + public func decode(_ type: Int8.Type) throws -> Int8 { + try expectNonNull(Int8.self) + return try self.unbox(self.storage.topContainer, as: Int8.self)! + } + + public func decode(_ type: Int16.Type) throws -> Int16 { + try expectNonNull(Int16.self) + return try self.unbox(self.storage.topContainer, as: Int16.self)! + } + + public func decode(_ type: Int32.Type) throws -> Int32 { + try expectNonNull(Int32.self) + return try self.unbox(self.storage.topContainer, as: Int32.self)! + } + + public func decode(_ type: Int64.Type) throws -> Int64 { + try expectNonNull(Int64.self) + return try self.unbox(self.storage.topContainer, as: Int64.self)! + } + + public func decode(_ type: UInt.Type) throws -> UInt { + try expectNonNull(UInt.self) + return try self.unbox(self.storage.topContainer, as: UInt.self)! + } + + public func decode(_ type: UInt8.Type) throws -> UInt8 { + try expectNonNull(UInt8.self) + return try self.unbox(self.storage.topContainer, as: UInt8.self)! + } + + public func decode(_ type: UInt16.Type) throws -> UInt16 { + try expectNonNull(UInt16.self) + return try self.unbox(self.storage.topContainer, as: UInt16.self)! + } + + public func decode(_ type: UInt32.Type) throws -> UInt32 { + try expectNonNull(UInt32.self) + return try self.unbox(self.storage.topContainer, as: UInt32.self)! + } + + public func decode(_ type: UInt64.Type) throws -> UInt64 { + try expectNonNull(UInt64.self) + return try self.unbox(self.storage.topContainer, as: UInt64.self)! + } + + public func decode(_ type: Float.Type) throws -> Float { + try expectNonNull(Float.self) + return try self.unbox(self.storage.topContainer, as: Float.self)! + } + + public func decode(_ type: Double.Type) throws -> Double { + try expectNonNull(Double.self) + return try self.unbox(self.storage.topContainer, as: Double.self)! + } + + public func decode(_ type: String.Type) throws -> String { + try expectNonNull(String.self) + return try self.unbox(self.storage.topContainer, as: String.self)! + } + + public func decode(_ type: T.Type) throws -> T { + try expectNonNull(type) + return try self.unbox(self.storage.topContainer, as: type)! + } +} + +// MARK: - Concrete Value Representations + +extension __JSONDecoder { + /// Returns the given value unboxed from a container. + fileprivate func unbox(_ value: Any, as type: Bool.Type) throws -> Bool? { + guard !(value is NSNull) else { return nil } + + if let rcValue = value as? FirebaseRemoteConfigValueDecoding { + return rcValue.boolValue() + } + if let number = value as? NSNumber { + // TODO: Add a flag to coerce non-boolean numbers into Bools? + if number === kCFBooleanTrue as NSNumber { + return true + } else if number === kCFBooleanFalse as NSNumber { + return false + } + + /* FIXME: If swift-corelibs-foundation doesn't change to use NSNumber, this code path will need to be included and tested: + } else if let bool = value as? Bool { + return bool + */ + + } + + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + + fileprivate func rcValNumberAdaptor(_ value: Any) -> Any { + if let rcValue = value as? FirebaseRemoteConfigValueDecoding { + return rcValue.numberValue() + } + return value + } + + fileprivate func getNumber(_ value: Any, as type: Any.Type) throws -> NSNumber { + let val = rcValNumberAdaptor(value) + guard let number = val as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: val) + } + return number + } + + fileprivate func unbox(_ value: Any, as type: Int.Type) throws -> Int? { + guard !(value is NSNull) else { return nil } + + let number = try getNumber(value, as: type) + let int = number.intValue + guard NSNumber(value: int) == number else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type).")) + } + + return int + } + + fileprivate func unbox(_ value: Any, as type: Int8.Type) throws -> Int8? { + guard !(value is NSNull) else { return nil } + + let number = try getNumber(value, as: type) + let int8 = number.int8Value + guard NSNumber(value: int8) == number else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type).")) + } + + return int8 + } + + fileprivate func unbox(_ value: Any, as type: Int16.Type) throws -> Int16? { + guard !(value is NSNull) else { return nil } + + let number = try getNumber(value, as: type) + let int16 = number.int16Value + guard NSNumber(value: int16) == number else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type).")) + } + + return int16 + } + + fileprivate func unbox(_ value: Any, as type: Int32.Type) throws -> Int32? { + guard !(value is NSNull) else { return nil } + + let number = try getNumber(value, as: type) + let int32 = number.int32Value + guard NSNumber(value: int32) == number else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type).")) + } + + return int32 + } + + fileprivate func unbox(_ value: Any, as type: Int64.Type) throws -> Int64? { + guard !(value is NSNull) else { return nil } + + let number = try getNumber(value, as: type) + let int64 = number.int64Value + guard NSNumber(value: int64) == number else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type).")) + } + + return int64 + } + + fileprivate func unbox(_ value: Any, as type: UInt.Type) throws -> UInt? { + guard !(value is NSNull) else { return nil } + + let number = try getNumber(value, as: type) + let uint = number.uintValue + guard NSNumber(value: uint) == number else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type).")) + } + + return uint + } + + fileprivate func unbox(_ value: Any, as type: UInt8.Type) throws -> UInt8? { + guard !(value is NSNull) else { return nil } + + let number = try getNumber(value, as: type) + let uint8 = number.uint8Value + guard NSNumber(value: uint8) == number else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type).")) + } + + return uint8 + } + + fileprivate func unbox(_ value: Any, as type: UInt16.Type) throws -> UInt16? { + guard !(value is NSNull) else { return nil } + + let number = try getNumber(value, as: type) + let uint16 = number.uint16Value + guard NSNumber(value: uint16) == number else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type).")) + } + + return uint16 + } + + fileprivate func unbox(_ value: Any, as type: UInt32.Type) throws -> UInt32? { + guard !(value is NSNull) else { return nil } + + let number = try getNumber(value, as: type) + let uint32 = number.uint32Value + guard NSNumber(value: uint32) == number else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type).")) + } + + return uint32 + } + + fileprivate func unbox(_ value: Any, as type: UInt64.Type) throws -> UInt64? { + guard !(value is NSNull) else { return nil } + + let number = try getNumber(value, as: type) + let uint64 = number.uint64Value + guard NSNumber(value: uint64) == number else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type).")) + } + + return uint64 + } + + fileprivate func unbox(_ value: Any, as type: Float.Type) throws -> Float? { + guard !(value is NSNull) else { return nil } + + let val = rcValNumberAdaptor(value) + if let number = val as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse { + // We are willing to return a Float by losing precision: + // * If the original value was integral, + // * and the integral value was > Float.greatestFiniteMagnitude, we will fail + // * and the integral value was <= Float.greatestFiniteMagnitude, we are willing to lose precision past 2^24 + // * If it was a Float, you will get back the precise value + // * If it was a Double or Decimal, you will get back the nearest approximation if it will fit + let double = number.doubleValue + guard abs(double) <= Double(Float.greatestFiniteMagnitude) else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number \(number) does not fit in \(type).")) + } + + return Float(double) + + /* FIXME: If swift-corelibs-foundation doesn't change to use NSNumber, this code path will need to be included and tested: + } else if let double = value as? Double { + if abs(double) <= Double(Float.max) { + return Float(double) + } + + overflow = true + } else if let int = value as? Int { + if let float = Float(exactly: int) { + return float + } + + overflow = true + */ + + } else if let string = val as? String, + case .convertFromString(let posInfString, let negInfString, let nanString) = self.options.nonConformingFloatDecodingStrategy { + if string == posInfString { + return Float.infinity + } else if string == negInfString { + return -Float.infinity + } else if string == nanString { + return Float.nan + } + } + + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + + fileprivate func unbox(_ value: Any, as type: Double.Type) throws -> Double? { + guard !(value is NSNull) else { return nil } + + let val = rcValNumberAdaptor(value) + if let number = val as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse { + // We are always willing to return the number as a Double: + // * If the original value was integral, it is guaranteed to fit in a Double; we are willing to lose precision past 2^53 if you encoded a UInt64 but requested a Double + // * If it was a Float or Double, you will get back the precise value + // * If it was Decimal, you will get back the nearest approximation + return number.doubleValue + + /* FIXME: If swift-corelibs-foundation doesn't change to use NSNumber, this code path will need to be included and tested: + } else if let double = value as? Double { + return double + } else if let int = value as? Int { + if let double = Double(exactly: int) { + return double + } + + overflow = true + */ + + } else if let string = val as? String, + case .convertFromString(let posInfString, let negInfString, let nanString) = self.options.nonConformingFloatDecodingStrategy { + if string == posInfString { + return Double.infinity + } else if string == negInfString { + return -Double.infinity + } else if string == nanString { + return Double.nan + } + } + + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + + fileprivate func unbox(_ value: Any, as type: String.Type) throws -> String? { + guard !(value is NSNull) else { return nil } + + if let rcValue = value as? FirebaseRemoteConfigValueDecoding { + return rcValue.stringValue() + } + guard let string = value as? String else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + + return string + } + + fileprivate func unbox(_ value: Any, as type: Date.Type) throws -> Date? { + guard !(value is NSNull) else { return nil } + + switch self.options.dateDecodingStrategy { + case .deferredToDate: + self.storage.push(container: value) + defer { self.storage.popContainer() } + return try Date(from: self) + + case .secondsSince1970: + let double = try self.unbox(value, as: Double.self)! + return Date(timeIntervalSince1970: double) + + case .millisecondsSince1970: + let double = try self.unbox(value, as: Double.self)! + return Date(timeIntervalSince1970: double / 1000.0) + + case .iso8601: + let string = try self.unbox(value, as: String.self)! + guard let date = _iso8601Formatter.date(from: string) else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Expected date string to be ISO8601-formatted.")) + } + + return date + + case .formatted(let formatter): + let string = try self.unbox(value, as: String.self)! + guard let date = formatter.date(from: string) else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Date string does not match format expected by formatter.")) + } + + return date + + case .custom(let closure): + self.storage.push(container: value) + defer { self.storage.popContainer() } + return try closure(self) + } + } + + fileprivate func unbox(_ value: Any, as type: Data.Type) throws -> Data? { + guard !(value is NSNull) else { return nil } + + if let rcValue = value as? FirebaseRemoteConfigValueDecoding { + return rcValue.dataValue() + } + + switch self.options.dataDecodingStrategy { + case .deferredToData: + self.storage.push(container: value) + defer { self.storage.popContainer() } + return try Data(from: self) + + case .base64: + guard let string = value as? String else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + + guard let data = Data(base64Encoded: string) else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Encountered Data is not valid Base64.")) + } + + return data + + case .blob: + if let data = value as? Data { + return data + } else if let string = value as? String, let data = Data(base64Encoded: string) { + // Support implicit migration of data that was written with .base64 (String type) using + // Firestore 10.0 through 10.3. + return data + } + + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + + case .custom(let closure): + self.storage.push(container: value) + defer { self.storage.popContainer() } + return try closure(self) + } + } + + fileprivate func unbox(_ value: Any, as type: Decimal.Type) throws -> Decimal? { + guard !(value is NSNull) else { return nil } + + let val = rcValNumberAdaptor(value) + + // Attempt to bridge from NSDecimalNumber. + if let decimal = val as? Decimal { + return decimal + } else { + let doubleValue = try self.unbox(val, as: Double.self)! + return Decimal(doubleValue) + } + } + + fileprivate func unbox(_ value: Any, as type: _JSONStringDictionaryDecodableMarker.Type) throws -> T? { + guard !(value is NSNull) else { return nil } + + if let rcValue = value as? FirebaseRemoteConfigValueDecoding { + guard let dictionaryValue = rcValue.dictionaryValue() else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: rcValue) + } + return dictionaryValue as? T + } + + var result = [String : Any]() + guard let dict = value as? NSDictionary else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + let elementType = type.elementType + for (key, value) in dict { + let key = key as! String + self.codingPath.append(_JSONKey(stringValue: key, intValue: nil)) + defer { self.codingPath.removeLast() } + + result[key] = try unbox_(value, as: elementType) + } + + return result as? T + } + + fileprivate func unbox(_ value: Any, as type: T.Type) throws -> T? { + return try unbox_(value, as: type) as? T + } + + fileprivate func unbox_(_ value: Any, as _type: Decodable.Type) throws -> Any? { + if _type == Date.self || _type == NSDate.self { + return try self.unbox(value, as: Date.self) + } else if _type == Data.self || _type == NSData.self { + return try self.unbox(value, as: Data.self) + } else if _type == URL.self || _type == NSURL.self { + guard let urlString = try self.unbox(value, as: String.self) else { + return nil + } + + guard let url = URL(string: urlString) else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, + debugDescription: "Invalid URL string.")) + } + return url + } else if _type == Decimal.self || _type == NSDecimalNumber.self { + return try self.unbox(value, as: Decimal.self) + } else if let stringKeyedDictType = _type as? _JSONStringDictionaryDecodableMarker.Type { + return try self.unbox(value, as: stringKeyedDictType) + } else { + self.storage.push(container: value) + defer { self.storage.popContainer() } + if self.options.passthroughTypeResolver.isPassthroughType(value) && type(of: value) == _type { + return value + } + return try _type.init(from: self) + } + } +} + +//===----------------------------------------------------------------------===// +// Shared Key Types +//===----------------------------------------------------------------------===// + +fileprivate struct _JSONKey : CodingKey { + public var stringValue: String + public var intValue: Int? + + public init?(stringValue: String) { + self.stringValue = stringValue + self.intValue = nil + } + + public init?(intValue: Int) { + self.stringValue = "\(intValue)" + self.intValue = intValue + } + + public init(stringValue: String, intValue: Int?) { + self.stringValue = stringValue + self.intValue = intValue + } + + fileprivate init(index: Int) { + self.stringValue = "Index \(index)" + self.intValue = index + } + + fileprivate static let `super` = _JSONKey(stringValue: "super")! +} + +//===----------------------------------------------------------------------===// +// Shared ISO8601 Date Formatter +//===----------------------------------------------------------------------===// + +// NOTE: This value is implicitly lazy and _must_ be lazy. We're compiled against the latest SDK (w/ ISO8601DateFormatter), but linked against whichever Foundation the user has. ISO8601DateFormatter might not exist, so we better not hit this code path on an older OS. +fileprivate var _iso8601Formatter: ISO8601DateFormatter = { + let formatter = ISO8601DateFormatter() + formatter.formatOptions = .withInternetDateTime + return formatter +}() + +//===----------------------------------------------------------------------===// +// Error Utilities +//===----------------------------------------------------------------------===// + +extension EncodingError { + /// Returns a `.invalidValue` error describing the given invalid floating-point value. + /// + /// + /// - parameter value: The value that was invalid to encode. + /// - parameter path: The path of `CodingKey`s taken to encode this value. + /// - returns: An `EncodingError` with the appropriate path and debug description. + fileprivate static func _invalidFloatingPointValue(_ value: T, at codingPath: [CodingKey]) -> EncodingError { + let valueDescription: String + if value == T.infinity { + valueDescription = "\(T.self).infinity" + } else if value == -T.infinity { + valueDescription = "-\(T.self).infinity" + } else { + valueDescription = "\(T.self).nan" + } + + let debugDescription = "Unable to encode \(valueDescription) directly in JSON. Use JSONEncoder.NonConformingFloatEncodingStrategy.convertToString to specify how the value should be encoded." + return .invalidValue(value, EncodingError.Context(codingPath: codingPath, debugDescription: debugDescription)) + } +} diff --git a/Pods/FirebaseSharedSwift/README.md b/Pods/FirebaseSharedSwift/README.md new file mode 100644 index 0000000..4c915ab --- /dev/null +++ b/Pods/FirebaseSharedSwift/README.md @@ -0,0 +1,297 @@ +

+ + + + + + + + +
+ + + + + + +

+ +# Firebase Apple Open Source Development + +This repository contains the source code for all Apple platform Firebase SDKs except FirebaseAnalytics. + +Firebase is an app development platform with tools to help you build, grow, and +monetize your app. More information about Firebase can be found on the +[official Firebase website](https://firebase.google.com). + +## Installation + +See the subsections below for details about the different installation methods. Where +available, it's recommended to install any libraries with a `Swift` suffix to get the +best experience when writing your app in Swift. + +1. [Standard pod install](#standard-pod-install) +2. [Swift Package Manager](#swift-package-manager) +3. [Installing from the GitHub repo](#installing-from-github) +4. [Experimental Carthage](#carthage-ios-only) + +### Standard pod install + +For instructions on the standard pod install, visit: +[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup). + +### Swift Package Manager + +Instructions for [Swift Package Manager](https://swift.org/package-manager/) support can be +found in the [SwiftPackageManager.md](SwiftPackageManager.md) Markdown file. + +### Installing from GitHub + +These instructions can be used to access the Firebase repo at other branches, +tags, or commits. + +#### Background + +See [the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod) +for instructions and options about overriding pod source locations. + +#### Accessing Firebase Source Snapshots + +All official releases are tagged in this repo and available via CocoaPods. To access a local +source snapshot or unreleased branch, use Podfile directives like the following: + +To access FirebaseFirestore via a branch: +```ruby +pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'main' +pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'main' +``` + +To access FirebaseMessaging via a checked-out version of the firebase-ios-sdk repo: +```ruby +pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk' +pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk' +``` + +### Carthage (iOS only) + +Instructions for the experimental Carthage distribution can be found at +[Carthage.md](Carthage.md). + +### Using Firebase from a Framework or a library + +For details on using Firebase from a Framework or a library, refer to [firebase_in_libraries.md](docs/firebase_in_libraries.md). + +## Development + +To develop Firebase software in this repository, ensure that you have at least +the following software: + +* Xcode 15.2 (or later) + +CocoaPods is still the canonical way to develop, but much of the repo now supports +development with Swift Package Manager. + +### CocoaPods + +Install the following: +* CocoaPods 1.12.0 (or later) +* [CocoaPods generate](https://github.com/square/cocoapods-generate) + +For the pod that you want to develop: + +```ruby +pod gen Firebase{name here}.podspec --local-sources=./ --auto-open --platforms=ios +``` + +Note: If the CocoaPods cache is out of date, you may need to run +`pod repo update` before the `pod gen` command. + +Note: Set the `--platforms` option to `macos` or `tvos` to develop/test for +those platforms. Since 10.2, Xcode does not properly handle multi-platform +CocoaPods workspaces. + +Firestore has a self-contained Xcode project. See +[Firestore/README](Firestore/README.md) Markdown file. + +#### Development for Catalyst +* `pod gen {name here}.podspec --local-sources=./ --auto-open --platforms=ios` +* Check the Mac box in the App-iOS Build Settings +* Sign the App in the Settings Signing & Capabilities tab +* Click Pods in the Project Manager +* Add Signing to the iOS host app and unit test targets +* Select the Unit-unit scheme +* Run it to build and test + +Alternatively, disable signing in each target: +* Go to Build Settings tab +* Click `+` +* Select `Add User-Defined Setting` +* Add `CODE_SIGNING_REQUIRED` setting with a value of `NO` + +### Swift Package Manager +* To enable test schemes: `./scripts/setup_spm_tests.sh` +* `open Package.swift` or double click `Package.swift` in Finder. +* Xcode will open the project + * Choose a scheme for a library to build or test suite to run + * Choose a target platform by selecting the run destination along with the scheme + +### Adding a New Firebase Pod + +Refer to [AddNewPod](AddNewPod.md) Markdown file for details. + +### Managing Headers and Imports + +For information about managing headers and imports, see [HeadersImports](HeadersImports.md) Markdown file. + +### Code Formatting + +To ensure that the code is formatted consistently, run the script +[./scripts/check.sh](https://github.com/firebase/firebase-ios-sdk/blob/main/scripts/check.sh) +before creating a pull request (PR). + +GitHub Actions will verify that any code changes are done in a style-compliant +way. Install `clang-format` and `mint`: + +```console +brew install clang-format@18 +brew install mint +``` + +### Running Unit Tests + +Select a scheme and press Command-u to build a component and run its unit tests. + +### Running Sample Apps +To run the sample apps and integration tests, you'll need a valid +`GoogleService-Info.plist +` file. The Firebase Xcode project contains dummy plist +files without real values, but they can be replaced with real plist files. To get your own +`GoogleService-Info.plist` files: + +1. Go to the [Firebase Console](https://console.firebase.google.com/) +2. Create a new Firebase project, if you don't already have one +3. For each sample app you want to test, create a new Firebase app with the sample app's bundle +identifier (e.g., `com.google.Database-Example`) +4. Download the resulting `GoogleService-Info.plist` and add it to the Xcode project. + +### Coverage Report Generation + +For coverage report generation instructions, see [scripts/code_coverage_report/README](scripts/code_coverage_report/README.md) Markdown file. + +## Specific Component Instructions +See the sections below for any special instructions for those components. + +### Firebase Auth + +For specific Firebase Auth development, refer to the [Auth Sample README](FirebaseAuth/Tests/Sample/README.md) for instructions about +building and running the FirebaseAuth pod along with various samples and tests. + +### Firebase Database + +The Firebase Database Integration tests can be run against a locally running Database Emulator +or against a production instance. + +To run against a local emulator instance, invoke `./scripts/run_database_emulator.sh start` before +running the integration test. + +To run against a production instance, provide a valid `GoogleServices-Info.plist` and copy it to +`FirebaseDatabase/Tests/Resources/GoogleService-Info.plist`. Your Security Rule must be set to +[public](https://firebase.google.com/docs/database/security/quickstart) while your tests are +running. + +### Firebase Dynamic Links + +Firebase Dynamic Links is **deprecated** and should not be used in new projects. The service will shut down on August 25, 2025. + +Please see our [Dynamic Links Deprecation FAQ documentation](https://firebase.google.com/support/dynamic-links-faq) for more guidance. + +### Firebase Performance Monitoring + +For specific Firebase Performance Monitoring development, see +[the Performance README](FirebasePerformance/README.md) for instructions about building the SDK +and [the Performance TestApp README](FirebasePerformance/Tests/TestApp/README.md) for instructions about +integrating Performance with the dev test App. + +### Firebase Storage + +To run the Storage Integration tests, follow the instructions in +[StorageIntegration.swift](FirebaseStorage/Tests/Integration/StorageIntegration.swift). + +#### Push Notifications + +Push notifications can only be delivered to specially provisioned App IDs in the developer portal. +In order to test receiving push notifications, you will need to: + +1. Change the bundle identifier of the sample app to something you own in your Apple Developer +account and enable that App ID for push notifications. +2. You'll also need to +[upload your APNs Provider Authentication Key or certificate to the +Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs) +at **Project Settings > Cloud Messaging > [Your Firebase App]**. +3. Ensure your iOS device is added to your Apple Developer portal as a test device. + +#### iOS Simulator + +The iOS Simulator cannot register for remote notifications and will not receive push notifications. +To receive push notifications, follow the steps above and run the app on a physical device. + +## Building with Firebase on Apple platforms + +Firebase provides official beta support for macOS, Catalyst, and tvOS. visionOS and watchOS +are community supported. Thanks to community contributions for many of the multi-platform PRs. + +At this time, most of Firebase's products are available across Apple platforms. There are still +a few gaps, especially on visionOS and watchOS. For details about the current support matrix, see +[this chart](https://firebase.google.com/docs/ios/learn-more#firebase_library_support_by_platform) +in Firebase's documentation. + +### visionOS + +Where supported, visionOS works as expected with the exception of Firestore via Swift Package +Manager where it is required to use the source distribution. + +To enable the Firestore source distribution, quit Xcode and open the desired +project from the command line with the `FIREBASE_SOURCE_FIRESTORE` environment +variable: `open --env FIREBASE_SOURCE_FIRESTORE /path/to/project.xcodeproj`. +To go back to using the binary distribution of Firestore, quit Xcode and open +Xcode like normal, without the environment variable. + +### watchOS +Thanks to contributions from the community, many of Firebase SDKs now compile, run unit tests, and +work on watchOS. See the [Independent Watch App Sample](Example/watchOSSample). + +Keep in mind that watchOS is not officially supported by Firebase. While we can catch basic unit +test issues with GitHub Actions, there may be some changes where the SDK no longer works as expected +on watchOS. If you encounter this, please +[file an issue](https://github.com/firebase/firebase-ios-sdk/issues). + +During app setup in the console, you may get to a step that mentions something like "Checking if the +app has communicated with our servers". This relies on Analytics and will not work on watchOS. +**It's safe to ignore the message and continue**, the rest of the SDKs will work as expected. + +#### Additional Crashlytics Notes +* watchOS has limited support. Due to watchOS restrictions, mach exceptions and signal crashes are +not recorded. (Crashes in SwiftUI are generated as mach exceptions, so will not be recorded) + +## Combine +Thanks to contributions from the community, _FirebaseCombineSwift_ contains support for Apple's Combine +framework. This module is currently under development and not yet supported for use in production +environments. For more details, please refer to the [docs](FirebaseCombineSwift/README.md). + +## Roadmap + +See [Roadmap](ROADMAP.md) for more about the Firebase Apple SDK Open Source +plans and directions. + +## Contributing + +See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase +Apple SDK. + +## License + +The contents of this repository are licensed under the +[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +Your use of Firebase is governed by the +[Terms of Service for Firebase Services](https://firebase.google.com/terms/). diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/Info.plist b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/Info.plist new file mode 100644 index 0000000..8955e96 --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/Info.plist @@ -0,0 +1,107 @@ + + + + + AvailableLibraries + + + BinaryPath + GoogleAppMeasurement.framework/Versions/A/GoogleAppMeasurement + LibraryIdentifier + ios-arm64_x86_64-maccatalyst + LibraryPath + GoogleAppMeasurement.framework + SupportedArchitectures + + arm64 + x86_64 + + SupportedPlatform + ios + SupportedPlatformVariant + maccatalyst + + + BinaryPath + GoogleAppMeasurement.framework/GoogleAppMeasurement + LibraryIdentifier + tvos-arm64_x86_64-simulator + LibraryPath + GoogleAppMeasurement.framework + SupportedArchitectures + + arm64 + x86_64 + + SupportedPlatform + tvos + SupportedPlatformVariant + simulator + + + BinaryPath + GoogleAppMeasurement.framework/GoogleAppMeasurement + LibraryIdentifier + ios-arm64 + LibraryPath + GoogleAppMeasurement.framework + SupportedArchitectures + + arm64 + + SupportedPlatform + ios + + + BinaryPath + GoogleAppMeasurement.framework/GoogleAppMeasurement + LibraryIdentifier + tvos-arm64 + LibraryPath + GoogleAppMeasurement.framework + SupportedArchitectures + + arm64 + + SupportedPlatform + tvos + + + BinaryPath + GoogleAppMeasurement.framework/Versions/A/GoogleAppMeasurement + LibraryIdentifier + macos-arm64_x86_64 + LibraryPath + GoogleAppMeasurement.framework + SupportedArchitectures + + arm64 + x86_64 + + SupportedPlatform + macos + + + BinaryPath + GoogleAppMeasurement.framework/GoogleAppMeasurement + LibraryIdentifier + ios-arm64_x86_64-simulator + LibraryPath + GoogleAppMeasurement.framework + SupportedArchitectures + + arm64 + x86_64 + + SupportedPlatform + ios + SupportedPlatformVariant + simulator + + + CFBundlePackageType + XFWK + XCFrameworkFormatVersion + 1.0 + + diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/_CodeSignature/CodeDirectory b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/_CodeSignature/CodeDirectory new file mode 100644 index 0000000..d6d7d07 Binary files /dev/null and b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/_CodeSignature/CodeDirectory differ diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/_CodeSignature/CodeRequirements b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/_CodeSignature/CodeRequirements new file mode 100644 index 0000000..001f5af Binary files /dev/null and b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/_CodeSignature/CodeRequirements differ diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/_CodeSignature/CodeRequirements-1 b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/_CodeSignature/CodeRequirements-1 new file mode 100644 index 0000000..7e3c078 Binary files /dev/null and b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/_CodeSignature/CodeRequirements-1 differ diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/_CodeSignature/CodeResources b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/_CodeSignature/CodeResources new file mode 100644 index 0000000..72c621d --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/_CodeSignature/CodeResources @@ -0,0 +1,408 @@ + + + + + files + + ios-arm64/GoogleAppMeasurement.framework/GoogleAppMeasurement + + 7kNWzqNLWz+nGzZnJ8qdO6+f0ZY= + + ios-arm64/GoogleAppMeasurement.framework/Info.plist + + qAdSFBAxuU3E6lcD/qsLi1CkU88= + + ios-arm64/GoogleAppMeasurement.framework/Modules/module.modulemap + + on1mkulwTtm+ufPJ4eClavLWAuQ= + + ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Versions/A/GoogleAppMeasurement + + PRAwq/FWSc07SUgyJyzO2W01sM8= + + ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Versions/A/Modules/module.modulemap + + on1mkulwTtm+ufPJ4eClavLWAuQ= + + ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Versions/A/Resources/Info.plist + + dOxxdjtpFFz1WVN5ZTtExGbSFZ8= + + ios-arm64_x86_64-simulator/GoogleAppMeasurement.framework/GoogleAppMeasurement + + +tAk7JhpRdcjvYHXbr8A44O8OhM= + + ios-arm64_x86_64-simulator/GoogleAppMeasurement.framework/Info.plist + + 0aGxpEjwwmjeq0eTsb5aSq/FBMY= + + ios-arm64_x86_64-simulator/GoogleAppMeasurement.framework/Modules/module.modulemap + + on1mkulwTtm+ufPJ4eClavLWAuQ= + + macos-arm64_x86_64/GoogleAppMeasurement.framework/Versions/A/GoogleAppMeasurement + + 0thsxy9kU29m01ayKJ+iq5He1MI= + + macos-arm64_x86_64/GoogleAppMeasurement.framework/Versions/A/Modules/module.modulemap + + on1mkulwTtm+ufPJ4eClavLWAuQ= + + macos-arm64_x86_64/GoogleAppMeasurement.framework/Versions/A/Resources/Info.plist + + 2aBFz0cGV5jbfJEGW4GSvb58PgY= + + tvos-arm64/GoogleAppMeasurement.framework/GoogleAppMeasurement + + M9bcWQrIbs3KCe/mmB+IKZlEtWY= + + tvos-arm64/GoogleAppMeasurement.framework/Info.plist + + BH3IPXizFx/7iFbKzJ+sSLVw9l8= + + tvos-arm64/GoogleAppMeasurement.framework/Modules/module.modulemap + + on1mkulwTtm+ufPJ4eClavLWAuQ= + + tvos-arm64_x86_64-simulator/GoogleAppMeasurement.framework/GoogleAppMeasurement + + JtLTuojY9AujgMlsD/Agr3L91zU= + + tvos-arm64_x86_64-simulator/GoogleAppMeasurement.framework/Info.plist + + PtSAqBbxOah7hBCCJgCFFTzYEM0= + + tvos-arm64_x86_64-simulator/GoogleAppMeasurement.framework/Modules/module.modulemap + + on1mkulwTtm+ufPJ4eClavLWAuQ= + + + files2 + + ios-arm64/GoogleAppMeasurement.framework/GoogleAppMeasurement + + hash + + 7kNWzqNLWz+nGzZnJ8qdO6+f0ZY= + + hash2 + + zBzAPufiCRbdVLx5Cp2C6qb28YBLrv2IftG1ux9hePc= + + + ios-arm64/GoogleAppMeasurement.framework/Info.plist + + hash + + qAdSFBAxuU3E6lcD/qsLi1CkU88= + + hash2 + + b0vdPx6HuL47CrfHwqcf+y3xXTC4TnDt6Pr5ra3Xx6U= + + + ios-arm64/GoogleAppMeasurement.framework/Modules/module.modulemap + + hash + + on1mkulwTtm+ufPJ4eClavLWAuQ= + + hash2 + + gd8e5hMrJihnXu8TQ0xecVPl3Z71GpsKaYxiLbmHezw= + + + ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/GoogleAppMeasurement + + symlink + Versions/Current/GoogleAppMeasurement + + ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Modules + + symlink + Versions/Current/Modules + + ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Resources + + symlink + Versions/Current/Resources + + ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Versions/A/GoogleAppMeasurement + + hash + + PRAwq/FWSc07SUgyJyzO2W01sM8= + + hash2 + + 3XeLFpK3TskOmMJs1tt2B7uNGPfIZjsJ2FT+IYSSmG4= + + + ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Versions/A/Modules/module.modulemap + + hash + + on1mkulwTtm+ufPJ4eClavLWAuQ= + + hash2 + + gd8e5hMrJihnXu8TQ0xecVPl3Z71GpsKaYxiLbmHezw= + + + ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Versions/A/Resources/Info.plist + + hash + + dOxxdjtpFFz1WVN5ZTtExGbSFZ8= + + hash2 + + wjdR7M3AxZqn/dZFPoaIIs3e3fkIiitQPoSq9E13LdM= + + + ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Versions/Current + + symlink + A + + ios-arm64_x86_64-simulator/GoogleAppMeasurement.framework/GoogleAppMeasurement + + hash + + +tAk7JhpRdcjvYHXbr8A44O8OhM= + + hash2 + + F4elCBzRtWPMKrimmlHQ6YeJpaZ7Y/8ko4k61NKXGDs= + + + ios-arm64_x86_64-simulator/GoogleAppMeasurement.framework/Info.plist + + hash + + 0aGxpEjwwmjeq0eTsb5aSq/FBMY= + + hash2 + + Wdxbj5TYGTQo4b4RueeiTG5+1aVwGLhtWpqXvrpvlqc= + + + ios-arm64_x86_64-simulator/GoogleAppMeasurement.framework/Modules/module.modulemap + + hash + + on1mkulwTtm+ufPJ4eClavLWAuQ= + + hash2 + + gd8e5hMrJihnXu8TQ0xecVPl3Z71GpsKaYxiLbmHezw= + + + macos-arm64_x86_64/GoogleAppMeasurement.framework/GoogleAppMeasurement + + symlink + Versions/Current/GoogleAppMeasurement + + macos-arm64_x86_64/GoogleAppMeasurement.framework/Modules + + symlink + Versions/Current/Modules + + macos-arm64_x86_64/GoogleAppMeasurement.framework/Resources + + symlink + Versions/Current/Resources + + macos-arm64_x86_64/GoogleAppMeasurement.framework/Versions/A/GoogleAppMeasurement + + hash + + 0thsxy9kU29m01ayKJ+iq5He1MI= + + hash2 + + dAuw56JdKzW2YhmIoROv5R3eFtbZq/TlweF2Q4N6xbM= + + + macos-arm64_x86_64/GoogleAppMeasurement.framework/Versions/A/Modules/module.modulemap + + hash + + on1mkulwTtm+ufPJ4eClavLWAuQ= + + hash2 + + gd8e5hMrJihnXu8TQ0xecVPl3Z71GpsKaYxiLbmHezw= + + + macos-arm64_x86_64/GoogleAppMeasurement.framework/Versions/A/Resources/Info.plist + + hash + + 2aBFz0cGV5jbfJEGW4GSvb58PgY= + + hash2 + + /WOMP8ILHPVYtd2eRcMvid1fkHV8Vdfk6c/GOmENjGc= + + + macos-arm64_x86_64/GoogleAppMeasurement.framework/Versions/Current + + symlink + A + + tvos-arm64/GoogleAppMeasurement.framework/GoogleAppMeasurement + + hash + + M9bcWQrIbs3KCe/mmB+IKZlEtWY= + + hash2 + + NXbcqghs/RpjAooRvZfVnBUFr2/o/BOjo3rHjDmYs5E= + + + tvos-arm64/GoogleAppMeasurement.framework/Info.plist + + hash + + BH3IPXizFx/7iFbKzJ+sSLVw9l8= + + hash2 + + muJSunUQbWe6Z6R0qIfnhqztMjhAwnNAx0JvarVKTMs= + + + tvos-arm64/GoogleAppMeasurement.framework/Modules/module.modulemap + + hash + + on1mkulwTtm+ufPJ4eClavLWAuQ= + + hash2 + + gd8e5hMrJihnXu8TQ0xecVPl3Z71GpsKaYxiLbmHezw= + + + tvos-arm64_x86_64-simulator/GoogleAppMeasurement.framework/GoogleAppMeasurement + + hash + + JtLTuojY9AujgMlsD/Agr3L91zU= + + hash2 + + VsGis/GriWAodwrKDdqdYYZmxkm1L02EyZMo/BTcU+E= + + + tvos-arm64_x86_64-simulator/GoogleAppMeasurement.framework/Info.plist + + hash + + PtSAqBbxOah7hBCCJgCFFTzYEM0= + + hash2 + + 5/LLqCokvaEVUQjGDjE8uZfZJecO3vt0fkmaWj0UbJY= + + + tvos-arm64_x86_64-simulator/GoogleAppMeasurement.framework/Modules/module.modulemap + + hash + + on1mkulwTtm+ufPJ4eClavLWAuQ= + + hash2 + + gd8e5hMrJihnXu8TQ0xecVPl3Z71GpsKaYxiLbmHezw= + + + + rules + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^.* + + ^.*\.lproj/ + + optional + + weight + 1000 + + ^.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Base\.lproj/ + + weight + 1010 + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/_CodeSignature/CodeSignature b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/_CodeSignature/CodeSignature new file mode 100644 index 0000000..cbaafc7 Binary files /dev/null and b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/_CodeSignature/CodeSignature differ diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64/GoogleAppMeasurement.framework/GoogleAppMeasurement b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64/GoogleAppMeasurement.framework/GoogleAppMeasurement new file mode 100644 index 0000000..93f05a7 Binary files /dev/null and b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64/GoogleAppMeasurement.framework/GoogleAppMeasurement differ diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64/GoogleAppMeasurement.framework/Info.plist b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64/GoogleAppMeasurement.framework/Info.plist new file mode 100644 index 0000000..a02ddec --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64/GoogleAppMeasurement.framework/Info.plist @@ -0,0 +1,57 @@ + + + + + BuildMachineOSBuild + 23F79 + CFBundleDevelopmentRegion + en + CFBundleExecutable + GoogleAppMeasurement + CFBundleIdentifier + org.cocoapods.GoogleAppMeasurement + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + GoogleAppMeasurement + CFBundlePackageType + FMWK + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + iPhoneOS + + CFBundleVersion + 1 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 21C52 + DTPlatformName + iphoneos + DTPlatformVersion + 17.2 + DTSDKBuild + 21C52 + DTSDKName + iphoneos17.2 + DTXcode + 1520 + DTXcodeBuild + 15C500b + MinimumOSVersion + 100.0 + UIDeviceFamily + + 1 + 2 + + UIRequiredDeviceCapabilities + + arm64 + + + diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64/GoogleAppMeasurement.framework/Modules/module.modulemap b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64/GoogleAppMeasurement.framework/Modules/module.modulemap new file mode 100644 index 0000000..d3499f0 --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64/GoogleAppMeasurement.framework/Modules/module.modulemap @@ -0,0 +1,10 @@ +framework module GoogleAppMeasurement { +umbrella header "GoogleAppMeasurement-umbrella.h" +export * +module * { export * } + link framework "Security" + link framework "SystemConfiguration" + link "c++" + link "sqlite3" + link "z" +} diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/GoogleAppMeasurement b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/GoogleAppMeasurement new file mode 120000 index 0000000..5a946b2 --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/GoogleAppMeasurement @@ -0,0 +1 @@ +Versions/Current/GoogleAppMeasurement \ No newline at end of file diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Modules b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Modules new file mode 120000 index 0000000..5736f31 --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Modules @@ -0,0 +1 @@ +Versions/Current/Modules \ No newline at end of file diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Resources b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Resources new file mode 120000 index 0000000..953ee36 --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Versions/A/GoogleAppMeasurement b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Versions/A/GoogleAppMeasurement new file mode 100644 index 0000000..f30e518 Binary files /dev/null and b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Versions/A/GoogleAppMeasurement differ diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Versions/A/Modules/module.modulemap b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Versions/A/Modules/module.modulemap new file mode 100644 index 0000000..d3499f0 --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Versions/A/Modules/module.modulemap @@ -0,0 +1,10 @@ +framework module GoogleAppMeasurement { +umbrella header "GoogleAppMeasurement-umbrella.h" +export * +module * { export * } + link framework "Security" + link framework "SystemConfiguration" + link "c++" + link "sqlite3" + link "z" +} diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Versions/A/Resources/Info.plist b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Versions/A/Resources/Info.plist new file mode 100644 index 0000000..68436bc --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Versions/A/Resources/Info.plist @@ -0,0 +1,54 @@ + + + + + BuildMachineOSBuild + 23F79 + CFBundleDevelopmentRegion + en + CFBundleExecutable + GoogleAppMeasurement + CFBundleIdentifier + org.cocoapods.GoogleAppMeasurement + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + GoogleAppMeasurement + CFBundlePackageType + FMWK + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 1 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + + DTPlatformName + macosx + DTPlatformVersion + 14.2 + DTSDKBuild + 23C53 + DTSDKName + macosx14.2 + DTXcode + 1520 + DTXcodeBuild + 15C500b + LSMinimumSystemVersion + 10.15 + MinimumOSVersion + 100.0 + UIDeviceFamily + + 2 + + + diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Versions/Current b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Versions/Current new file mode 120000 index 0000000..8c7e5a6 --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst/GoogleAppMeasurement.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-simulator/GoogleAppMeasurement.framework/GoogleAppMeasurement b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-simulator/GoogleAppMeasurement.framework/GoogleAppMeasurement new file mode 100644 index 0000000..5c7c831 Binary files /dev/null and b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-simulator/GoogleAppMeasurement.framework/GoogleAppMeasurement differ diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-simulator/GoogleAppMeasurement.framework/Info.plist b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-simulator/GoogleAppMeasurement.framework/Info.plist new file mode 100644 index 0000000..631c821 --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-simulator/GoogleAppMeasurement.framework/Info.plist @@ -0,0 +1,53 @@ + + + + + BuildMachineOSBuild + 23F79 + CFBundleDevelopmentRegion + en + CFBundleExecutable + GoogleAppMeasurement + CFBundleIdentifier + org.cocoapods.GoogleAppMeasurement + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + GoogleAppMeasurement + CFBundlePackageType + FMWK + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + iPhoneSimulator + + CFBundleVersion + 1 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 21C52 + DTPlatformName + iphonesimulator + DTPlatformVersion + 17.2 + DTSDKBuild + 21C52 + DTSDKName + iphonesimulator17.2 + DTXcode + 1520 + DTXcodeBuild + 15C500b + MinimumOSVersion + 100.0 + UIDeviceFamily + + 1 + 2 + + + diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-simulator/GoogleAppMeasurement.framework/Modules/module.modulemap b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-simulator/GoogleAppMeasurement.framework/Modules/module.modulemap new file mode 100644 index 0000000..d3499f0 --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/ios-arm64_x86_64-simulator/GoogleAppMeasurement.framework/Modules/module.modulemap @@ -0,0 +1,10 @@ +framework module GoogleAppMeasurement { +umbrella header "GoogleAppMeasurement-umbrella.h" +export * +module * { export * } + link framework "Security" + link framework "SystemConfiguration" + link "c++" + link "sqlite3" + link "z" +} diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/GoogleAppMeasurement b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/GoogleAppMeasurement new file mode 120000 index 0000000..5a946b2 --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/GoogleAppMeasurement @@ -0,0 +1 @@ +Versions/Current/GoogleAppMeasurement \ No newline at end of file diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/Modules b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/Modules new file mode 120000 index 0000000..5736f31 --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/Modules @@ -0,0 +1 @@ +Versions/Current/Modules \ No newline at end of file diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/Resources b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/Resources new file mode 120000 index 0000000..953ee36 --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/Versions/A/GoogleAppMeasurement b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/Versions/A/GoogleAppMeasurement new file mode 100644 index 0000000..49faf82 Binary files /dev/null and b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/Versions/A/GoogleAppMeasurement differ diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/Versions/A/Modules/module.modulemap b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/Versions/A/Modules/module.modulemap new file mode 100644 index 0000000..d3499f0 --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/Versions/A/Modules/module.modulemap @@ -0,0 +1,10 @@ +framework module GoogleAppMeasurement { +umbrella header "GoogleAppMeasurement-umbrella.h" +export * +module * { export * } + link framework "Security" + link framework "SystemConfiguration" + link "c++" + link "sqlite3" + link "z" +} diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/Versions/A/Resources/Info.plist b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/Versions/A/Resources/Info.plist new file mode 100644 index 0000000..fffe553 --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/Versions/A/Resources/Info.plist @@ -0,0 +1,50 @@ + + + + + BuildMachineOSBuild + 23F79 + CFBundleDevelopmentRegion + en + CFBundleExecutable + GoogleAppMeasurement + CFBundleIdentifier + org.cocoapods.GoogleAppMeasurement + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + GoogleAppMeasurement + CFBundlePackageType + FMWK + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 1 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + + DTPlatformName + macosx + DTPlatformVersion + 14.2 + DTSDKBuild + 23C53 + DTSDKName + macosx14.2 + DTXcode + 1520 + DTXcodeBuild + 15C500b + LSMinimumSystemVersion + 10.13 + MinimumOSVersion + 100.0 + + diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/Versions/Current b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/Versions/Current new file mode 120000 index 0000000..8c7e5a6 --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/macos-arm64_x86_64/GoogleAppMeasurement.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/tvos-arm64/GoogleAppMeasurement.framework/GoogleAppMeasurement b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/tvos-arm64/GoogleAppMeasurement.framework/GoogleAppMeasurement new file mode 100644 index 0000000..bd387e4 Binary files /dev/null and b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/tvos-arm64/GoogleAppMeasurement.framework/GoogleAppMeasurement differ diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/tvos-arm64/GoogleAppMeasurement.framework/Info.plist b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/tvos-arm64/GoogleAppMeasurement.framework/Info.plist new file mode 100644 index 0000000..7041cdd --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/tvos-arm64/GoogleAppMeasurement.framework/Info.plist @@ -0,0 +1,52 @@ + + + + + BuildMachineOSBuild + 23F79 + CFBundleDevelopmentRegion + en + CFBundleExecutable + GoogleAppMeasurement + CFBundleIdentifier + org.cocoapods.GoogleAppMeasurement + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + GoogleAppMeasurement + CFBundlePackageType + FMWK + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + AppleTVOS + + CFBundleVersion + 1 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 21K354 + DTPlatformName + appletvos + DTPlatformVersion + 17.2 + DTSDKBuild + 21K354 + DTSDKName + appletvos17.2 + DTXcode + 1520 + DTXcodeBuild + 15C500b + MinimumOSVersion + 100.0 + UIDeviceFamily + + 3 + + + diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/tvos-arm64/GoogleAppMeasurement.framework/Modules/module.modulemap b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/tvos-arm64/GoogleAppMeasurement.framework/Modules/module.modulemap new file mode 100644 index 0000000..d3499f0 --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/tvos-arm64/GoogleAppMeasurement.framework/Modules/module.modulemap @@ -0,0 +1,10 @@ +framework module GoogleAppMeasurement { +umbrella header "GoogleAppMeasurement-umbrella.h" +export * +module * { export * } + link framework "Security" + link framework "SystemConfiguration" + link "c++" + link "sqlite3" + link "z" +} diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/tvos-arm64_x86_64-simulator/GoogleAppMeasurement.framework/GoogleAppMeasurement b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/tvos-arm64_x86_64-simulator/GoogleAppMeasurement.framework/GoogleAppMeasurement new file mode 100644 index 0000000..41e0fa6 Binary files /dev/null and b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/tvos-arm64_x86_64-simulator/GoogleAppMeasurement.framework/GoogleAppMeasurement differ diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/tvos-arm64_x86_64-simulator/GoogleAppMeasurement.framework/Info.plist b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/tvos-arm64_x86_64-simulator/GoogleAppMeasurement.framework/Info.plist new file mode 100644 index 0000000..abde33e --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/tvos-arm64_x86_64-simulator/GoogleAppMeasurement.framework/Info.plist @@ -0,0 +1,52 @@ + + + + + BuildMachineOSBuild + 23F79 + CFBundleDevelopmentRegion + en + CFBundleExecutable + GoogleAppMeasurement + CFBundleIdentifier + org.cocoapods.GoogleAppMeasurement + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + GoogleAppMeasurement + CFBundlePackageType + FMWK + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + AppleTVSimulator + + CFBundleVersion + 1 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 21K354 + DTPlatformName + appletvsimulator + DTPlatformVersion + 17.2 + DTSDKBuild + 21K354 + DTSDKName + appletvsimulator17.2 + DTXcode + 1520 + DTXcodeBuild + 15C500b + MinimumOSVersion + 100.0 + UIDeviceFamily + + 3 + + + diff --git a/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/tvos-arm64_x86_64-simulator/GoogleAppMeasurement.framework/Modules/module.modulemap b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/tvos-arm64_x86_64-simulator/GoogleAppMeasurement.framework/Modules/module.modulemap new file mode 100644 index 0000000..d3499f0 --- /dev/null +++ b/Pods/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework/tvos-arm64_x86_64-simulator/GoogleAppMeasurement.framework/Modules/module.modulemap @@ -0,0 +1,10 @@ +framework module GoogleAppMeasurement { +umbrella header "GoogleAppMeasurement-umbrella.h" +export * +module * { export * } + link framework "Security" + link framework "SystemConfiguration" + link "c++" + link "sqlite3" + link "z" +} diff --git a/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/GULAppDelegateSwizzler.m b/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/GULAppDelegateSwizzler.m new file mode 100644 index 0000000..06261d3 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/GULAppDelegateSwizzler.m @@ -0,0 +1,1072 @@ +// 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 + +#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 +#import + +// 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 *); + +#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); + +// 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 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)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 originalDelegate = + [GULAppDelegateSwizzler sharedApplication].delegate; + [GULAppDelegateSwizzler proxyAppDelegate:originalDelegate]; + }); +} + ++ (void)proxyOriginalDelegateIncludingAPNSMethods { + if ([GULAppEnvironmentUtil isAppExtension]) { + return; + } + + [self proxyOriginalDelegate]; + + dispatch_once(&sProxyAppDelegateRemoteNotificationOnceToken, ^{ + id 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)appDelegate { + Class realClass = [appDelegate class]; + + // Create GUL__ + 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 *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 didReceiveRemoteNotificationDonorSEL = @selector(application: + donor_didReceiveRemoteNotification:); + + [self proxyDestinationSelector:didReceiveRemoteNotificationSEL + implementationsFromSourceSelector:didReceiveRemoteNotificationDonorSEL + 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 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 *)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 *)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 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 + +// TODO(Xcode 15): When Xcode 15 is the minimum supported Xcode version, +// it will be unnecessary to check if `TARGET_OS_VISION` is defined. +#if TARGET_OS_IOS && (!defined(TARGET_OS_VISION) || !TARGET_OS_VISION) + +- (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 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 && (!defined(TARGET_OS_VISION) || !TARGET_OS_VISION) + +#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 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 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 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 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 *__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 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 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)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 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)originalDelegate { + return gOriginalAppDelegate; +} + +@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/GULSceneDelegateSwizzler.m b/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/GULSceneDelegateSwizzler.m new file mode 100644 index 0000000..36ba1ca --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/GULSceneDelegateSwizzler.m @@ -0,0 +1,439 @@ +// 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 + +#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 + +#if UISCENE_SUPPORTED +API_AVAILABLE(ios(13.0), tvos(13.0)) +typedef void (*GULOpenURLContextsIMP)(id, SEL, UIScene *, NSSet *); + +API_AVAILABLE(ios(13.0), tvos(13.0)) +typedef void (^GULSceneDelegateInterceptorCallback)(id); + +// 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)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 *)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 *)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 interceptor) { + if ([interceptor + conformsToProtocol:@protocol(UISceneDelegate)]) { + id sceneInterceptor = + (id)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 *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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Internal/GULAppDelegateSwizzler_Private.h b/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Internal/GULAppDelegateSwizzler_Private.h new file mode 100644 index 0000000..38e9315 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Internal/GULAppDelegateSwizzler_Private.h @@ -0,0 +1,55 @@ +/* + * 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 +#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)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)originalDelegate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Internal/GULSceneDelegateSwizzler_Private.h b/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Internal/GULSceneDelegateSwizzler_Private.h new file mode 100644 index 0000000..89896f7 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Internal/GULSceneDelegateSwizzler_Private.h @@ -0,0 +1,48 @@ +/* + * 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 +#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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULAppDelegateSwizzler.h b/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULAppDelegateSwizzler.h new file mode 100644 index 0000000..58dec49 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULAppDelegateSwizzler.h @@ -0,0 +1,107 @@ +/* + * 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 + +#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)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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULApplication.h b/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULApplication.h new file mode 100644 index 0000000..6c44058 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULApplication.h @@ -0,0 +1,50 @@ +/* + * 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 + +#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) + +#import + +#define GULApplication UIApplication +#define GULApplicationDelegate UIApplicationDelegate +#define GULUserActivityRestoring UIUserActivityRestoring + +static NSString *const kGULApplicationClassName = @"UIApplication"; + +#elif TARGET_OS_OSX + +#import + +#define GULApplication NSApplication +#define GULApplicationDelegate NSApplicationDelegate +#define GULUserActivityRestoring NSUserActivityRestoring + +static NSString *const kGULApplicationClassName = @"NSApplication"; + +#elif TARGET_OS_WATCH + +#import + +// 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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULSceneDelegateSwizzler.h b/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULSceneDelegateSwizzler.h new file mode 100644 index 0000000..ed080a3 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULSceneDelegateSwizzler.h @@ -0,0 +1,76 @@ +/* + * 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 +#import + +#if !TARGET_OS_OSX +#import +#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)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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/Common/GULLoggerCodes.h b/Pods/GoogleUtilities/GoogleUtilities/Common/GULLoggerCodes.h new file mode 100644 index 0000000..053ce84 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Common/GULLoggerCodes.h @@ -0,0 +1,56 @@ +/* + * 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 + +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 +}; diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/GULAppEnvironmentUtil.m b/Pods/GoogleUtilities/GoogleUtilities/Environment/GULAppEnvironmentUtil.m new file mode 100644 index 0000000..8883eb5 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Environment/GULAppEnvironmentUtil.m @@ -0,0 +1,305 @@ +// 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 +#import +#import +#import + +#import "third_party/IsAppEncrypted/Public/IsAppEncrypted.h" + +#if TARGET_OS_IOS +#import +#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"; + +static BOOL HasSCInfoFolder(void) { +#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(void) { +#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 *)getSysctlEntry:(const char *)sysctlKey { + static NSString *entryValue; + size_t size; + sysctlbyname(sysctlKey, NULL, &size, NULL, 0); + if (size > 0) { + char *entryValueCStr = malloc(size); + sysctlbyname(sysctlKey, entryValueCStr, &size, NULL, 0); + entryValue = [NSString stringWithCString:entryValueCStr encoding:NSUTF8StringEncoding]; + free(entryValueCStr); + return entryValue; + } else { + return nil; + } +} + ++ (NSString *)deviceModel { + static dispatch_once_t once; + static NSString *deviceModel; + +#if TARGET_OS_OSX || TARGET_OS_MACCATALYST + dispatch_once(&once, ^{ + // The `uname` function only returns x86_64 for Macs. Use `sysctlbyname` instead, but fall back + // to the `uname` function if it fails. + deviceModel = [GULAppEnvironmentUtil getSysctlEntry:"hw.model"]; + if (deviceModel.length == 0) { + struct utsname systemInfo; + if (uname(&systemInfo) == 0) { + deviceModel = [NSString stringWithUTF8String:systemInfo.machine]; + } + } + }); +#else + dispatch_once(&once, ^{ + struct utsname systemInfo; + if (uname(&systemInfo) == 0) { + deviceModel = [NSString stringWithUTF8String:systemInfo.machine]; + } + }); +#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST + return deviceModel; +} + ++ (NSString *)deviceSimulatorModel { + static dispatch_once_t once; + static NSString *model = nil; + + dispatch_once(&once, ^{ +#if TARGET_OS_SIMULATOR +#if TARGET_OS_WATCH + model = @"watchOS Simulator"; +#elif TARGET_OS_TV + model = @"tvOS Simulator"; +#elif defined(TARGET_OS_VISION) && TARGET_OS_VISION + model = @"visionOS Simulator"; +#elif TARGET_OS_IOS + switch ([[UIDevice currentDevice] userInterfaceIdiom]) { + case UIUserInterfaceIdiomPhone: + model = @"iOS Simulator (iPhone)"; + break; + case UIUserInterfaceIdiomPad: + model = @"iOS Simulator (iPad)"; + break; + default: + model = @"iOS Simulator (Unknown)"; + break; + } +#endif +#elif TARGET_OS_EMBEDDED + model = [GULAppEnvironmentUtil getSysctlEntry:"hw.machine"]; +#else + model = [GULAppEnvironmentUtil getSysctlEntry:"hw.model"]; +#endif + }); + + return model; +} + ++ (NSString *)systemVersion { +#if TARGET_OS_IOS + return [UIDevice currentDevice].systemVersion; +#elif TARGET_OS_OSX || TARGET_OS_TV || TARGET_OS_WATCH || \ + (defined(TARGET_OS_VISION) && TARGET_OS_VISION) + // 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 Apple + 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 && (!defined(TARGET_OS_VISION) || !TARGET_OS_VISION) +#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"; +#elif defined(TARGET_OS_VISION) && TARGET_OS_VISION + applePlatform = @"visionos"; +#endif // TARGET_OS_MACCATALYST + + return applePlatform; +} + ++ (NSString *)appleDevicePlatform { + NSString *firebasePlatform = [GULAppEnvironmentUtil applePlatform]; +#if TARGET_OS_IOS + // This check is necessary because iOS-only apps running on iPad + // will report UIUserInterfaceIdiomPhone via UI_USER_INTERFACE_IDIOM(). + if ([firebasePlatform isEqualToString:@"ios"] && + ([[UIDevice currentDevice].model.lowercaseString containsString:@"ipad"] || + [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)) { + return @"ipados"; + } +#endif + + return firebasePlatform; +} + ++ (NSString *)deploymentType { +#if SWIFT_PACKAGE + NSString *deploymentType = @"swiftpm"; +#elif FIREBASE_BUILD_CARTHAGE + NSString *deploymentType = @"carthage"; +#elif FIREBASE_BUILD_ZIP_FILE + NSString *deploymentType = @"zip"; +#elif COCOAPODS + NSString *deploymentType = @"cocoapods"; +#else + NSString *deploymentType = @"unknown"; +#endif + + return deploymentType; +} + +@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/GULHeartbeatDateStorage.m b/Pods/GoogleUtilities/GoogleUtilities/Environment/GULHeartbeatDateStorage.m new file mode 100644 index 0000000..f1d8ddc --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Environment/GULHeartbeatDateStorage.m @@ -0,0 +1,153 @@ +/* + * 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" + +NSString *const kGULHeartbeatStorageDirectory = @"Google/FIRApp"; + +@interface GULHeartbeatDateStorage () + +/** 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) { + _fileName = fileName; + } + return self; +} + +/** Lazy getter for fileURL. + * @return fileURL where heartbeat information is stored. + */ +- (NSURL *)fileURL { + if (!_fileURL) { + NSURL *directoryURL = [self directoryPathURL]; + [self checkAndCreateDirectory:directoryURL]; + _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 { + NSArray *paths; +#if TARGET_OS_TV + paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); +#else + paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); +#endif // TARGET_OS_TV + NSString *rootPath = [paths lastObject]; + NSURL *rootURL = [NSURL fileURLWithPath:rootPath]; + NSURL *directoryURL = [rootURL URLByAppendingPathComponent:kGULHeartbeatStorageDirectory]; + return directoryURL; +} + +/** Check for the existence of the directory specified by the URL, and create it if it does not + * exist. + * @param directoryPathURL The path to the directory that needs to exist. + */ +- (void)checkAndCreateDirectory:(NSURL *)directoryPathURL { + NSError *error; + if (![directoryPathURL checkResourceIsReachableAndReturnError:&error]) { + NSError *error; + [[NSFileManager defaultManager] createDirectoryAtURL:directoryPathURL + withIntermediateDirectories:YES + attributes:nil + error:&error]; + } +} + +- (nullable NSDate *)heartbeatDateForTag:(NSString *)tag { + @synchronized(self.class) { + NSDictionary *heartbeatDictionary = [self heartbeatDictionaryWithFileURL:self.fileURL]; + NSDate *heartbeatDate = heartbeatDictionary[tag]; + + // Validate the value type. If the storage file was corrupted or updated with a different format + // by a newer SDK version the value type may be different. + if (![heartbeatDate isKindOfClass:[NSDate class]]) { + heartbeatDate = nil; + } + + return heartbeatDate; + } +} + +- (BOOL)setHearbeatDate:(NSDate *)date forTag:(NSString *)tag { + // Synchronize on the class to ensure that the different instances of the class will not access + // the same file concurrently. + // TODO: Consider a different synchronization strategy here and in `-heartbeatDateForTag:` method. + // Currently no heartbeats can be read/written concurrently even if they are in different files. + @synchronized(self.class) { + NSMutableDictionary *heartbeatDictionary = + [[self heartbeatDictionaryWithFileURL:self.fileURL] mutableCopy]; + heartbeatDictionary[tag] = date; + NSError *error; + BOOL isSuccess = [self writeDictionary:[heartbeatDictionary copy] + forWritingURL:self.fileURL + error:&error]; + return isSuccess; + } +} + +- (NSDictionary *)heartbeatDictionaryWithFileURL:(NSURL *)readingFileURL { + NSDictionary *heartbeatDictionary; + + NSError *error; + NSData *objectData = [NSData dataWithContentsOfURL:readingFileURL options:0 error:&error]; + + if (objectData.length > 0 && error == nil) { + NSSet *objectClasses = + [NSSet setWithArray:@[ NSDictionary.class, NSDate.class, NSString.class ]]; + heartbeatDictionary = [GULSecureCoding unarchivedObjectOfClasses:objectClasses + fromData:objectData + error:&error]; + } + + if (heartbeatDictionary.count == 0 || error != nil) { + heartbeatDictionary = [NSDictionary dictionary]; + } + + return heartbeatDictionary; +} + +- (BOOL)writeDictionary:(NSDictionary *)dictionary + forWritingURL:(NSURL *)writingFileURL + error:(NSError **)outError { + // Archive a mutable copy `dictionary` for writing to disk. This is done for + // backwards compatibility. See Google Utilities issue #36 for more context. + // TODO: Remove usage of mutable copy in a future version of Google Utilities. + NSData *data = [GULSecureCoding archivedDataWithRootObject:[dictionary mutableCopy] + error:outError]; + if (data.length == 0) { + return NO; + } + + return [data writeToURL:writingFileURL atomically:YES]; +} + +@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/GULHeartbeatDateStorageUserDefaults.m b/Pods/GoogleUtilities/GoogleUtilities/Environment/GULHeartbeatDateStorageUserDefaults.m new file mode 100644 index 0000000..f8f1159 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Environment/GULHeartbeatDateStorageUserDefaults.m @@ -0,0 +1,68 @@ +/* + * Copyright 2021 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/GULHeartbeatDateStorageUserDefaults.h" + +@interface GULHeartbeatDateStorageUserDefaults () + +/** The storage to store the date of the last sent heartbeat. */ +@property(nonatomic, readonly) NSUserDefaults *userDefaults; + +/** The key for user defaults to store heartbeat information. */ +@property(nonatomic, readonly) NSString *key; + +@end + +@implementation GULHeartbeatDateStorageUserDefaults + +- (instancetype)initWithDefaults:(NSUserDefaults *)defaults key:(NSString *)key { + self = [super init]; + if (self) { + _userDefaults = defaults; + _key = key; + } + return self; +} + +- (NSMutableDictionary *)heartbeatDictionaryFromDefaults { + NSDictionary *heartbeatDict = [self.userDefaults objectForKey:self.key]; + if (heartbeatDict != nil) { + return [heartbeatDict mutableCopy]; + } else { + return [NSMutableDictionary dictionary]; + } +} + +- (nullable NSDate *)heartbeatDateForTag:(NSString *)tag { + NSDate *date = nil; + @synchronized(self.userDefaults) { + NSMutableDictionary *dict = [self heartbeatDictionaryFromDefaults]; + date = dict[tag]; + } + + return date; +} + +- (BOOL)setHearbeatDate:(NSDate *)date forTag:(NSString *)tag { + @synchronized(self.userDefaults) { + NSMutableDictionary *dict = [self heartbeatDictionaryFromDefaults]; + dict[tag] = date; + [self.userDefaults setObject:dict forKey:self.key]; + } + return true; +} + +@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/GULSecureCoding.m b/Pods/GoogleUtilities/GoogleUtilities/Environment/GULSecureCoding.m new file mode 100644 index 0000000..a066825 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Environment/GULSecureCoding.m @@ -0,0 +1,103 @@ +// 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 *)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)aClass + fromData:(NSData *)data + error:(NSError **)outError { + return [self unarchivedObjectOfClasses:[NSSet setWithObject:aClass] fromData:data error:outError]; +} + ++ (nullable NSData *)archivedDataWithRootObject:(id)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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/NetworkInfo/GULNetworkInfo.m b/Pods/GoogleUtilities/GoogleUtilities/Environment/NetworkInfo/GULNetworkInfo.m new file mode 100644 index 0000000..622ae4a --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Environment/NetworkInfo/GULNetworkInfo.m @@ -0,0 +1,138 @@ +// Copyright 2022 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/GULNetworkInfo.h" + +#import + +#import +#if __has_include("CoreTelephony/CTTelephonyNetworkInfo.h") && !TARGET_OS_MACCATALYST && \ + !TARGET_OS_OSX && !TARGET_OS_TV && !TARGET_OS_WATCH +#define TARGET_HAS_MOBILE_CONNECTIVITY +#import +#import +#import +#endif + +@implementation GULNetworkInfo + +#ifdef TARGET_HAS_MOBILE_CONNECTIVITY ++ (CTTelephonyNetworkInfo *)getNetworkInfo { + static CTTelephonyNetworkInfo *networkInfo; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + networkInfo = [[CTTelephonyNetworkInfo alloc] init]; + }); + return networkInfo; +} +#endif + ++ (NSString *_Nullable)getNetworkMobileCountryCode { +#ifdef TARGET_HAS_MOBILE_CONNECTIVITY + CTTelephonyNetworkInfo *networkInfo = [GULNetworkInfo getNetworkInfo]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + CTCarrier *provider = networkInfo.subscriberCellularProvider; +#pragma clang diagnostic push + return provider.mobileCountryCode; +#endif + return nil; +} + ++ (NSString *_Nullable)getNetworkMobileNetworkCode { +#ifdef TARGET_HAS_MOBILE_CONNECTIVITY + CTTelephonyNetworkInfo *networkInfo = [GULNetworkInfo getNetworkInfo]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + CTCarrier *provider = networkInfo.subscriberCellularProvider; +#pragma clang diagnostic push + return provider.mobileNetworkCode; +#endif + return nil; +} + +/** + * Returns the formatted MccMnc if the inputs are valid, otherwise nil + * @param mcc The Mobile Country Code returned from `getNetworkMobileCountryCode` + * @param mnc The Mobile Network Code returned from `getNetworkMobileNetworkCode` + * @returns A string with the concatenated mccMnc if both inputs are valid, otherwise nil + */ ++ (NSString *_Nullable)formatMcc:(NSString *)mcc andMNC:(NSString *)mnc { + // These are both nil if the target does not support mobile connectivity + if (mcc == nil && mnc == nil) { + return nil; + } + + if (mcc.length != 3 || mnc.length < 2 || mnc.length > 3) { + return nil; + } + + // If the resulting appended mcc + mnc contains characters that are not + // decimal digits, return nil + static NSCharacterSet *notDigits; + static dispatch_once_t token; + dispatch_once(&token, ^{ + notDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet]; + }); + NSString *mccMnc = [mcc stringByAppendingString:mnc]; + if ([mccMnc rangeOfCharacterFromSet:notDigits].location != NSNotFound) { + return nil; + } + + return mccMnc; +} + ++ (GULNetworkType)getNetworkType { + GULNetworkType networkType = GULNetworkTypeNone; + +#ifdef TARGET_HAS_MOBILE_CONNECTIVITY + static SCNetworkReachabilityRef reachabilityRef = 0; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + reachabilityRef = SCNetworkReachabilityCreateWithName(kCFAllocatorSystemDefault, "google.com"); + }); + + if (!reachabilityRef) { + return GULNetworkTypeNone; + } + + SCNetworkReachabilityFlags reachabilityFlags = 0; + SCNetworkReachabilityGetFlags(reachabilityRef, &reachabilityFlags); + + // Parse the network flags to set the network type. + if (reachabilityFlags & kSCNetworkReachabilityFlagsReachable) { + if (reachabilityFlags & kSCNetworkReachabilityFlagsIsWWAN) { + networkType = GULNetworkTypeMobile; + } else { + networkType = GULNetworkTypeWIFI; + } + } +#endif + + return networkType; +} + ++ (NSString *)getNetworkRadioType { +#ifdef TARGET_HAS_MOBILE_CONNECTIVITY + CTTelephonyNetworkInfo *networkInfo = [GULNetworkInfo getNetworkInfo]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + return networkInfo.currentRadioAccessTechnology; +#pragma clang diagnostic pop +#else + return @""; +#endif +} + +@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULAppEnvironmentUtil.h b/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULAppEnvironmentUtil.h new file mode 100644 index 0000000..e84ab9e --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULAppEnvironmentUtil.h @@ -0,0 +1,69 @@ +/* + * 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 + +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 device model, with simulator-specific values. Returns an empty string if device +/// model cannot be retrieved. ++ (nullable NSString *)deviceSimulatorModel; + +/// 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 __deprecated; + +/// @return An Apple platform. Possible values "ios", "tvos", "macos", "watchos", "maccatalyst", and +/// "visionos". ++ (NSString *)applePlatform; + +/// @return An Apple Device platform. Same possible values as `applePlatform`, with the addition of +/// "ipados". ++ (NSString *)appleDevicePlatform; + +/// @return The way the library was added to the app, e.g. "swiftpm", "cocoapods", etc. ++ (NSString *)deploymentType; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorable.h b/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorable.h new file mode 100644 index 0000000..43d3740 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorable.h @@ -0,0 +1,40 @@ +/* + * Copyright 2021 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 + +NS_ASSUME_NONNULL_BEGIN + +/** + * Describes an object that can store and fetch heartbeat dates for given tags. + */ +@protocol GULHeartbeatDateStorable + +/** + * 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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorage.h b/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorage.h new file mode 100644 index 0000000..245b1a2 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorage.h @@ -0,0 +1,54 @@ +/* + * 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 + +#import "GULHeartbeatDateStorable.h" + +NS_ASSUME_NONNULL_BEGIN + +/// The name of the directory where the heartbeat data is stored. +extern NSString *const kGULHeartbeatStorageDirectory; + +/// 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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorageUserDefaults.h b/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorageUserDefaults.h new file mode 100644 index 0000000..e6c7dda --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorageUserDefaults.h @@ -0,0 +1,51 @@ +/* + * Copyright 2021 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 + +#import "GULHeartbeatDateStorable.h" + +NS_ASSUME_NONNULL_BEGIN + +/// Stores either a date or a dictionary to a specified file. +@interface GULHeartbeatDateStorageUserDefaults : NSObject + +/** + * Default initializer. tvOS can only write to the cache directory and + * there are no guarantees that the directory will persist. User defaults will + * be retained, so that should be used instead. + * @param defaults User defaults instance to store the heartbeat information. + * @param key The key to be used with the user defaults instance. + */ +- (instancetype)initWithDefaults:(NSUserDefaults *)defaults key:(NSString *)key; + +- (instancetype)init NS_UNAVAILABLE; + +/** + * 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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainStorage.h b/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainStorage.h new file mode 100644 index 0000000..af10cb4 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainStorage.h @@ -0,0 +1,82 @@ +/* + * 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 + +@class FBLPromise; + +NS_ASSUME_NONNULL_BEGIN + +/// The class provides a convenient, multiplatform abstraction of the Keychain. +/// +/// When using this API on macOS, the corresponding target must be signed with a provisioning +/// profile that has the Keychain Sharing capability enabled. +@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> *)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 *)setObject:(id)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 *)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_OS_OSX + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainUtils.h b/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainUtils.h new file mode 100644 index 0000000..9c17356 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainUtils.h @@ -0,0 +1,64 @@ +/* + * 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 + +NS_ASSUME_NONNULL_BEGIN + +FOUNDATION_EXPORT NSString *const kGULKeychainUtilsErrorDomain; + +/// A collection of helper functions that abstract away common Keychain operations. +/// +/// When using this API on macOS, the corresponding target must be signed with a provisioning +/// profile that has the Keychain Sharing capability enabled. +@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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULNetworkInfo.h b/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULNetworkInfo.h new file mode 100644 index 0000000..d3025cd --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULNetworkInfo.h @@ -0,0 +1,57 @@ +// Copyright 2022 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 + +NS_ASSUME_NONNULL_BEGIN + +/// The type of network that the device is running with. Values should correspond to the NetworkType +/// values in android/play/playlog/proto/clientanalytics.proto +typedef NS_ENUM(NSInteger, GULNetworkType) { + GULNetworkTypeNone = -1, + GULNetworkTypeMobile = 0, + GULNetworkTypeWIFI = 1, +}; + +/// Collection of utilities to read network status information +@interface GULNetworkInfo : NSObject + +/// Returns the cellular mobile country code (mcc) if CoreTelephony is supported, otherwise nil ++ (NSString *_Nullable)getNetworkMobileCountryCode; + +/// Returns the cellular mobile network code (mnc) if CoreTelephony is supported, otherwise nil ++ (NSString *_Nullable)getNetworkMobileNetworkCode; + +/** + * Returns the formatted MccMnc if the inputs are valid, otherwise nil + * @param mcc The Mobile Country Code returned from `getNetworkMobileCountryCode` + * @param mnc The Mobile Network Code returned from `getNetworkMobileNetworkCode` + * @returns A string with the concatenated mccMnc if both inputs are valid, otherwise nil + */ ++ (NSString *_Nullable)formatMcc:(NSString *_Nullable)mcc andMNC:(NSString *_Nullable)mnc; + +/// Returns an enum indicating the network type. The enum values should be easily transferrable to +/// the NetworkType value in android/play/playlog/proto/clientanalytics.proto. Right now this always +/// returns None on platforms other than iOS. This should be updated in the future to return Wi-Fi +/// values for the other platforms when applicable. ++ (GULNetworkType)getNetworkType; + +/// Returns a string indicating the radio access technology used by the app. The return value will +/// be one of CTRadioAccess constants defined in +/// https://developer.apple.com/documentation/coretelephony/cttelephonynetworkinfo/radio_access_technology_constants ++ (NSString *)getNetworkRadioType; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULSecureCoding.h b/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULSecureCoding.h new file mode 100644 index 0000000..e9acc8e --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULSecureCoding.h @@ -0,0 +1,36 @@ +// 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 + +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 *)classes + fromData:(NSData *)data + error:(NSError **)outError; + ++ (nullable id)unarchivedObjectOfClass:(Class)aClass + fromData:(NSData *)data + error:(NSError **)outError; + ++ (nullable NSData *)archivedDataWithRootObject:(id)object error:(NSError **)outError; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULURLSessionDataResponse.h b/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULURLSessionDataResponse.h new file mode 100644 index 0000000..e88eb67 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/GULURLSessionDataResponse.h @@ -0,0 +1,31 @@ +/* + * 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 + +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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/NSURLSession+GULPromises.h b/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/NSURLSession+GULPromises.h new file mode 100644 index 0000000..7bed005 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Environment/Public/GoogleUtilities/NSURLSession+GULPromises.h @@ -0,0 +1,37 @@ +/* + * 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 + +@class FBLPromise; +@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 *)gul_dataTaskPromiseWithRequest: + (NSURLRequest *)URLRequest; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/SecureStorage/GULKeychainStorage.m b/Pods/GoogleUtilities/GoogleUtilities/Environment/SecureStorage/GULKeychainStorage.m new file mode 100644 index 0000000..022c1bf --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Environment/SecureStorage/GULKeychainStorage.m @@ -0,0 +1,198 @@ +/* + * 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 + +#if __has_include() +#import +#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> *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> *)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 *)setObject:(id)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 *)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> *)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 _Nullable(id _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 *)keychainQueryWithKey:(NSString *)key + accessGroup:(nullable NSString *)accessGroup { + NSMutableDictionary *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 (@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 6.0, *)) { + // Ensures that the keychain query behaves the same across all platforms. + // See go/firebase-macos-keychain-popups for details. + query[(__bridge id)kSecUseDataProtectionKeychain] = (__bridge id)kCFBooleanTrue; + } + +#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_OS_OSX + + return query; +} + +@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/SecureStorage/GULKeychainUtils.m b/Pods/GoogleUtilities/GoogleUtilities/Environment/SecureStorage/GULKeychainUtils.m new file mode 100644 index 0000000..57855a0 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Environment/SecureStorage/GULKeychainUtils.m @@ -0,0 +1,133 @@ +/* + * 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 *mutableGetItemQuery = + [[[self class] multiplatformQueryWithQuery:query] mutableCopy]; + + mutableGetItemQuery[(__bridge id)kSecReturnData] = @YES; + mutableGetItemQuery[(__bridge id)kSecMatchLimit] = (__bridge id)kSecMatchLimitOne; + + CFDataRef result = NULL; + OSStatus status = + SecItemCopyMatching((__bridge CFDictionaryRef)mutableGetItemQuery, (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 { + NSDictionary *multiplatformQuery = [[self class] multiplatformQueryWithQuery:query]; + + NSData *existingItem = [self getItemWithQuery:multiplatformQuery error:outError]; + if (outError && *outError) { + return NO; + } + + OSStatus status; + if (!existingItem) { + NSMutableDictionary *mutableAddItemQuery = [multiplatformQuery mutableCopy]; + mutableAddItemQuery[(__bridge id)kSecAttrAccessible] = + (__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly; + mutableAddItemQuery[(__bridge id)kSecValueData] = item; + + status = SecItemAdd((__bridge CFDictionaryRef)mutableAddItemQuery, NULL); + } else { + NSDictionary *attributes = @{(__bridge id)kSecValueData : item}; + status = SecItemUpdate((__bridge CFDictionaryRef)multiplatformQuery, + (__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 { + NSDictionary *deleteItemQuery = [[self class] multiplatformQueryWithQuery:query]; + + OSStatus status = SecItemDelete((__bridge CFDictionaryRef)deleteItemQuery); + + if (status == noErr || status == errSecItemNotFound) { + if (outError) { + *outError = nil; + } + return YES; + } + + if (outError) { + *outError = [self keychainErrorWithFunction:@"SecItemDelete" status:status]; + } + return NO; +} + +#pragma mark - Private + +/// Returns a `NSDictionary` query that behaves the same across all platforms. +/// - Note: In practice, this API only makes a difference to keychain queries on macOS. +/// See go/firebase-macos-keychain-popups for details. +/// - Parameter query: A query to create the protected keychain query with. ++ (NSDictionary *)multiplatformQueryWithQuery:(NSDictionary *)query { + NSMutableDictionary *multiplatformQuery = [query mutableCopy]; + if (@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 6.0, *)) { + multiplatformQuery[(__bridge id)kSecUseDataProtectionKeychain] = (__bridge id)kCFBooleanTrue; + } + return [multiplatformQuery copy]; +} + +#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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/URLSessionPromiseWrapper/GULURLSessionDataResponse.m b/Pods/GoogleUtilities/GoogleUtilities/Environment/URLSessionPromiseWrapper/GULURLSessionDataResponse.m new file mode 100644 index 0000000..559875a --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Environment/URLSessionPromiseWrapper/GULURLSessionDataResponse.m @@ -0,0 +1,30 @@ +/* + * 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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/Environment/URLSessionPromiseWrapper/NSURLSession+GULPromises.m b/Pods/GoogleUtilities/GoogleUtilities/Environment/URLSessionPromiseWrapper/NSURLSession+GULPromises.m new file mode 100644 index 0000000..6c70310 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Environment/URLSessionPromiseWrapper/NSURLSession+GULPromises.m @@ -0,0 +1,46 @@ +/* + * 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() +#import +#else +#import "FBLPromises.h" +#endif + +#import "GoogleUtilities/Environment/Public/GoogleUtilities/GULURLSessionDataResponse.h" + +@implementation NSURLSession (GULPromises) + +- (FBLPromise *)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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/Logger/GULLogger.m b/Pods/GoogleUtilities/GoogleUtilities/Logger/GULLogger.m new file mode 100644 index 0000000..015db14 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Logger/GULLogger.m @@ -0,0 +1,219 @@ +// 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 + +#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); + } +} + +GULLoggerLevel GULGetLoggerLevel(void) { + return sGULLoggerMaximumLevel; +} + +__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(void) { + sGULLoggerOnceToken = 0; + sGULLoggerDebugMode = NO; + sGULLoggerMaximumLevel = GULLoggerLevelNotice; +} + +aslclient getGULLoggerClient(void) { + return sGULLoggerClient; +} + +dispatch_queue_t getGULClientQueue(void) { + return sGULClientQueue; +} + +BOOL getGULLoggerDebugMode(void) { + 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 __unused 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] [{service}][I-XYZ000001] Configure blah failed. + * Calling GULLogDebug({service}, @"I-XYZ000001", @"Configure succeed.") shows: + * yyyy-mm-dd hh:mm:ss.SSS sender[PID] [{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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h b/Pods/GoogleUtilities/GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h new file mode 100644 index 0000000..3643568 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h @@ -0,0 +1,164 @@ +/* + * 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 + +#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); + +/** + * Gets the current GULLoggerLevel. + */ +extern GULLoggerLevel GULGetLoggerLevel(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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/Logger/Public/GoogleUtilities/GULLoggerLevel.h b/Pods/GoogleUtilities/GoogleUtilities/Logger/Public/GoogleUtilities/GULLoggerLevel.h new file mode 100644 index 0000000..f0ee435 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Logger/Public/GoogleUtilities/GULLoggerLevel.h @@ -0,0 +1,37 @@ +/* + * 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 + +/** + * 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); diff --git a/Pods/GoogleUtilities/GoogleUtilities/MethodSwizzler/GULSwizzler.m b/Pods/GoogleUtilities/GoogleUtilities/MethodSwizzler/GULSwizzler.m new file mode 100644 index 0000000..7f0c82e --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/MethodSwizzler/GULSwizzler.m @@ -0,0 +1,153 @@ +// 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 + +#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 *)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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/GULOriginalIMPConvenienceMacros.h b/Pods/GoogleUtilities/GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/GULOriginalIMPConvenienceMacros.h new file mode 100644 index 0000000..a33262a --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/GULOriginalIMPConvenienceMacros.h @@ -0,0 +1,207 @@ +/* + * 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) diff --git a/Pods/GoogleUtilities/GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/GULSwizzler.h b/Pods/GoogleUtilities/GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/GULSwizzler.h new file mode 100644 index 0000000..26949c8 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/GULSwizzler.h @@ -0,0 +1,71 @@ +/* + * 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 + +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 *)ivarObjectsForObject:(id)object; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleUtilities/GoogleUtilities/NSData+zlib/GULNSData+zlib.m b/Pods/GoogleUtilities/GoogleUtilities/NSData+zlib/GULNSData+zlib.m new file mode 100644 index 0000000..e441e36 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/NSData+zlib/GULNSData+zlib.m @@ -0,0 +1,207 @@ +// 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 + +#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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/NSData+zlib/Public/GoogleUtilities/GULNSData+zlib.h b/Pods/GoogleUtilities/GoogleUtilities/NSData+zlib/Public/GoogleUtilities/GULNSData+zlib.h new file mode 100644 index 0000000..36f94a7 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/NSData+zlib/Public/GoogleUtilities/GULNSData+zlib.h @@ -0,0 +1,49 @@ +// 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 + +/// 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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/GULMutableDictionary.m b/Pods/GoogleUtilities/GoogleUtilities/Network/GULMutableDictionary.m new file mode 100644 index 0000000..7726d15 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Network/GULMutableDictionary.m @@ -0,0 +1,101 @@ +// 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)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)key { + __block id object; + dispatch_sync(_queue, ^{ + object = self->_objects[key]; + }); + return object; +} + +- (void)setObject:(id)obj forKeyedSubscript:(id)key { + dispatch_async(_queue, ^{ + self->_objects[key] = obj; + }); +} + +- (NSDictionary *)dictionary { + __block NSDictionary *dictionary; + dispatch_sync(_queue, ^{ + dictionary = [self->_objects copy]; + }); + return dictionary; +} + +@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/GULNetwork.m b/Pods/GoogleUtilities/GoogleUtilities/Network/GULNetwork.m new file mode 100644 index 0000000..327a3a0 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Network/GULNetwork.m @@ -0,0 +1,405 @@ +// 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 () +@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 { + return [self postURL:url + headers:nil + payload:payload + queue:queue + usingBackgroundSession:usingBackgroundSession + completionHandler:handler]; +} + +- (NSString *)postURL:(NSURL *)url + headers:(NSDictionary *)headers + 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; + } + request.allHTTPHeaderFields = headers; + + 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)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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/GULNetworkConstants.m b/Pods/GoogleUtilities/GoogleUtilities/Network/GULNetworkConstants.m new file mode 100644 index 0000000..e4b8469 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Network/GULNetworkConstants.m @@ -0,0 +1,41 @@ +// 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 + +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]"; diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/GULNetworkInternal.h b/Pods/GoogleUtilities/GoogleUtilities/Network/GULNetworkInternal.h new file mode 100644 index 0000000..5aca9fd --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Network/GULNetworkInternal.h @@ -0,0 +1,24 @@ +/* + * 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 + +#import "GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h" + +extern NSString *const kGULNetworkErrorDomain; + +/// The logger service for GULNetwork. +extern GULLoggerService kGULLoggerNetwork; diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/GULNetworkURLSession.m b/Pods/GoogleUtilities/GoogleUtilities/Network/GULNetworkURLSession.m new file mode 100644 index 0000000..0847647 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Network/GULNetworkURLSession.m @@ -0,0 +1,744 @@ +// 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 + +#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 () +@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)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]]; + // To avoid a runtime warning in Xcode 15 Beta 4, the given `URLRequest` + // should have a nil `HTTPBody`. To workaround this, the given `URLRequest` + // is copied and the `HTTPBody` data is removed. + NSData *givenRequestHTTPBody = [request.HTTPBody copy]; + NSMutableURLRequest *requestWithoutHTTPBody = [request mutableCopy]; + requestWithoutHTTPBody.HTTPBody = nil; + + postRequestTask = [session uploadTaskWithRequest:requestWithoutHTTPBody + fromData:givenRequestHTTPBody]; + } + + 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 diagnostic 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 { + return [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:sessionID]; +} + +- (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 *)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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h b/Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h new file mode 100644 index 0000000..a8cc45b --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h @@ -0,0 +1,46 @@ +/* + * 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 + +/// 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)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)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)key; + +/// Returns the immutable dictionary. +- (NSDictionary *)dictionary; + +@end diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULNetwork.h b/Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULNetwork.h new file mode 100644 index 0000000..8631b8b --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULNetwork.h @@ -0,0 +1,97 @@ +/* + * 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 + +#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 reachabilityDelegate; + +/// An optional delegate that can be used to log messages, warnings or errors that occur in the +/// network operations. +@property(nonatomic, weak) id 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; + +/// Compresses and sends a POST request with the provided headers and 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 + headers:(NSDictionary *)headers + 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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkConstants.h b/Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkConstants.h new file mode 100644 index 0000000..1cbedd1 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkConstants.h @@ -0,0 +1,71 @@ +/* + * 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 + +/// 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; diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkLoggerProtocol.h b/Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkLoggerProtocol.h new file mode 100644 index 0000000..425c073 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkLoggerProtocol.h @@ -0,0 +1,49 @@ +/* + * 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 + +#import "GULNetworkMessageCode.h" + +/// The log levels used by GULNetworkLogger. +typedef NS_ENUM(NSInteger, GULNetworkLogLevel) { + kGULNetworkLogLevelError = 3, + kGULNetworkLogLevelWarning = 4, + kGULNetworkLogLevelInfo = 6, + kGULNetworkLogLevelDebug = 7, +}; + +@protocol GULNetworkLoggerDelegate + +@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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkMessageCode.h b/Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkMessageCode.h new file mode 100644 index 0000000..507bc5a --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkMessageCode.h @@ -0,0 +1,47 @@ +/* + * 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 + +// 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 +}; diff --git a/Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkURLSession.h b/Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkURLSession.h new file mode 100644 index 0000000..3f9f7f9 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkURLSession.h @@ -0,0 +1,62 @@ +/* + * 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 + +#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 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)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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/Privacy/Resources/PrivacyInfo.xcprivacy b/Pods/GoogleUtilities/GoogleUtilities/Privacy/Resources/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..eba704d --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Privacy/Resources/PrivacyInfo.xcprivacy @@ -0,0 +1,35 @@ + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + + NSPrivacyCollectedDataTypes + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryUserDefaults + NSPrivacyAccessedAPITypeReasons + + 1C8F.1 + C56D.1 + + + + + + diff --git a/Pods/GoogleUtilities/GoogleUtilities/Reachability/GULReachabilityChecker+Internal.h b/Pods/GoogleUtilities/GoogleUtilities/Reachability/GULReachabilityChecker+Internal.h new file mode 100644 index 0000000..103ed3b --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Reachability/GULReachabilityChecker+Internal.h @@ -0,0 +1,48 @@ +/* + * 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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/Reachability/GULReachabilityChecker.m b/Pods/GoogleUtilities/GoogleUtilities/Reachability/GULReachabilityChecker.m new file mode 100644 index 0000000..929fd99 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Reachability/GULReachabilityChecker.m @@ -0,0 +1,263 @@ +// 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 + +#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)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)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 || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) + 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 || (defined(TARGET_OS_VISION) && TARGET_OS_VISION) + 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]; + } +} diff --git a/Pods/GoogleUtilities/GoogleUtilities/Reachability/GULReachabilityMessageCode.h b/Pods/GoogleUtilities/GoogleUtilities/Reachability/GULReachabilityMessageCode.h new file mode 100644 index 0000000..373e0af --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Reachability/GULReachabilityMessageCode.h @@ -0,0 +1,29 @@ +/* + * 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 + +// 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 +}; diff --git a/Pods/GoogleUtilities/GoogleUtilities/Reachability/Public/GoogleUtilities/GULReachabilityChecker.h b/Pods/GoogleUtilities/GoogleUtilities/Reachability/Public/GoogleUtilities/GULReachabilityChecker.h new file mode 100644 index 0000000..0c70c05 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/Reachability/Public/GoogleUtilities/GULReachabilityChecker.h @@ -0,0 +1,79 @@ +/* + * 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 +#if !TARGET_OS_WATCH +#import +#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 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)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 diff --git a/Pods/GoogleUtilities/GoogleUtilities/UserDefaults/GULUserDefaults.m b/Pods/GoogleUtilities/GoogleUtilities/UserDefaults/GULUserDefaults.m new file mode 100644 index 0000000..6c45048 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/UserDefaults/GULUserDefaults.m @@ -0,0 +1,196 @@ +// 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/UserDefaults/Public/GoogleUtilities/GULUserDefaults.h" + +#import "GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h" + +NS_ASSUME_NONNULL_BEGIN + +static NSString *const kGULLogFormat = @"I-GUL%06ld"; + +static GULLoggerService kGULLogUserDefaultsService = @"[GoogleUtilities/UserDefaults]"; + +typedef NS_ENUM(NSInteger, GULUDMessageCode) { + GULUDMessageCodeInvalidKeyGet = 1, + GULUDMessageCodeInvalidKeySet = 2, + GULUDMessageCodeInvalidObjectSet = 3, + GULUDMessageCodeSynchronizeFailed = 4, +}; + +@interface GULUserDefaults () + +/// Equivalent to the suite name for NSUserDefaults. +@property(readonly) CFStringRef appNameRef; + +@property(atomic) BOOL isPreferenceFileExcluded; + +@end + +@implementation GULUserDefaults { + // The application name is the same with the suite name of the NSUserDefaults, and it is used for + // preferences. + CFStringRef _appNameRef; +} + ++ (GULUserDefaults *)standardUserDefaults { + static GULUserDefaults *standardUserDefaults; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + standardUserDefaults = [[GULUserDefaults alloc] init]; + }); + return standardUserDefaults; +} + +- (instancetype)init { + return [self initWithSuiteName:nil]; +} + +- (instancetype)initWithSuiteName:(nullable NSString *)suiteName { + self = [super init]; + + NSString *name = [suiteName copy]; + + if (self) { + // `kCFPreferencesCurrentApplication` maps to the same defaults database as + // `[NSUserDefaults standardUserDefaults]`. + _appNameRef = + name.length ? (__bridge_retained CFStringRef)name : kCFPreferencesCurrentApplication; + } + + return self; +} + +- (void)dealloc { + // If we're using a custom `_appNameRef` it needs to be released. If it's a constant, it shouldn't + // need to be released since we don't own it. + if (CFStringCompare(_appNameRef, kCFPreferencesCurrentApplication, 0) != kCFCompareEqualTo) { + CFRelease(_appNameRef); + } + + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(synchronize) + object:nil]; +} + +- (nullable id)objectForKey:(NSString *)defaultName { + NSString *key = [defaultName copy]; + if (![key isKindOfClass:[NSString class]] || !key.length) { + GULLogWarning(@"", NO, + [NSString stringWithFormat:kGULLogFormat, (long)GULUDMessageCodeInvalidKeyGet], + @"Cannot get object for invalid user default key."); + return nil; + } + return (__bridge_transfer id)CFPreferencesCopyAppValue((__bridge CFStringRef)key, _appNameRef); +} + +- (void)setObject:(nullable id)value forKey:(NSString *)defaultName { + NSString *key = [defaultName copy]; + if (![key isKindOfClass:[NSString class]] || !key.length) { + GULLogWarning(kGULLogUserDefaultsService, NO, + [NSString stringWithFormat:kGULLogFormat, (long)GULUDMessageCodeInvalidKeySet], + @"Cannot set object for invalid user default key."); + return; + } + if (!value) { + CFPreferencesSetAppValue((__bridge CFStringRef)key, NULL, _appNameRef); + [self synchronize]; + return; + } + BOOL isAcceptableValue = + [value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]] || + [value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]] || + [value isKindOfClass:[NSDate class]] || [value isKindOfClass:[NSData class]]; + if (!isAcceptableValue) { + GULLogWarning(kGULLogUserDefaultsService, NO, + [NSString stringWithFormat:kGULLogFormat, (long)GULUDMessageCodeInvalidObjectSet], + @"Cannot set invalid object to user defaults. Must be a string, number, array, " + @"dictionary, date, or data. Value: %@", + value); + return; + } + + CFPreferencesSetAppValue((__bridge CFStringRef)key, (__bridge CFStringRef)value, _appNameRef); + [self synchronize]; +} + +- (void)removeObjectForKey:(NSString *)key { + [self setObject:nil forKey:key]; +} + +#pragma mark - Getters + +- (NSInteger)integerForKey:(NSString *)defaultName { + NSNumber *object = [self objectForKey:defaultName]; + return object.integerValue; +} + +- (float)floatForKey:(NSString *)defaultName { + NSNumber *object = [self objectForKey:defaultName]; + return object.floatValue; +} + +- (double)doubleForKey:(NSString *)defaultName { + NSNumber *object = [self objectForKey:defaultName]; + return object.doubleValue; +} + +- (BOOL)boolForKey:(NSString *)defaultName { + NSNumber *object = [self objectForKey:defaultName]; + return object.boolValue; +} + +- (nullable NSString *)stringForKey:(NSString *)defaultName { + return [self objectForKey:defaultName]; +} + +- (nullable NSArray *)arrayForKey:(NSString *)defaultName { + return [self objectForKey:defaultName]; +} + +- (nullable NSDictionary *)dictionaryForKey:(NSString *)defaultName { + return [self objectForKey:defaultName]; +} + +#pragma mark - Setters + +- (void)setInteger:(NSInteger)integer forKey:(NSString *)defaultName { + [self setObject:@(integer) forKey:defaultName]; +} + +- (void)setFloat:(float)value forKey:(NSString *)defaultName { + [self setObject:@(value) forKey:defaultName]; +} + +- (void)setDouble:(double)doubleNumber forKey:(NSString *)defaultName { + [self setObject:@(doubleNumber) forKey:defaultName]; +} + +- (void)setBool:(BOOL)boolValue forKey:(NSString *)defaultName { + [self setObject:@(boolValue) forKey:defaultName]; +} + +#pragma mark - Save data + +- (void)synchronize { + if (!CFPreferencesAppSynchronize(_appNameRef)) { + GULLogError(kGULLogUserDefaultsService, NO, + [NSString stringWithFormat:kGULLogFormat, (long)GULUDMessageCodeSynchronizeFailed], + @"Cannot synchronize user defaults to disk"); + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleUtilities/GoogleUtilities/UserDefaults/Public/GoogleUtilities/GULUserDefaults.h b/Pods/GoogleUtilities/GoogleUtilities/UserDefaults/Public/GoogleUtilities/GULUserDefaults.h new file mode 100644 index 0000000..0d04781 --- /dev/null +++ b/Pods/GoogleUtilities/GoogleUtilities/UserDefaults/Public/GoogleUtilities/GULUserDefaults.h @@ -0,0 +1,110 @@ +// 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 + +NS_ASSUME_NONNULL_BEGIN + +/// A thread-safe user defaults that uses C functions from CFPreferences.h instead of +/// `NSUserDefaults`. This is to avoid sending an `NSNotification` when it's changed from a +/// background thread to avoid crashing. // TODO: Insert radar number here. +@interface GULUserDefaults : NSObject + +/// A shared user defaults similar to +[NSUserDefaults standardUserDefaults] and accesses the same +/// data of the standardUserDefaults. ++ (GULUserDefaults *)standardUserDefaults; + +/// Initializes preferences with a suite name that is the same with the NSUserDefaults' suite name. +/// Both of CFPreferences and NSUserDefaults share the same plist file so their data will exactly +/// the same. +/// +/// @param suiteName The name of the suite of the user defaults. +- (instancetype)initWithSuiteName:(nullable NSString *)suiteName; + +#pragma mark - Getters + +/// Searches the receiver's search list for a default with the key 'defaultName' and return it. If +/// another process has changed defaults in the search list, NSUserDefaults will automatically +/// update to the latest values. If the key in question has been marked as ubiquitous via a Defaults +/// Configuration File, the latest value may not be immediately available, and the registered value +/// will be returned instead. +- (nullable id)objectForKey:(NSString *)defaultName; + +/// Equivalent to -objectForKey:, except that it will return nil if the value is not an NSArray. +- (nullable NSArray *)arrayForKey:(NSString *)defaultName; + +/// Equivalent to -objectForKey:, except that it will return nil if the value +/// is not an NSDictionary. +- (nullable NSDictionary *)dictionaryForKey:(NSString *)defaultName; + +/// Equivalent to -objectForKey:, except that it will convert NSNumber values to their NSString +/// representation. If a non-string non-number value is found, nil will be returned. +- (nullable NSString *)stringForKey:(NSString *)defaultName; + +/// Equivalent to -objectForKey:, except that it converts the returned value to an NSInteger. If the +/// value is an NSNumber, the result of -integerValue will be returned. If the value is an NSString, +/// it will be converted to NSInteger if possible. If the value is a boolean, it will be converted +/// to either 1 for YES or 0 for NO. If the value is absent or can't be converted to an integer, 0 +/// will be returned. +- (NSInteger)integerForKey:(NSString *)defaultName; + +/// Similar to -integerForKey:, except that it returns a float, and boolean values will not be +/// converted. +- (float)floatForKey:(NSString *)defaultName; + +/// Similar to -integerForKey:, except that it returns a double, and boolean values will not be +/// converted. +- (double)doubleForKey:(NSString *)defaultName; + +/// Equivalent to -objectForKey:, except that it converts the returned value to a BOOL. If the value +/// is an NSNumber, NO will be returned if the value is 0, YES otherwise. If the value is an +/// NSString, values of "YES" or "1" will return YES, and values of "NO", "0", or any other string +/// will return NO. If the value is absent or can't be converted to a BOOL, NO will be returned. +- (BOOL)boolForKey:(NSString *)defaultName; + +#pragma mark - Setters + +/// Immediately stores a value (or removes the value if `nil` is passed as the value) for the +/// provided key in the search list entry for the receiver's suite name in the current user and any +/// host, then asynchronously stores the value persistently, where it is made available to other +/// processes. +- (void)setObject:(nullable id)value forKey:(NSString *)defaultName; + +/// Equivalent to -setObject:forKey: except that the value is converted from a float to an NSNumber. +- (void)setFloat:(float)value forKey:(NSString *)defaultName; + +/// Equivalent to -setObject:forKey: except that the value is converted from a double to an +/// NSNumber. +- (void)setDouble:(double)value forKey:(NSString *)defaultName; + +/// Equivalent to -setObject:forKey: except that the value is converted from an NSInteger to an +/// NSNumber. +- (void)setInteger:(NSInteger)value forKey:(NSString *)defaultName; + +/// Equivalent to -setObject:forKey: except that the value is converted from a BOOL to an NSNumber. +- (void)setBool:(BOOL)value forKey:(NSString *)defaultName; + +#pragma mark - Removing Defaults + +/// Equivalent to -[... setObject:nil forKey:defaultName] +- (void)removeObjectForKey:(NSString *)defaultName; + +#pragma mark - Save data + +/// Blocks the calling thread until all in-progress set operations have completed. +- (void)synchronize; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/GoogleUtilities/LICENSE b/Pods/GoogleUtilities/LICENSE new file mode 100644 index 0000000..47e7301 --- /dev/null +++ b/Pods/GoogleUtilities/LICENSE @@ -0,0 +1,224 @@ + + 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. + +================================================================================ + +Copyright (c) 2017 Landon J. Fuller +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Pods/GoogleUtilities/README.md b/Pods/GoogleUtilities/README.md new file mode 100644 index 0000000..bfe77f0 --- /dev/null +++ b/Pods/GoogleUtilities/README.md @@ -0,0 +1,189 @@ +[![Version](https://img.shields.io/cocoapods/v/GoogleUtilities.svg?style=flat)](https://cocoapods.org/pods/GoogleUtilities) +[![License](https://img.shields.io/cocoapods/l/GoogleUtilities.svg?style=flat)](https://cocoapods.org/pods/GoogleUtilities) +[![Platform](https://img.shields.io/cocoapods/p/GoogleUtilities.svg?style=flat)](https://cocoapods.org/pods/GoogleUtilities) + +[![Actions Status][gh-google-utilities-badge]][gh-actions] + +# GoogleUtilities + +GoogleUtilities provides a set of utilities for Firebase and other Google SDKs for Apple platform +development. + +The utilities are not directly supported for non-Google library usage. + +## Integration Testing +These instructions apply to minor and patch version updates. Major versions need +a customized adaptation. + +After the CI is green: +* Determine the next version for release by checking the + [tagged releases](https://github.com/google/GoogleUtilities/tags). + Ensure that the next release version keeps the Swift PM and CocoaPods versions in sync. +* Verify that the releasing version is the latest entry in the [CHANGELOG.md](CHANGELOG.md), + updating it if necessary. +* Update the version in the podspec to match the latest entry in the [CHANGELOG.md](CHANGELOG.md) +* Checkout the `main` branch and ensure it is up to date + ```console + git checkout main + git pull + ``` +* Add the CocoaPods tag (`{version}` will be the latest version in the [podspec](GoogleUtilities.podspec#L3)) + ```console + git tag CocoaPods-{version} + git push origin CocoaPods-{version} + ``` +* Push the podspec to the designated repo + * If this version of GoogleUtilities is intended to launch **before or with** the next Firebase release: +
+ Push to SpecsStaging + + ```console + pod repo push --skip-tests staging GoogleUtilities.podspec + ``` + + If the command fails with `Unable to find the 'staging' repo.`, add the staging repo with: + ```console + pod repo add staging git@github.com:firebase/SpecsStaging.git + ``` +
+ * Otherwise: +
+ Push to SpecsDev + + ```console + pod repo push --skip-tests dev GoogleUtilities.podspec + ``` + + If the command fails with `Unable to find the 'dev' repo.`, add the dev repo with: + ```console + pod repo add dev git@github.com:firebase/SpecsDev.git + ``` +
+* Run Firebase CI by waiting until next nightly or adding a PR that touches `Gemfile`. +* On google3, run copybara using the command below. Then, start a global TAP on the generated CL. Deflake as needed. + ```console + third_party/firebase/ios/Releases/run_copy_bara.py --directory GoogleUtilities --branch main + ``` + +## Publishing +The release process is as follows: +1. [Tag and release for Swift PM](#swift-package-manager) +2. [Publish to CocoaPods](#cocoapods) +3. [Create GitHub Release](#create-github-release) +4. [Perform post release cleanup](#post-release-cleanup) + +### Swift Package Manager + By creating and [pushing a tag](https://github.com/google/GoogleUtilities/tags) + for Swift PM, the newly tagged version will be immediately released for public use. + Given this, please verify the intended time of release for Swift PM. + * Add a version tag for Swift PM + ```console + git tag {version} + git push origin {version} + ``` + *Note: Ensure that any inflight PRs that depend on the new `GoogleUtilities` version are updated to point to the + newly tagged version rather than a checksum.* + +### CocoaPods +* Publish the newly versioned pod to CocoaPods + + It's recommended to point to the `GoogleUtilities.podspec` in `staging` to make sure the correct spec is being published. + ```console + pod trunk push ~/.cocoapods/repos/staging/GoogleUtilities/{version}/GoogleUtilities.podspec + ``` + *Note: In some cases, it may be acceptable to `pod trunk push` with the `--skip-tests` flag. Please double check with + the maintainers before doing so.* + + The pod push was successful if the above command logs: `🚀 GoogleUtilities ({version}) successfully published`. + In addition, a new commit that publishes the new version (co-authored by [CocoaPodsAtGoogle](https://github.com/CocoaPodsAtGoogle)) + should appear in the [CocoaPods specs repo](https://github.com/CocoaPods/Specs). Last, the latest version should be displayed + on [GoogleUtilities's CocoaPods page](https://cocoapods.org/pods/GoogleUtilities). + +### [Create GitHub Release](https://github.com/google/GoogleUtilities/releases/new/) + Update the [release template](https://github.com/google/GoogleUtilities/releases/new/)'s **Tag version** and **Release title** + fields with the latest version. In addition, reference the [Release Notes](./CHANGELOG.md) in the release's description. + + See [this release](https://github.com/google/GoogleUtilities/releases/edit/7.7.0) for an example. + + *Don't forget to perform the [post release cleanup](#post-release-cleanup)!* + +### Post Release Cleanup +
+ Clean up SpecsStaging + + ```console + pwd=$(pwd) + mkdir -p /tmp/release-cleanup && cd $_ + git clone git@github.com:firebase/SpecsStaging.git + cd SpecsStaging/ + git rm -rf GoogleUtilities/ + git commit -m "Post publish cleanup" + git push origin master + rm -rf /tmp/release-cleanup + cd $pwd + ``` +
+ +## Development + +To develop in this repository, ensure that you have at least the following software: + + * Xcode 12.0 (or later) + * CocoaPods 1.10.0 (or later) + * [CocoaPods generate](https://github.com/square/cocoapods-generate) + +For the pod that you want to develop: + +`pod gen GoogleUtilities.podspec --local-sources=./ --auto-open --platforms=ios` + +Note: If the CocoaPods cache is out of date, you may need to run +`pod repo update` before the `pod gen` command. + +Note: Set the `--platforms` option to `macos` or `tvos` to develop/test for +those platforms. Since 10.2, Xcode does not properly handle multi-platform +CocoaPods workspaces. + +### Development for Catalyst +* `pod gen GoogleUtilities.podspec --local-sources=./ --auto-open --platforms=ios` +* Check the Mac box in the App-iOS Build Settings +* Sign the App in the Settings Signing & Capabilities tab +* Click Pods in the Project Manager +* Add Signing to the iOS host app and unit test targets +* Select the Unit-unit scheme +* Run it to build and test + +Alternatively disable signing in each target: +* Go to Build Settings tab +* Click `+` +* Select `Add User-Defined Setting` +* Add `CODE_SIGNING_REQUIRED` setting with a value of `NO` + +### Code Formatting + +To ensure that the code is formatted consistently, run the script +[./scripts/check.sh](https://github.com/firebase/firebase-ios-sdk/blob/main/scripts/check.sh) +before creating a PR. + +GitHub Actions will verify that any code changes are done in a style compliant +way. Install `clang-format` and `mint`: + +```console +brew install clang-format@18 +brew install mint +``` + +### Running Unit Tests + +Select a scheme and press Command-u to build a component and run its unit tests. + +## Contributing + +See [Contributing](CONTRIBUTING.md). + +## License + +The contents of this repository is licensed under the +[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +[gh-actions]: https://github.com/firebase/firebase-ios-sdk/actions +[gh-google-utilities-badge]: https://github.com/firebase/firebase-ios-sdk/workflows/google-utilities/badge.svg diff --git a/Pods/GoogleUtilities/third_party/IsAppEncrypted/IsAppEncrypted.m b/Pods/GoogleUtilities/third_party/IsAppEncrypted/IsAppEncrypted.m new file mode 100644 index 0000000..e2f7275 --- /dev/null +++ b/Pods/GoogleUtilities/third_party/IsAppEncrypted/IsAppEncrypted.m @@ -0,0 +1,104 @@ +// Copyright (c) 2017 Landon J. Fuller +// 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 +// iPhone Dev +// Wiki Crack Prevention: +// 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 +// Landon Fuller's blog + +#import "third_party/IsAppEncrypted/Public/IsAppEncrypted.h" + +#import +#import + +/// 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 + +BOOL IsAppEncrypted(void) { + 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; +} diff --git a/Pods/GoogleUtilities/third_party/IsAppEncrypted/Public/IsAppEncrypted.h b/Pods/GoogleUtilities/third_party/IsAppEncrypted/Public/IsAppEncrypted.h new file mode 100644 index 0000000..1a4305a --- /dev/null +++ b/Pods/GoogleUtilities/third_party/IsAppEncrypted/Public/IsAppEncrypted.h @@ -0,0 +1,24 @@ +// Copyright (c) 2017 Landon J. Fuller +// 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. + +#import + +BOOL IsAppEncrypted(void); diff --git a/Pods/Headers/Private/Firebase/Firebase.h b/Pods/Headers/Private/Firebase/Firebase.h new file mode 120000 index 0000000..07ac6eb --- /dev/null +++ b/Pods/Headers/Private/Firebase/Firebase.h @@ -0,0 +1 @@ +../../../Firebase/CoreOnly/Sources/Firebase.h \ No newline at end of file diff --git a/Pods/Headers/Public/Firebase/Firebase.h b/Pods/Headers/Public/Firebase/Firebase.h new file mode 120000 index 0000000..07ac6eb --- /dev/null +++ b/Pods/Headers/Public/Firebase/Firebase.h @@ -0,0 +1 @@ +../../../Firebase/CoreOnly/Sources/Firebase.h \ No newline at end of file diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock index bd90c1d..32f7bd1 100644 --- a/Pods/Manifest.lock +++ b/Pods/Manifest.lock @@ -1,3 +1,117 @@ -PODFILE CHECKSUM: 8bd30fbf8fb43ccff22be3db42a9e910ca8a34af +PODS: + - Firebase/AnalyticsWithoutAdIdSupport (10.28.1): + - Firebase/CoreOnly + - FirebaseAnalytics/WithoutAdIdSupport (~> 10.28.0) + - Firebase/CoreOnly (10.28.1): + - FirebaseCore (= 10.28.1) + - FirebaseABTesting (10.28.0): + - FirebaseCore (~> 10.0) + - FirebaseAnalytics/WithoutAdIdSupport (10.28.0): + - FirebaseCore (~> 10.0) + - FirebaseInstallations (~> 10.0) + - GoogleAppMeasurement/WithoutAdIdSupport (= 10.28.0) + - GoogleUtilities/AppDelegateSwizzler (~> 7.11) + - GoogleUtilities/MethodSwizzler (~> 7.11) + - GoogleUtilities/Network (~> 7.11) + - "GoogleUtilities/NSData+zlib (~> 7.11)" + - nanopb (< 2.30911.0, >= 2.30908.0) + - FirebaseCore (10.28.1): + - FirebaseCoreInternal (~> 10.0) + - GoogleUtilities/Environment (~> 7.12) + - GoogleUtilities/Logger (~> 7.12) + - FirebaseCoreInternal (10.28.0): + - "GoogleUtilities/NSData+zlib (~> 7.8)" + - FirebaseInstallations (10.28.0): + - FirebaseCore (~> 10.0) + - GoogleUtilities/Environment (~> 7.8) + - GoogleUtilities/UserDefaults (~> 7.8) + - PromisesObjC (~> 2.1) + - FirebaseRemoteConfig (10.28.0): + - FirebaseABTesting (~> 10.0) + - FirebaseCore (~> 10.0) + - FirebaseInstallations (~> 10.0) + - FirebaseRemoteConfigInterop (~> 10.23) + - FirebaseSharedSwift (~> 10.0) + - GoogleUtilities/Environment (~> 7.8) + - "GoogleUtilities/NSData+zlib (~> 7.8)" + - FirebaseRemoteConfigInterop (10.28.0) + - FirebaseSharedSwift (10.28.0) + - GoogleAppMeasurement/WithoutAdIdSupport (10.28.0): + - GoogleUtilities/AppDelegateSwizzler (~> 7.11) + - GoogleUtilities/MethodSwizzler (~> 7.11) + - GoogleUtilities/Network (~> 7.11) + - "GoogleUtilities/NSData+zlib (~> 7.11)" + - nanopb (< 2.30911.0, >= 2.30908.0) + - GoogleUtilities/AppDelegateSwizzler (7.13.3): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Privacy + - GoogleUtilities/Environment (7.13.3): + - GoogleUtilities/Privacy + - PromisesObjC (< 3.0, >= 1.2) + - GoogleUtilities/Logger (7.13.3): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - GoogleUtilities/MethodSwizzler (7.13.3): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/Network (7.13.3): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Privacy + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (7.13.3)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (7.13.3) + - GoogleUtilities/Reachability (7.13.3): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/UserDefaults (7.13.3): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - nanopb (2.30910.0): + - nanopb/decode (= 2.30910.0) + - nanopb/encode (= 2.30910.0) + - nanopb/decode (2.30910.0) + - nanopb/encode (2.30910.0) + - PromisesObjC (2.4.0) + +DEPENDENCIES: + - Firebase/AnalyticsWithoutAdIdSupport + - FirebaseRemoteConfig + +SPEC REPOS: + trunk: + - Firebase + - FirebaseABTesting + - FirebaseAnalytics + - FirebaseCore + - FirebaseCoreInternal + - FirebaseInstallations + - FirebaseRemoteConfig + - FirebaseRemoteConfigInterop + - FirebaseSharedSwift + - GoogleAppMeasurement + - GoogleUtilities + - nanopb + - PromisesObjC + +SPEC CHECKSUMS: + Firebase: 49e62242b3ae422a002ab647a7e62a332a8c3ec1 + FirebaseABTesting: 589bc28c0ab3e5554336895a34aa262e24276665 + FirebaseAnalytics: 1e06fe7d246af7230b08d1d9cdca54a4624dd461 + FirebaseCore: dfc33f0dffba05f76181da9cc0151171ebb3bd10 + FirebaseCoreInternal: 58d07f1362fddeb0feb6a857d1d1d1c5e558e698 + FirebaseInstallations: 60c1d3bc1beef809fd1ad1189a8057a040c59f2e + FirebaseRemoteConfig: f0879a8dccf4e8905716ed849569130efaeab3e2 + FirebaseRemoteConfigInterop: 70d200c6956ef3b5c3592a95e824c1210682d785 + FirebaseSharedSwift: 48de4aec81a6b79bb30404e5e6db43ea74848fed + GoogleAppMeasurement: 55a4a3c8000c1280d68bf4c084adbfef20c49db1 + GoogleUtilities: ea963c370a38a8069cc5f7ba4ca849a60b6d7d15 + nanopb: 438bc412db1928dac798aa6fd75726007be04262 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + +PODFILE CHECKSUM: 2f2e5df210dba6ae9a689623ed2ba20922376bc0 COCOAPODS: 1.15.2 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj index 97daf58..4c276fb 100644 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -6,128 +6,2762 @@ objectVersion = 56; objects = { +/* Begin PBXAggregateTarget section */ + 072CEA044D2EF26F03496D5996BBF59F /* Firebase */ = { + isa = PBXAggregateTarget; + buildConfigurationList = C6E4A38F24896DABC7A364E6DB2C7A7F /* Build configuration list for PBXAggregateTarget "Firebase" */; + buildPhases = ( + ); + dependencies = ( + 5504F5CCDA2C7DD64917C28D2AAF3C03 /* PBXTargetDependency */, + D23980920D5AEB09BDA01D2F83A235F3 /* PBXTargetDependency */, + ); + name = Firebase; + }; + B53D977A951AFC38B21751B706C1DF83 /* GoogleAppMeasurement */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 899D32CA20311051D748DCDA67B8F798 /* Build configuration list for PBXAggregateTarget "GoogleAppMeasurement" */; + buildPhases = ( + EC57F3132A92F1704B35D2C5B32C64D9 /* [CP] Copy XCFrameworks */, + ); + dependencies = ( + B41BA038223454414C96FC1849286958 /* PBXTargetDependency */, + 119AE19212762697A6043151CF3C47B7 /* PBXTargetDependency */, + ); + name = GoogleAppMeasurement; + }; + C49E7A4D59E5C8BE8DE9FB1EFB150185 /* FirebaseAnalytics */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 45F8006A959C88B6482BAFA1C0189E98 /* Build configuration list for PBXAggregateTarget "FirebaseAnalytics" */; + buildPhases = ( + B82725F813044246C9CBD2EF41A0ECAF /* [CP] Copy XCFrameworks */, + ); + dependencies = ( + 4D66D657EB58B5A47C67F6C942C9105F /* PBXTargetDependency */, + 8F80413E521828C624F263B3595BCEEF /* PBXTargetDependency */, + 1F7B568D1965EE6C1B1EE4491FFB841B /* PBXTargetDependency */, + 3C59CC503E185A0918BA50B67B4C5871 /* PBXTargetDependency */, + AC3A40B2B4AF5C8BA73C61BA5E083D27 /* PBXTargetDependency */, + ); + name = FirebaseAnalytics; + }; +/* End PBXAggregateTarget section */ + /* Begin PBXBuildFile section */ - 04DD5FEA6CF97D9EFE8730A973046585 /* Pods-HD wallpaper-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A195F190B302CCB9E52FF10ACF4E658 /* Pods-HD wallpaper-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 05FD1465944F134ABF7A9930D4CD3572 /* Pods-HD wallpaper-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4012E5D2ED98BF15C346FA7E4ECBB040 /* Pods-HD wallpaper-dummy.m */; }; - 4BD7E4981856283B65F5339AB3FFD1E0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; + 002E4A327A3CB44F4D16C0A226238A90 /* FIRLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = CE57D042251A378B73A66A09A3B56D12 /* FIRLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 01080947AB08367F88AE23969144BD16 /* FIRAnalyticsInteropListener.h in Headers */ = {isa = PBXBuildFile; fileRef = CB840AE072916EC3EE874FF2EC26AEED /* FIRAnalyticsInteropListener.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 014A51D10A5E8B19B19B1E39AFC6CC7E /* FIRRemoteConfigUpdate.m in Sources */ = {isa = PBXBuildFile; fileRef = 833E65C1466FF27BF0A1EB4826561F87 /* FIRRemoteConfigUpdate.m */; }; + 014B59D13FE778C995C7E06BA82823F3 /* FIROptionsInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C7375716F8DCA3F01D012DEC4BEEF3C /* FIROptionsInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 01F6C082EC4E80AAEA6A7D8E2E1ED66F /* GULNetworkInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = EFBB5170B9DDDDB35675FD09905C8A04 /* GULNetworkInfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 02957B05E9F36148482D0F520B66E6A0 /* GULSceneDelegateSwizzler.h in Headers */ = {isa = PBXBuildFile; fileRef = A07DD31D3AA0F19C2DC3448743583819 /* GULSceneDelegateSwizzler.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 02F16F9C7A20763496824FB3DECEEA5F /* GULAppEnvironmentUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DB188C0BCE4FACAF79E2AF7CEF0F18E /* GULAppEnvironmentUtil.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0310D0AAACDFA43D80CC48E7FD8BC830 /* RCNDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F6803F3719C4B619CDE8B52350A8999 /* RCNDevice.m */; }; + 037EB8A9DABF4FDAC5B429B1A15B6E18 /* FirebaseCore-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 0465BFA65D53A47C84AA386E5A316F4C /* FirebaseCore-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 03B92DAF7A6605A05A9E6464DD425DBB /* RCNConfigExperiment.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DD06FC5913D15BB4DAAFF191168CD95 /* RCNConfigExperiment.m */; }; + 03D98F176B8F3123C881DC02EA547FBB /* GULNSData+zlib.m in Sources */ = {isa = PBXBuildFile; fileRef = 51500E287FB6075B9E55988901D1E18F /* GULNSData+zlib.m */; }; + 03F75F13B17E635D2C9431C9DCA81D95 /* GULNetworkInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 47CBFE8B2613056F638460A4E11FFBD7 /* GULNetworkInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 04914681DC621F7499CC6AE5FB64D8CB /* FirebaseRemoteConfigInterop-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 89240F4F5527DD6175A8F52D945F63D3 /* FirebaseRemoteConfigInterop-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 059B07C3DEDB4EE0C32821FBCFFEA387 /* FIRComponentType.m in Sources */ = {isa = PBXBuildFile; fileRef = 546B1716181B9A0BEB19FFC225D5D68B /* FIRComponentType.m */; }; + 072C74210202BF611391E7651910BF5F /* GULKeychainUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = D2B69AE52F9C6F680F8FD0D12EB58010 /* GULKeychainUtils.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0821509889AFAF943FE41ECA9AFA7CA1 /* RCNUserDefaultsManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 27204B2F94BC80BF02755E6EE6FF48B4 /* RCNUserDefaultsManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 087ECD801CFD198243ED84F4B2BFD5D1 /* GULAppEnvironmentUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = BF5B5C6CC493F3D8DC306BAEA16AF1A8 /* GULAppEnvironmentUtil.m */; }; + 09C139863044A20A7D7FD8193995541C /* GULUserDefaults.h in Headers */ = {isa = PBXBuildFile; fileRef = 588C2AC34B379F3F961AFEB8F4B0DF34 /* GULUserDefaults.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0A63944CC9F6F3BB72EB30CBC2E53457 /* FIRInstallationsAuthTokenResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 34A6D6776B3743C799B000FB60E1527A /* FIRInstallationsAuthTokenResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0B42662391E1F0B20862AD619625A34A /* ABTConditionalUserPropertyController.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BB9853B86E5B2B10DD7DFC3AB58367A /* ABTConditionalUserPropertyController.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0BA30D76A9C94F8B1ABE3C5AA81128ED /* FIRComponentContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 67524CD86B6C8F70B1DAA3450E89D13F /* FIRComponentContainer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0C862A2FB61BF294B990C92D3D39EDB5 /* FIRInstallationsItem+RegisterInstallationAPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A96D4ECF706EA7F8633B03C8908FE34 /* FIRInstallationsItem+RegisterInstallationAPI.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0CB6A0D1E953EDB1F4962DC56C23E288 /* _ObjC_HeartbeatsPayload.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95FDC4862675CD7B54307601CC53D624 /* _ObjC_HeartbeatsPayload.swift */; }; + 0EA7754F7184C6AA03B1C22E54FE9A3C /* FIRInstallationsAPIService.h in Headers */ = {isa = PBXBuildFile; fileRef = D74D68E534A6E7E9393D8546BD226005 /* FIRInstallationsAPIService.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0F1F54BB51451311D842553F2606C5E6 /* FIRInstallationsStoredItem.m in Sources */ = {isa = PBXBuildFile; fileRef = EA1221DCC616541422CC2368EA18C392 /* FIRInstallationsStoredItem.m */; }; + 0FB7E75647175C56A48237E7F7666D56 /* FIRLibrary.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D08833CDC51AB4B8E3948BB24DFE839 /* FIRLibrary.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0FB8B94B29A09F300D2A47AA6C362029 /* ABTConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 0899876952EBC0C6C6B0997B6126F021 /* ABTConstants.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0FD802B43A35E41447F1B71A497D090F /* FIRBundleUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = DF0BA02847EB4ABDA457947FB6B41E30 /* FIRBundleUtil.m */; }; + 10612C85BCFD0682CB18712E8A6E5AE8 /* FBLPromise+Any.h in Headers */ = {isa = PBXBuildFile; fileRef = FAAA993ABD04FA1089D554165000BA87 /* FBLPromise+Any.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1187C0D8D69372171147A9F16A0AEAB9 /* GULAppDelegateSwizzler.h in Headers */ = {isa = PBXBuildFile; fileRef = F1AD7256FFE15B28CC6582DBE2DC008C /* GULAppDelegateSwizzler.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 11A2AB5E67441BBF3D98B4CBAF439DA7 /* FIRInstallationsErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F45CF142336996E92BD55A74678256C /* FIRInstallationsErrors.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 11B6F16D57ABC141F6EF25010A8E1BEE /* FBLPromise+Wrap.m in Sources */ = {isa = PBXBuildFile; fileRef = 684935040366A7E92ECE09FA526B16FC /* FBLPromise+Wrap.m */; }; + 12D35D0F555699A4FD519C8579D6E2FE /* FIRLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = D70D527EAFF19A24102D57E5A969F179 /* FIRLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 12DD488E276CEDA5D2262B7EF7870929 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67B07E9904CAAD5AD2278E2CBF9E13DD /* Foundation.framework */; }; + 1334B9C4A6A8E74699F8B21A2657444E /* FirebaseInstallationsInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = B0AFA6042055C466A9D374B0CE32AB71 /* FirebaseInstallationsInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1347271F0EA972C5DF766D832816A22A /* pb_encode.h in Headers */ = {isa = PBXBuildFile; fileRef = 394AF72A812A8B1F5953451EEB694CA2 /* pb_encode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1366AD596ACDC5211422F1489C8C6579 /* FIRRemoteConfigComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = 13A178CFE40985F6D199227F9EB9E967 /* FIRRemoteConfigComponent.m */; }; + 16B05E7BFB1F2ED538AAED5247E263BA /* FIRInstallationsHTTPError.h in Headers */ = {isa = PBXBuildFile; fileRef = 71B7ACC5DB8FDB728C1DAD182338C36B /* FIRInstallationsHTTPError.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1792C6D8511CC67EF1FD8864BE80E311 /* RCNConfigConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = FCD93D3F203DE0688BBFB884B5B4E161 /* RCNConfigConstants.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 17AD06278B2721840A94FD449A960503 /* GULNetwork.h in Headers */ = {isa = PBXBuildFile; fileRef = F34EB1616AF9DD15B68765C1B5BB7DA1 /* GULNetwork.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 17C3BD9EF58BA88ADFFB8C14346ACA3A /* FIRComponentType.h in Headers */ = {isa = PBXBuildFile; fileRef = AE46E3547BEF96B859A66E4F599C0293 /* FIRComponentType.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 18993DAD06C256FBACD140FFF30A7223 /* RCNConfigFetch.h in Headers */ = {isa = PBXBuildFile; fileRef = 48A7B329FA4A60E00C7AE22844CE713C /* RCNConfigFetch.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 19754842DC0D791C9E12C473444B14B6 /* FIRConfigValue.m in Sources */ = {isa = PBXBuildFile; fileRef = B649188460A2C149984BF3FA48EC2520 /* FIRConfigValue.m */; }; + 197BE4EF714B4E66AD0E6A22A626F765 /* FIRComponentType.h in Headers */ = {isa = PBXBuildFile; fileRef = A5144EB8AF8D2E78332EA7C5D348E258 /* FIRComponentType.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1A489BD53A52433956CD9B21ACE04971 /* FIRLibrary.h in Headers */ = {isa = PBXBuildFile; fileRef = 897DBA56069DE92BC7EB9DF3BF3325C5 /* FIRLibrary.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1B43D41766EE45509711E38E3AD9FE1C /* nanopb-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = B64E6FEC8DDBCA02C6D886874B9294E1 /* nanopb-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1BB615CDFB5FA1D38F49E757AD326403 /* FirebaseCoreInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = A187810449E6822F25E6ABFC9CDA3446 /* FirebaseCoreInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1BBC5C2368E990779CEC13E0CE698058 /* FBLPromise+Then.m in Sources */ = {isa = PBXBuildFile; fileRef = B3350961DE46986C41D825A8C4B105A6 /* FBLPromise+Then.m */; }; + 1BC6D049D48A0F4D0429F41CB3AF7E0E /* FIROptionsInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = A9A3F96F9B98448D3D1C019ABA7492CE /* FIROptionsInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1C26F266BB57D7E76DB3F0C82D027847 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67B07E9904CAAD5AD2278E2CBF9E13DD /* Foundation.framework */; }; + 1CD95F21E8C0DD476470B6D20C4A5ECD /* _ObjC_HeartbeatController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47072AE8853F2DC6D613ABAF62339C5 /* _ObjC_HeartbeatController.swift */; }; + 1E30147BC31330EDB52A8CBF4BA47DA1 /* FIRInstallationsStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 73A8C5803F0CB377BFBCB3DDE9E42E30 /* FIRInstallationsStore.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1E9AD700B357DCFA3E1E317B5490FEF0 /* RCNConfigDBManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 65D221126ACC9BF46EE8E173D19CD3BE /* RCNConfigDBManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 1F83A6EEA5B5D0610425A09BD79A1BCE /* FIRComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 151395376150327AE967B52B05253632 /* FIRComponent.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 20860BEF9C0743437CC8EE2A219FD033 /* FBLPromise+Race.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C27787F3CC35AB19EA596344B611B8D /* FBLPromise+Race.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 20EB7353C65195AD8900D7EA4AC3D72E /* RCNConfigDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 75BDFC4520B3CA5BB214D5D272F4B5C5 /* RCNConfigDefines.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 22A7845FA88AEB261651C57A150D7A06 /* FBLPromise+Async.m in Sources */ = {isa = PBXBuildFile; fileRef = EB641D7D849DE451E99A9F4274E6E660 /* FBLPromise+Async.m */; }; + 23719F5ABD7E5E38966B82FAF5656D0F /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = E0C5EA433D75F11E6031A6F955C5E567 /* PrivacyInfo.xcprivacy */; }; + 2376DF4DF42EB2D5791EC4E82BF818D7 /* RCNConfigDBManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D8AD0FE5507402DAFD68DC4AC643DD4C /* RCNConfigDBManager.m */; }; + 23E9269777AC1BF8044B3AD3EFF0750E /* RCNConfigFetch.m in Sources */ = {isa = PBXBuildFile; fileRef = 94889F55D5C5243AAF1FE316D39114DF /* RCNConfigFetch.m */; }; + 24C51517170700E2BAA2677E4BA0FB6C /* FIRInteropEventNames.h in Headers */ = {isa = PBXBuildFile; fileRef = CD872021C34DBAC0D7D1533418F1B928 /* FIRInteropEventNames.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 24EA40D936EC29376E681C41E68E8664 /* FIRConfigurationInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 395D5D902752144C46050A4CAB669598 /* FIRConfigurationInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 250FFF1BA8E20B668D2628E20D1DAA99 /* RCNConfigValue_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 17B62497EB13A290B2423E0AED196DF0 /* RCNConfigValue_Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 256679AACBB27292744C8F1903829ADF /* FBLPromiseError.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA4975B9DCACEEF18DC342426A3945B /* FBLPromiseError.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 25AC76518081926C91722FE32C8E6E91 /* RCNConfigContent.h in Headers */ = {isa = PBXBuildFile; fileRef = 59F0842B76A5CE38951E72F18B5EE1EF /* RCNConfigContent.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 25E6BAB845B7F3DC6FEC1A5023644C34 /* FirebaseCoreInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 478C534DD7748F70AB26FA7391ACFE8F /* FirebaseCoreInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 26236648451E619B85D3FF2BC350AA91 /* FBLPromise.h in Headers */ = {isa = PBXBuildFile; fileRef = 02871E8BD2CDB997D08FE36292EBBEF9 /* FBLPromise.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 26FA710EBA60374B07343233050ACCCB /* FIRBundleUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BEBB95E96263213DF218487B37FF912 /* FIRBundleUtil.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2718981AE6D24D01EC6E73E2702F9446 /* FBLPromisePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = EA7E4CACAF799A4CA84D8D9AC6F21B46 /* FBLPromisePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 27AA7BE5357FB5A00F78424D1340BF2C /* FIRHeartbeatLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = E40D7FB16BEC3AE602AFAED30D109A05 /* FIRHeartbeatLogger.m */; }; + 286BCA33EB9D749D9D20BA6465837BAD /* GULAppDelegateSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = 556F34BAB0A4E2A0D26EA3A940B25AE0 /* GULAppDelegateSwizzler.m */; }; + 2A5F9F84107D692A393457F5A79B6CFC /* FIRInstallationsErrorUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 449FEAA30D59A791B55D657D08C52734 /* FIRInstallationsErrorUtil.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2B485D0E4571DF73B974CAF678E53C39 /* pb_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AFD897D1A76B25F34416E25BC1BA8C2 /* pb_common.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2CE2FED50A50A7A9D8D990E935F12678 /* RingBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E660666F02B98329C9A43343BED1238A /* RingBuffer.swift */; }; + 2E73FC652C5267CE8132E7143EADA20D /* FIRInstallationsStoredItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4093B147058BF1AF526933AB6A8AA56B /* FIRInstallationsStoredItem.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 2E80313FCD3EEEA68DA6F34E0416BBC9 /* FirebaseABTesting-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = A732C7A211777FCF0919357C264E1362 /* FirebaseABTesting-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2EDAC56F996DFF0E863359050DAF3E36 /* FIRDependency.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B0DBA62A90CC2A21478E9B430CF5DC0 /* FIRDependency.m */; }; + 2F09EDE65BB44FC238E52830EE033B04 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67B07E9904CAAD5AD2278E2CBF9E13DD /* Foundation.framework */; }; + 30E0DFE91FC8A124561506C723A2403C /* GULApplication.h in Headers */ = {isa = PBXBuildFile; fileRef = 0137629091A47137D26044343F6BB38B /* GULApplication.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3197E355FBA0C489C3F51AE8A653B529 /* FBLPromise+Do.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A185451B2353A2D9FEAEC50BFFD6813 /* FBLPromise+Do.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 324EF1B0910B956CCB4E0F82DBDF0797 /* FIRLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = D0A7743AD9C9F7D31F8A8299B1A91AD1 /* FIRLogger.m */; }; + 3277F31807CFBF0EDAAACEF1108B25F3 /* FBLPromises.h in Headers */ = {isa = PBXBuildFile; fileRef = 872BF4BB62F31E9551393F836AEBA807 /* FBLPromises.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 32C60E34AB6CA0D9E4BACC656A02525F /* FBLPromise+Do.m in Sources */ = {isa = PBXBuildFile; fileRef = 52CAD59895924651BB63FAEBBD1E3456 /* FBLPromise+Do.m */; }; + 346D17FFD27BACCC84201FB599E04910 /* FIRFirebaseUserAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 173A1D2BA8A434F883C4F3756BCF6890 /* FIRFirebaseUserAgent.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 357DC605857D030BD54BC503421BEB4D /* FIRApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 73372DCA3D12A27E168929C0BA8FE4E4 /* FIRApp.m */; }; + 35FF4EAE2DE6D820314B27CD73C87423 /* GULLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = CFEEDDBB077CF5DE8FF2B0226A3A1BB0 /* GULLogger.m */; }; + 36FD69B6E2108E8F9375ABFD2867DD5B /* RCNConfigSettings.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BBC9EB741E7CFE4CA52A7BBE3F28221 /* RCNConfigSettings.m */; }; + 3987D09E5123084EE5C490645C9CA8DE /* GULHeartbeatDateStorageUserDefaults.h in Headers */ = {isa = PBXBuildFile; fileRef = 17AAC41742538CD112A3BAEAB2641C31 /* GULHeartbeatDateStorageUserDefaults.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3999EF5960E10C4219B6A0D1B95F268C /* FIRInstallationsIIDTokenStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C591D11BE25070AE683077BDA9F01890 /* FIRInstallationsIIDTokenStore.m */; }; + 39BAA79584AFA48101FB8E72FD506C20 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67B07E9904CAAD5AD2278E2CBF9E13DD /* Foundation.framework */; }; + 3B82B056885EBDDF3353C29A20F2553B /* FIRLibrary.h in Headers */ = {isa = PBXBuildFile; fileRef = 671CFBB67B468EF837F4A4DC3E436A69 /* FIRLibrary.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3BEBD0E43705EFB4DF2D8C2A80B413D1 /* FIRInstallationsSingleOperationPromiseCache.h in Headers */ = {isa = PBXBuildFile; fileRef = DABB52F57033CB4CAE17345DED78D177 /* FIRInstallationsSingleOperationPromiseCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3BF93076E8ABE2B97F4E027497E8F1D9 /* GULHeartbeatDateStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 88FC70FB88B2D354EB6C42AB9E23A429 /* GULHeartbeatDateStorage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3EC815D5C5AD33607C81B8250C32D611 /* FIRInstallationsLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 18FC8810EE8510F55DA41D4B374702C4 /* FIRInstallationsLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3FB703A256519703177EC8EB1334E991 /* FIRCurrentDateProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 34FE9444CEE6E7A31895765C269BD245 /* FIRCurrentDateProvider.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3FD4D9902B88B07E5905D92C5854EDD3 /* GULNetworkURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D4CD4D55DFDEE21C6AA44018034B74B /* GULNetworkURLSession.m */; }; + 4120C92556C96D027AF77A1BF758F844 /* RCNConfigRealtime.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B3F82B7B8AE59C50EF98ED4CBA2FDB1 /* RCNConfigRealtime.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4484E06A0A2460BAE386EEDBDF0501DF /* FBLPromise+Then.h in Headers */ = {isa = PBXBuildFile; fileRef = 53AF62816637B22C90309A1F74CE3704 /* FBLPromise+Then.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 44A551E2F2E4CE9CDE673BE91DFF9F69 /* FBLPromise+Retry.h in Headers */ = {isa = PBXBuildFile; fileRef = F14AAE7E4E7FDC32CA35C9E913B00DCB /* FBLPromise+Retry.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 452BD48CFEDB75603E1DCADDD1C1C6F0 /* ABTExperimentPayload.h in Headers */ = {isa = PBXBuildFile; fileRef = 382AD4608DA6265D2ADAB72C9F0E70A0 /* ABTExperimentPayload.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 46EDA447619C827F1E710C762A98C20F /* FIRInstallationsIDController.m in Sources */ = {isa = PBXBuildFile; fileRef = 459101C0E8221FBA77B32BADBCB9C383 /* FIRInstallationsIDController.m */; }; + 47E92504DCF98D8F7CB7DB38EBA0A047 /* FirebaseRemoteConfig-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = A25E28A8A12040D16275D2D1DA2EDB83 /* FirebaseRemoteConfig-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 49FA4D2509EF4907230A2CA0CC16134A /* FBLPromise+Retry.m in Sources */ = {isa = PBXBuildFile; fileRef = FB9A9209281A23DA9F33ADA8E99957E4 /* FBLPromise+Retry.m */; }; + 4A5323703044C47F8A859F6C8103121C /* StorageFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A097E8C3EAC2A58C6A5B7BFE9E75AD1 /* StorageFactory.swift */; }; + 4AC11245E6B6573CC318C9102085C0E3 /* FIRRemoteConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = CC596C20253971D585510A397BA0A500 /* FIRRemoteConfig.m */; }; + 4B1D9CB7CB83021A706FC5FC731CA551 /* FirebaseABTesting-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = AACD723663F5D1C61B04933E98DB59EA /* FirebaseABTesting-dummy.m */; }; + 4B94C053073406FF1FCDED43F07E9092 /* Heartbeat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 308C8B46912372B5807BEFB1E6E1F65B /* Heartbeat.swift */; }; + 4BBAF07A8197B54CA7665D7EDB6CAD61 /* GULKeychainStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = DD6A8B198CAD93CEFDF3C333B5653006 /* GULKeychainStorage.m */; }; + 4C3B8513C6C0BD42F6CBC837EC429DBC /* FIRAnalyticsConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 4253C08D4EC49D0B717837CE370785F1 /* FIRAnalyticsConfiguration.m */; }; + 4CAEB207FDC8F20F988669FDF167DC91 /* NSURLSession+GULPromises.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AC9D23ABC43B3AC297A939A82852C2C /* NSURLSession+GULPromises.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4CE9E79838F1A2E38395FF32B053B582 /* FIRAnalyticsInterop.h in Headers */ = {isa = PBXBuildFile; fileRef = 7F50D584D8AC434EF9B0E3E2FF17B3DF /* FIRAnalyticsInterop.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4D7B1114E5F43E042AE48E1D6608B15B /* FIRHeartbeatLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = F6156AA9C2B244ECB4C8537A6F25F442 /* FIRHeartbeatLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 4DE548D16C2ED9005D12CC6144DFA6A2 /* FirebaseABTesting-FirebaseABTesting_Privacy in Resources */ = {isa = PBXBuildFile; fileRef = EBC0124F859F5CDD9578E444B7412AC6 /* FirebaseABTesting-FirebaseABTesting_Privacy */; }; + 4F71CCF30BEAEF31781B41180EB6DBC6 /* GULReachabilityMessageCode.h in Headers */ = {isa = PBXBuildFile; fileRef = A9FC8A579BACB56FB5239942F9A2B978 /* GULReachabilityMessageCode.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5013C036BF99F09CDC5E52E846A3959B /* GULNetworkLoggerProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B1CB57BD2FCA1ED789D36520B26010 /* GULNetworkLoggerProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 503063D4D411A3C0CCBF15CC14E048B0 /* FirebaseInstallations-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 7F84DEC2F9ADBD86654E93E70FDDCAE4 /* FirebaseInstallations-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 50DDCD88E26C61D7557E6D5595EA3351 /* FirebaseSharedSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 608BF1BE349FF2A40C28196D17A0BD80 /* FirebaseSharedSwift-dummy.m */; }; + 52DBA511452DC665C02C38546E90D290 /* FIRInstallations.h in Headers */ = {isa = PBXBuildFile; fileRef = 3176BDD8AA7AC5A550A4FB1DC652A480 /* FIRInstallations.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 53070110301B29EC210F0E24EAA65166 /* IsAppEncrypted.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E5CC88FBF5B87E058EE0D5A44911700 /* IsAppEncrypted.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5308B4B1F4AD24CCB9D6D126C404AFF8 /* GULSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = B10FE88CF1A03212F65DBAA5942A8636 /* GULSwizzler.m */; }; + 53466019F0BC6E3BED9E1ED420F2CFCF /* GULSceneDelegateSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = 30A4C68C973005FCD0A890D52035EBAD /* GULSceneDelegateSwizzler.m */; }; + 557ED1CA94051856C92FFB5F85896FE6 /* nanopb-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 206885B8EC1F263A4198751B7308476D /* nanopb-dummy.m */; }; + 55FBDB7F7C29F2363F1AE3B6DED07449 /* RemoteConfigConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86727521F4E83A0C8B674023644BD670 /* RemoteConfigConstants.swift */; }; + 560D0045B045EE16B370BBB060176A2E /* HeartbeatLoggingTestUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE5CAD8109EFA33FCEDE23763DF22FFC /* HeartbeatLoggingTestUtils.swift */; }; + 56477103480E7B535B3855A1239B1124 /* FIRFirebaseUserAgent.m in Sources */ = {isa = PBXBuildFile; fileRef = 143D42ABF58FD977F7BD2B817A79E6DC /* FIRFirebaseUserAgent.m */; }; + 56996F206EBF485324F937A41EF6F1B9 /* GULSecureCoding.h in Headers */ = {isa = PBXBuildFile; fileRef = D86E0DA970995D79FBCBDFC2FB00E7B7 /* GULSecureCoding.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5701F6CC9D0D3D0675B40C02914442B1 /* FBLPromise+Timeout.m in Sources */ = {isa = PBXBuildFile; fileRef = 830BACEF103B1B9D5C9511B2905411D4 /* FBLPromise+Timeout.m */; }; + 574A6495897B88B04CF915DE37312072 /* FIRInstallations.m in Sources */ = {isa = PBXBuildFile; fileRef = 36791595F93467472A8A233FCEF63536 /* FIRInstallations.m */; }; + 593C81214C42B4B00CFCB24EC4ADD14F /* FIRInstallationsHTTPError.m in Sources */ = {isa = PBXBuildFile; fileRef = 28EE1B16B384D2A8C8351D936C0C2512 /* FIRInstallationsHTTPError.m */; }; + 59468502EA5577F2B444DBCA74B1857F /* FBLPromise+Timeout.h in Headers */ = {isa = PBXBuildFile; fileRef = FDAA695864CC3BBE1FD6F2033E99903B /* FBLPromise+Timeout.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5973655F7EBDB83AF303F476E7C55157 /* FBLPromise.m in Sources */ = {isa = PBXBuildFile; fileRef = 6167BB02AD2CD052706EDB458E3A97DB /* FBLPromise.m */; }; + 59B8FB4B3A535AEE9992E95DABDE052D /* FIRComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 13E37AC54D7B24C66BD6CF82160052F3 /* FIRComponent.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5B036FD0C741D0E9EA660BEF6B129E77 /* FBLPromise+Await.h in Headers */ = {isa = PBXBuildFile; fileRef = 20971D3E3E7A40040BA9738697676BA2 /* FBLPromise+Await.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5BBD22AF1059269BC43EDF075ECE6406 /* FirebaseInstallations.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CBFB84887978A38D184D9B7509CEC70 /* FirebaseInstallations.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5CA8FEEDB54C293F4A74F580FF26E9B5 /* FIRInstallationsStoredAuthToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A6312DF21B12CC8C98107D510F999C5 /* FIRInstallationsStoredAuthToken.m */; }; + 5CCB09383FE8A66A9D3237082E7BB297 /* GULAppDelegateSwizzler_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A425BF5F9C0B0E67F5AFE9FAF490F42 /* GULAppDelegateSwizzler_Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5D2ED5A6F743E912A640F744CE331A3A /* FIRInstallationsErrorUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = C1D7F2BB9523A403818EA1338A8C4E4C /* FIRInstallationsErrorUtil.m */; }; + 5D937AA5259A707253557CF2F7C95BFB /* FBLPromise+Recover.h in Headers */ = {isa = PBXBuildFile; fileRef = 173A51C8B399291A7286A1EA617D1CF0 /* FBLPromise+Recover.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5DF89FFB676DA8E2E76D397065AE9663 /* RCNConfigContent.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE5D5601C9BF11D3E42C54F8A897736 /* RCNConfigContent.m */; }; + 5EA59E72AD35D1A8AA8B9C0EF7AE597F /* FIRAppInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = B45CD6FF2824BB7E404063328EF1829E /* FIRAppInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5EAC001221627DE7EC876B4040E75825 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67B07E9904CAAD5AD2278E2CBF9E13DD /* Foundation.framework */; }; + 6029C05E1DAB4EC6FC7F82DBB9796FF2 /* FIRDependency.h in Headers */ = {isa = PBXBuildFile; fileRef = 3AE8C3C914D009BC2BDBFB067F87FEF1 /* FIRDependency.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 60516003FF3241145859BC05A6697D67 /* FIRInstallationsBackoffController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F94FD91DF6337BC57E7EA5284B2A6FB /* FIRInstallationsBackoffController.m */; }; + 6168BAF01AB3B54660F57ACD3290AE0F /* FirebaseABTesting.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DC58B6F6E92A6FC58C6F549C51A3CD /* FirebaseABTesting.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 618CFDC4CC93B88B788BDA1894884976 /* pb_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 74B167474413405779DB425345668971 /* pb_decode.c */; settings = {COMPILER_FLAGS = "-fno-objc-arc -fno-objc-arc"; }; }; + 619DC42D768882B852156984DE521225 /* FIRInstallationsStoredAuthToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F23D0A780659D9A3CF4A10623BE1252 /* FIRInstallationsStoredAuthToken.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 628E298A412E6558078B51060D4C7310 /* FBLPromise+All.h in Headers */ = {isa = PBXBuildFile; fileRef = C2B7B7EAEDA74CFFA097EACEF29D0360 /* FBLPromise+All.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 629D11E5D9046B8FB80C6C814192A28F /* FBLPromise+Validate.m in Sources */ = {isa = PBXBuildFile; fileRef = E3D737720132A2E8C17A55188DA5BDE2 /* FBLPromise+Validate.m */; }; + 635C245F7FDB055D7BCB689F31EF04BC /* FIRRemoteConfig_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E0979A22E08784374AD00FBC125A929 /* FIRRemoteConfig_Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 648E136EA15B1689CD2BFE14069EF1B3 /* FirebaseRemoteConfigInterop-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 887DF535D5AF38FB365886AA77A0812C /* FirebaseRemoteConfigInterop-dummy.m */; }; + 65A8B640E3C161CB733FA87ECC087DC3 /* GULReachabilityChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = DDE5B58E518997E805EADBF552B035FA /* GULReachabilityChecker.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6641A38036C59D4A0B98E18F432A73C5 /* pb.h in Headers */ = {isa = PBXBuildFile; fileRef = DFF6D1196E0850AB81108EA139B13210 /* pb.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 672DDDE7DBD4EFF8357036DEBA0EFBC0 /* FBLPromise+Always.m in Sources */ = {isa = PBXBuildFile; fileRef = 8D49CEAEB219CE213CEE1380AA1870BC /* FBLPromise+Always.m */; }; + 67F806FA54A209B2DD19DFC752100041 /* FBLPromise+Async.h in Headers */ = {isa = PBXBuildFile; fileRef = FC344F258013D38B7813914E157B899F /* FBLPromise+Async.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6826C1FE06A215D2F6B8F51574FB1709 /* FIRRemoteConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 1BDFC4369892278777AFAE8FFCD7277A /* FIRRemoteConfig.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 69868DADA44E53CE51042BDADCB10765 /* FIRInstallationsItem+RegisterInstallationAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = 131FF3C379BFE19D94DB2D886BB5BD09 /* FIRInstallationsItem+RegisterInstallationAPI.m */; }; + 69C92D56BDF88146A168DAB810E6FBBE /* FIRConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 04767AC0916A11CA33FD803E732157A8 /* FIRConfiguration.m */; }; + 6AA982405AAD20B8FA6CFBFD7D486209 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = CEAFD5DBF95CB3ABF170F4D40038A4F5 /* PrivacyInfo.xcprivacy */; }; + 6BEDD7EED2AC8B76AE804DFA62841D3B /* HeartbeatController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72A9AC917567336C9C984D1E7E746E1D /* HeartbeatController.swift */; }; + 6D098ED385C81818E081BB4ACB3F08F6 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = C2C3CD7B96F82905F982A1C5A0A9568C /* PrivacyInfo.xcprivacy */; }; + 6E73A2E14B1800D1D3EC46D4D9560823 /* FirebaseCoreInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 656CA2FAECAEF3A41E8D3D9087334EB0 /* FirebaseCoreInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7104C97A514DFB3AA20BC595BA586E74 /* FIRInstallationsIIDTokenStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DF10E3FFB628E822CD5414D0DBC68B6 /* FIRInstallationsIIDTokenStore.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 72496DE8DCAF02B279C0E0792AEE398C /* FBLPromise+Any.m in Sources */ = {isa = PBXBuildFile; fileRef = 5425C8D0A9046622BEF46F6897052F98 /* FBLPromise+Any.m */; }; + 728F05428C749DD035897D811D42F99D /* FIRConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = A05DB176F7E6E83F7C2C63C9B7339E34 /* FIRConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 72D2E4336EFDEFCDE0708A284C93D874 /* FIRInstallationsAPIService.m in Sources */ = {isa = PBXBuildFile; fileRef = B9DB932484D54621537D7243450AD8B2 /* FIRInstallationsAPIService.m */; }; + 72F0168B4185A0A3727E8E09213139CB /* RemoteConfigProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41245A942268D2918A793101A1C60D05 /* RemoteConfigProperty.swift */; }; + 74081F542B64A38B39EA1346E138F933 /* FBLPromise+Reduce.m in Sources */ = {isa = PBXBuildFile; fileRef = 5752F61E868014DF81F980C566E3F44A /* FBLPromise+Reduce.m */; }; + 752CCCF6F24425B1B5AF180776639C8F /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 8F47A304F0B244DCCCF9EF7AA4BEBDD0 /* PrivacyInfo.xcprivacy */; }; + 77908124E99723653397D15F4684F06A /* FIRAnalyticsConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = C613060075D2D23E82D47FBEFEFEF43F /* FIRAnalyticsConfiguration.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 77DAB8C1A6901060DDDE58E682735233 /* FIRInstallationsSingleOperationPromiseCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 51C43A45BC6750EB6447FBC60A17AD4B /* FIRInstallationsSingleOperationPromiseCache.m */; }; + 79032BE000CEB45525B533AC5C035479 /* GULURLSessionDataResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 45DD421EB44E103C4624D35713AF2EC0 /* GULURLSessionDataResponse.m */; }; + 7AC0142D7F858DE4B67276904397F482 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 2759CDC1BBC5F2836E0734189AD22A89 /* PrivacyInfo.xcprivacy */; }; + 7C3806D3917DBC74D91E2D327AC3E66F /* FIRInteropEventNames.h in Headers */ = {isa = PBXBuildFile; fileRef = 12630B4D77778737AB3054E94B5E4D13 /* FIRInteropEventNames.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7C3CABFBAB9CBA2E914D9452CA37197B /* FIRExperimentController.m in Sources */ = {isa = PBXBuildFile; fileRef = E18CC3662CCE66A69D82B77B033C9B46 /* FIRExperimentController.m */; }; + 7CAC6C750F0FD866960F2EA287FEE0E8 /* PromisesObjC-FBLPromises_Privacy in Resources */ = {isa = PBXBuildFile; fileRef = 3F238BB22C5201CE689CAF2F766AED95 /* PromisesObjC-FBLPromises_Privacy */; }; + 7DCF6508F810FC485A58ED8861939C89 /* GULKeychainUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 59BC2A3E0993030DFEFBA1CA95D52CFD /* GULKeychainUtils.m */; }; + 80326CDBC48B1A73EB9FB8D2C27EA74B /* FIRCurrentDateProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 00313E759C28515403069130FA405A1E /* FIRCurrentDateProvider.m */; }; + 82A3F699E1244A47A48903B10462C483 /* FirebaseRemoteConfig-FirebaseRemoteConfig_Privacy in Resources */ = {isa = PBXBuildFile; fileRef = E75B0787FCDF53EA02071FEB9C2AE06A /* FirebaseRemoteConfig-FirebaseRemoteConfig_Privacy */; }; + 838F47C14943DD453B90E52B9615C050 /* RemoteConfigInterop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86EA04F76C2197F2C271094EF717A765 /* RemoteConfigInterop.swift */; }; + 84C26AA894C559C3E27DAC10EAD274F3 /* GULNetworkConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = C052BE7FB135A8ED2D6F28462B5A5737 /* GULNetworkConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 86B8BF288312F0318C0D069D3FD0D0ED /* FIRDependency.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A70510981FED68DF2BA809205D387A1 /* FIRDependency.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8728A7BFA216C50DA58F998A0F009FAC /* FIRInstallationsAuthTokenResult.m in Sources */ = {isa = PBXBuildFile; fileRef = A2AC3E8875E0CA8FD82FD435FCE63364 /* FIRInstallationsAuthTokenResult.m */; }; + 87A6BC96D33D542F867E8433A393F8FF /* GULKeychainStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 6AEF5C6A396D1ADA764611D687A920DB /* GULKeychainStorage.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8802FDF2420F8F1A2EE05CC8F1F86B91 /* RCNPersonalization.h in Headers */ = {isa = PBXBuildFile; fileRef = 36BBCAB899B1451687368290E880F5DF /* RCNPersonalization.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8835DA541490CC3B33F51EF2A1D3F5A1 /* FirebaseCoreInternal-FirebaseCoreInternal_Privacy in Resources */ = {isa = PBXBuildFile; fileRef = 4DB03FD262B678178A44272143846563 /* FirebaseCoreInternal-FirebaseCoreInternal_Privacy */; }; + 8AB6112E62DF1F97AC2FF4B3CF2E92D8 /* FIRInstallationsAuthTokenResultInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A32F0B2BEBD1CA7080B398F9E8452DB /* FIRInstallationsAuthTokenResultInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8D97FDA2F690B52492945338C49D35E1 /* GULHeartbeatDateStorageUserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = B7D094B1082789787A18E641F494B66E /* GULHeartbeatDateStorageUserDefaults.m */; }; + 8E6842275FCB472F515F9528F0365F16 /* FIRInteropParameterNames.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E895F248780B5169A797546598A50BD /* FIRInteropParameterNames.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8F94F3558D5B686DAFBA973B60C1B2A9 /* FIRInteropParameterNames.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F8375C661ADB48616C20299291EF091 /* FIRInteropParameterNames.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 8FD0E1D5C2BB2195E79BC4D5AB72C450 /* IsAppEncrypted.m in Sources */ = {isa = PBXBuildFile; fileRef = BF05C566026B4B2AEE16937A0686C96F /* IsAppEncrypted.m */; }; + 8FEA3F31AE13E6091C45C33A854CF62D /* FBLPromise+Recover.m in Sources */ = {isa = PBXBuildFile; fileRef = 83BF6D454D688FFBF8927B7141A2DF7E /* FBLPromise+Recover.m */; }; + 9093CC638BA2F194622C4F167A0A986C /* GULReachabilityChecker+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 94A29B8A8E4681B099C6CAF62AA8A044 /* GULReachabilityChecker+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9118BC86E6B23F80844218DB19E824ED /* FirebaseCore-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 06FF91B187C4B0F98539DC23C557D3CE /* FirebaseCore-dummy.m */; }; + 928636DE392A2592668AB49616E4FA07 /* FIRInstallationsBackoffController.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BE74F652D97F4762ABB42AAF26E0C68 /* FIRInstallationsBackoffController.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 92F9225A6F58ABB6EFFB67423315C15C /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7E343B046961E2648346BE23F8986EE7 /* SystemConfiguration.framework */; }; + 93415317A87C8D569C1F0FA3557F3C11 /* FIRVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 30256146DAEF27572A9F84BA3B0A5F90 /* FIRVersion.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 941FD9A53A9154E8BCD773F23E0CFB96 /* GULMutableDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = 022EFA2DC80ADD08AC7DD6A6A92329F1 /* GULMutableDictionary.m */; }; + 95A793820AE75639718FE3085EA9A6D5 /* FIRDependency.h in Headers */ = {isa = PBXBuildFile; fileRef = B846B97AF0194E6DDACEC9BB57748022 /* FIRDependency.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 97BB1C9234BCC0A9F40DF9B5B0439742 /* FBLPromise+Delay.m in Sources */ = {isa = PBXBuildFile; fileRef = D4ADC435328F01979C154BA5BF31669E /* FBLPromise+Delay.m */; }; + 97DD20E649353DE7D33074543438D0FE /* FIRAppInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = CEBB3CDF6B0397C596B3FAC80F041A98 /* FIRAppInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 981CB56D93FAF3DC8707FA0E35B4B310 /* FIRRemoteConfigComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 6698255073FCECA95BAED5CF2741CB12 /* FIRRemoteConfigComponent.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 98BCC34BD5FA508AB31593E96CF8DB10 /* GULURLSessionDataResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = BB56505360994F7A2EA65103F67C45FC /* GULURLSessionDataResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 98F4DB88F9C58DAAC21DCCD25411E48A /* FIRAnalyticsInterop.h in Headers */ = {isa = PBXBuildFile; fileRef = 5850429FAFBF3E9AA20DA67FFDF87D21 /* FIRAnalyticsInterop.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 996D15BD575A804A99E050B681C08F38 /* FIROptionsInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 24B9416E0B1FEE48AEB998B591133150 /* FIROptionsInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9C5C32D7C6FB396A5EB18E18695F5C69 /* HeartbeatsPayload.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3697C479CB24A72810F620D522393AF /* HeartbeatsPayload.swift */; }; + 9F4562A5BB1A5A39D1FE7BABC86BB9AB /* FBLPromise+Validate.h in Headers */ = {isa = PBXBuildFile; fileRef = 8797262413E3361B1F54135C6663A7F8 /* FBLPromise+Validate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9F5B3B58A35158B9687F3A9293E8DA8E /* FIRLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = B7F57ADFFFC393FF08F641F431134560 /* FIRLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 9F5E26F9089A8BBBDB39B6F9303D6483 /* FIRAppInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4D42DB954888D3DF8711540421EDA0 /* FIRAppInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A0EBB3819B68180B49D8F8D93BA3975F /* RCNPersonalization.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6820EB6EFEF734C44466B9387E7DF6 /* RCNPersonalization.m */; }; + A20CB02436409B5180B742C3487CB59A /* FIRVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = C3676C9257F1642F10902F42713C0ACD /* FIRVersion.m */; }; + A250E7BD7A742393573ED67256664322 /* FBLPromise+Testing.m in Sources */ = {isa = PBXBuildFile; fileRef = 6278570AF7F9F1EE5D5C487492D2EF7B /* FBLPromise+Testing.m */; }; + A256296DB5CF98380551076BBD4F4E97 /* FIRComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = B2AE340D7642101AA00A4094E6AF160C /* FIRComponent.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A2A12185E9E1165D3593761FBC1C5C5F /* FIRAppInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = C427612ED1543E2B1D60315509C9F971 /* FIRAppInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A2E4C1641A519E43A078374895FBBB98 /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B574DE5A4BC941F957A0DFF28756FCC /* Value.swift */; }; + A300E387017BE7F2390B5E9612CB0DE4 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93D0EB62190227CEBABBCE3968D0A977 /* Storage.swift */; }; + A34A76385D4414BB3007090AE6955DFE /* FIRComponentType.h in Headers */ = {isa = PBXBuildFile; fileRef = DA78B83E4AE85283B84FD1556F0740F5 /* FIRComponentType.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A5611C2B60D19A01A35D0B795D104DCD /* FIRHeartbeatLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = A1B3C129DCD5CB6FCBCE9B7F8D3FAB57 /* FIRHeartbeatLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; + A566222F15526FBA76CA10F2FC6D802A /* FIRLifecycleEvents.h in Headers */ = {isa = PBXBuildFile; fileRef = 89B98D107632C56A5971828F9ADFA29B /* FIRLifecycleEvents.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A64A2A673CABF907CEB1627752509A27 /* FBLPromise+Await.m in Sources */ = {isa = PBXBuildFile; fileRef = 88B571252A6FB34BC3358B9CEED97997 /* FBLPromise+Await.m */; }; + A65482320A15BD2D8BC34E0C7E45C32C /* GoogleUtilities-GoogleUtilities_Privacy in Resources */ = {isa = PBXBuildFile; fileRef = 44E291D18340EAC3F761346198515323 /* GoogleUtilities-GoogleUtilities_Privacy */; }; + A7A19779A3ACF4A1013D4B1254F17346 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1849556DA704B3114935A27CAD427E6C /* Security.framework */; }; + A7A2C5B7E0949A25B272EDAF2984A836 /* GULNetworkURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = C298ECA85B7369EC0FAE4312D770EA90 /* GULNetworkURLSession.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A7A5493867F1CB91002EC0B2668EFC1B /* pb_decode.h in Headers */ = {isa = PBXBuildFile; fileRef = 96D94CC74872ED59F27326449C32D262 /* pb_decode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A84E754C7D9B7BFA2F3B02B40619CC87 /* Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBD324685A27CEBC247F0D8C032F02C2 /* Codable.swift */; }; + A96900969B4DD93F3CA898C4020B5A25 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 2FD212450F47D61769C92212B52858AE /* PrivacyInfo.xcprivacy */; }; + A9FB28CD29CFD806E77F4D23718252EA /* RCNConstants3P.m in Sources */ = {isa = PBXBuildFile; fileRef = FDE851ED44CB1FF18D1F3D91CA170717 /* RCNConstants3P.m */; }; + AA15CDD5887BD912E07296B223DD26D3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67B07E9904CAAD5AD2278E2CBF9E13DD /* Foundation.framework */; }; + AA72AD3F145E11FB00205BCBAF4F70A0 /* FIRInstallationsLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = ABD115BB1BB820D2B2DE5F541A263736 /* FIRInstallationsLogger.m */; }; + AAE0AF48937F401710EFDAF669CCBE6B /* FirebaseRemoteConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DA9F090A9FABC1CBF232329F4E99A08 /* FirebaseRemoteConfig.h */; settings = {ATTRIBUTES = (Public, ); }; }; + AB4461579566B0CEA2255E743823C9D4 /* pb_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 8D079EC2785A105640FF2D0A76EC3E12 /* pb_common.c */; settings = {COMPILER_FLAGS = "-fno-objc-arc -fno-objc-arc -fno-objc-arc"; }; }; + ABBCC2BAB977D5AFD784D959F39E5382 /* FIRLibrary.h in Headers */ = {isa = PBXBuildFile; fileRef = E0C03855FD2E0FD02564160EEB28B12A /* FIRLibrary.h */; settings = {ATTRIBUTES = (Project, ); }; }; + AC5D9019D657C5DFE041375928416970 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 9AEFF81FC9CB7DCC949B85FDD1F205E6 /* PrivacyInfo.xcprivacy */; }; + AD2EC8DC4ABFC1C99A2C5150DDA5D70E /* FirebaseCore-FirebaseCore_Privacy in Resources */ = {isa = PBXBuildFile; fileRef = 8BB937B1C0DFFCF92F41861C2BC54DDA /* FirebaseCore-FirebaseCore_Privacy */; }; + AD5DF41E3B0B948D39237A5BB2D984F7 /* GULNetworkConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 455CFD151B0136FC6DB54FFE8395B810 /* GULNetworkConstants.m */; }; + AD6871FCDC88B2AAD1B74DF690D59541 /* FIRComponentContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 827A5C477414E206AF248DC46644C144 /* FIRComponentContainer.m */; }; + ADA7060BE42FC191AB4C76DBC920E168 /* RolloutAssignment.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD138F64499748EC08B4AC157DA1942B /* RolloutAssignment.swift */; }; + AEEDE83E1A6B856FE9FB16B6E90AB69F /* FBLPromise+Reduce.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AEECCD4B6E11F92852CC3FC55B6324 /* FBLPromise+Reduce.h */; settings = {ATTRIBUTES = (Public, ); }; }; + AF4E2A33DCEB9CF99022210A9CF1ED77 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67B07E9904CAAD5AD2278E2CBF9E13DD /* Foundation.framework */; }; + AF6ADB20A25E4279518F0B3C71722DFB /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67B07E9904CAAD5AD2278E2CBF9E13DD /* Foundation.framework */; }; + B0AA56A7BA4557EF616346CE6CF37E8D /* RCNDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 3386426474977F173391F1AED6A15D14 /* RCNDevice.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B15AA88E5B9438ED215AD6FAA1CC7075 /* ABTExperimentPayload.m in Sources */ = {isa = PBXBuildFile; fileRef = BF9778E519F419B6D3B8C346697725CD /* ABTExperimentPayload.m */; }; + B1772E69A33CADF4339590E3C89A51F4 /* FirebaseRemoteConfig-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 10C51F25D08AD933A8D3D02017AAA772 /* FirebaseRemoteConfig-dummy.m */; }; + B254EF09E23C51171972082A0009D002 /* GULHeartbeatDateStorable.h in Headers */ = {isa = PBXBuildFile; fileRef = 63B19F7DC4A4137A291CB841984B5FF8 /* GULHeartbeatDateStorable.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B36F54FC2A5557A5A3EDA62C3204F818 /* FIRInstallationsStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = B5BF445ADA4090C888DD3072A33376DC /* FIRInstallationsStatus.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B50F4DC2C07D8A33270EA188F0526734 /* GoogleUtilities-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = B1418672FD1A27E1215382BCE06B7573 /* GoogleUtilities-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B5322FAE78BBCD4A8889E5182EB708C0 /* FirebaseABTestingInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = C6C18CB3FD8877D00962967DD1E82DFD /* FirebaseABTestingInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B535EC928F517F977809F9C9721AEB18 /* FBLPromise+Testing.h in Headers */ = {isa = PBXBuildFile; fileRef = C53FC0372E7FECFF10949B01A02A4CB4 /* FBLPromise+Testing.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B68303147CFA60059219EB7C3A3C9D64 /* FirebaseDataEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 327179067DDF273E45A553A98667E75F /* FirebaseDataEncoder.swift */; }; + B6B2F4FB00A438AB6A699CDFD6DA4D20 /* GULUserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 239C079A4AE35E4BD38756DDD53ABB0C /* GULUserDefaults.m */; }; + B76DF41921B90D311203DEB3858F29E8 /* FIROptions.m in Sources */ = {isa = PBXBuildFile; fileRef = A96707865509075B195429CC67DDA479 /* FIROptions.m */; }; + B7C36CA4F98AD5446DE6F8F0E60A1CE2 /* FIRLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 54298054E074C62E86E20743BAC7925B /* FIRLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B7FC193A51569B977BB5C9EEE9D0CFE0 /* ABTExperimentPayload.h in Headers */ = {isa = PBXBuildFile; fileRef = CA48D768E2943DB7CA80E8A3D9F4ED8B /* ABTExperimentPayload.h */; settings = {ATTRIBUTES = (Project, ); }; }; + B898215E708FB5A0FCE5E8095D0B29E7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67B07E9904CAAD5AD2278E2CBF9E13DD /* Foundation.framework */; }; + B8D2D0DFAE7AD26E529972849964D74D /* FirebaseSharedSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = C18EC549B1DB7F87B0815997C8171F7F /* FirebaseSharedSwift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B940ACBAB30D76C2ED49BE466EF88D5B /* GULSceneDelegateSwizzler_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 0018232DF6477FC636A008D8AFCB7E22 /* GULSceneDelegateSwizzler_Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BA0070AD057C1F6A84A0BDEA97AFED3C /* PromisesObjC-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = B4A385C153D6F521F08424F73860D4A8 /* PromisesObjC-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BA53AEB692E8DE3DA1951888CBBFFC4B /* FBLPromise+Catch.h in Headers */ = {isa = PBXBuildFile; fileRef = B0B4202E023736A8A3E0FE9A4D8B2AEC /* FBLPromise+Catch.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BABD7A92C6F68B2FFA6EEDDB31DB609C /* GULNetwork.m in Sources */ = {isa = PBXBuildFile; fileRef = 90197B074482ED0230AA6216050C39B9 /* GULNetwork.m */; }; + BAC8ADFE352B585A8809A69152DB7A09 /* FBLPromise+Race.m in Sources */ = {isa = PBXBuildFile; fileRef = 611D27690CF7F6A20F3EF9942C5B4237 /* FBLPromise+Race.m */; }; + BD64038B193F6559C5A39AE5142296F7 /* FIROptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 31FAA9917871C7362008C56D223BCC4E /* FIROptions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BDAB010CAC043B15B6BEC882ADE47538 /* FIRInstallationsItem.h in Headers */ = {isa = PBXBuildFile; fileRef = E1370FB83C7D43687612F478D53CDFC6 /* FIRInstallationsItem.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BE996023DD3BFB1B6ACA569102CA5584 /* HeartbeatStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B4F89BBECD80988BC20EE63A99419F3 /* HeartbeatStorage.swift */; }; + BEC305229B8658BB752ADC9A1B38A0B5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67B07E9904CAAD5AD2278E2CBF9E13DD /* Foundation.framework */; }; + BF6EC2D659FFD114F8099F95181A2AEB /* FirebaseABTestingInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AE5232B5B0309B48780B3AF3A05D81E /* FirebaseABTestingInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + BFF03FA96140B5AC649C2BD02DE596BD /* FIRInstallationsIIDStore.h in Headers */ = {isa = PBXBuildFile; fileRef = B71E2D50301EECF023F1665D60BA21BF /* FIRInstallationsIIDStore.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C0AEB9B2CC89EFFBCA8BD250CD2EDD56 /* GoogleUtilities-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E36F090C3CFAF989AD74042701EAA7A /* GoogleUtilities-dummy.m */; }; + C15597EE7BE6CF4118F22F036FFB98BE /* GULNetworkInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 412DB5FFEF51E5BF36A217CC81C300F3 /* GULNetworkInfo.m */; }; + C245F54DBA994B6AA16F4F1E9FD36256 /* FIRAnalyticsInteropListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 128501E0F71587BAB05408A6D4FA83A6 /* FIRAnalyticsInteropListener.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C6656E6B25AF7D92BCA7ED357A317CFF /* RCNConfigSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FAA823A58ECCDA34B2453B1D1AF7CD8 /* RCNConfigSettings.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C755818FF2D566A24463020C6C38BDC6 /* RemoteConfigValueObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 950567D7B0395602E154D61249ECABC0 /* RemoteConfigValueObservable.swift */; }; + C7C78919F036C1FA7512B32BD3845694 /* WeakContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF97197EBBA43BAEC3E91489B34B278 /* WeakContainer.swift */; }; + C8AAEA20390A2D089C96122F666A0F05 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = BF3A1C11412FF332396C54BC7C6A034A /* PrivacyInfo.xcprivacy */; }; + C90466464C9DB45B03F726E0389B1524 /* FIRExperimentController.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C4A9E5C64494B1180C1901417EE3A70 /* FIRExperimentController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CB12128F080101291E224B3091C696D7 /* FirebaseCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 693374012D5FCD40E265F23036EF69F4 /* FirebaseCore.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CD0E2DBE8F28F8D1D5D10F16D7A00F63 /* FIRInstallationsIDController.h in Headers */ = {isa = PBXBuildFile; fileRef = D28D72B939EE470EF1B5DACA418C4F24 /* FIRInstallationsIDController.h */; settings = {ATTRIBUTES = (Project, ); }; }; + CDAA53809FE4658AB62E6F6A8CF6A955 /* FIRInstallationsStore.m in Sources */ = {isa = PBXBuildFile; fileRef = FF73936EF5B735B0E2F409E78191F589 /* FIRInstallationsStore.m */; }; + CDF51BB2D8DDD5143D508CD8C66E76B8 /* FIRLoggerLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = 907A242DBA66A1E0981EF0B63C0D29AE /* FIRLoggerLevel.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CFD7BCC70BA2D7A112DF87CC8A0E2621 /* FIRHeartbeatLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 89E7AF6C56924AFEFF0740DAF9255057 /* FIRHeartbeatLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D1C88B402B77260D2EA25F86159A1A25 /* GULOriginalIMPConvenienceMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = DD5BC1764C4EAE896681C235C95E0286 /* GULOriginalIMPConvenienceMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D2802874422630C0AA946A8ABC7D2289 /* FIRLifecycleEvents.m in Sources */ = {isa = PBXBuildFile; fileRef = B61F28CD0635CE23F8558A1083BC9241 /* FIRLifecycleEvents.m */; }; + D30FD08897F3A30CB10471D4FF9C7EC2 /* Pods-TallPaper-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 06491AEEA188D72888328E5AB0F9CBC3 /* Pods-TallPaper-dummy.m */; }; + D5DB89F63CF0A8A18FE137E3DBB62D4A /* GULSecureCoding.m in Sources */ = {isa = PBXBuildFile; fileRef = 7A8A262ED4D43839241892A6F812378D /* GULSecureCoding.m */; }; + D740B923690C7625A0A1FD365DED048C /* RolloutsStateSubscriber.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAE22D4EEFFF5C5797BE1668FD4894A5 /* RolloutsStateSubscriber.swift */; }; + D808FD94A874D4D45793C05444120FB3 /* ABTConditionalUserPropertyController.m in Sources */ = {isa = PBXBuildFile; fileRef = A8D24523EA654703855D1DAA0199A882 /* ABTConditionalUserPropertyController.m */; }; + D838A6D7510456D5B09DC1A635EFB4C3 /* GULLoggerCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7A73C3ECBA2E58085DF48768CABE2D /* GULLoggerCodes.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D8709F58EFA494EDF3B249214531FADC /* GULHeartbeatDateStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = FEFD82F6B39F8137121EE2D17DE0DCE6 /* GULHeartbeatDateStorage.m */; }; + D95F975AFEB7A4FF338B9D4627E65CB5 /* GULNetworkMessageCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 392DEC1EDF4E22D389A2EDC1AF4D38FB /* GULNetworkMessageCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D9C9596E93439FF9D3B8AC079406C889 /* FirebaseInstallations-FirebaseInstallations_Privacy in Resources */ = {isa = PBXBuildFile; fileRef = 47C581450CDB4A6111CB97EEE0711A8C /* FirebaseInstallations-FirebaseInstallations_Privacy */; }; + DA3D50737941CF3BB793F829A04B259B /* RCNConfigExperiment.h in Headers */ = {isa = PBXBuildFile; fileRef = FB6D773DC97F08768351C491F656B9E1 /* RCNConfigExperiment.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DB0D5CAF12790F157CD3AD8A3F8A9834 /* Pods-TallPaper-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 5733B5B6AFDDBF8B33A452723B5C73D0 /* Pods-TallPaper-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DB5B0C8F049B2AF8553C4565ECBB3221 /* FIRComponentContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3157854626C2B77AB6D211A676035453 /* FIRComponentContainer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DBD30DC1722D92C82E21BC6BCC692BF2 /* GULLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D99B8E0EA2E8B23A27BE04B1EC4B047 /* GULLogger.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DC95016776F4C4775BC83A5B9BBA67FF /* RCNConfigRealtime.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BD1F1E087564A3A043995BF657118C3 /* RCNConfigRealtime.m */; }; + DD1235F0F860A6AA680D9EE0A57DA0F7 /* SPMSwiftHeaderWorkaround.swift in Sources */ = {isa = PBXBuildFile; fileRef = D772A4B1414311177A62C6472414F917 /* SPMSwiftHeaderWorkaround.swift */; }; + DECAED39C7FCFADDAF75B0E0A727AA2F /* FBLPromise+Delay.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EAC051EED6ADDE1239220D47C008B7 /* FBLPromise+Delay.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DF03D2792E54B7E3D0BD33C742A21EA7 /* FIRComponentContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = F9802C5B40648D558005507BDB98BE1B /* FIRComponentContainer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + DFAF92029191B2912C5B9F07334D3463 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1849556DA704B3114935A27CAD427E6C /* Security.framework */; }; + DFFCF54CF20255E992DDCF41F73E33EB /* HeartbeatsBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 317F794A5B19A6A14FEB7AC5E8BDF1B5 /* HeartbeatsBundle.swift */; }; + E0AC3898D7732FAD5B6081F410CE1CF9 /* FirebaseInstallationsInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B1CA5B6B4CD43186F239F052D3F3EC2 /* FirebaseInstallationsInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E0BA9F9123D18022EA10BA2DB1757068 /* FIRDependency.h in Headers */ = {isa = PBXBuildFile; fileRef = 76F64C73760FB11EFEC43D654BE7D019 /* FIRDependency.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E11B91D74B6E42A4B013F1CFD3D3F119 /* NSURLSession+GULPromises.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B886DEF7892AC07BF604D685DDA2AEB /* NSURLSession+GULPromises.m */; }; + E2B85544E9B6D80BC8E3FA8E7AB7C2F3 /* FBLPromise+Always.h in Headers */ = {isa = PBXBuildFile; fileRef = E3D01BB112572C34FB89531B632D4D1E /* FBLPromise+Always.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E41B1FCB33F7920ED92FBAA41200FC21 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F37EF8D61BF172AB143158A5442AB923 /* UIKit.framework */; }; + E6004AC19BDD36271DFCA990FC3B17F4 /* FIRComponentContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25BEFF708DB6FD0A3B4A9DB9D1900BAD /* FIRComponentContainer.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E84BD01ED4077B1640D9DB3AD895CBA3 /* FirebaseInstallations-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E6D67077386032B4727AC1223EC5020 /* FirebaseInstallations-dummy.m */; }; + E8E5C8BBD8B94C603912CEF6A984E292 /* FBLPromiseError.m in Sources */ = {isa = PBXBuildFile; fileRef = 64DCFEC8D5593700D342D1B7E1F2685B /* FBLPromiseError.m */; }; + E971E1E6E1FE6C74F80303051F741096 /* FIRHeartbeatLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 3F68F0820FA5987836BABB37620BBC7F /* FIRHeartbeatLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; + E97BD92C36FE57719D233B6FE8732853 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67B07E9904CAAD5AD2278E2CBF9E13DD /* Foundation.framework */; }; + EA11597688903C5320AD86904A6E1928 /* RCNUserDefaultsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10A07C1E2DBB2A9D4EA51FAA71EA410D /* RCNUserDefaultsManager.m */; }; + EAC2A886D88EEA6419C9C2950F6000A3 /* FIRInstallationsItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 28B1D4B5A9F28E5152E07C5C14754E25 /* FIRInstallationsItem.m */; }; + EB486F00D483C5DD151C2724316E3BAF /* pb_encode.c in Sources */ = {isa = PBXBuildFile; fileRef = ECB81467705B90F303806DFA82967938 /* pb_encode.c */; settings = {COMPILER_FLAGS = "-fno-objc-arc -fno-objc-arc"; }; }; + EBE128E6F0CCC85440CEEF9B880FE73F /* FirebaseCoreInternal-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = B295501A485E49383772BDE110D3AE32 /* FirebaseCoreInternal-dummy.m */; }; + ED45843DF658E3B968B28FF4E239497D /* GULMutableDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = CCD202A0BEC7B9F25A622E8AAD0881E0 /* GULMutableDictionary.h */; settings = {ATTRIBUTES = (Public, ); }; }; + EE04EF1645806C0E759BABA063E9B9B2 /* GULNSData+zlib.h in Headers */ = {isa = PBXBuildFile; fileRef = 0723B2CC8105941D5D54C6703FFEC746 /* GULNSData+zlib.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F00678FAE83AD45D280DA59B3FAE1B79 /* FirebaseCoreInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = EDF547F1045BB22A439576978EC18D29 /* FirebaseCoreInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F0D69983AC6B8E8030E469B20F15A035 /* GULSwizzler.h in Headers */ = {isa = PBXBuildFile; fileRef = 6661A473DB214FE0EEB7DCA0DCA731C1 /* GULSwizzler.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F0FE0939029DB44980E4992515EAE0C7 /* FirebaseCoreInternal-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = B411BC492A95118344F161DBDD11C0D6 /* FirebaseCoreInternal-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F1E816465C3D3C871C582D66551F9B1E /* GULLoggerLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C9CE713B787FE75F0F3C7D7E9E5A4BF /* GULLoggerLevel.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F20CB06C3AD93285E5EAE2A060035F92 /* FIRComponentType.h in Headers */ = {isa = PBXBuildFile; fileRef = AF7CD070A6EBC4ABAC149FE0885CAA98 /* FIRComponentType.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F2D3FE6849FBB1C5C98B881E573FBBB3 /* GULReachabilityChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = E6716339F23C20BC1ED183E8FBE8FB6D /* GULReachabilityChecker.m */; }; + F3A5A0177DA043B370520334D484B83D /* FBLPromise+All.m in Sources */ = {isa = PBXBuildFile; fileRef = 463DFF8A5EA5177997B4E5AAB61B18C9 /* FBLPromise+All.m */; }; + F426D94A9E79290D9AA64985A2589789 /* FIRInstallationsIIDStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 7671C8543FF5F9E45F6C0ECC84E4546A /* FIRInstallationsIIDStore.m */; }; + F4EA10237210D16D24066CBA18DC8713 /* FIRComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = D1B88D82044B86B4E61B8CAED0322C12 /* FIRComponent.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F640D820B4E7C66D4EF6FC5D1FAE3431 /* FIRComponentContainerInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 7DF3A1166255CF3E0C68A1C007CC0F4E /* FIRComponentContainerInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F65C2E1BE094262E7819BF79D69F6FEC /* FirebaseRemoteConfigValueDecoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABB78103AD0C89A5FD52D081ABD277ED /* FirebaseRemoteConfigValueDecoding.swift */; }; + F6AD3A5D8A3C8499B8C9C18B17320E3A /* PromisesObjC-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 085FB0A6565460730815B2F7CE7E5896 /* PromisesObjC-dummy.m */; }; + F74B316FB409406995A7F37CE7DEE1D4 /* FIROptionsInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = C5C2F43474B905E02BDFE3A517E2FC3B /* FIROptionsInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + F83500E29BE9745AB16A0D80BCAB3DED /* FIRComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = 92CDB8AAF698BCDEC7E8FDA1401BBBBE /* FIRComponent.m */; }; + F9442DC6740E99FA242BEDA1B5D5688F /* FIRApp.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A6FE737AE93759D79B96FB0CB940B1F /* FIRApp.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FADB0173B4714D97704DC4B93AE2191C /* FirebaseRemoteConfigValueDecoderHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3AC93E4D423A4A3A651F8753C72C28E /* FirebaseRemoteConfigValueDecoderHelper.swift */; }; + FAEEEEB22A63428133C9D69418119A43 /* nanopb-nanopb_Privacy in Resources */ = {isa = PBXBuildFile; fileRef = 3227F3FC45681D7CEE5D1355A532398A /* nanopb-nanopb_Privacy */; }; + FDB0F2DEC86D0B1696DECC7D1C10C64E /* FBLPromise+Wrap.h in Headers */ = {isa = PBXBuildFile; fileRef = 982C459C8AFB771ED709220BAE6D3BD6 /* FBLPromise+Wrap.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FDB3FAC8CAA298F8E638D1B0B5E73DD6 /* FBLPromise+Catch.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E7C94E810B158112FA354F33B2FDDFD /* FBLPromise+Catch.m */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 081CF40DBBEB51B3F1D7EC7F8D7BF166 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2BBF7206D7FAC92C82A042A99C4A98F8; + remoteInfo = PromisesObjC; + }; + 0D860AB6942AA508FC7C0073DC2ADDC4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 51471EE35F2E9E19E51A74944E5ABB7F; + remoteInfo = FirebaseRemoteConfig; + }; + 0FF7E72E45CB0340F82E7EA377DDCD6A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = C49E7A4D59E5C8BE8DE9FB1EFB150185; + remoteInfo = FirebaseAnalytics; + }; + 1503E6F56D354428B148B3BBB051D738 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 328CC04F43300C6CAB81659260A3799D; + remoteInfo = FirebaseRemoteConfigInterop; + }; + 152F093DB2B8DC111604E8D8B1DD4C04 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = C49E7A4D59E5C8BE8DE9FB1EFB150185; + remoteInfo = FirebaseAnalytics; + }; + 21F39E95BA677075F8EB4DCB42CBFD95 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D7F5D5DD528D21A72DC87ADA5B12E2D; + remoteInfo = GoogleUtilities; + }; + 2682C74FFD35473726B30A0FAB0876F7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 25E9E9A17BC3F670357D7385C521E48E; + remoteInfo = FirebaseCoreInternal; + }; + 32C8AA9B091FEC1C555AC02739E998B0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1BFBEDBF7E03729D43C96530EE190825; + remoteInfo = "PromisesObjC-FBLPromises_Privacy"; + }; + 39D1346C189AA8F3A4B697C6F17A3A71 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2BBF7206D7FAC92C82A042A99C4A98F8; + remoteInfo = PromisesObjC; + }; + 442DF15F710983695AB9CB115C0784A1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2949783F7EDB27AD4666B5427B63DC79; + remoteInfo = "FirebaseCoreInternal-FirebaseCoreInternal_Privacy"; + }; + 45A1D9A21E0A7BED244127A2709B8AD7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2BBF7206D7FAC92C82A042A99C4A98F8; + remoteInfo = PromisesObjC; + }; + 70A4665888585A341356023A8C1D7DF2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 3EB14444A17F9D4F1F697F7C1FF32245; + remoteInfo = "FirebaseInstallations-FirebaseInstallations_Privacy"; + }; + 7312CE961258952B14B56854CC250D56 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2B5E7DCCBBFB32341D857D01211A1A3; + remoteInfo = nanopb; + }; + 7CB8E94492E7953D2AC2B8BD6F61C662 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E9F5D289F4688880F8AEA528F4783976; + remoteInfo = "FirebaseABTesting-FirebaseABTesting_Privacy"; + }; + 7E229544576078E2663FB7115D6BA2D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5FF1A58DEEC5DB749FCD6C120B97CC82; + remoteInfo = "GoogleUtilities-GoogleUtilities_Privacy"; + }; + 7F3934CE37EBC805566C0343C5AAD216 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8F68D031908A0059566798048C48F776; + remoteInfo = FirebaseABTesting; + }; + 810E572A545C1D2DBB14727D74D6E9A3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 55522A91938FF505CFEBEAD2DD85AE2D; + remoteInfo = "nanopb-nanopb_Privacy"; + }; + 87432F1B75017FCB8A9E80E9043CB0B4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4402AFF83DBDC4DD07E198685FDC2DF2; + remoteInfo = FirebaseCore; + }; + 949DD4FCC278727B99CC98911ADBE73C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D7F5D5DD528D21A72DC87ADA5B12E2D; + remoteInfo = GoogleUtilities; + }; + 9681F3A466FAEA2D485242C889D16173 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D7F5D5DD528D21A72DC87ADA5B12E2D; + remoteInfo = GoogleUtilities; + }; + 97C4F13AA2985BD9D9577598788E1550 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4402AFF83DBDC4DD07E198685FDC2DF2; + remoteInfo = FirebaseCore; + }; + 9E8B23BDF693F044427951359FB201EE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 94706DD5BBE215339DF893D4434E1084; + remoteInfo = FirebaseSharedSwift; + }; + A09177654ADF7396E89786374177223E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D7F5D5DD528D21A72DC87ADA5B12E2D; + remoteInfo = GoogleUtilities; + }; + A0E8D0C6AF9DAA7396F1CFF4CD2B5DBB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D7F5D5DD528D21A72DC87ADA5B12E2D; + remoteInfo = GoogleUtilities; + }; + A8848EF3927118035050B6F7396FB872 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4402AFF83DBDC4DD07E198685FDC2DF2; + remoteInfo = FirebaseCore; + }; + AC4EDC404AE09AF4AD137D1C2C444D91 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 072CEA044D2EF26F03496D5996BBF59F; + remoteInfo = Firebase; + }; + B2DE9CCD596806BBAAFE458D5C9DBF80 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4402AFF83DBDC4DD07E198685FDC2DF2; + remoteInfo = FirebaseCore; + }; + B35F65BE3D4B5256D6CFB33DE33929C5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 328CC04F43300C6CAB81659260A3799D; + remoteInfo = FirebaseRemoteConfigInterop; + }; + B46B8910E9A0F50A4DCEC43C91553F54 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8F68D031908A0059566798048C48F776; + remoteInfo = FirebaseABTesting; + }; + B6392751A6B18AC3E9E0523D7A71D924 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D7F5D5DD528D21A72DC87ADA5B12E2D; + remoteInfo = GoogleUtilities; + }; + B703119491DFB27D9223BA2E79900887 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 94706DD5BBE215339DF893D4434E1084; + remoteInfo = FirebaseSharedSwift; + }; + BA15A2694F4A203217DEF9FEDF62AB73 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 87803597EB3F20FC46472B85392EC4FD; + remoteInfo = FirebaseInstallations; + }; + BD94AE6BF3081863C9CE8BF10451D85D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4402AFF83DBDC4DD07E198685FDC2DF2; + remoteInfo = FirebaseCore; + }; + BED2A89948352F8B2C01A03D8161E15D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B53D977A951AFC38B21751B706C1DF83; + remoteInfo = GoogleAppMeasurement; + }; + C07D7085FA2EF9F7F250A2792F7ED609 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1001C16510D946B47CFF8B19DBC0B787; + remoteInfo = "FirebaseCore-FirebaseCore_Privacy"; + }; + C6754D2B8C7AE5717C8F82883EE437A2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2B5E7DCCBBFB32341D857D01211A1A3; + remoteInfo = nanopb; + }; + CC5168CDA80D76FE411928416EA29ECA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 87803597EB3F20FC46472B85392EC4FD; + remoteInfo = FirebaseInstallations; + }; + CD1003A3DC1C3B4A9FFB55030249A2FA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4402AFF83DBDC4DD07E198685FDC2DF2; + remoteInfo = FirebaseCore; + }; + DEC6BF4C1423886E88E1748C33B55136 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = C7B621349CB28ED0EBA4C3E416947AB6; + remoteInfo = "FirebaseRemoteConfig-FirebaseRemoteConfig_Privacy"; + }; + E4689F6887BEF6932C075C938C4B2A40 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B53D977A951AFC38B21751B706C1DF83; + remoteInfo = GoogleAppMeasurement; + }; + EA34ADD006B1476EE422DFE42432FBD1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2B5E7DCCBBFB32341D857D01211A1A3; + remoteInfo = nanopb; + }; + EF2C4220D15ECAD4A347EBDA5C55A94C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 25E9E9A17BC3F670357D7385C521E48E; + remoteInfo = FirebaseCoreInternal; + }; + F9502B61921E53BF09F3FC0ED83B6CD6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 87803597EB3F20FC46472B85392EC4FD; + remoteInfo = FirebaseInstallations; + }; + FD3770C78E4F8B33613DC7B41452AB5A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8D7F5D5DD528D21A72DC87ADA5B12E2D; + remoteInfo = GoogleUtilities; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXFileReference section */ - 00A8DCAE9B7B3EF7B8C45FDAEFC36A4B /* Pods-HD wallpaper-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-HD wallpaper-acknowledgements.plist"; sourceTree = ""; }; - 1A195F190B302CCB9E52FF10ACF4E658 /* Pods-HD wallpaper-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-HD wallpaper-umbrella.h"; sourceTree = ""; }; - 4012E5D2ED98BF15C346FA7E4ECBB040 /* Pods-HD wallpaper-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-HD wallpaper-dummy.m"; sourceTree = ""; }; - 625A821940DC5522089C482A22E4EDD0 /* Pods-HD wallpaper.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-HD wallpaper.debug.xcconfig"; sourceTree = ""; }; - 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 0018232DF6477FC636A008D8AFCB7E22 /* GULSceneDelegateSwizzler_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULSceneDelegateSwizzler_Private.h; path = GoogleUtilities/AppDelegateSwizzler/Internal/GULSceneDelegateSwizzler_Private.h; sourceTree = ""; }; + 00313E759C28515403069130FA405A1E /* FIRCurrentDateProvider.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRCurrentDateProvider.m; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRCurrentDateProvider.m; sourceTree = ""; }; + 00B1CB57BD2FCA1ED789D36520B26010 /* GULNetworkLoggerProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkLoggerProtocol.h; path = GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkLoggerProtocol.h; sourceTree = ""; }; + 0137629091A47137D26044343F6BB38B /* GULApplication.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULApplication.h; path = GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULApplication.h; sourceTree = ""; }; + 022EFA2DC80ADD08AC7DD6A6A92329F1 /* GULMutableDictionary.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULMutableDictionary.m; path = GoogleUtilities/Network/GULMutableDictionary.m; sourceTree = ""; }; + 02871E8BD2CDB997D08FE36292EBBEF9 /* FBLPromise.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBLPromise.h; path = Sources/FBLPromises/include/FBLPromise.h; sourceTree = ""; }; + 02EDB16B4C9AE7695C2AF1BBE4D06F36 /* Pods-TallPaper-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-TallPaper-Info.plist"; sourceTree = ""; }; + 0465BFA65D53A47C84AA386E5A316F4C /* FirebaseCore-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FirebaseCore-umbrella.h"; sourceTree = ""; }; + 04767AC0916A11CA33FD803E732157A8 /* FIRConfiguration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRConfiguration.m; path = FirebaseCore/Sources/FIRConfiguration.m; sourceTree = ""; }; + 0491E43DC23FC5E37105C21C201F973B /* ResourceBundle-FirebaseCore_Privacy-FirebaseCore-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-FirebaseCore_Privacy-FirebaseCore-Info.plist"; sourceTree = ""; }; + 04DA273D6CD199F3F5E1A9ACA1888AD5 /* ResourceBundle-nanopb_Privacy-nanopb-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-nanopb_Privacy-nanopb-Info.plist"; sourceTree = ""; }; + 05A0C6A166AB6A227A42FE62B5491689 /* PromisesObjC.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = PromisesObjC.release.xcconfig; sourceTree = ""; }; + 06491AEEA188D72888328E5AB0F9CBC3 /* Pods-TallPaper-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-TallPaper-dummy.m"; sourceTree = ""; }; + 06FC5C9CF96D60C50FCD47D339C91951 /* nanopb */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = nanopb; path = nanopb.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 06FF91B187C4B0F98539DC23C557D3CE /* FirebaseCore-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FirebaseCore-dummy.m"; sourceTree = ""; }; + 0723B2CC8105941D5D54C6703FFEC746 /* GULNSData+zlib.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "GULNSData+zlib.h"; path = "GoogleUtilities/NSData+zlib/Public/GoogleUtilities/GULNSData+zlib.h"; sourceTree = ""; }; + 07679DB88FE797CC272089440CCF0229 /* nanopb-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "nanopb-prefix.pch"; sourceTree = ""; }; + 085FB0A6565460730815B2F7CE7E5896 /* PromisesObjC-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "PromisesObjC-dummy.m"; sourceTree = ""; }; + 088F19A523410C4D1489640C952BFF4E /* nanopb.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = nanopb.release.xcconfig; sourceTree = ""; }; + 0899876952EBC0C6C6B0997B6126F021 /* ABTConstants.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ABTConstants.h; path = FirebaseABTesting/Sources/ABTConstants.h; sourceTree = ""; }; + 0A425BF5F9C0B0E67F5AFE9FAF490F42 /* GULAppDelegateSwizzler_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULAppDelegateSwizzler_Private.h; path = GoogleUtilities/AppDelegateSwizzler/Internal/GULAppDelegateSwizzler_Private.h; sourceTree = ""; }; + 0D08833CDC51AB4B8E3948BB24DFE839 /* FIRLibrary.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLibrary.h; path = FirebaseCore/Extension/FIRLibrary.h; sourceTree = ""; }; + 0E5CC88FBF5B87E058EE0D5A44911700 /* IsAppEncrypted.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = IsAppEncrypted.h; path = third_party/IsAppEncrypted/Public/IsAppEncrypted.h; sourceTree = ""; }; + 10A07C1E2DBB2A9D4EA51FAA71EA410D /* RCNUserDefaultsManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCNUserDefaultsManager.m; path = FirebaseRemoteConfig/Sources/RCNUserDefaultsManager.m; sourceTree = ""; }; + 10C51F25D08AD933A8D3D02017AAA772 /* FirebaseRemoteConfig-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FirebaseRemoteConfig-dummy.m"; sourceTree = ""; }; + 117FB7DD9722C3296E517F8DA59AE404 /* FirebaseCoreInternal.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseCoreInternal.debug.xcconfig; sourceTree = ""; }; + 12630B4D77778737AB3054E94B5E4D13 /* FIRInteropEventNames.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInteropEventNames.h; path = Interop/Analytics/Public/FIRInteropEventNames.h; sourceTree = ""; }; + 128501E0F71587BAB05408A6D4FA83A6 /* FIRAnalyticsInteropListener.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAnalyticsInteropListener.h; path = Interop/Analytics/Public/FIRAnalyticsInteropListener.h; sourceTree = ""; }; + 131FF3C379BFE19D94DB2D886BB5BD09 /* FIRInstallationsItem+RegisterInstallationAPI.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FIRInstallationsItem+RegisterInstallationAPI.m"; path = "FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.m"; sourceTree = ""; }; + 13A178CFE40985F6D199227F9EB9E967 /* FIRRemoteConfigComponent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRRemoteConfigComponent.m; path = FirebaseRemoteConfig/Sources/FIRRemoteConfigComponent.m; sourceTree = ""; }; + 13C8C8B254851998F9289F71229B28A2 /* FirebaseInstallations */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = FirebaseInstallations; path = FirebaseInstallations.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 13DF7CFA55D10890541BE0D89C69E5C1 /* PromisesObjC-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "PromisesObjC-Info.plist"; sourceTree = ""; }; + 13E37AC54D7B24C66BD6CF82160052F3 /* FIRComponent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponent.h; path = FirebaseCore/Extension/FIRComponent.h; sourceTree = ""; }; + 13EB0519F4816AC5CD163BF70502E536 /* GoogleAppMeasurement.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleAppMeasurement.release.xcconfig; sourceTree = ""; }; + 143D42ABF58FD977F7BD2B817A79E6DC /* FIRFirebaseUserAgent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRFirebaseUserAgent.m; path = FirebaseCore/Sources/FIRFirebaseUserAgent.m; sourceTree = ""; }; + 148D0F9E8C7373FEAF40D800FC5F1BAA /* FirebaseCoreInternal */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = FirebaseCoreInternal; path = FirebaseCoreInternal.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 151395376150327AE967B52B05253632 /* FIRComponent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponent.h; path = FirebaseCore/Extension/FIRComponent.h; sourceTree = ""; }; + 173A1D2BA8A434F883C4F3756BCF6890 /* FIRFirebaseUserAgent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRFirebaseUserAgent.h; path = FirebaseCore/Sources/FIRFirebaseUserAgent.h; sourceTree = ""; }; + 173A51C8B399291A7286A1EA617D1CF0 /* FBLPromise+Recover.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Recover.h"; path = "Sources/FBLPromises/include/FBLPromise+Recover.h"; sourceTree = ""; }; + 17AAC41742538CD112A3BAEAB2641C31 /* GULHeartbeatDateStorageUserDefaults.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULHeartbeatDateStorageUserDefaults.h; path = GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorageUserDefaults.h; sourceTree = ""; }; + 17B62497EB13A290B2423E0AED196DF0 /* RCNConfigValue_Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCNConfigValue_Internal.h; path = FirebaseRemoteConfig/Sources/RCNConfigValue_Internal.h; sourceTree = ""; }; + 1849556DA704B3114935A27CAD427E6C /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; + 18FC8810EE8510F55DA41D4B374702C4 /* FIRInstallationsLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsLogger.h; path = FirebaseInstallations/Source/Library/FIRInstallationsLogger.h; sourceTree = ""; }; + 1AE5232B5B0309B48780B3AF3A05D81E /* FirebaseABTestingInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseABTestingInternal.h; path = FirebaseABTesting/Sources/Private/FirebaseABTestingInternal.h; sourceTree = ""; }; + 1B0DBA62A90CC2A21478E9B430CF5DC0 /* FIRDependency.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRDependency.m; path = FirebaseCore/Sources/FIRDependency.m; sourceTree = ""; }; + 1B574DE5A4BC941F957A0DFF28756FCC /* Value.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Value.swift; path = FirebaseRemoteConfig/Swift/Value.swift; sourceTree = ""; }; + 1BD1F1E087564A3A043995BF657118C3 /* RCNConfigRealtime.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCNConfigRealtime.m; path = FirebaseRemoteConfig/Sources/RCNConfigRealtime.m; sourceTree = ""; }; + 1BDFC4369892278777AFAE8FFCD7277A /* FIRRemoteConfig.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRRemoteConfig.h; path = FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h; sourceTree = ""; }; + 1D99B8E0EA2E8B23A27BE04B1EC4B047 /* GULLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULLogger.h; path = GoogleUtilities/Logger/Public/GoogleUtilities/GULLogger.h; sourceTree = ""; }; + 206885B8EC1F263A4198751B7308476D /* nanopb-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "nanopb-dummy.m"; sourceTree = ""; }; + 20971D3E3E7A40040BA9738697676BA2 /* FBLPromise+Await.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Await.h"; path = "Sources/FBLPromises/include/FBLPromise+Await.h"; sourceTree = ""; }; + 209B54CF7D994B06541AB454EE9CAA34 /* FirebaseABTesting.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseABTesting.debug.xcconfig; sourceTree = ""; }; + 239C079A4AE35E4BD38756DDD53ABB0C /* GULUserDefaults.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULUserDefaults.m; path = GoogleUtilities/UserDefaults/GULUserDefaults.m; sourceTree = ""; }; + 24B9416E0B1FEE48AEB998B591133150 /* FIROptionsInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIROptionsInternal.h; path = FirebaseCore/Extension/FIROptionsInternal.h; sourceTree = ""; }; + 25BEFF708DB6FD0A3B4A9DB9D1900BAD /* FIRComponentContainer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentContainer.h; path = FirebaseCore/Extension/FIRComponentContainer.h; sourceTree = ""; }; + 27204B2F94BC80BF02755E6EE6FF48B4 /* RCNUserDefaultsManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCNUserDefaultsManager.h; path = FirebaseRemoteConfig/Sources/RCNUserDefaultsManager.h; sourceTree = ""; }; + 2759CDC1BBC5F2836E0734189AD22A89 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = FirebaseABTesting/Sources/Resources/PrivacyInfo.xcprivacy; sourceTree = ""; }; + 279FA0556ED8D6821E91A2A2606D431B /* FirebaseSharedSwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = FirebaseSharedSwift.modulemap; sourceTree = ""; }; + 2834B6BD9246A467EF26B83F6D9E3154 /* nanopb.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = nanopb.debug.xcconfig; sourceTree = ""; }; + 284758AE50272963E0D9B62E0EDE3D07 /* ResourceBundle-GoogleUtilities_Privacy-GoogleUtilities-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-GoogleUtilities_Privacy-GoogleUtilities-Info.plist"; sourceTree = ""; }; + 285D84A0377A267C0513653225E27A7F /* FirebaseCoreInternal.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = FirebaseCoreInternal.modulemap; sourceTree = ""; }; + 28B1D4B5A9F28E5152E07C5C14754E25 /* FIRInstallationsItem.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsItem.m; path = FirebaseInstallations/Source/Library/FIRInstallationsItem.m; sourceTree = ""; }; + 28EE1B16B384D2A8C8351D936C0C2512 /* FIRInstallationsHTTPError.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsHTTPError.m; path = FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.m; sourceTree = ""; }; + 2A097E8C3EAC2A58C6A5B7BFE9E75AD1 /* StorageFactory.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StorageFactory.swift; path = FirebaseCore/Internal/Sources/HeartbeatLogging/StorageFactory.swift; sourceTree = ""; }; + 2A2C481DB452CB7996C1C84958339D48 /* Pods-TallPaper-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-TallPaper-acknowledgements.plist"; sourceTree = ""; }; + 2A6312DF21B12CC8C98107D510F999C5 /* FIRInstallationsStoredAuthToken.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsStoredAuthToken.m; path = FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.m; sourceTree = ""; }; + 2AC9D23ABC43B3AC297A939A82852C2C /* NSURLSession+GULPromises.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSURLSession+GULPromises.h"; path = "GoogleUtilities/Environment/Public/GoogleUtilities/NSURLSession+GULPromises.h"; sourceTree = ""; }; + 2BE74F652D97F4762ABB42AAF26E0C68 /* FIRInstallationsBackoffController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsBackoffController.h; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsBackoffController.h; sourceTree = ""; }; + 2BEBB95E96263213DF218487B37FF912 /* FIRBundleUtil.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRBundleUtil.h; path = FirebaseCore/Sources/FIRBundleUtil.h; sourceTree = ""; }; + 2CBFB84887978A38D184D9B7509CEC70 /* FirebaseInstallations.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseInstallations.h; path = FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FirebaseInstallations.h; sourceTree = ""; }; + 2DF97197EBBA43BAEC3E91489B34B278 /* WeakContainer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WeakContainer.swift; path = FirebaseCore/Internal/Sources/HeartbeatLogging/WeakContainer.swift; sourceTree = ""; }; + 2FD212450F47D61769C92212B52858AE /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = FirebaseInstallations/Source/Library/Resources/PrivacyInfo.xcprivacy; sourceTree = ""; }; + 301D057D7C395E459311054BEA2DCDB9 /* FirebaseCore-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "FirebaseCore-Info.plist"; sourceTree = ""; }; + 30256146DAEF27572A9F84BA3B0A5F90 /* FIRVersion.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRVersion.h; path = FirebaseCore/Sources/Public/FirebaseCore/FIRVersion.h; sourceTree = ""; }; + 3053A1109EE95419C9FE468E7C6496EC /* FirebaseInstallations.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = FirebaseInstallations.modulemap; sourceTree = ""; }; + 308C8B46912372B5807BEFB1E6E1F65B /* Heartbeat.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Heartbeat.swift; path = FirebaseCore/Internal/Sources/HeartbeatLogging/Heartbeat.swift; sourceTree = ""; }; + 30A4C68C973005FCD0A890D52035EBAD /* GULSceneDelegateSwizzler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULSceneDelegateSwizzler.m; path = GoogleUtilities/AppDelegateSwizzler/GULSceneDelegateSwizzler.m; sourceTree = ""; }; + 3157854626C2B77AB6D211A676035453 /* FIRComponentContainer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentContainer.h; path = FirebaseCore/Extension/FIRComponentContainer.h; sourceTree = ""; }; + 3176BDD8AA7AC5A550A4FB1DC652A480 /* FIRInstallations.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallations.h; path = FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallations.h; sourceTree = ""; }; + 317F794A5B19A6A14FEB7AC5E8BDF1B5 /* HeartbeatsBundle.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HeartbeatsBundle.swift; path = FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatsBundle.swift; sourceTree = ""; }; + 31FAA9917871C7362008C56D223BCC4E /* FIROptions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIROptions.h; path = FirebaseCore/Sources/Public/FirebaseCore/FIROptions.h; sourceTree = ""; }; + 3227F3FC45681D7CEE5D1355A532398A /* nanopb-nanopb_Privacy */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "nanopb-nanopb_Privacy"; path = nanopb_Privacy.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 327179067DDF273E45A553A98667E75F /* FirebaseDataEncoder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FirebaseDataEncoder.swift; path = FirebaseSharedSwift/Sources/third_party/FirebaseDataEncoder/FirebaseDataEncoder.swift; sourceTree = ""; }; + 3347A1AB6546F0A3977529B8F199DC41 /* PromisesObjC */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = PromisesObjC; path = FBLPromises.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 3386426474977F173391F1AED6A15D14 /* RCNDevice.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCNDevice.h; path = FirebaseRemoteConfig/Sources/RCNDevice.h; sourceTree = ""; }; + 34A6D6776B3743C799B000FB60E1527A /* FIRInstallationsAuthTokenResult.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsAuthTokenResult.h; path = FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallationsAuthTokenResult.h; sourceTree = ""; }; + 34FE9444CEE6E7A31895765C269BD245 /* FIRCurrentDateProvider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRCurrentDateProvider.h; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRCurrentDateProvider.h; sourceTree = ""; }; + 355F27AC7B489492967576003F3B4992 /* FirebaseSharedSwift-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "FirebaseSharedSwift-Info.plist"; sourceTree = ""; }; + 36791595F93467472A8A233FCEF63536 /* FIRInstallations.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallations.m; path = FirebaseInstallations/Source/Library/FIRInstallations.m; sourceTree = ""; }; + 36BBCAB899B1451687368290E880F5DF /* RCNPersonalization.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCNPersonalization.h; path = FirebaseRemoteConfig/Sources/RCNPersonalization.h; sourceTree = ""; }; + 370761029B7BF9DB774682C5248D31FA /* GoogleUtilities.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleUtilities.debug.xcconfig; sourceTree = ""; }; + 382AD4608DA6265D2ADAB72C9F0E70A0 /* ABTExperimentPayload.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ABTExperimentPayload.h; path = FirebaseABTesting/Sources/Private/ABTExperimentPayload.h; sourceTree = ""; }; + 392DEC1EDF4E22D389A2EDC1AF4D38FB /* GULNetworkMessageCode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkMessageCode.h; path = GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkMessageCode.h; sourceTree = ""; }; + 394AF72A812A8B1F5953451EEB694CA2 /* pb_encode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb_encode.h; sourceTree = ""; }; + 395D5D902752144C46050A4CAB669598 /* FIRConfigurationInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRConfigurationInternal.h; path = FirebaseCore/Sources/FIRConfigurationInternal.h; sourceTree = ""; }; + 3AE8C3C914D009BC2BDBFB067F87FEF1 /* FIRDependency.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDependency.h; path = FirebaseCore/Extension/FIRDependency.h; sourceTree = ""; }; + 3C7375716F8DCA3F01D012DEC4BEEF3C /* FIROptionsInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIROptionsInternal.h; path = FirebaseCore/Extension/FIROptionsInternal.h; sourceTree = ""; }; + 3CB3BCF1390F1406B03BC8DB4735D727 /* FirebaseRemoteConfigInterop */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = FirebaseRemoteConfigInterop; path = FirebaseRemoteConfigInterop.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 3F238BB22C5201CE689CAF2F766AED95 /* PromisesObjC-FBLPromises_Privacy */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "PromisesObjC-FBLPromises_Privacy"; path = FBLPromises_Privacy.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 3F68F0820FA5987836BABB37620BBC7F /* FIRHeartbeatLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRHeartbeatLogger.h; path = FirebaseCore/Extension/FIRHeartbeatLogger.h; sourceTree = ""; }; + 3F94FD91DF6337BC57E7EA5284B2A6FB /* FIRInstallationsBackoffController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsBackoffController.m; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsBackoffController.m; sourceTree = ""; }; + 4093B147058BF1AF526933AB6A8AA56B /* FIRInstallationsStoredItem.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsStoredItem.h; path = FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.h; sourceTree = ""; }; + 41245A942268D2918A793101A1C60D05 /* RemoteConfigProperty.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RemoteConfigProperty.swift; path = FirebaseRemoteConfig/Swift/PropertyWrapper/RemoteConfigProperty.swift; sourceTree = ""; }; + 412DB5FFEF51E5BF36A217CC81C300F3 /* GULNetworkInfo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULNetworkInfo.m; path = GoogleUtilities/Environment/NetworkInfo/GULNetworkInfo.m; sourceTree = ""; }; + 4253C08D4EC49D0B717837CE370785F1 /* FIRAnalyticsConfiguration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRAnalyticsConfiguration.m; path = FirebaseCore/Sources/FIRAnalyticsConfiguration.m; sourceTree = ""; }; + 449FEAA30D59A791B55D657D08C52734 /* FIRInstallationsErrorUtil.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsErrorUtil.h; path = FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h; sourceTree = ""; }; + 44E291D18340EAC3F761346198515323 /* GoogleUtilities-GoogleUtilities_Privacy */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "GoogleUtilities-GoogleUtilities_Privacy"; path = GoogleUtilities_Privacy.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 455CFD151B0136FC6DB54FFE8395B810 /* GULNetworkConstants.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULNetworkConstants.m; path = GoogleUtilities/Network/GULNetworkConstants.m; sourceTree = ""; }; + 459101C0E8221FBA77B32BADBCB9C383 /* FIRInstallationsIDController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsIDController.m; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.m; sourceTree = ""; }; + 45DD421EB44E103C4624D35713AF2EC0 /* GULURLSessionDataResponse.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULURLSessionDataResponse.m; path = GoogleUtilities/Environment/URLSessionPromiseWrapper/GULURLSessionDataResponse.m; sourceTree = ""; }; + 463C249E94E6A1B183CAC712AD387BCC /* GoogleUtilities.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = GoogleUtilities.modulemap; sourceTree = ""; }; + 463DFF8A5EA5177997B4E5AAB61B18C9 /* FBLPromise+All.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+All.m"; path = "Sources/FBLPromises/FBLPromise+All.m"; sourceTree = ""; }; + 46EAC051EED6ADDE1239220D47C008B7 /* FBLPromise+Delay.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Delay.h"; path = "Sources/FBLPromises/include/FBLPromise+Delay.h"; sourceTree = ""; }; + 478C534DD7748F70AB26FA7391ACFE8F /* FirebaseCoreInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseCoreInternal.h; path = FirebaseCore/Extension/FirebaseCoreInternal.h; sourceTree = ""; }; + 47C581450CDB4A6111CB97EEE0711A8C /* FirebaseInstallations-FirebaseInstallations_Privacy */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "FirebaseInstallations-FirebaseInstallations_Privacy"; path = FirebaseInstallations_Privacy.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 47CBFE8B2613056F638460A4E11FFBD7 /* GULNetworkInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkInternal.h; path = GoogleUtilities/Network/GULNetworkInternal.h; sourceTree = ""; }; + 48A7B329FA4A60E00C7AE22844CE713C /* RCNConfigFetch.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCNConfigFetch.h; path = FirebaseRemoteConfig/Sources/Private/RCNConfigFetch.h; sourceTree = ""; }; + 499ADF1B3B37AD57C1A48C8AADD41D0B /* FirebaseCore.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseCore.debug.xcconfig; sourceTree = ""; }; + 4A96D4ECF706EA7F8633B03C8908FE34 /* FIRInstallationsItem+RegisterInstallationAPI.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FIRInstallationsItem+RegisterInstallationAPI.h"; path = "FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsItem+RegisterInstallationAPI.h"; sourceTree = ""; }; + 4CE5D5601C9BF11D3E42C54F8A897736 /* RCNConfigContent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCNConfigContent.m; path = FirebaseRemoteConfig/Sources/RCNConfigContent.m; sourceTree = ""; }; + 4CE77D1A4D5DB11FF22EF3BAD0A777F2 /* FirebaseAnalytics-xcframeworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "FirebaseAnalytics-xcframeworks.sh"; sourceTree = ""; }; + 4DB03FD262B678178A44272143846563 /* FirebaseCoreInternal-FirebaseCoreInternal_Privacy */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "FirebaseCoreInternal-FirebaseCoreInternal_Privacy"; path = FirebaseCoreInternal_Privacy.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 4DD06FC5913D15BB4DAAFF191168CD95 /* RCNConfigExperiment.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCNConfigExperiment.m; path = FirebaseRemoteConfig/Sources/RCNConfigExperiment.m; sourceTree = ""; }; + 4F23D0A780659D9A3CF4A10623BE1252 /* FIRInstallationsStoredAuthToken.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsStoredAuthToken.h; path = FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredAuthToken.h; sourceTree = ""; }; + 4F6803F3719C4B619CDE8B52350A8999 /* RCNDevice.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCNDevice.m; path = FirebaseRemoteConfig/Sources/RCNDevice.m; sourceTree = ""; }; + 4FA704F6371EFDBD73E41DBCE1ABB342 /* FirebaseInstallations-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "FirebaseInstallations-Info.plist"; sourceTree = ""; }; + 4FAA823A58ECCDA34B2453B1D1AF7CD8 /* RCNConfigSettings.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCNConfigSettings.h; path = FirebaseRemoteConfig/Sources/Private/RCNConfigSettings.h; sourceTree = ""; }; + 500BF231A850BA165F5C4776F563AF37 /* FirebaseInstallations.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseInstallations.release.xcconfig; sourceTree = ""; }; + 51500E287FB6075B9E55988901D1E18F /* GULNSData+zlib.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "GULNSData+zlib.m"; path = "GoogleUtilities/NSData+zlib/GULNSData+zlib.m"; sourceTree = ""; }; + 519172F62353C84795D05BA8A499936B /* FirebaseSharedSwift */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = FirebaseSharedSwift; path = FirebaseSharedSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 51C43A45BC6750EB6447FBC60A17AD4B /* FIRInstallationsSingleOperationPromiseCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsSingleOperationPromiseCache.m; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.m; sourceTree = ""; }; + 5251BF505D3C9A126E287F8CB6AB0221 /* GoogleAppMeasurement-xcframeworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "GoogleAppMeasurement-xcframeworks.sh"; sourceTree = ""; }; + 52CAD59895924651BB63FAEBBD1E3456 /* FBLPromise+Do.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Do.m"; path = "Sources/FBLPromises/FBLPromise+Do.m"; sourceTree = ""; }; + 53AF62816637B22C90309A1F74CE3704 /* FBLPromise+Then.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Then.h"; path = "Sources/FBLPromises/include/FBLPromise+Then.h"; sourceTree = ""; }; + 5425C8D0A9046622BEF46F6897052F98 /* FBLPromise+Any.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Any.m"; path = "Sources/FBLPromises/FBLPromise+Any.m"; sourceTree = ""; }; + 54298054E074C62E86E20743BAC7925B /* FIRLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLogger.h; path = FirebaseCore/Extension/FIRLogger.h; sourceTree = ""; }; + 546B1716181B9A0BEB19FFC225D5D68B /* FIRComponentType.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRComponentType.m; path = FirebaseCore/Sources/FIRComponentType.m; sourceTree = ""; }; + 556F34BAB0A4E2A0D26EA3A940B25AE0 /* GULAppDelegateSwizzler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULAppDelegateSwizzler.m; path = GoogleUtilities/AppDelegateSwizzler/GULAppDelegateSwizzler.m; sourceTree = ""; }; + 5733B5B6AFDDBF8B33A452723B5C73D0 /* Pods-TallPaper-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TallPaper-umbrella.h"; sourceTree = ""; }; + 5752F61E868014DF81F980C566E3F44A /* FBLPromise+Reduce.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Reduce.m"; path = "Sources/FBLPromises/FBLPromise+Reduce.m"; sourceTree = ""; }; + 576A75191D634A570D307E2DC68294B7 /* GoogleUtilities-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "GoogleUtilities-Info.plist"; sourceTree = ""; }; + 5850429FAFBF3E9AA20DA67FFDF87D21 /* FIRAnalyticsInterop.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAnalyticsInterop.h; path = Interop/Analytics/Public/FIRAnalyticsInterop.h; sourceTree = ""; }; + 588C2AC34B379F3F961AFEB8F4B0DF34 /* GULUserDefaults.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULUserDefaults.h; path = GoogleUtilities/UserDefaults/Public/GoogleUtilities/GULUserDefaults.h; sourceTree = ""; }; + 59B5796B0A4C9A227C8B300E065EDA13 /* FirebaseRemoteConfig.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseRemoteConfig.release.xcconfig; sourceTree = ""; }; + 59BC2A3E0993030DFEFBA1CA95D52CFD /* GULKeychainUtils.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULKeychainUtils.m; path = GoogleUtilities/Environment/SecureStorage/GULKeychainUtils.m; sourceTree = ""; }; + 59F0842B76A5CE38951E72F18B5EE1EF /* RCNConfigContent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCNConfigContent.h; path = FirebaseRemoteConfig/Sources/RCNConfigContent.h; sourceTree = ""; }; + 5A185451B2353A2D9FEAEC50BFFD6813 /* FBLPromise+Do.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Do.h"; path = "Sources/FBLPromises/include/FBLPromise+Do.h"; sourceTree = ""; }; + 5A70510981FED68DF2BA809205D387A1 /* FIRDependency.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDependency.h; path = FirebaseCore/Extension/FIRDependency.h; sourceTree = ""; }; + 5B1CA5B6B4CD43186F239F052D3F3EC2 /* FirebaseInstallationsInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseInstallationsInternal.h; path = FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h; sourceTree = ""; }; + 5BCF6CF17B85CFEE227E0466CB41E82D /* FirebaseAnalytics.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseAnalytics.debug.xcconfig; sourceTree = ""; }; + 5C4D42DB954888D3DF8711540421EDA0 /* FIRAppInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAppInternal.h; path = FirebaseCore/Extension/FIRAppInternal.h; sourceTree = ""; }; + 5DA9F090A9FABC1CBF232329F4E99A08 /* FirebaseRemoteConfig.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseRemoteConfig.h; path = FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FirebaseRemoteConfig.h; sourceTree = ""; }; + 5DB188C0BCE4FACAF79E2AF7CEF0F18E /* GULAppEnvironmentUtil.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULAppEnvironmentUtil.h; path = GoogleUtilities/Environment/Public/GoogleUtilities/GULAppEnvironmentUtil.h; sourceTree = ""; }; + 5DF10E3FFB628E822CD5414D0DBC68B6 /* FIRInstallationsIIDTokenStore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsIIDTokenStore.h; path = FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.h; sourceTree = ""; }; + 5E0979A22E08784374AD00FBC125A929 /* FIRRemoteConfig_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRRemoteConfig_Private.h; path = FirebaseRemoteConfig/Sources/Private/FIRRemoteConfig_Private.h; sourceTree = ""; }; + 5E0E4A140DDE5EDD0CB1990620DC75FA /* Pods-TallPaper-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-TallPaper-acknowledgements.markdown"; sourceTree = ""; }; + 5E895F248780B5169A797546598A50BD /* FIRInteropParameterNames.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInteropParameterNames.h; path = Interop/Analytics/Public/FIRInteropParameterNames.h; sourceTree = ""; }; + 5F76D90C2948429C9CE7E3475DE0B924 /* FirebaseInstallations.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseInstallations.debug.xcconfig; sourceTree = ""; }; + 608BF1BE349FF2A40C28196D17A0BD80 /* FirebaseSharedSwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FirebaseSharedSwift-dummy.m"; sourceTree = ""; }; + 611D27690CF7F6A20F3EF9942C5B4237 /* FBLPromise+Race.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Race.m"; path = "Sources/FBLPromises/FBLPromise+Race.m"; sourceTree = ""; }; + 6167BB02AD2CD052706EDB458E3A97DB /* FBLPromise.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBLPromise.m; path = Sources/FBLPromises/FBLPromise.m; sourceTree = ""; }; + 6278570AF7F9F1EE5D5C487492D2EF7B /* FBLPromise+Testing.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Testing.m"; path = "Sources/FBLPromises/FBLPromise+Testing.m"; sourceTree = ""; }; + 62AEECCD4B6E11F92852CC3FC55B6324 /* FBLPromise+Reduce.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Reduce.h"; path = "Sources/FBLPromises/include/FBLPromise+Reduce.h"; sourceTree = ""; }; + 63B19F7DC4A4137A291CB841984B5FF8 /* GULHeartbeatDateStorable.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULHeartbeatDateStorable.h; path = GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorable.h; sourceTree = ""; }; + 64DCFEC8D5593700D342D1B7E1F2685B /* FBLPromiseError.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBLPromiseError.m; path = Sources/FBLPromises/FBLPromiseError.m; sourceTree = ""; }; + 656CA2FAECAEF3A41E8D3D9087334EB0 /* FirebaseCoreInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseCoreInternal.h; path = FirebaseCore/Extension/FirebaseCoreInternal.h; sourceTree = ""; }; + 65D221126ACC9BF46EE8E173D19CD3BE /* RCNConfigDBManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCNConfigDBManager.h; path = FirebaseRemoteConfig/Sources/RCNConfigDBManager.h; sourceTree = ""; }; + 65DC58B6F6E92A6FC58C6F549C51A3CD /* FirebaseABTesting.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseABTesting.h; path = FirebaseABTesting/Sources/Public/FirebaseABTesting/FirebaseABTesting.h; sourceTree = ""; }; + 6661A473DB214FE0EEB7DCA0DCA731C1 /* GULSwizzler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULSwizzler.h; path = GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/GULSwizzler.h; sourceTree = ""; }; + 6698255073FCECA95BAED5CF2741CB12 /* FIRRemoteConfigComponent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRRemoteConfigComponent.h; path = FirebaseRemoteConfig/Sources/FIRRemoteConfigComponent.h; sourceTree = ""; }; + 671CFBB67B468EF837F4A4DC3E436A69 /* FIRLibrary.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLibrary.h; path = FirebaseCore/Extension/FIRLibrary.h; sourceTree = ""; }; + 67524CD86B6C8F70B1DAA3450E89D13F /* FIRComponentContainer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentContainer.h; path = FirebaseCore/Extension/FIRComponentContainer.h; sourceTree = ""; }; + 67B07E9904CAAD5AD2278E2CBF9E13DD /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 684935040366A7E92ECE09FA526B16FC /* FBLPromise+Wrap.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Wrap.m"; path = "Sources/FBLPromises/FBLPromise+Wrap.m"; sourceTree = ""; }; + 693374012D5FCD40E265F23036EF69F4 /* FirebaseCore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseCore.h; path = FirebaseCore/Sources/Public/FirebaseCore/FirebaseCore.h; sourceTree = ""; }; + 6AEF5C6A396D1ADA764611D687A920DB /* GULKeychainStorage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULKeychainStorage.h; path = GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainStorage.h; sourceTree = ""; }; + 6B4F89BBECD80988BC20EE63A99419F3 /* HeartbeatStorage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HeartbeatStorage.swift; path = FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatStorage.swift; sourceTree = ""; }; + 6B886DEF7892AC07BF604D685DDA2AEB /* NSURLSession+GULPromises.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSURLSession+GULPromises.m"; path = "GoogleUtilities/Environment/URLSessionPromiseWrapper/NSURLSession+GULPromises.m"; sourceTree = ""; }; + 6BA4975B9DCACEEF18DC342426A3945B /* FBLPromiseError.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBLPromiseError.h; path = Sources/FBLPromises/include/FBLPromiseError.h; sourceTree = ""; }; + 6BBC9EB741E7CFE4CA52A7BBE3F28221 /* RCNConfigSettings.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCNConfigSettings.m; path = FirebaseRemoteConfig/Sources/RCNConfigSettings.m; sourceTree = ""; }; + 6C4A9E5C64494B1180C1901417EE3A70 /* FIRExperimentController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRExperimentController.h; path = FirebaseABTesting/Sources/Public/FirebaseABTesting/FIRExperimentController.h; sourceTree = ""; }; + 6CEAC286AE0F41633E3C3970E7048199 /* FirebaseAnalytics.xcframework */ = {isa = PBXFileReference; includeInIndex = 1; name = FirebaseAnalytics.xcframework; path = Frameworks/FirebaseAnalytics.xcframework; sourceTree = ""; }; + 6D9A00D587445BCE41F470B03CFAB326 /* Firebase.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Firebase.release.xcconfig; sourceTree = ""; }; + 6DF900A74765E9831F99A4819F5414F7 /* FirebaseABTesting.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseABTesting.release.xcconfig; sourceTree = ""; }; + 6E36F090C3CFAF989AD74042701EAA7A /* GoogleUtilities-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "GoogleUtilities-dummy.m"; sourceTree = ""; }; + 6E6D67077386032B4727AC1223EC5020 /* FirebaseInstallations-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FirebaseInstallations-dummy.m"; sourceTree = ""; }; + 6F45CF142336996E92BD55A74678256C /* FIRInstallationsErrors.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsErrors.h; path = FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallationsErrors.h; sourceTree = ""; }; + 6F8375C661ADB48616C20299291EF091 /* FIRInteropParameterNames.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInteropParameterNames.h; path = Interop/Analytics/Public/FIRInteropParameterNames.h; sourceTree = ""; }; + 71B7ACC5DB8FDB728C1DAD182338C36B /* FIRInstallationsHTTPError.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsHTTPError.h; path = FirebaseInstallations/Source/Library/Errors/FIRInstallationsHTTPError.h; sourceTree = ""; }; + 72A9AC917567336C9C984D1E7E746E1D /* HeartbeatController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HeartbeatController.swift; path = FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatController.swift; sourceTree = ""; }; + 73372DCA3D12A27E168929C0BA8FE4E4 /* FIRApp.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRApp.m; path = FirebaseCore/Sources/FIRApp.m; sourceTree = ""; }; + 73A8C5803F0CB377BFBCB3DDE9E42E30 /* FIRInstallationsStore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsStore.h; path = FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.h; sourceTree = ""; }; + 74B167474413405779DB425345668971 /* pb_decode.c */ = {isa = PBXFileReference; includeInIndex = 1; path = pb_decode.c; sourceTree = ""; }; + 74EAFD355DC790AE5A4AB3E447BEFD85 /* ResourceBundle-FirebaseInstallations_Privacy-FirebaseInstallations-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-FirebaseInstallations_Privacy-FirebaseInstallations-Info.plist"; sourceTree = ""; }; + 75BDFC4520B3CA5BB214D5D272F4B5C5 /* RCNConfigDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCNConfigDefines.h; path = FirebaseRemoteConfig/Sources/RCNConfigDefines.h; sourceTree = ""; }; + 7671C8543FF5F9E45F6C0ECC84E4546A /* FIRInstallationsIIDStore.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsIIDStore.m; path = FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.m; sourceTree = ""; }; + 76F64C73760FB11EFEC43D654BE7D019 /* FIRDependency.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDependency.h; path = FirebaseCore/Extension/FIRDependency.h; sourceTree = ""; }; + 79908E934101753D311CBFB79C5A165F /* FirebaseABTesting.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = FirebaseABTesting.modulemap; sourceTree = ""; }; + 7A6FE737AE93759D79B96FB0CB940B1F /* FIRApp.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRApp.h; path = FirebaseCore/Sources/Public/FirebaseCore/FIRApp.h; sourceTree = ""; }; + 7A8A262ED4D43839241892A6F812378D /* GULSecureCoding.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULSecureCoding.m; path = GoogleUtilities/Environment/GULSecureCoding.m; sourceTree = ""; }; + 7C27787F3CC35AB19EA596344B611B8D /* FBLPromise+Race.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Race.h"; path = "Sources/FBLPromises/include/FBLPromise+Race.h"; sourceTree = ""; }; + 7C3AE4425E7B08F16F1B4FD32951CA7F /* FirebaseABTesting */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = FirebaseABTesting; path = FirebaseABTesting.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7D4CD4D55DFDEE21C6AA44018034B74B /* GULNetworkURLSession.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULNetworkURLSession.m; path = GoogleUtilities/Network/GULNetworkURLSession.m; sourceTree = ""; }; + 7DF3A1166255CF3E0C68A1C007CC0F4E /* FIRComponentContainerInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentContainerInternal.h; path = FirebaseCore/Sources/FIRComponentContainerInternal.h; sourceTree = ""; }; + 7E343B046961E2648346BE23F8986EE7 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/SystemConfiguration.framework; sourceTree = DEVELOPER_DIR; }; + 7E7C94E810B158112FA354F33B2FDDFD /* FBLPromise+Catch.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Catch.m"; path = "Sources/FBLPromises/FBLPromise+Catch.m"; sourceTree = ""; }; + 7F50D584D8AC434EF9B0E3E2FF17B3DF /* FIRAnalyticsInterop.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAnalyticsInterop.h; path = Interop/Analytics/Public/FIRAnalyticsInterop.h; sourceTree = ""; }; + 7F84DEC2F9ADBD86654E93E70FDDCAE4 /* FirebaseInstallations-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FirebaseInstallations-umbrella.h"; sourceTree = ""; }; + 827A5C477414E206AF248DC46644C144 /* FIRComponentContainer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRComponentContainer.m; path = FirebaseCore/Sources/FIRComponentContainer.m; sourceTree = ""; }; + 830BACEF103B1B9D5C9511B2905411D4 /* FBLPromise+Timeout.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Timeout.m"; path = "Sources/FBLPromises/FBLPromise+Timeout.m"; sourceTree = ""; }; + 833E65C1466FF27BF0A1EB4826561F87 /* FIRRemoteConfigUpdate.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRRemoteConfigUpdate.m; path = FirebaseRemoteConfig/Sources/FIRRemoteConfigUpdate.m; sourceTree = ""; }; + 83BF6D454D688FFBF8927B7141A2DF7E /* FBLPromise+Recover.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Recover.m"; path = "Sources/FBLPromises/FBLPromise+Recover.m"; sourceTree = ""; }; + 86727521F4E83A0C8B674023644BD670 /* RemoteConfigConstants.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RemoteConfigConstants.swift; path = FirebaseRemoteConfig/Interop/RemoteConfigConstants.swift; sourceTree = ""; }; + 86EA04F76C2197F2C271094EF717A765 /* RemoteConfigInterop.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RemoteConfigInterop.swift; path = FirebaseRemoteConfig/Interop/RemoteConfigInterop.swift; sourceTree = ""; }; + 872BF4BB62F31E9551393F836AEBA807 /* FBLPromises.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBLPromises.h; path = Sources/FBLPromises/include/FBLPromises.h; sourceTree = ""; }; + 8797262413E3361B1F54135C6663A7F8 /* FBLPromise+Validate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Validate.h"; path = "Sources/FBLPromises/include/FBLPromise+Validate.h"; sourceTree = ""; }; + 887DF535D5AF38FB365886AA77A0812C /* FirebaseRemoteConfigInterop-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FirebaseRemoteConfigInterop-dummy.m"; sourceTree = ""; }; + 88B571252A6FB34BC3358B9CEED97997 /* FBLPromise+Await.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Await.m"; path = "Sources/FBLPromises/FBLPromise+Await.m"; sourceTree = ""; }; + 88FC70FB88B2D354EB6C42AB9E23A429 /* GULHeartbeatDateStorage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULHeartbeatDateStorage.h; path = GoogleUtilities/Environment/Public/GoogleUtilities/GULHeartbeatDateStorage.h; sourceTree = ""; }; + 89240F4F5527DD6175A8F52D945F63D3 /* FirebaseRemoteConfigInterop-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FirebaseRemoteConfigInterop-umbrella.h"; sourceTree = ""; }; + 8960BC88B8B1DD67A680DD51EB058E5A /* Firebase.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Firebase.h; path = CoreOnly/Sources/Firebase.h; sourceTree = ""; }; + 897DBA56069DE92BC7EB9DF3BF3325C5 /* FIRLibrary.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLibrary.h; path = FirebaseCore/Extension/FIRLibrary.h; sourceTree = ""; }; + 89B98D107632C56A5971828F9ADFA29B /* FIRLifecycleEvents.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLifecycleEvents.h; path = FirebaseABTesting/Sources/Public/FirebaseABTesting/FIRLifecycleEvents.h; sourceTree = ""; }; + 89E7AF6C56924AFEFF0740DAF9255057 /* FIRHeartbeatLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRHeartbeatLogger.h; path = FirebaseCore/Extension/FIRHeartbeatLogger.h; sourceTree = ""; }; + 8A32F0B2BEBD1CA7080B398F9E8452DB /* FIRInstallationsAuthTokenResultInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsAuthTokenResultInternal.h; path = FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResultInternal.h; sourceTree = ""; }; + 8B3F82B7B8AE59C50EF98ED4CBA2FDB1 /* RCNConfigRealtime.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCNConfigRealtime.h; path = FirebaseRemoteConfig/Sources/RCNConfigRealtime.h; sourceTree = ""; }; + 8BB937B1C0DFFCF92F41861C2BC54DDA /* FirebaseCore-FirebaseCore_Privacy */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "FirebaseCore-FirebaseCore_Privacy"; path = FirebaseCore_Privacy.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 8BB9853B86E5B2B10DD7DFC3AB58367A /* ABTConditionalUserPropertyController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ABTConditionalUserPropertyController.h; path = FirebaseABTesting/Sources/ABTConditionalUserPropertyController.h; sourceTree = ""; }; + 8D079EC2785A105640FF2D0A76EC3E12 /* pb_common.c */ = {isa = PBXFileReference; includeInIndex = 1; path = pb_common.c; sourceTree = ""; }; + 8D49CEAEB219CE213CEE1380AA1870BC /* FBLPromise+Always.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Always.m"; path = "Sources/FBLPromises/FBLPromise+Always.m"; sourceTree = ""; }; + 8F47A304F0B244DCCCF9EF7AA4BEBDD0 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = FirebaseCore/Internal/Sources/Resources/PrivacyInfo.xcprivacy; sourceTree = ""; }; + 90197B074482ED0230AA6216050C39B9 /* GULNetwork.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULNetwork.m; path = GoogleUtilities/Network/GULNetwork.m; sourceTree = ""; }; + 907A242DBA66A1E0981EF0B63C0D29AE /* FIRLoggerLevel.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLoggerLevel.h; path = FirebaseCore/Sources/Public/FirebaseCore/FIRLoggerLevel.h; sourceTree = ""; }; + 9215C1E551E14508B96DC201A475BD3F /* FirebaseCoreInternal-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "FirebaseCoreInternal-Info.plist"; sourceTree = ""; }; + 92CDB8AAF698BCDEC7E8FDA1401BBBBE /* FIRComponent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRComponent.m; path = FirebaseCore/Sources/FIRComponent.m; sourceTree = ""; }; + 92D8EE1F84DCA42475750D5985E978CB /* FirebaseRemoteConfigInterop.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = FirebaseRemoteConfigInterop.modulemap; sourceTree = ""; }; + 93D0EB62190227CEBABBCE3968D0A977 /* Storage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Storage.swift; path = FirebaseCore/Internal/Sources/HeartbeatLogging/Storage.swift; sourceTree = ""; }; + 94889F55D5C5243AAF1FE316D39114DF /* RCNConfigFetch.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCNConfigFetch.m; path = FirebaseRemoteConfig/Sources/RCNConfigFetch.m; sourceTree = ""; }; + 94A29B8A8E4681B099C6CAF62AA8A044 /* GULReachabilityChecker+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "GULReachabilityChecker+Internal.h"; path = "GoogleUtilities/Reachability/GULReachabilityChecker+Internal.h"; sourceTree = ""; }; + 94D673910AC3AB74ABC0B829468A2823 /* FirebaseRemoteConfig.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = FirebaseRemoteConfig.modulemap; sourceTree = ""; }; + 950567D7B0395602E154D61249ECABC0 /* RemoteConfigValueObservable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RemoteConfigValueObservable.swift; path = FirebaseRemoteConfig/Swift/PropertyWrapper/RemoteConfigValueObservable.swift; sourceTree = ""; }; + 95FDC4862675CD7B54307601CC53D624 /* _ObjC_HeartbeatsPayload.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = _ObjC_HeartbeatsPayload.swift; path = FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatsPayload.swift; sourceTree = ""; }; + 96D94CC74872ED59F27326449C32D262 /* pb_decode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb_decode.h; sourceTree = ""; }; + 9815B1F94F6849187E0096CC2CF3728F /* PromisesObjC.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = PromisesObjC.modulemap; sourceTree = ""; }; + 982C459C8AFB771ED709220BAE6D3BD6 /* FBLPromise+Wrap.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Wrap.h"; path = "Sources/FBLPromises/include/FBLPromise+Wrap.h"; sourceTree = ""; }; + 9AEFF81FC9CB7DCC949B85FDD1F205E6 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = spm_resources/PrivacyInfo.xcprivacy; sourceTree = ""; }; + 9AFD897D1A76B25F34416E25BC1BA8C2 /* pb_common.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb_common.h; sourceTree = ""; }; + 9B3E3D3170028F2395F08A6CF1F5D821 /* FirebaseSharedSwift.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseSharedSwift.debug.xcconfig; sourceTree = ""; }; + 9C9CE713B787FE75F0F3C7D7E9E5A4BF /* GULLoggerLevel.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULLoggerLevel.h; path = GoogleUtilities/Logger/Public/GoogleUtilities/GULLoggerLevel.h; sourceTree = ""; }; 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; - A3FAA9E33EBDA1A67760BF69587CAB2B /* Pods-HD wallpaper.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-HD wallpaper.release.xcconfig"; sourceTree = ""; }; - BB848298CB5EF55D6DD3F22151BA69F2 /* Pods-HD wallpaper-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-HD wallpaper-Info.plist"; sourceTree = ""; }; - D4F5D20D0D27BF4763A0FF29FA829EBB /* Pods-HD wallpaper.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-HD wallpaper.modulemap"; sourceTree = ""; }; - D7825A4BCC67CCBD76E10C2F5BFB03AC /* Pods-HD wallpaper-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-HD wallpaper-acknowledgements.markdown"; sourceTree = ""; }; - E707D19F3B4314DCCECC25261215E9EE /* Pods-HD wallpaper */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-HD wallpaper"; path = Pods_HD_wallpaper.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + A05DB176F7E6E83F7C2C63C9B7339E34 /* FIRConfiguration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRConfiguration.h; path = FirebaseCore/Sources/Public/FirebaseCore/FIRConfiguration.h; sourceTree = ""; }; + A07DD31D3AA0F19C2DC3448743583819 /* GULSceneDelegateSwizzler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULSceneDelegateSwizzler.h; path = GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULSceneDelegateSwizzler.h; sourceTree = ""; }; + A187810449E6822F25E6ABFC9CDA3446 /* FirebaseCoreInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseCoreInternal.h; path = FirebaseCore/Extension/FirebaseCoreInternal.h; sourceTree = ""; }; + A1B3C129DCD5CB6FCBCE9B7F8D3FAB57 /* FIRHeartbeatLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRHeartbeatLogger.h; path = FirebaseCore/Extension/FIRHeartbeatLogger.h; sourceTree = ""; }; + A25E28A8A12040D16275D2D1DA2EDB83 /* FirebaseRemoteConfig-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FirebaseRemoteConfig-umbrella.h"; sourceTree = ""; }; + A2AC3E8875E0CA8FD82FD435FCE63364 /* FIRInstallationsAuthTokenResult.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsAuthTokenResult.m; path = FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResult.m; sourceTree = ""; }; + A3697C479CB24A72810F620D522393AF /* HeartbeatsPayload.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HeartbeatsPayload.swift; path = FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatsPayload.swift; sourceTree = ""; }; + A4FDFA29063041935CA3BC2D9D793F2F /* ResourceBundle-FirebaseRemoteConfig_Privacy-FirebaseRemoteConfig-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-FirebaseRemoteConfig_Privacy-FirebaseRemoteConfig-Info.plist"; sourceTree = ""; }; + A5144EB8AF8D2E78332EA7C5D348E258 /* FIRComponentType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentType.h; path = FirebaseCore/Extension/FIRComponentType.h; sourceTree = ""; }; + A732C7A211777FCF0919357C264E1362 /* FirebaseABTesting-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FirebaseABTesting-umbrella.h"; sourceTree = ""; }; + A8D24523EA654703855D1DAA0199A882 /* ABTConditionalUserPropertyController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = ABTConditionalUserPropertyController.m; path = FirebaseABTesting/Sources/ABTConditionalUserPropertyController.m; sourceTree = ""; }; + A96707865509075B195429CC67DDA479 /* FIROptions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIROptions.m; path = FirebaseCore/Sources/FIROptions.m; sourceTree = ""; }; + A9A3F96F9B98448D3D1C019ABA7492CE /* FIROptionsInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIROptionsInternal.h; path = FirebaseCore/Extension/FIROptionsInternal.h; sourceTree = ""; }; + A9FC8A579BACB56FB5239942F9A2B978 /* GULReachabilityMessageCode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULReachabilityMessageCode.h; path = GoogleUtilities/Reachability/GULReachabilityMessageCode.h; sourceTree = ""; }; + AA7A73C3ECBA2E58085DF48768CABE2D /* GULLoggerCodes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULLoggerCodes.h; path = GoogleUtilities/Common/GULLoggerCodes.h; sourceTree = ""; }; + AACD723663F5D1C61B04933E98DB59EA /* FirebaseABTesting-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FirebaseABTesting-dummy.m"; sourceTree = ""; }; + ABB78103AD0C89A5FD52D081ABD277ED /* FirebaseRemoteConfigValueDecoding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FirebaseRemoteConfigValueDecoding.swift; path = FirebaseSharedSwift/Sources/FirebaseRemoteConfigValueDecoding.swift; sourceTree = ""; }; + ABD115BB1BB820D2B2DE5F541A263736 /* FIRInstallationsLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsLogger.m; path = FirebaseInstallations/Source/Library/FIRInstallationsLogger.m; sourceTree = ""; }; + ABEE4483D32A73C25A946778F7E52969 /* Firebase.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Firebase.debug.xcconfig; sourceTree = ""; }; + AD776F1C94991D3E551CEAA515DB110A /* FirebaseRemoteConfig */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = FirebaseRemoteConfig; path = FirebaseRemoteConfig.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + AE46E3547BEF96B859A66E4F599C0293 /* FIRComponentType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentType.h; path = FirebaseCore/Extension/FIRComponentType.h; sourceTree = ""; }; + AF4B2E39D62BB92335F109AD58F06757 /* Pods-TallPaper.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-TallPaper.modulemap"; sourceTree = ""; }; + AF7CD070A6EBC4ABAC149FE0885CAA98 /* FIRComponentType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentType.h; path = FirebaseCore/Extension/FIRComponentType.h; sourceTree = ""; }; + B0AFA6042055C466A9D374B0CE32AB71 /* FirebaseInstallationsInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseInstallationsInternal.h; path = FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h; sourceTree = ""; }; + B0B4202E023736A8A3E0FE9A4D8B2AEC /* FBLPromise+Catch.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Catch.h"; path = "Sources/FBLPromises/include/FBLPromise+Catch.h"; sourceTree = ""; }; + B10FE88CF1A03212F65DBAA5942A8636 /* GULSwizzler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULSwizzler.m; path = GoogleUtilities/MethodSwizzler/GULSwizzler.m; sourceTree = ""; }; + B1171D62A677850856BB79B87509D75E /* FirebaseRemoteConfig-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "FirebaseRemoteConfig-Info.plist"; sourceTree = ""; }; + B1418672FD1A27E1215382BCE06B7573 /* GoogleUtilities-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GoogleUtilities-umbrella.h"; sourceTree = ""; }; + B16BBE23543FAD12BB2BD35971F6DA1B /* Pods-TallPaper.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TallPaper.release.xcconfig"; sourceTree = ""; }; + B262493D4292A974CE6560BE08D8513B /* ResourceBundle-FirebaseCoreInternal_Privacy-FirebaseCoreInternal-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-FirebaseCoreInternal_Privacy-FirebaseCoreInternal-Info.plist"; sourceTree = ""; }; + B295501A485E49383772BDE110D3AE32 /* FirebaseCoreInternal-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FirebaseCoreInternal-dummy.m"; sourceTree = ""; }; + B2AE340D7642101AA00A4094E6AF160C /* FIRComponent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponent.h; path = FirebaseCore/Extension/FIRComponent.h; sourceTree = ""; }; + B3350961DE46986C41D825A8C4B105A6 /* FBLPromise+Then.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Then.m"; path = "Sources/FBLPromises/FBLPromise+Then.m"; sourceTree = ""; }; + B3A907F7A54CD12D5B532362DD53ED4F /* Pods-TallPaper.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TallPaper.debug.xcconfig"; sourceTree = ""; }; + B411BC492A95118344F161DBDD11C0D6 /* FirebaseCoreInternal-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FirebaseCoreInternal-umbrella.h"; sourceTree = ""; }; + B43874C6CBB50E7134FBEC24BABFE14F /* GoogleUtilities */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = GoogleUtilities; path = GoogleUtilities.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B45CD6FF2824BB7E404063328EF1829E /* FIRAppInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAppInternal.h; path = FirebaseCore/Extension/FIRAppInternal.h; sourceTree = ""; }; + B4A385C153D6F521F08424F73860D4A8 /* PromisesObjC-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "PromisesObjC-umbrella.h"; sourceTree = ""; }; + B530EE4AE87824511A048DA41F2BD27A /* Pods-TallPaper */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-TallPaper"; path = Pods_TallPaper.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B5BF445ADA4090C888DD3072A33376DC /* FIRInstallationsStatus.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsStatus.h; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsStatus.h; sourceTree = ""; }; + B61F28CD0635CE23F8558A1083BC9241 /* FIRLifecycleEvents.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRLifecycleEvents.m; path = FirebaseABTesting/Sources/FIRLifecycleEvents.m; sourceTree = ""; }; + B649188460A2C149984BF3FA48EC2520 /* FIRConfigValue.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRConfigValue.m; path = FirebaseRemoteConfig/Sources/FIRConfigValue.m; sourceTree = ""; }; + B64E6FEC8DDBCA02C6D886874B9294E1 /* nanopb-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "nanopb-umbrella.h"; sourceTree = ""; }; + B71E2D50301EECF023F1665D60BA21BF /* FIRInstallationsIIDStore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsIIDStore.h; path = FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDStore.h; sourceTree = ""; }; + B7D094B1082789787A18E641F494B66E /* GULHeartbeatDateStorageUserDefaults.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULHeartbeatDateStorageUserDefaults.m; path = GoogleUtilities/Environment/GULHeartbeatDateStorageUserDefaults.m; sourceTree = ""; }; + B7F57ADFFFC393FF08F641F431134560 /* FIRLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLogger.h; path = FirebaseCore/Extension/FIRLogger.h; sourceTree = ""; }; + B846B97AF0194E6DDACEC9BB57748022 /* FIRDependency.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDependency.h; path = FirebaseCore/Extension/FIRDependency.h; sourceTree = ""; }; + B9DB932484D54621537D7243450AD8B2 /* FIRInstallationsAPIService.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsAPIService.m; path = FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.m; sourceTree = ""; }; + BB56505360994F7A2EA65103F67C45FC /* GULURLSessionDataResponse.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULURLSessionDataResponse.h; path = GoogleUtilities/Environment/Public/GoogleUtilities/GULURLSessionDataResponse.h; sourceTree = ""; }; + BE6684043E8F6230C6F2B5B9962A27FA /* GoogleAppMeasurement.xcframework */ = {isa = PBXFileReference; includeInIndex = 1; name = GoogleAppMeasurement.xcframework; path = Frameworks/GoogleAppMeasurement.xcframework; sourceTree = ""; }; + BF05C566026B4B2AEE16937A0686C96F /* IsAppEncrypted.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = IsAppEncrypted.m; path = third_party/IsAppEncrypted/IsAppEncrypted.m; sourceTree = ""; }; + BF3A1C11412FF332396C54BC7C6A034A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Sources/FBLPromises/Resources/PrivacyInfo.xcprivacy; sourceTree = ""; }; + BF5B5C6CC493F3D8DC306BAEA16AF1A8 /* GULAppEnvironmentUtil.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULAppEnvironmentUtil.m; path = GoogleUtilities/Environment/GULAppEnvironmentUtil.m; sourceTree = ""; }; + BF9778E519F419B6D3B8C346697725CD /* ABTExperimentPayload.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = ABTExperimentPayload.m; path = FirebaseABTesting/Sources/ABTExperimentPayload.m; sourceTree = ""; }; + C052BE7FB135A8ED2D6F28462B5A5737 /* GULNetworkConstants.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkConstants.h; path = GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkConstants.h; sourceTree = ""; }; + C18EC549B1DB7F87B0815997C8171F7F /* FirebaseSharedSwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FirebaseSharedSwift-umbrella.h"; sourceTree = ""; }; + C1D7F2BB9523A403818EA1338A8C4E4C /* FIRInstallationsErrorUtil.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsErrorUtil.m; path = FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.m; sourceTree = ""; }; + C267AF2E92505F6750EAA8C33424B4F6 /* PromisesObjC.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = PromisesObjC.debug.xcconfig; sourceTree = ""; }; + C298ECA85B7369EC0FAE4312D770EA90 /* GULNetworkURLSession.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkURLSession.h; path = GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkURLSession.h; sourceTree = ""; }; + C2B7B7EAEDA74CFFA097EACEF29D0360 /* FBLPromise+All.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+All.h"; path = "Sources/FBLPromises/include/FBLPromise+All.h"; sourceTree = ""; }; + C2C3CD7B96F82905F982A1C5A0A9568C /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = FirebaseRemoteConfig/Swift/Resources/PrivacyInfo.xcprivacy; sourceTree = ""; }; + C3676C9257F1642F10902F42713C0ACD /* FIRVersion.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRVersion.m; path = FirebaseCore/Sources/FIRVersion.m; sourceTree = ""; }; + C427612ED1543E2B1D60315509C9F971 /* FIRAppInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAppInternal.h; path = FirebaseCore/Extension/FIRAppInternal.h; sourceTree = ""; }; + C47072AE8853F2DC6D613ABAF62339C5 /* _ObjC_HeartbeatController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = _ObjC_HeartbeatController.swift; path = FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift; sourceTree = ""; }; + C5226FA90D56682283AE4D6601CD7175 /* nanopb-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "nanopb-Info.plist"; sourceTree = ""; }; + C53FC0372E7FECFF10949B01A02A4CB4 /* FBLPromise+Testing.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Testing.h"; path = "Sources/FBLPromises/include/FBLPromise+Testing.h"; sourceTree = ""; }; + C543619250755351CE882118D75DB383 /* FirebaseSharedSwift.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseSharedSwift.release.xcconfig; sourceTree = ""; }; + C57AE3985C348E1AA78A6B527D39F32F /* FirebaseCore.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = FirebaseCore.modulemap; sourceTree = ""; }; + C591D11BE25070AE683077BDA9F01890 /* FIRInstallationsIIDTokenStore.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsIIDTokenStore.m; path = FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.m; sourceTree = ""; }; + C5C2F43474B905E02BDFE3A517E2FC3B /* FIROptionsInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIROptionsInternal.h; path = FirebaseCore/Extension/FIROptionsInternal.h; sourceTree = ""; }; + C613060075D2D23E82D47FBEFEFEF43F /* FIRAnalyticsConfiguration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAnalyticsConfiguration.h; path = FirebaseCore/Sources/FIRAnalyticsConfiguration.h; sourceTree = ""; }; + C6C18CB3FD8877D00962967DD1E82DFD /* FirebaseABTestingInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseABTestingInternal.h; path = FirebaseABTesting/Sources/Private/FirebaseABTestingInternal.h; sourceTree = ""; }; + CA48D768E2943DB7CA80E8A3D9F4ED8B /* ABTExperimentPayload.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ABTExperimentPayload.h; path = FirebaseABTesting/Sources/Private/ABTExperimentPayload.h; sourceTree = ""; }; + CB840AE072916EC3EE874FF2EC26AEED /* FIRAnalyticsInteropListener.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAnalyticsInteropListener.h; path = Interop/Analytics/Public/FIRAnalyticsInteropListener.h; sourceTree = ""; }; + CC596C20253971D585510A397BA0A500 /* FIRRemoteConfig.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRRemoteConfig.m; path = FirebaseRemoteConfig/Sources/FIRRemoteConfig.m; sourceTree = ""; }; + CCD202A0BEC7B9F25A622E8AAD0881E0 /* GULMutableDictionary.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULMutableDictionary.h; path = GoogleUtilities/Network/Public/GoogleUtilities/GULMutableDictionary.h; sourceTree = ""; }; + CD872021C34DBAC0D7D1533418F1B928 /* FIRInteropEventNames.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInteropEventNames.h; path = Interop/Analytics/Public/FIRInteropEventNames.h; sourceTree = ""; }; + CE57D042251A378B73A66A09A3B56D12 /* FIRLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLogger.h; path = FirebaseCore/Extension/FIRLogger.h; sourceTree = ""; }; + CEAFD5DBF95CB3ABF170F4D40038A4F5 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = GoogleUtilities/Privacy/Resources/PrivacyInfo.xcprivacy; sourceTree = ""; }; + CEBB3CDF6B0397C596B3FAC80F041A98 /* FIRAppInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAppInternal.h; path = FirebaseCore/Extension/FIRAppInternal.h; sourceTree = ""; }; + CFEEDDBB077CF5DE8FF2B0226A3A1BB0 /* GULLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULLogger.m; path = GoogleUtilities/Logger/GULLogger.m; sourceTree = ""; }; + D08B6832CD4F41F567E328E586FA7708 /* ResourceBundle-FBLPromises_Privacy-PromisesObjC-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-FBLPromises_Privacy-PromisesObjC-Info.plist"; sourceTree = ""; }; + D0A7743AD9C9F7D31F8A8299B1A91AD1 /* FIRLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRLogger.m; path = FirebaseCore/Sources/FIRLogger.m; sourceTree = ""; }; + D1B88D82044B86B4E61B8CAED0322C12 /* FIRComponent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponent.h; path = FirebaseCore/Extension/FIRComponent.h; sourceTree = ""; }; + D28D72B939EE470EF1B5DACA418C4F24 /* FIRInstallationsIDController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsIDController.h; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsIDController.h; sourceTree = ""; }; + D2B69AE52F9C6F680F8FD0D12EB58010 /* GULKeychainUtils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULKeychainUtils.h; path = GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainUtils.h; sourceTree = ""; }; + D45EDC5CDA793CACEAC775C09DCD8147 /* GoogleUtilities.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleUtilities.release.xcconfig; sourceTree = ""; }; + D4ADC435328F01979C154BA5BF31669E /* FBLPromise+Delay.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Delay.m"; path = "Sources/FBLPromises/FBLPromise+Delay.m"; sourceTree = ""; }; + D70D527EAFF19A24102D57E5A969F179 /* FIRLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLogger.h; path = FirebaseCore/Extension/FIRLogger.h; sourceTree = ""; }; + D74D68E534A6E7E9393D8546BD226005 /* FIRInstallationsAPIService.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsAPIService.h; path = FirebaseInstallations/Source/Library/InstallationsAPI/FIRInstallationsAPIService.h; sourceTree = ""; }; + D772A4B1414311177A62C6472414F917 /* SPMSwiftHeaderWorkaround.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SPMSwiftHeaderWorkaround.swift; path = FirebaseRemoteConfig/Swift/SPMSwiftHeaderWorkaround.swift; sourceTree = ""; }; + D86E0DA970995D79FBCBDFC2FB00E7B7 /* GULSecureCoding.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULSecureCoding.h; path = GoogleUtilities/Environment/Public/GoogleUtilities/GULSecureCoding.h; sourceTree = ""; }; + D8AD0FE5507402DAFD68DC4AC643DD4C /* RCNConfigDBManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCNConfigDBManager.m; path = FirebaseRemoteConfig/Sources/RCNConfigDBManager.m; sourceTree = ""; }; + DA78B83E4AE85283B84FD1556F0740F5 /* FIRComponentType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentType.h; path = FirebaseCore/Extension/FIRComponentType.h; sourceTree = ""; }; + DAB1A6B8B900533E013246FF9E1B15FF /* FirebaseRemoteConfigInterop.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseRemoteConfigInterop.debug.xcconfig; sourceTree = ""; }; + DABB52F57033CB4CAE17345DED78D177 /* FIRInstallationsSingleOperationPromiseCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsSingleOperationPromiseCache.h; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.h; sourceTree = ""; }; + DC6820EB6EFEF734C44466B9387E7DF6 /* RCNPersonalization.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCNPersonalization.m; path = FirebaseRemoteConfig/Sources/RCNPersonalization.m; sourceTree = ""; }; + DCB1DF4DB075689625A34E2FF8A84C89 /* GoogleAppMeasurement.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleAppMeasurement.debug.xcconfig; sourceTree = ""; }; + DD138F64499748EC08B4AC157DA1942B /* RolloutAssignment.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RolloutAssignment.swift; path = FirebaseRemoteConfig/Interop/RolloutAssignment.swift; sourceTree = ""; }; + DD5BC1764C4EAE896681C235C95E0286 /* GULOriginalIMPConvenienceMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULOriginalIMPConvenienceMacros.h; path = GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/GULOriginalIMPConvenienceMacros.h; sourceTree = ""; }; + DD6A8B198CAD93CEFDF3C333B5653006 /* GULKeychainStorage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULKeychainStorage.m; path = GoogleUtilities/Environment/SecureStorage/GULKeychainStorage.m; sourceTree = ""; }; + DDE5B58E518997E805EADBF552B035FA /* GULReachabilityChecker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULReachabilityChecker.h; path = GoogleUtilities/Reachability/Public/GoogleUtilities/GULReachabilityChecker.h; sourceTree = ""; }; + DE5CAD8109EFA33FCEDE23763DF22FFC /* HeartbeatLoggingTestUtils.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HeartbeatLoggingTestUtils.swift; path = FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatLoggingTestUtils.swift; sourceTree = ""; }; + DEAED314EEC7194C4AC5185394A7B3B1 /* FirebaseRemoteConfigInterop-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "FirebaseRemoteConfigInterop-Info.plist"; sourceTree = ""; }; + DF0BA02847EB4ABDA457947FB6B41E30 /* FIRBundleUtil.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRBundleUtil.m; path = FirebaseCore/Sources/FIRBundleUtil.m; sourceTree = ""; }; + DFF6D1196E0850AB81108EA139B13210 /* pb.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb.h; sourceTree = ""; }; + E0C03855FD2E0FD02564160EEB28B12A /* FIRLibrary.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLibrary.h; path = FirebaseCore/Extension/FIRLibrary.h; sourceTree = ""; }; + E0C5EA433D75F11E6031A6F955C5E567 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = FirebaseCore/Sources/Resources/PrivacyInfo.xcprivacy; sourceTree = ""; }; + E1370FB83C7D43687612F478D53CDFC6 /* FIRInstallationsItem.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsItem.h; path = FirebaseInstallations/Source/Library/FIRInstallationsItem.h; sourceTree = ""; }; + E18CC3662CCE66A69D82B77B033C9B46 /* FIRExperimentController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRExperimentController.m; path = FirebaseABTesting/Sources/FIRExperimentController.m; sourceTree = ""; }; + E2252E0AFE170D46891542C10E59CEB0 /* FirebaseRemoteConfigInterop.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseRemoteConfigInterop.release.xcconfig; sourceTree = ""; }; + E2B63D462DB7F827C4B11FD51E4F8E2D /* FirebaseCore */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = FirebaseCore; path = FirebaseCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E3D01BB112572C34FB89531B632D4D1E /* FBLPromise+Always.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Always.h"; path = "Sources/FBLPromises/include/FBLPromise+Always.h"; sourceTree = ""; }; + E3D737720132A2E8C17A55188DA5BDE2 /* FBLPromise+Validate.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Validate.m"; path = "Sources/FBLPromises/FBLPromise+Validate.m"; sourceTree = ""; }; + E40D7FB16BEC3AE602AFAED30D109A05 /* FIRHeartbeatLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRHeartbeatLogger.m; path = FirebaseCore/Sources/FIRHeartbeatLogger.m; sourceTree = ""; }; + E497E19587A1EB38FE47E2DB48D9BF40 /* FirebaseCoreInternal-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FirebaseCoreInternal-prefix.pch"; sourceTree = ""; }; + E660666F02B98329C9A43343BED1238A /* RingBuffer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RingBuffer.swift; path = FirebaseCore/Internal/Sources/HeartbeatLogging/RingBuffer.swift; sourceTree = ""; }; + E6716339F23C20BC1ED183E8FBE8FB6D /* GULReachabilityChecker.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULReachabilityChecker.m; path = GoogleUtilities/Reachability/GULReachabilityChecker.m; sourceTree = ""; }; + E75B0787FCDF53EA02071FEB9C2AE06A /* FirebaseRemoteConfig-FirebaseRemoteConfig_Privacy */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "FirebaseRemoteConfig-FirebaseRemoteConfig_Privacy"; path = FirebaseRemoteConfig_Privacy.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + E90CD2DC1A9C50D83F61A8C480CBC447 /* FirebaseAnalytics.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseAnalytics.release.xcconfig; sourceTree = ""; }; + EA1221DCC616541422CC2368EA18C392 /* FIRInstallationsStoredItem.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsStoredItem.m; path = FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.m; sourceTree = ""; }; + EA7E4CACAF799A4CA84D8D9AC6F21B46 /* FBLPromisePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBLPromisePrivate.h; path = Sources/FBLPromises/include/FBLPromisePrivate.h; sourceTree = ""; }; + EAE22D4EEFFF5C5797BE1668FD4894A5 /* RolloutsStateSubscriber.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RolloutsStateSubscriber.swift; path = FirebaseRemoteConfig/Interop/RolloutsStateSubscriber.swift; sourceTree = ""; }; + EB641D7D849DE451E99A9F4274E6E660 /* FBLPromise+Async.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Async.m"; path = "Sources/FBLPromises/FBLPromise+Async.m"; sourceTree = ""; }; + EBC0124F859F5CDD9578E444B7412AC6 /* FirebaseABTesting-FirebaseABTesting_Privacy */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "FirebaseABTesting-FirebaseABTesting_Privacy"; path = FirebaseABTesting_Privacy.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + EBD324685A27CEBC247F0D8C032F02C2 /* Codable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Codable.swift; path = FirebaseRemoteConfig/Swift/Codable.swift; sourceTree = ""; }; + ECB81467705B90F303806DFA82967938 /* pb_encode.c */ = {isa = PBXFileReference; includeInIndex = 1; path = pb_encode.c; sourceTree = ""; }; + EDF547F1045BB22A439576978EC18D29 /* FirebaseCoreInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseCoreInternal.h; path = FirebaseCore/Extension/FirebaseCoreInternal.h; sourceTree = ""; }; + EFBB5170B9DDDDB35675FD09905C8A04 /* GULNetworkInfo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkInfo.h; path = GoogleUtilities/Environment/Public/GoogleUtilities/GULNetworkInfo.h; sourceTree = ""; }; + F01BBFEEAF81A1476BDDDBBA556212EC /* ResourceBundle-FirebaseABTesting_Privacy-FirebaseABTesting-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-FirebaseABTesting_Privacy-FirebaseABTesting-Info.plist"; sourceTree = ""; }; + F14AAE7E4E7FDC32CA35C9E913B00DCB /* FBLPromise+Retry.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Retry.h"; path = "Sources/FBLPromises/include/FBLPromise+Retry.h"; sourceTree = ""; }; + F1AD7256FFE15B28CC6582DBE2DC008C /* GULAppDelegateSwizzler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULAppDelegateSwizzler.h; path = GoogleUtilities/AppDelegateSwizzler/Public/GoogleUtilities/GULAppDelegateSwizzler.h; sourceTree = ""; }; + F34EB1616AF9DD15B68765C1B5BB7DA1 /* GULNetwork.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetwork.h; path = GoogleUtilities/Network/Public/GoogleUtilities/GULNetwork.h; sourceTree = ""; }; + F37EF8D61BF172AB143158A5442AB923 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; + F3AC93E4D423A4A3A651F8753C72C28E /* FirebaseRemoteConfigValueDecoderHelper.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FirebaseRemoteConfigValueDecoderHelper.swift; path = FirebaseRemoteConfig/Swift/FirebaseRemoteConfigValueDecoderHelper.swift; sourceTree = ""; }; + F6156AA9C2B244ECB4C8537A6F25F442 /* FIRHeartbeatLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRHeartbeatLogger.h; path = FirebaseCore/Extension/FIRHeartbeatLogger.h; sourceTree = ""; }; + F90BB92CC0FE04D253857FD130A06539 /* FirebaseABTesting-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "FirebaseABTesting-Info.plist"; sourceTree = ""; }; + F94DBF950FEE4B41C6A0305D7271CA14 /* Pods-TallPaper-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-TallPaper-frameworks.sh"; sourceTree = ""; }; + F9802C5B40648D558005507BDB98BE1B /* FIRComponentContainer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentContainer.h; path = FirebaseCore/Extension/FIRComponentContainer.h; sourceTree = ""; }; + FAAA993ABD04FA1089D554165000BA87 /* FBLPromise+Any.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Any.h"; path = "Sources/FBLPromises/include/FBLPromise+Any.h"; sourceTree = ""; }; + FB6D773DC97F08768351C491F656B9E1 /* RCNConfigExperiment.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCNConfigExperiment.h; path = FirebaseRemoteConfig/Sources/RCNConfigExperiment.h; sourceTree = ""; }; + FB6DA6C7D9B42CE353DDC209EC05786F /* nanopb.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = nanopb.modulemap; sourceTree = ""; }; + FB9620C9FFC61A502AFB127D5149EDCC /* FirebaseCoreInternal.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseCoreInternal.release.xcconfig; sourceTree = ""; }; + FB9A9209281A23DA9F33ADA8E99957E4 /* FBLPromise+Retry.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Retry.m"; path = "Sources/FBLPromises/FBLPromise+Retry.m"; sourceTree = ""; }; + FC344F258013D38B7813914E157B899F /* FBLPromise+Async.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Async.h"; path = "Sources/FBLPromises/include/FBLPromise+Async.h"; sourceTree = ""; }; + FCD93D3F203DE0688BBFB884B5B4E161 /* RCNConfigConstants.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RCNConfigConstants.h; path = FirebaseRemoteConfig/Sources/RCNConfigConstants.h; sourceTree = ""; }; + FDA3280B4DFDC7BC8325D81A6E655FB7 /* FirebaseRemoteConfig.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseRemoteConfig.debug.xcconfig; sourceTree = ""; }; + FDAA695864CC3BBE1FD6F2033E99903B /* FBLPromise+Timeout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Timeout.h"; path = "Sources/FBLPromises/include/FBLPromise+Timeout.h"; sourceTree = ""; }; + FDE851ED44CB1FF18D1F3D91CA170717 /* RCNConstants3P.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RCNConstants3P.m; path = FirebaseRemoteConfig/Sources/RCNConstants3P.m; sourceTree = ""; }; + FEFD82F6B39F8137121EE2D17DE0DCE6 /* GULHeartbeatDateStorage.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULHeartbeatDateStorage.m; path = GoogleUtilities/Environment/GULHeartbeatDateStorage.m; sourceTree = ""; }; + FF6FA42898B7D5C4D981D2EBA2C47BFB /* FirebaseCore.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseCore.release.xcconfig; sourceTree = ""; }; + FF73936EF5B735B0E2F409E78191F589 /* FIRInstallationsStore.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsStore.m; path = FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 0FC4ED0413E03C14B6BA2B68F0B82572 /* Frameworks */ = { + 089A9012774DD24B758E1274541149BF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 174C7953D00C8BD50BDF1694D1939E82 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + AF4E2A33DCEB9CF99022210A9CF1ED77 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1BCEE596258863A4EA090C4C48692179 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 2F09EDE65BB44FC238E52830EE033B04 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2750492709CD6408547843A71B8D69DB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + AF6ADB20A25E4279518F0B3C71722DFB /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 425EB47BD11893928B2B68EA7595474B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 580411DBDA000E517D949BCF8BE0B18B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 12DD488E276CEDA5D2262B7EF7870929 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5EA365C8991970FE1F08D59B4D7949CC /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + E97BD92C36FE57719D233B6FE8732853 /* Foundation.framework in Frameworks */, + DFAF92029191B2912C5B9F07334D3463 /* Security.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D1A6D3F9005793C8BA47EC09F11CA0B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 39BAA79584AFA48101FB8E72FD506C20 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 781F16AC8C8D58000461057C6E2BB705 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 83E687FDB288231A011E95B87301CD46 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + B898215E708FB5A0FCE5E8095D0B29E7 /* Foundation.framework in Frameworks */, + A7A19779A3ACF4A1013D4B1254F17346 /* Security.framework in Frameworks */, + 92F9225A6F58ABB6EFFB67423315C15C /* SystemConfiguration.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 86DB900B69DBE26980A76BD3BA8E2D79 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 944FF9EE6C3A0AF20C8C3F13D9344FC0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EAC001221627DE7EC876B4040E75825 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 96A116B8F4B32F63C36070D7974E82BF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + BEC305229B8658BB752ADC9A1B38A0B5 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AE8D3B85B6DCC726B1E6EB39264991F0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1C26F266BB57D7E76DB3F0C82D027847 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BE23B454B3E4E17F61E9319930B8097F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + AA15CDD5887BD912E07296B223DD26D3 /* Foundation.framework in Frameworks */, + E41B1FCB33F7920ED92FBAA41200FC21 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C3AA9C16BA9DDC01E2EEEECF3E56A700 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DB0C0623E1CF1D79BEB084BD89217422 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E777ED48436FB6FC3F9C286B98706D92 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EFA35509CD37400709F5024CE521F109 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4BD7E4981856283B65F5339AB3FFD1E0 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 07F789675B2818165881ED23AF0A24D2 /* Products */ = { + 0B1E93C0281220EB0A83C11001A8EB94 /* Support Files */ = { isa = PBXGroup; children = ( - E707D19F3B4314DCCECC25261215E9EE /* Pods-HD wallpaper */, + 92D8EE1F84DCA42475750D5985E978CB /* FirebaseRemoteConfigInterop.modulemap */, + 887DF535D5AF38FB365886AA77A0812C /* FirebaseRemoteConfigInterop-dummy.m */, + DEAED314EEC7194C4AC5185394A7B3B1 /* FirebaseRemoteConfigInterop-Info.plist */, + 89240F4F5527DD6175A8F52D945F63D3 /* FirebaseRemoteConfigInterop-umbrella.h */, + DAB1A6B8B900533E013246FF9E1B15FF /* FirebaseRemoteConfigInterop.debug.xcconfig */, + E2252E0AFE170D46891542C10E59CEB0 /* FirebaseRemoteConfigInterop.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/FirebaseRemoteConfigInterop"; + sourceTree = ""; + }; + 12A8F60F596D91C5D6CCB61440D6FEC5 /* FirebaseCoreInternal */ = { + isa = PBXGroup; + children = ( + C47072AE8853F2DC6D613ABAF62339C5 /* _ObjC_HeartbeatController.swift */, + 95FDC4862675CD7B54307601CC53D624 /* _ObjC_HeartbeatsPayload.swift */, + 308C8B46912372B5807BEFB1E6E1F65B /* Heartbeat.swift */, + 72A9AC917567336C9C984D1E7E746E1D /* HeartbeatController.swift */, + DE5CAD8109EFA33FCEDE23763DF22FFC /* HeartbeatLoggingTestUtils.swift */, + 317F794A5B19A6A14FEB7AC5E8BDF1B5 /* HeartbeatsBundle.swift */, + A3697C479CB24A72810F620D522393AF /* HeartbeatsPayload.swift */, + 6B4F89BBECD80988BC20EE63A99419F3 /* HeartbeatStorage.swift */, + E660666F02B98329C9A43343BED1238A /* RingBuffer.swift */, + 93D0EB62190227CEBABBCE3968D0A977 /* Storage.swift */, + 2A097E8C3EAC2A58C6A5B7BFE9E75AD1 /* StorageFactory.swift */, + 2DF97197EBBA43BAEC3E91489B34B278 /* WeakContainer.swift */, + BFDBB7838A82782784D86DA7F9BD813B /* Resources */, + F81EC966949C3A4AF6F06BE4963BF243 /* Support Files */, + ); + name = FirebaseCoreInternal; + path = FirebaseCoreInternal; + sourceTree = ""; + }; + 1D6AEEB46B8BDA347B2214FFDE636C38 /* GoogleUtilities */ = { + isa = PBXGroup; + children = ( + BF33374187B18C2DCF11E5005F9E40A5 /* AppDelegateSwizzler */, + 4875748D4902F34D8FE9158422178918 /* Environment */, + 79C42E7517EB1684D848A2E0AFD2B416 /* Logger */, + AB095B9B59B22E5845A876F7F34FF430 /* MethodSwizzler */, + 4EB71435BDA0A41EF80327A21C9A0382 /* Network */, + 50E4354969FF20327E41189C2ED884C5 /* NSData+zlib */, + C36F3193FCFA4F7C8859CE688970E8C8 /* Privacy */, + 32B4BF4F39966D9B2EC341E6CC8EB4A9 /* Reachability */, + 5137D2EC0C7835472F089E2F77BA5758 /* Support Files */, + AB85BCFEB8AFDF0FC96709E1680DF584 /* UserDefaults */, + ); + name = GoogleUtilities; + path = GoogleUtilities; + sourceTree = ""; + }; + 23B7724B1CB5F2F21FDE992424192685 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 6CEAC286AE0F41633E3C3970E7048199 /* FirebaseAnalytics.xcframework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 302A34DBF5FE212E3517CF9A8936E80C /* Resources */ = { + isa = PBXGroup; + children = ( + CEAFD5DBF95CB3ABF170F4D40038A4F5 /* PrivacyInfo.xcprivacy */, + ); + name = Resources; + sourceTree = ""; + }; + 32B4BF4F39966D9B2EC341E6CC8EB4A9 /* Reachability */ = { + isa = PBXGroup; + children = ( + DDE5B58E518997E805EADBF552B035FA /* GULReachabilityChecker.h */, + E6716339F23C20BC1ED183E8FBE8FB6D /* GULReachabilityChecker.m */, + 94A29B8A8E4681B099C6CAF62AA8A044 /* GULReachabilityChecker+Internal.h */, + A9FC8A579BACB56FB5239942F9A2B978 /* GULReachabilityMessageCode.h */, + ); + name = Reachability; + sourceTree = ""; + }; + 422682F712047B2B285A4D6C1418DF2F /* Pods-TallPaper */ = { + isa = PBXGroup; + children = ( + AF4B2E39D62BB92335F109AD58F06757 /* Pods-TallPaper.modulemap */, + 5E0E4A140DDE5EDD0CB1990620DC75FA /* Pods-TallPaper-acknowledgements.markdown */, + 2A2C481DB452CB7996C1C84958339D48 /* Pods-TallPaper-acknowledgements.plist */, + 06491AEEA188D72888328E5AB0F9CBC3 /* Pods-TallPaper-dummy.m */, + F94DBF950FEE4B41C6A0305D7271CA14 /* Pods-TallPaper-frameworks.sh */, + 02EDB16B4C9AE7695C2AF1BBE4D06F36 /* Pods-TallPaper-Info.plist */, + 5733B5B6AFDDBF8B33A452723B5C73D0 /* Pods-TallPaper-umbrella.h */, + B3A907F7A54CD12D5B532362DD53ED4F /* Pods-TallPaper.debug.xcconfig */, + B16BBE23543FAD12BB2BD35971F6DA1B /* Pods-TallPaper.release.xcconfig */, + ); + name = "Pods-TallPaper"; + path = "Target Support Files/Pods-TallPaper"; + sourceTree = ""; + }; + 4461BF8183A8B93CC370BA4D626BFFBD /* Support Files */ = { + isa = PBXGroup; + children = ( + 94D673910AC3AB74ABC0B829468A2823 /* FirebaseRemoteConfig.modulemap */, + 10C51F25D08AD933A8D3D02017AAA772 /* FirebaseRemoteConfig-dummy.m */, + B1171D62A677850856BB79B87509D75E /* FirebaseRemoteConfig-Info.plist */, + A25E28A8A12040D16275D2D1DA2EDB83 /* FirebaseRemoteConfig-umbrella.h */, + FDA3280B4DFDC7BC8325D81A6E655FB7 /* FirebaseRemoteConfig.debug.xcconfig */, + 59B5796B0A4C9A227C8B300E065EDA13 /* FirebaseRemoteConfig.release.xcconfig */, + A4FDFA29063041935CA3BC2D9D793F2F /* ResourceBundle-FirebaseRemoteConfig_Privacy-FirebaseRemoteConfig-Info.plist */, + ); + name = "Support Files"; + path = "../Target Support Files/FirebaseRemoteConfig"; + sourceTree = ""; + }; + 462ED1EA65DFAB61A21BB0A33F6C557B /* FirebaseCore */ = { + isa = PBXGroup; + children = ( + C613060075D2D23E82D47FBEFEFEF43F /* FIRAnalyticsConfiguration.h */, + 4253C08D4EC49D0B717837CE370785F1 /* FIRAnalyticsConfiguration.m */, + 7A6FE737AE93759D79B96FB0CB940B1F /* FIRApp.h */, + 73372DCA3D12A27E168929C0BA8FE4E4 /* FIRApp.m */, + B45CD6FF2824BB7E404063328EF1829E /* FIRAppInternal.h */, + 2BEBB95E96263213DF218487B37FF912 /* FIRBundleUtil.h */, + DF0BA02847EB4ABDA457947FB6B41E30 /* FIRBundleUtil.m */, + B2AE340D7642101AA00A4094E6AF160C /* FIRComponent.h */, + 92CDB8AAF698BCDEC7E8FDA1401BBBBE /* FIRComponent.m */, + 25BEFF708DB6FD0A3B4A9DB9D1900BAD /* FIRComponentContainer.h */, + 827A5C477414E206AF248DC46644C144 /* FIRComponentContainer.m */, + 7DF3A1166255CF3E0C68A1C007CC0F4E /* FIRComponentContainerInternal.h */, + AF7CD070A6EBC4ABAC149FE0885CAA98 /* FIRComponentType.h */, + 546B1716181B9A0BEB19FFC225D5D68B /* FIRComponentType.m */, + A05DB176F7E6E83F7C2C63C9B7339E34 /* FIRConfiguration.h */, + 04767AC0916A11CA33FD803E732157A8 /* FIRConfiguration.m */, + 395D5D902752144C46050A4CAB669598 /* FIRConfigurationInternal.h */, + 5A70510981FED68DF2BA809205D387A1 /* FIRDependency.h */, + 1B0DBA62A90CC2A21478E9B430CF5DC0 /* FIRDependency.m */, + 693374012D5FCD40E265F23036EF69F4 /* FirebaseCore.h */, + A187810449E6822F25E6ABFC9CDA3446 /* FirebaseCoreInternal.h */, + 173A1D2BA8A434F883C4F3756BCF6890 /* FIRFirebaseUserAgent.h */, + 143D42ABF58FD977F7BD2B817A79E6DC /* FIRFirebaseUserAgent.m */, + 89E7AF6C56924AFEFF0740DAF9255057 /* FIRHeartbeatLogger.h */, + E40D7FB16BEC3AE602AFAED30D109A05 /* FIRHeartbeatLogger.m */, + 897DBA56069DE92BC7EB9DF3BF3325C5 /* FIRLibrary.h */, + 54298054E074C62E86E20743BAC7925B /* FIRLogger.h */, + D0A7743AD9C9F7D31F8A8299B1A91AD1 /* FIRLogger.m */, + 907A242DBA66A1E0981EF0B63C0D29AE /* FIRLoggerLevel.h */, + 31FAA9917871C7362008C56D223BCC4E /* FIROptions.h */, + A96707865509075B195429CC67DDA479 /* FIROptions.m */, + 24B9416E0B1FEE48AEB998B591133150 /* FIROptionsInternal.h */, + 30256146DAEF27572A9F84BA3B0A5F90 /* FIRVersion.h */, + C3676C9257F1642F10902F42713C0ACD /* FIRVersion.m */, + E1EEC55A310ACA8F05482C7C1F6BD340 /* Resources */, + AB5EDB3D497447DDAD21A79CF5353857 /* Support Files */, + ); + name = FirebaseCore; + path = FirebaseCore; + sourceTree = ""; + }; + 469A873740E7479EB74EA47CCE36DB80 /* WithoutAdIdSupport */ = { + isa = PBXGroup; + children = ( + A6A4B6813F1951F068A4B4FA9EE3F5C6 /* Frameworks */, + ); + name = WithoutAdIdSupport; + sourceTree = ""; + }; + 4875748D4902F34D8FE9158422178918 /* Environment */ = { + isa = PBXGroup; + children = ( + 5DB188C0BCE4FACAF79E2AF7CEF0F18E /* GULAppEnvironmentUtil.h */, + BF5B5C6CC493F3D8DC306BAEA16AF1A8 /* GULAppEnvironmentUtil.m */, + 63B19F7DC4A4137A291CB841984B5FF8 /* GULHeartbeatDateStorable.h */, + 88FC70FB88B2D354EB6C42AB9E23A429 /* GULHeartbeatDateStorage.h */, + FEFD82F6B39F8137121EE2D17DE0DCE6 /* GULHeartbeatDateStorage.m */, + 17AAC41742538CD112A3BAEAB2641C31 /* GULHeartbeatDateStorageUserDefaults.h */, + B7D094B1082789787A18E641F494B66E /* GULHeartbeatDateStorageUserDefaults.m */, + 6AEF5C6A396D1ADA764611D687A920DB /* GULKeychainStorage.h */, + DD6A8B198CAD93CEFDF3C333B5653006 /* GULKeychainStorage.m */, + D2B69AE52F9C6F680F8FD0D12EB58010 /* GULKeychainUtils.h */, + 59BC2A3E0993030DFEFBA1CA95D52CFD /* GULKeychainUtils.m */, + EFBB5170B9DDDDB35675FD09905C8A04 /* GULNetworkInfo.h */, + 412DB5FFEF51E5BF36A217CC81C300F3 /* GULNetworkInfo.m */, + D86E0DA970995D79FBCBDFC2FB00E7B7 /* GULSecureCoding.h */, + 7A8A262ED4D43839241892A6F812378D /* GULSecureCoding.m */, + BB56505360994F7A2EA65103F67C45FC /* GULURLSessionDataResponse.h */, + 45DD421EB44E103C4624D35713AF2EC0 /* GULURLSessionDataResponse.m */, + 0E5CC88FBF5B87E058EE0D5A44911700 /* IsAppEncrypted.h */, + BF05C566026B4B2AEE16937A0686C96F /* IsAppEncrypted.m */, + 2AC9D23ABC43B3AC297A939A82852C2C /* NSURLSession+GULPromises.h */, + 6B886DEF7892AC07BF604D685DDA2AEB /* NSURLSession+GULPromises.m */, + ); + name = Environment; + sourceTree = ""; + }; + 4EB71435BDA0A41EF80327A21C9A0382 /* Network */ = { + isa = PBXGroup; + children = ( + CCD202A0BEC7B9F25A622E8AAD0881E0 /* GULMutableDictionary.h */, + 022EFA2DC80ADD08AC7DD6A6A92329F1 /* GULMutableDictionary.m */, + F34EB1616AF9DD15B68765C1B5BB7DA1 /* GULNetwork.h */, + 90197B074482ED0230AA6216050C39B9 /* GULNetwork.m */, + C052BE7FB135A8ED2D6F28462B5A5737 /* GULNetworkConstants.h */, + 455CFD151B0136FC6DB54FFE8395B810 /* GULNetworkConstants.m */, + 47CBFE8B2613056F638460A4E11FFBD7 /* GULNetworkInternal.h */, + 00B1CB57BD2FCA1ED789D36520B26010 /* GULNetworkLoggerProtocol.h */, + 392DEC1EDF4E22D389A2EDC1AF4D38FB /* GULNetworkMessageCode.h */, + C298ECA85B7369EC0FAE4312D770EA90 /* GULNetworkURLSession.h */, + 7D4CD4D55DFDEE21C6AA44018034B74B /* GULNetworkURLSession.m */, + ); + name = Network; + sourceTree = ""; + }; + 50E4354969FF20327E41189C2ED884C5 /* NSData+zlib */ = { + isa = PBXGroup; + children = ( + 0723B2CC8105941D5D54C6703FFEC746 /* GULNSData+zlib.h */, + 51500E287FB6075B9E55988901D1E18F /* GULNSData+zlib.m */, + ); + name = "NSData+zlib"; + sourceTree = ""; + }; + 5137D2EC0C7835472F089E2F77BA5758 /* Support Files */ = { + isa = PBXGroup; + children = ( + 463C249E94E6A1B183CAC712AD387BCC /* GoogleUtilities.modulemap */, + 6E36F090C3CFAF989AD74042701EAA7A /* GoogleUtilities-dummy.m */, + 576A75191D634A570D307E2DC68294B7 /* GoogleUtilities-Info.plist */, + B1418672FD1A27E1215382BCE06B7573 /* GoogleUtilities-umbrella.h */, + 370761029B7BF9DB774682C5248D31FA /* GoogleUtilities.debug.xcconfig */, + D45EDC5CDA793CACEAC775C09DCD8147 /* GoogleUtilities.release.xcconfig */, + 284758AE50272963E0D9B62E0EDE3D07 /* ResourceBundle-GoogleUtilities_Privacy-GoogleUtilities-Info.plist */, + ); + name = "Support Files"; + path = "../Target Support Files/GoogleUtilities"; + sourceTree = ""; + }; + 5E4F37EE520164205CF7D32ADDD75606 /* Firebase */ = { + isa = PBXGroup; + children = ( + E7F46540A1A987773CC41AEA7BF9D51B /* CoreOnly */, + DB5122F454FEA39791E023AE64A0E5DB /* Support Files */, + ); + name = Firebase; + path = Firebase; + sourceTree = ""; + }; + 642288BC0D13831A49A869BD2613E0F6 /* WithoutAdIdSupport */ = { + isa = PBXGroup; + children = ( + 23B7724B1CB5F2F21FDE992424192685 /* Frameworks */, + ); + name = WithoutAdIdSupport; + sourceTree = ""; + }; + 666DC2E83C46DCD9AB9D0F726F3385A6 /* Resources */ = { + isa = PBXGroup; + children = ( + 2FD212450F47D61769C92212B52858AE /* PrivacyInfo.xcprivacy */, + ); + name = Resources; + sourceTree = ""; + }; + 67612F19F0739202FD73891F86499DB1 /* Targets Support Files */ = { + isa = PBXGroup; + children = ( + 422682F712047B2B285A4D6C1418DF2F /* Pods-TallPaper */, + ); + name = "Targets Support Files"; + sourceTree = ""; + }; + 79C42E7517EB1684D848A2E0AFD2B416 /* Logger */ = { + isa = PBXGroup; + children = ( + 1D99B8E0EA2E8B23A27BE04B1EC4B047 /* GULLogger.h */, + CFEEDDBB077CF5DE8FF2B0226A3A1BB0 /* GULLogger.m */, + 9C9CE713B787FE75F0F3C7D7E9E5A4BF /* GULLoggerLevel.h */, + ); + name = Logger; + sourceTree = ""; + }; + 7B5E76A391FE995FFFF29DF088A50744 /* Support Files */ = { + isa = PBXGroup; + children = ( + 9815B1F94F6849187E0096CC2CF3728F /* PromisesObjC.modulemap */, + 085FB0A6565460730815B2F7CE7E5896 /* PromisesObjC-dummy.m */, + 13DF7CFA55D10890541BE0D89C69E5C1 /* PromisesObjC-Info.plist */, + B4A385C153D6F521F08424F73860D4A8 /* PromisesObjC-umbrella.h */, + C267AF2E92505F6750EAA8C33424B4F6 /* PromisesObjC.debug.xcconfig */, + 05A0C6A166AB6A227A42FE62B5491689 /* PromisesObjC.release.xcconfig */, + D08B6832CD4F41F567E328E586FA7708 /* ResourceBundle-FBLPromises_Privacy-PromisesObjC-Info.plist */, + ); + name = "Support Files"; + path = "../Target Support Files/PromisesObjC"; + sourceTree = ""; + }; + 7F73BE71AF139D2C7FF90BD571551D08 /* FirebaseABTesting */ = { + isa = PBXGroup; + children = ( + 8BB9853B86E5B2B10DD7DFC3AB58367A /* ABTConditionalUserPropertyController.h */, + A8D24523EA654703855D1DAA0199A882 /* ABTConditionalUserPropertyController.m */, + 0899876952EBC0C6C6B0997B6126F021 /* ABTConstants.h */, + 382AD4608DA6265D2ADAB72C9F0E70A0 /* ABTExperimentPayload.h */, + BF9778E519F419B6D3B8C346697725CD /* ABTExperimentPayload.m */, + 7F50D584D8AC434EF9B0E3E2FF17B3DF /* FIRAnalyticsInterop.h */, + CB840AE072916EC3EE874FF2EC26AEED /* FIRAnalyticsInteropListener.h */, + CEBB3CDF6B0397C596B3FAC80F041A98 /* FIRAppInternal.h */, + 151395376150327AE967B52B05253632 /* FIRComponent.h */, + 67524CD86B6C8F70B1DAA3450E89D13F /* FIRComponentContainer.h */, + AE46E3547BEF96B859A66E4F599C0293 /* FIRComponentType.h */, + 3AE8C3C914D009BC2BDBFB067F87FEF1 /* FIRDependency.h */, + 65DC58B6F6E92A6FC58C6F549C51A3CD /* FirebaseABTesting.h */, + 1AE5232B5B0309B48780B3AF3A05D81E /* FirebaseABTestingInternal.h */, + 656CA2FAECAEF3A41E8D3D9087334EB0 /* FirebaseCoreInternal.h */, + 6C4A9E5C64494B1180C1901417EE3A70 /* FIRExperimentController.h */, + E18CC3662CCE66A69D82B77B033C9B46 /* FIRExperimentController.m */, + F6156AA9C2B244ECB4C8537A6F25F442 /* FIRHeartbeatLogger.h */, + 12630B4D77778737AB3054E94B5E4D13 /* FIRInteropEventNames.h */, + 6F8375C661ADB48616C20299291EF091 /* FIRInteropParameterNames.h */, + 0D08833CDC51AB4B8E3948BB24DFE839 /* FIRLibrary.h */, + 89B98D107632C56A5971828F9ADFA29B /* FIRLifecycleEvents.h */, + B61F28CD0635CE23F8558A1083BC9241 /* FIRLifecycleEvents.m */, + CE57D042251A378B73A66A09A3B56D12 /* FIRLogger.h */, + 3C7375716F8DCA3F01D012DEC4BEEF3C /* FIROptionsInternal.h */, + 9666C778B4AD8938668B16EC60ADA086 /* Resources */, + A57DC95E636C6AECDBC444548C9FAA4E /* Support Files */, + ); + name = FirebaseABTesting; + path = FirebaseABTesting; + sourceTree = ""; + }; + 8277849A4963096BAF873DDDE1A1D272 /* Support Files */ = { + isa = PBXGroup; + children = ( + 5251BF505D3C9A126E287F8CB6AB0221 /* GoogleAppMeasurement-xcframeworks.sh */, + DCB1DF4DB075689625A34E2FF8A84C89 /* GoogleAppMeasurement.debug.xcconfig */, + 13EB0519F4816AC5CD163BF70502E536 /* GoogleAppMeasurement.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/GoogleAppMeasurement"; + sourceTree = ""; + }; + 8A714097FF5A136478984656696C5B5A /* Resources */ = { + isa = PBXGroup; + children = ( + BF3A1C11412FF332396C54BC7C6A034A /* PrivacyInfo.xcprivacy */, + ); + name = Resources; + sourceTree = ""; + }; + 8CF9931DD42ED5CF7EF8846FFC90507B /* Support Files */ = { + isa = PBXGroup; + children = ( + 4CE77D1A4D5DB11FF22EF3BAD0A777F2 /* FirebaseAnalytics-xcframeworks.sh */, + 5BCF6CF17B85CFEE227E0466CB41E82D /* FirebaseAnalytics.debug.xcconfig */, + E90CD2DC1A9C50D83F61A8C480CBC447 /* FirebaseAnalytics.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/FirebaseAnalytics"; + sourceTree = ""; + }; + 9134D6817AC4DBFB37D3D183C5E3D9B1 /* iOS */ = { + isa = PBXGroup; + children = ( + 67B07E9904CAAD5AD2278E2CBF9E13DD /* Foundation.framework */, + 1849556DA704B3114935A27CAD427E6C /* Security.framework */, + 7E343B046961E2648346BE23F8986EE7 /* SystemConfiguration.framework */, + F37EF8D61BF172AB143158A5442AB923 /* UIKit.framework */, + ); + name = iOS; + sourceTree = ""; + }; + 9666C778B4AD8938668B16EC60ADA086 /* Resources */ = { + isa = PBXGroup; + children = ( + 2759CDC1BBC5F2836E0734189AD22A89 /* PrivacyInfo.xcprivacy */, + ); + name = Resources; + sourceTree = ""; + }; + 9D4A8700F018AF5B7EB82B8559AB5FC3 /* Resources */ = { + isa = PBXGroup; + children = ( + 9AEFF81FC9CB7DCC949B85FDD1F205E6 /* PrivacyInfo.xcprivacy */, + ); + name = Resources; + sourceTree = ""; + }; + 9F3E5E9828229C3173D8C4A75290FA25 /* nanopb */ = { + isa = PBXGroup; + children = ( + DFF6D1196E0850AB81108EA139B13210 /* pb.h */, + 8D079EC2785A105640FF2D0A76EC3E12 /* pb_common.c */, + 9AFD897D1A76B25F34416E25BC1BA8C2 /* pb_common.h */, + 74B167474413405779DB425345668971 /* pb_decode.c */, + 96D94CC74872ED59F27326449C32D262 /* pb_decode.h */, + ECB81467705B90F303806DFA82967938 /* pb_encode.c */, + 394AF72A812A8B1F5953451EEB694CA2 /* pb_encode.h */, + C359CF63E664BFA8AFBCF6878311FF80 /* decode */, + BB556410988A12CB302516C562BBF797 /* encode */, + 9D4A8700F018AF5B7EB82B8559AB5FC3 /* Resources */, + A5A44D2AB003D3E5752A1A3EAA7EECEE /* Support Files */, + ); + name = nanopb; + path = nanopb; + sourceTree = ""; + }; + A57DC95E636C6AECDBC444548C9FAA4E /* Support Files */ = { + isa = PBXGroup; + children = ( + 79908E934101753D311CBFB79C5A165F /* FirebaseABTesting.modulemap */, + AACD723663F5D1C61B04933E98DB59EA /* FirebaseABTesting-dummy.m */, + F90BB92CC0FE04D253857FD130A06539 /* FirebaseABTesting-Info.plist */, + A732C7A211777FCF0919357C264E1362 /* FirebaseABTesting-umbrella.h */, + 209B54CF7D994B06541AB454EE9CAA34 /* FirebaseABTesting.debug.xcconfig */, + 6DF900A74765E9831F99A4819F5414F7 /* FirebaseABTesting.release.xcconfig */, + F01BBFEEAF81A1476BDDDBBA556212EC /* ResourceBundle-FirebaseABTesting_Privacy-FirebaseABTesting-Info.plist */, + ); + name = "Support Files"; + path = "../Target Support Files/FirebaseABTesting"; + sourceTree = ""; + }; + A5A44D2AB003D3E5752A1A3EAA7EECEE /* Support Files */ = { + isa = PBXGroup; + children = ( + FB6DA6C7D9B42CE353DDC209EC05786F /* nanopb.modulemap */, + 206885B8EC1F263A4198751B7308476D /* nanopb-dummy.m */, + C5226FA90D56682283AE4D6601CD7175 /* nanopb-Info.plist */, + 07679DB88FE797CC272089440CCF0229 /* nanopb-prefix.pch */, + B64E6FEC8DDBCA02C6D886874B9294E1 /* nanopb-umbrella.h */, + 2834B6BD9246A467EF26B83F6D9E3154 /* nanopb.debug.xcconfig */, + 088F19A523410C4D1489640C952BFF4E /* nanopb.release.xcconfig */, + 04DA273D6CD199F3F5E1A9ACA1888AD5 /* ResourceBundle-nanopb_Privacy-nanopb-Info.plist */, + ); + name = "Support Files"; + path = "../Target Support Files/nanopb"; + sourceTree = ""; + }; + A6A4B6813F1951F068A4B4FA9EE3F5C6 /* Frameworks */ = { + isa = PBXGroup; + children = ( + BE6684043E8F6230C6F2B5B9962A27FA /* GoogleAppMeasurement.xcframework */, + ); + name = Frameworks; + sourceTree = ""; + }; + A920CEC491568A3EA1CF962FD6066BB6 /* FirebaseRemoteConfig */ = { + isa = PBXGroup; + children = ( + CA48D768E2943DB7CA80E8A3D9F4ED8B /* ABTExperimentPayload.h */, + EBD324685A27CEBC247F0D8C032F02C2 /* Codable.swift */, + 5850429FAFBF3E9AA20DA67FFDF87D21 /* FIRAnalyticsInterop.h */, + 128501E0F71587BAB05408A6D4FA83A6 /* FIRAnalyticsInteropListener.h */, + 5C4D42DB954888D3DF8711540421EDA0 /* FIRAppInternal.h */, + 13E37AC54D7B24C66BD6CF82160052F3 /* FIRComponent.h */, + F9802C5B40648D558005507BDB98BE1B /* FIRComponentContainer.h */, + A5144EB8AF8D2E78332EA7C5D348E258 /* FIRComponentType.h */, + B649188460A2C149984BF3FA48EC2520 /* FIRConfigValue.m */, + B846B97AF0194E6DDACEC9BB57748022 /* FIRDependency.h */, + C6C18CB3FD8877D00962967DD1E82DFD /* FirebaseABTestingInternal.h */, + EDF547F1045BB22A439576978EC18D29 /* FirebaseCoreInternal.h */, + B0AFA6042055C466A9D374B0CE32AB71 /* FirebaseInstallationsInternal.h */, + 5DA9F090A9FABC1CBF232329F4E99A08 /* FirebaseRemoteConfig.h */, + F3AC93E4D423A4A3A651F8753C72C28E /* FirebaseRemoteConfigValueDecoderHelper.swift */, + 3F68F0820FA5987836BABB37620BBC7F /* FIRHeartbeatLogger.h */, + CD872021C34DBAC0D7D1533418F1B928 /* FIRInteropEventNames.h */, + 5E895F248780B5169A797546598A50BD /* FIRInteropParameterNames.h */, + E0C03855FD2E0FD02564160EEB28B12A /* FIRLibrary.h */, + D70D527EAFF19A24102D57E5A969F179 /* FIRLogger.h */, + C5C2F43474B905E02BDFE3A517E2FC3B /* FIROptionsInternal.h */, + 1BDFC4369892278777AFAE8FFCD7277A /* FIRRemoteConfig.h */, + CC596C20253971D585510A397BA0A500 /* FIRRemoteConfig.m */, + 5E0979A22E08784374AD00FBC125A929 /* FIRRemoteConfig_Private.h */, + 6698255073FCECA95BAED5CF2741CB12 /* FIRRemoteConfigComponent.h */, + 13A178CFE40985F6D199227F9EB9E967 /* FIRRemoteConfigComponent.m */, + 833E65C1466FF27BF0A1EB4826561F87 /* FIRRemoteConfigUpdate.m */, + FCD93D3F203DE0688BBFB884B5B4E161 /* RCNConfigConstants.h */, + 59F0842B76A5CE38951E72F18B5EE1EF /* RCNConfigContent.h */, + 4CE5D5601C9BF11D3E42C54F8A897736 /* RCNConfigContent.m */, + 65D221126ACC9BF46EE8E173D19CD3BE /* RCNConfigDBManager.h */, + D8AD0FE5507402DAFD68DC4AC643DD4C /* RCNConfigDBManager.m */, + 75BDFC4520B3CA5BB214D5D272F4B5C5 /* RCNConfigDefines.h */, + FB6D773DC97F08768351C491F656B9E1 /* RCNConfigExperiment.h */, + 4DD06FC5913D15BB4DAAFF191168CD95 /* RCNConfigExperiment.m */, + 48A7B329FA4A60E00C7AE22844CE713C /* RCNConfigFetch.h */, + 94889F55D5C5243AAF1FE316D39114DF /* RCNConfigFetch.m */, + 8B3F82B7B8AE59C50EF98ED4CBA2FDB1 /* RCNConfigRealtime.h */, + 1BD1F1E087564A3A043995BF657118C3 /* RCNConfigRealtime.m */, + 4FAA823A58ECCDA34B2453B1D1AF7CD8 /* RCNConfigSettings.h */, + 6BBC9EB741E7CFE4CA52A7BBE3F28221 /* RCNConfigSettings.m */, + 17B62497EB13A290B2423E0AED196DF0 /* RCNConfigValue_Internal.h */, + FDE851ED44CB1FF18D1F3D91CA170717 /* RCNConstants3P.m */, + 3386426474977F173391F1AED6A15D14 /* RCNDevice.h */, + 4F6803F3719C4B619CDE8B52350A8999 /* RCNDevice.m */, + 36BBCAB899B1451687368290E880F5DF /* RCNPersonalization.h */, + DC6820EB6EFEF734C44466B9387E7DF6 /* RCNPersonalization.m */, + 27204B2F94BC80BF02755E6EE6FF48B4 /* RCNUserDefaultsManager.h */, + 10A07C1E2DBB2A9D4EA51FAA71EA410D /* RCNUserDefaultsManager.m */, + 41245A942268D2918A793101A1C60D05 /* RemoteConfigProperty.swift */, + 950567D7B0395602E154D61249ECABC0 /* RemoteConfigValueObservable.swift */, + D772A4B1414311177A62C6472414F917 /* SPMSwiftHeaderWorkaround.swift */, + 1B574DE5A4BC941F957A0DFF28756FCC /* Value.swift */, + F84CDAC2096CC962FB92D2D0C7EB06F8 /* Resources */, + 4461BF8183A8B93CC370BA4D626BFFBD /* Support Files */, + ); + name = FirebaseRemoteConfig; + path = FirebaseRemoteConfig; + sourceTree = ""; + }; + A9F2AA7A1F765390A6809BEA33E5FF99 /* FirebaseRemoteConfigInterop */ = { + isa = PBXGroup; + children = ( + 86727521F4E83A0C8B674023644BD670 /* RemoteConfigConstants.swift */, + 86EA04F76C2197F2C271094EF717A765 /* RemoteConfigInterop.swift */, + DD138F64499748EC08B4AC157DA1942B /* RolloutAssignment.swift */, + EAE22D4EEFFF5C5797BE1668FD4894A5 /* RolloutsStateSubscriber.swift */, + 0B1E93C0281220EB0A83C11001A8EB94 /* Support Files */, + ); + name = FirebaseRemoteConfigInterop; + path = FirebaseRemoteConfigInterop; + sourceTree = ""; + }; + AB095B9B59B22E5845A876F7F34FF430 /* MethodSwizzler */ = { + isa = PBXGroup; + children = ( + DD5BC1764C4EAE896681C235C95E0286 /* GULOriginalIMPConvenienceMacros.h */, + 6661A473DB214FE0EEB7DCA0DCA731C1 /* GULSwizzler.h */, + B10FE88CF1A03212F65DBAA5942A8636 /* GULSwizzler.m */, + ); + name = MethodSwizzler; + sourceTree = ""; + }; + AB5EDB3D497447DDAD21A79CF5353857 /* Support Files */ = { + isa = PBXGroup; + children = ( + C57AE3985C348E1AA78A6B527D39F32F /* FirebaseCore.modulemap */, + 06FF91B187C4B0F98539DC23C557D3CE /* FirebaseCore-dummy.m */, + 301D057D7C395E459311054BEA2DCDB9 /* FirebaseCore-Info.plist */, + 0465BFA65D53A47C84AA386E5A316F4C /* FirebaseCore-umbrella.h */, + 499ADF1B3B37AD57C1A48C8AADD41D0B /* FirebaseCore.debug.xcconfig */, + FF6FA42898B7D5C4D981D2EBA2C47BFB /* FirebaseCore.release.xcconfig */, + 0491E43DC23FC5E37105C21C201F973B /* ResourceBundle-FirebaseCore_Privacy-FirebaseCore-Info.plist */, + ); + name = "Support Files"; + path = "../Target Support Files/FirebaseCore"; + sourceTree = ""; + }; + AB85BCFEB8AFDF0FC96709E1680DF584 /* UserDefaults */ = { + isa = PBXGroup; + children = ( + 588C2AC34B379F3F961AFEB8F4B0DF34 /* GULUserDefaults.h */, + 239C079A4AE35E4BD38756DDD53ABB0C /* GULUserDefaults.m */, + ); + name = UserDefaults; + sourceTree = ""; + }; + B4D8B1C4140AE51C1D7646DD5E21226B /* Products */ = { + isa = PBXGroup; + children = ( + 7C3AE4425E7B08F16F1B4FD32951CA7F /* FirebaseABTesting */, + EBC0124F859F5CDD9578E444B7412AC6 /* FirebaseABTesting-FirebaseABTesting_Privacy */, + E2B63D462DB7F827C4B11FD51E4F8E2D /* FirebaseCore */, + 8BB937B1C0DFFCF92F41861C2BC54DDA /* FirebaseCore-FirebaseCore_Privacy */, + 148D0F9E8C7373FEAF40D800FC5F1BAA /* FirebaseCoreInternal */, + 4DB03FD262B678178A44272143846563 /* FirebaseCoreInternal-FirebaseCoreInternal_Privacy */, + 13C8C8B254851998F9289F71229B28A2 /* FirebaseInstallations */, + 47C581450CDB4A6111CB97EEE0711A8C /* FirebaseInstallations-FirebaseInstallations_Privacy */, + AD776F1C94991D3E551CEAA515DB110A /* FirebaseRemoteConfig */, + E75B0787FCDF53EA02071FEB9C2AE06A /* FirebaseRemoteConfig-FirebaseRemoteConfig_Privacy */, + 3CB3BCF1390F1406B03BC8DB4735D727 /* FirebaseRemoteConfigInterop */, + 519172F62353C84795D05BA8A499936B /* FirebaseSharedSwift */, + B43874C6CBB50E7134FBEC24BABFE14F /* GoogleUtilities */, + 44E291D18340EAC3F761346198515323 /* GoogleUtilities-GoogleUtilities_Privacy */, + 06FC5C9CF96D60C50FCD47D339C91951 /* nanopb */, + 3227F3FC45681D7CEE5D1355A532398A /* nanopb-nanopb_Privacy */, + B530EE4AE87824511A048DA41F2BD27A /* Pods-TallPaper */, + 3347A1AB6546F0A3977529B8F199DC41 /* PromisesObjC */, + 3F238BB22C5201CE689CAF2F766AED95 /* PromisesObjC-FBLPromises_Privacy */, ); name = Products; sourceTree = ""; }; - 578452D2E740E91742655AC8F1636D1F /* iOS */ = { + BA4F31F07263C99FC76E66D632A59F09 /* Frameworks */ = { isa = PBXGroup; children = ( - 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */, + 9134D6817AC4DBFB37D3D183C5E3D9B1 /* iOS */, ); - name = iOS; + name = Frameworks; + sourceTree = ""; + }; + BB556410988A12CB302516C562BBF797 /* encode */ = { + isa = PBXGroup; + children = ( + ); + name = encode; + sourceTree = ""; + }; + BC02B1C2C043EDC42282E3B4CB69D241 /* PromisesObjC */ = { + isa = PBXGroup; + children = ( + 02871E8BD2CDB997D08FE36292EBBEF9 /* FBLPromise.h */, + 6167BB02AD2CD052706EDB458E3A97DB /* FBLPromise.m */, + C2B7B7EAEDA74CFFA097EACEF29D0360 /* FBLPromise+All.h */, + 463DFF8A5EA5177997B4E5AAB61B18C9 /* FBLPromise+All.m */, + E3D01BB112572C34FB89531B632D4D1E /* FBLPromise+Always.h */, + 8D49CEAEB219CE213CEE1380AA1870BC /* FBLPromise+Always.m */, + FAAA993ABD04FA1089D554165000BA87 /* FBLPromise+Any.h */, + 5425C8D0A9046622BEF46F6897052F98 /* FBLPromise+Any.m */, + FC344F258013D38B7813914E157B899F /* FBLPromise+Async.h */, + EB641D7D849DE451E99A9F4274E6E660 /* FBLPromise+Async.m */, + 20971D3E3E7A40040BA9738697676BA2 /* FBLPromise+Await.h */, + 88B571252A6FB34BC3358B9CEED97997 /* FBLPromise+Await.m */, + B0B4202E023736A8A3E0FE9A4D8B2AEC /* FBLPromise+Catch.h */, + 7E7C94E810B158112FA354F33B2FDDFD /* FBLPromise+Catch.m */, + 46EAC051EED6ADDE1239220D47C008B7 /* FBLPromise+Delay.h */, + D4ADC435328F01979C154BA5BF31669E /* FBLPromise+Delay.m */, + 5A185451B2353A2D9FEAEC50BFFD6813 /* FBLPromise+Do.h */, + 52CAD59895924651BB63FAEBBD1E3456 /* FBLPromise+Do.m */, + 7C27787F3CC35AB19EA596344B611B8D /* FBLPromise+Race.h */, + 611D27690CF7F6A20F3EF9942C5B4237 /* FBLPromise+Race.m */, + 173A51C8B399291A7286A1EA617D1CF0 /* FBLPromise+Recover.h */, + 83BF6D454D688FFBF8927B7141A2DF7E /* FBLPromise+Recover.m */, + 62AEECCD4B6E11F92852CC3FC55B6324 /* FBLPromise+Reduce.h */, + 5752F61E868014DF81F980C566E3F44A /* FBLPromise+Reduce.m */, + F14AAE7E4E7FDC32CA35C9E913B00DCB /* FBLPromise+Retry.h */, + FB9A9209281A23DA9F33ADA8E99957E4 /* FBLPromise+Retry.m */, + C53FC0372E7FECFF10949B01A02A4CB4 /* FBLPromise+Testing.h */, + 6278570AF7F9F1EE5D5C487492D2EF7B /* FBLPromise+Testing.m */, + 53AF62816637B22C90309A1F74CE3704 /* FBLPromise+Then.h */, + B3350961DE46986C41D825A8C4B105A6 /* FBLPromise+Then.m */, + FDAA695864CC3BBE1FD6F2033E99903B /* FBLPromise+Timeout.h */, + 830BACEF103B1B9D5C9511B2905411D4 /* FBLPromise+Timeout.m */, + 8797262413E3361B1F54135C6663A7F8 /* FBLPromise+Validate.h */, + E3D737720132A2E8C17A55188DA5BDE2 /* FBLPromise+Validate.m */, + 982C459C8AFB771ED709220BAE6D3BD6 /* FBLPromise+Wrap.h */, + 684935040366A7E92ECE09FA526B16FC /* FBLPromise+Wrap.m */, + 6BA4975B9DCACEEF18DC342426A3945B /* FBLPromiseError.h */, + 64DCFEC8D5593700D342D1B7E1F2685B /* FBLPromiseError.m */, + EA7E4CACAF799A4CA84D8D9AC6F21B46 /* FBLPromisePrivate.h */, + 872BF4BB62F31E9551393F836AEBA807 /* FBLPromises.h */, + 8A714097FF5A136478984656696C5B5A /* Resources */, + 7B5E76A391FE995FFFF29DF088A50744 /* Support Files */, + ); + name = PromisesObjC; + path = PromisesObjC; + sourceTree = ""; + }; + BF33374187B18C2DCF11E5005F9E40A5 /* AppDelegateSwizzler */ = { + isa = PBXGroup; + children = ( + F1AD7256FFE15B28CC6582DBE2DC008C /* GULAppDelegateSwizzler.h */, + 556F34BAB0A4E2A0D26EA3A940B25AE0 /* GULAppDelegateSwizzler.m */, + 0A425BF5F9C0B0E67F5AFE9FAF490F42 /* GULAppDelegateSwizzler_Private.h */, + 0137629091A47137D26044343F6BB38B /* GULApplication.h */, + AA7A73C3ECBA2E58085DF48768CABE2D /* GULLoggerCodes.h */, + A07DD31D3AA0F19C2DC3448743583819 /* GULSceneDelegateSwizzler.h */, + 30A4C68C973005FCD0A890D52035EBAD /* GULSceneDelegateSwizzler.m */, + 0018232DF6477FC636A008D8AFCB7E22 /* GULSceneDelegateSwizzler_Private.h */, + ); + name = AppDelegateSwizzler; + sourceTree = ""; + }; + BFDBB7838A82782784D86DA7F9BD813B /* Resources */ = { + isa = PBXGroup; + children = ( + 8F47A304F0B244DCCCF9EF7AA4BEBDD0 /* PrivacyInfo.xcprivacy */, + ); + name = Resources; + sourceTree = ""; + }; + C02345F115C4550A75A456B2334F8585 /* FirebaseAnalytics */ = { + isa = PBXGroup; + children = ( + 8CF9931DD42ED5CF7EF8846FFC90507B /* Support Files */, + 642288BC0D13831A49A869BD2613E0F6 /* WithoutAdIdSupport */, + ); + name = FirebaseAnalytics; + path = FirebaseAnalytics; + sourceTree = ""; + }; + C359CF63E664BFA8AFBCF6878311FF80 /* decode */ = { + isa = PBXGroup; + children = ( + ); + name = decode; + sourceTree = ""; + }; + C36F3193FCFA4F7C8859CE688970E8C8 /* Privacy */ = { + isa = PBXGroup; + children = ( + 302A34DBF5FE212E3517CF9A8936E80C /* Resources */, + ); + name = Privacy; + sourceTree = ""; + }; + C70C16A36A430087DF84FC5AE8DB31E4 /* FirebaseInstallations */ = { + isa = PBXGroup; + children = ( + C427612ED1543E2B1D60315509C9F971 /* FIRAppInternal.h */, + D1B88D82044B86B4E61B8CAED0322C12 /* FIRComponent.h */, + 3157854626C2B77AB6D211A676035453 /* FIRComponentContainer.h */, + DA78B83E4AE85283B84FD1556F0740F5 /* FIRComponentType.h */, + 34FE9444CEE6E7A31895765C269BD245 /* FIRCurrentDateProvider.h */, + 00313E759C28515403069130FA405A1E /* FIRCurrentDateProvider.m */, + 76F64C73760FB11EFEC43D654BE7D019 /* FIRDependency.h */, + 478C534DD7748F70AB26FA7391ACFE8F /* FirebaseCoreInternal.h */, + 2CBFB84887978A38D184D9B7509CEC70 /* FirebaseInstallations.h */, + 5B1CA5B6B4CD43186F239F052D3F3EC2 /* FirebaseInstallationsInternal.h */, + A1B3C129DCD5CB6FCBCE9B7F8D3FAB57 /* FIRHeartbeatLogger.h */, + 3176BDD8AA7AC5A550A4FB1DC652A480 /* FIRInstallations.h */, + 36791595F93467472A8A233FCEF63536 /* FIRInstallations.m */, + D74D68E534A6E7E9393D8546BD226005 /* FIRInstallationsAPIService.h */, + B9DB932484D54621537D7243450AD8B2 /* FIRInstallationsAPIService.m */, + 34A6D6776B3743C799B000FB60E1527A /* FIRInstallationsAuthTokenResult.h */, + A2AC3E8875E0CA8FD82FD435FCE63364 /* FIRInstallationsAuthTokenResult.m */, + 8A32F0B2BEBD1CA7080B398F9E8452DB /* FIRInstallationsAuthTokenResultInternal.h */, + 2BE74F652D97F4762ABB42AAF26E0C68 /* FIRInstallationsBackoffController.h */, + 3F94FD91DF6337BC57E7EA5284B2A6FB /* FIRInstallationsBackoffController.m */, + 6F45CF142336996E92BD55A74678256C /* FIRInstallationsErrors.h */, + 449FEAA30D59A791B55D657D08C52734 /* FIRInstallationsErrorUtil.h */, + C1D7F2BB9523A403818EA1338A8C4E4C /* FIRInstallationsErrorUtil.m */, + 71B7ACC5DB8FDB728C1DAD182338C36B /* FIRInstallationsHTTPError.h */, + 28EE1B16B384D2A8C8351D936C0C2512 /* FIRInstallationsHTTPError.m */, + D28D72B939EE470EF1B5DACA418C4F24 /* FIRInstallationsIDController.h */, + 459101C0E8221FBA77B32BADBCB9C383 /* FIRInstallationsIDController.m */, + B71E2D50301EECF023F1665D60BA21BF /* FIRInstallationsIIDStore.h */, + 7671C8543FF5F9E45F6C0ECC84E4546A /* FIRInstallationsIIDStore.m */, + 5DF10E3FFB628E822CD5414D0DBC68B6 /* FIRInstallationsIIDTokenStore.h */, + C591D11BE25070AE683077BDA9F01890 /* FIRInstallationsIIDTokenStore.m */, + E1370FB83C7D43687612F478D53CDFC6 /* FIRInstallationsItem.h */, + 28B1D4B5A9F28E5152E07C5C14754E25 /* FIRInstallationsItem.m */, + 4A96D4ECF706EA7F8633B03C8908FE34 /* FIRInstallationsItem+RegisterInstallationAPI.h */, + 131FF3C379BFE19D94DB2D886BB5BD09 /* FIRInstallationsItem+RegisterInstallationAPI.m */, + 18FC8810EE8510F55DA41D4B374702C4 /* FIRInstallationsLogger.h */, + ABD115BB1BB820D2B2DE5F541A263736 /* FIRInstallationsLogger.m */, + DABB52F57033CB4CAE17345DED78D177 /* FIRInstallationsSingleOperationPromiseCache.h */, + 51C43A45BC6750EB6447FBC60A17AD4B /* FIRInstallationsSingleOperationPromiseCache.m */, + B5BF445ADA4090C888DD3072A33376DC /* FIRInstallationsStatus.h */, + 73A8C5803F0CB377BFBCB3DDE9E42E30 /* FIRInstallationsStore.h */, + FF73936EF5B735B0E2F409E78191F589 /* FIRInstallationsStore.m */, + 4F23D0A780659D9A3CF4A10623BE1252 /* FIRInstallationsStoredAuthToken.h */, + 2A6312DF21B12CC8C98107D510F999C5 /* FIRInstallationsStoredAuthToken.m */, + 4093B147058BF1AF526933AB6A8AA56B /* FIRInstallationsStoredItem.h */, + EA1221DCC616541422CC2368EA18C392 /* FIRInstallationsStoredItem.m */, + 671CFBB67B468EF837F4A4DC3E436A69 /* FIRLibrary.h */, + B7F57ADFFFC393FF08F641F431134560 /* FIRLogger.h */, + A9A3F96F9B98448D3D1C019ABA7492CE /* FIROptionsInternal.h */, + 666DC2E83C46DCD9AB9D0F726F3385A6 /* Resources */, + DA60071505BCD354931B91660D69648F /* Support Files */, + ); + name = FirebaseInstallations; + path = FirebaseInstallations; sourceTree = ""; }; CF1408CF629C7361332E53B88F7BD30C = { isa = PBXGroup; children = ( 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, - D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */, - 07F789675B2818165881ED23AF0A24D2 /* Products */, - D75D56E844F551892C57E57DB83470EF /* Targets Support Files */, + BA4F31F07263C99FC76E66D632A59F09 /* Frameworks */, + E952279FCFC0F856568CA2D8AD13FEB5 /* Pods */, + B4D8B1C4140AE51C1D7646DD5E21226B /* Products */, + 67612F19F0739202FD73891F86499DB1 /* Targets Support Files */, ); sourceTree = ""; }; - D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */ = { + D0E6F2960C4808F724AA587FFECEDCDE /* FirebaseSharedSwift */ = { isa = PBXGroup; children = ( - 578452D2E740E91742655AC8F1636D1F /* iOS */, + 327179067DDF273E45A553A98667E75F /* FirebaseDataEncoder.swift */, + ABB78103AD0C89A5FD52D081ABD277ED /* FirebaseRemoteConfigValueDecoding.swift */, + F765A84F4DA6C024554DC9829E5FD06E /* Support Files */, ); - name = Frameworks; + name = FirebaseSharedSwift; + path = FirebaseSharedSwift; sourceTree = ""; }; - D75D56E844F551892C57E57DB83470EF /* Targets Support Files */ = { + DA60071505BCD354931B91660D69648F /* Support Files */ = { isa = PBXGroup; children = ( - E30107EF8248B63106D68C9457B24B5A /* Pods-HD wallpaper */, + 3053A1109EE95419C9FE468E7C6496EC /* FirebaseInstallations.modulemap */, + 6E6D67077386032B4727AC1223EC5020 /* FirebaseInstallations-dummy.m */, + 4FA704F6371EFDBD73E41DBCE1ABB342 /* FirebaseInstallations-Info.plist */, + 7F84DEC2F9ADBD86654E93E70FDDCAE4 /* FirebaseInstallations-umbrella.h */, + 5F76D90C2948429C9CE7E3475DE0B924 /* FirebaseInstallations.debug.xcconfig */, + 500BF231A850BA165F5C4776F563AF37 /* FirebaseInstallations.release.xcconfig */, + 74EAFD355DC790AE5A4AB3E447BEFD85 /* ResourceBundle-FirebaseInstallations_Privacy-FirebaseInstallations-Info.plist */, ); - name = "Targets Support Files"; + name = "Support Files"; + path = "../Target Support Files/FirebaseInstallations"; sourceTree = ""; }; - E30107EF8248B63106D68C9457B24B5A /* Pods-HD wallpaper */ = { + DB5122F454FEA39791E023AE64A0E5DB /* Support Files */ = { isa = PBXGroup; children = ( - D4F5D20D0D27BF4763A0FF29FA829EBB /* Pods-HD wallpaper.modulemap */, - D7825A4BCC67CCBD76E10C2F5BFB03AC /* Pods-HD wallpaper-acknowledgements.markdown */, - 00A8DCAE9B7B3EF7B8C45FDAEFC36A4B /* Pods-HD wallpaper-acknowledgements.plist */, - 4012E5D2ED98BF15C346FA7E4ECBB040 /* Pods-HD wallpaper-dummy.m */, - BB848298CB5EF55D6DD3F22151BA69F2 /* Pods-HD wallpaper-Info.plist */, - 1A195F190B302CCB9E52FF10ACF4E658 /* Pods-HD wallpaper-umbrella.h */, - 625A821940DC5522089C482A22E4EDD0 /* Pods-HD wallpaper.debug.xcconfig */, - A3FAA9E33EBDA1A67760BF69587CAB2B /* Pods-HD wallpaper.release.xcconfig */, + ABEE4483D32A73C25A946778F7E52969 /* Firebase.debug.xcconfig */, + 6D9A00D587445BCE41F470B03CFAB326 /* Firebase.release.xcconfig */, ); - name = "Pods-HD wallpaper"; - path = "Target Support Files/Pods-HD wallpaper"; + name = "Support Files"; + path = "../Target Support Files/Firebase"; + sourceTree = ""; + }; + E1EEC55A310ACA8F05482C7C1F6BD340 /* Resources */ = { + isa = PBXGroup; + children = ( + E0C5EA433D75F11E6031A6F955C5E567 /* PrivacyInfo.xcprivacy */, + ); + name = Resources; + sourceTree = ""; + }; + E5EEEB982A442103FA7ED5F2E1DF3A11 /* GoogleAppMeasurement */ = { + isa = PBXGroup; + children = ( + 8277849A4963096BAF873DDDE1A1D272 /* Support Files */, + 469A873740E7479EB74EA47CCE36DB80 /* WithoutAdIdSupport */, + ); + name = GoogleAppMeasurement; + path = GoogleAppMeasurement; + sourceTree = ""; + }; + E7F46540A1A987773CC41AEA7BF9D51B /* CoreOnly */ = { + isa = PBXGroup; + children = ( + 8960BC88B8B1DD67A680DD51EB058E5A /* Firebase.h */, + ); + name = CoreOnly; + sourceTree = ""; + }; + E952279FCFC0F856568CA2D8AD13FEB5 /* Pods */ = { + isa = PBXGroup; + children = ( + 5E4F37EE520164205CF7D32ADDD75606 /* Firebase */, + 7F73BE71AF139D2C7FF90BD571551D08 /* FirebaseABTesting */, + C02345F115C4550A75A456B2334F8585 /* FirebaseAnalytics */, + 462ED1EA65DFAB61A21BB0A33F6C557B /* FirebaseCore */, + 12A8F60F596D91C5D6CCB61440D6FEC5 /* FirebaseCoreInternal */, + C70C16A36A430087DF84FC5AE8DB31E4 /* FirebaseInstallations */, + A920CEC491568A3EA1CF962FD6066BB6 /* FirebaseRemoteConfig */, + A9F2AA7A1F765390A6809BEA33E5FF99 /* FirebaseRemoteConfigInterop */, + D0E6F2960C4808F724AA587FFECEDCDE /* FirebaseSharedSwift */, + E5EEEB982A442103FA7ED5F2E1DF3A11 /* GoogleAppMeasurement */, + 1D6AEEB46B8BDA347B2214FFDE636C38 /* GoogleUtilities */, + 9F3E5E9828229C3173D8C4A75290FA25 /* nanopb */, + BC02B1C2C043EDC42282E3B4CB69D241 /* PromisesObjC */, + ); + name = Pods; + sourceTree = ""; + }; + F765A84F4DA6C024554DC9829E5FD06E /* Support Files */ = { + isa = PBXGroup; + children = ( + 279FA0556ED8D6821E91A2A2606D431B /* FirebaseSharedSwift.modulemap */, + 608BF1BE349FF2A40C28196D17A0BD80 /* FirebaseSharedSwift-dummy.m */, + 355F27AC7B489492967576003F3B4992 /* FirebaseSharedSwift-Info.plist */, + C18EC549B1DB7F87B0815997C8171F7F /* FirebaseSharedSwift-umbrella.h */, + 9B3E3D3170028F2395F08A6CF1F5D821 /* FirebaseSharedSwift.debug.xcconfig */, + C543619250755351CE882118D75DB383 /* FirebaseSharedSwift.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/FirebaseSharedSwift"; + sourceTree = ""; + }; + F81EC966949C3A4AF6F06BE4963BF243 /* Support Files */ = { + isa = PBXGroup; + children = ( + 285D84A0377A267C0513653225E27A7F /* FirebaseCoreInternal.modulemap */, + B295501A485E49383772BDE110D3AE32 /* FirebaseCoreInternal-dummy.m */, + 9215C1E551E14508B96DC201A475BD3F /* FirebaseCoreInternal-Info.plist */, + E497E19587A1EB38FE47E2DB48D9BF40 /* FirebaseCoreInternal-prefix.pch */, + B411BC492A95118344F161DBDD11C0D6 /* FirebaseCoreInternal-umbrella.h */, + 117FB7DD9722C3296E517F8DA59AE404 /* FirebaseCoreInternal.debug.xcconfig */, + FB9620C9FFC61A502AFB127D5149EDCC /* FirebaseCoreInternal.release.xcconfig */, + B262493D4292A974CE6560BE08D8513B /* ResourceBundle-FirebaseCoreInternal_Privacy-FirebaseCoreInternal-Info.plist */, + ); + name = "Support Files"; + path = "../Target Support Files/FirebaseCoreInternal"; + sourceTree = ""; + }; + F84CDAC2096CC962FB92D2D0C7EB06F8 /* Resources */ = { + isa = PBXGroup; + children = ( + C2C3CD7B96F82905F982A1C5A0A9568C /* PrivacyInfo.xcprivacy */, + ); + name = Resources; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 2F2E032924324BE1CD0AE7F16D24156D /* Headers */ = { + 0BA75D4D961131C3DE96FC8C17220B18 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 04DD5FEA6CF97D9EFE8730A973046585 /* Pods-HD wallpaper-umbrella.h in Headers */, + 1B43D41766EE45509711E38E3AD9FE1C /* nanopb-umbrella.h in Headers */, + 6641A38036C59D4A0B98E18F432A73C5 /* pb.h in Headers */, + 2B485D0E4571DF73B974CAF678E53C39 /* pb_common.h in Headers */, + A7A5493867F1CB91002EC0B2668EFC1B /* pb_decode.h in Headers */, + 1347271F0EA972C5DF766D832816A22A /* pb_encode.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 200759A6408E9F20065F3A1F75196691 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 26236648451E619B85D3FF2BC350AA91 /* FBLPromise.h in Headers */, + 628E298A412E6558078B51060D4C7310 /* FBLPromise+All.h in Headers */, + E2B85544E9B6D80BC8E3FA8E7AB7C2F3 /* FBLPromise+Always.h in Headers */, + 10612C85BCFD0682CB18712E8A6E5AE8 /* FBLPromise+Any.h in Headers */, + 67F806FA54A209B2DD19DFC752100041 /* FBLPromise+Async.h in Headers */, + 5B036FD0C741D0E9EA660BEF6B129E77 /* FBLPromise+Await.h in Headers */, + BA53AEB692E8DE3DA1951888CBBFFC4B /* FBLPromise+Catch.h in Headers */, + DECAED39C7FCFADDAF75B0E0A727AA2F /* FBLPromise+Delay.h in Headers */, + 3197E355FBA0C489C3F51AE8A653B529 /* FBLPromise+Do.h in Headers */, + 20860BEF9C0743437CC8EE2A219FD033 /* FBLPromise+Race.h in Headers */, + 5D937AA5259A707253557CF2F7C95BFB /* FBLPromise+Recover.h in Headers */, + AEEDE83E1A6B856FE9FB16B6E90AB69F /* FBLPromise+Reduce.h in Headers */, + 44A551E2F2E4CE9CDE673BE91DFF9F69 /* FBLPromise+Retry.h in Headers */, + B535EC928F517F977809F9C9721AEB18 /* FBLPromise+Testing.h in Headers */, + 4484E06A0A2460BAE386EEDBDF0501DF /* FBLPromise+Then.h in Headers */, + 59468502EA5577F2B444DBCA74B1857F /* FBLPromise+Timeout.h in Headers */, + 9F4562A5BB1A5A39D1FE7BABC86BB9AB /* FBLPromise+Validate.h in Headers */, + FDB0F2DEC86D0B1696DECC7D1C10C64E /* FBLPromise+Wrap.h in Headers */, + 256679AACBB27292744C8F1903829ADF /* FBLPromiseError.h in Headers */, + 2718981AE6D24D01EC6E73E2702F9446 /* FBLPromisePrivate.h in Headers */, + 3277F31807CFBF0EDAAACEF1108B25F3 /* FBLPromises.h in Headers */, + BA0070AD057C1F6A84A0BDEA97AFED3C /* PromisesObjC-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 29C3318D994534443B08EFEC6457EC40 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 77908124E99723653397D15F4684F06A /* FIRAnalyticsConfiguration.h in Headers */, + F9442DC6740E99FA242BEDA1B5D5688F /* FIRApp.h in Headers */, + 5EA59E72AD35D1A8AA8B9C0EF7AE597F /* FIRAppInternal.h in Headers */, + 26FA710EBA60374B07343233050ACCCB /* FIRBundleUtil.h in Headers */, + A256296DB5CF98380551076BBD4F4E97 /* FIRComponent.h in Headers */, + E6004AC19BDD36271DFCA990FC3B17F4 /* FIRComponentContainer.h in Headers */, + F640D820B4E7C66D4EF6FC5D1FAE3431 /* FIRComponentContainerInternal.h in Headers */, + F20CB06C3AD93285E5EAE2A060035F92 /* FIRComponentType.h in Headers */, + 728F05428C749DD035897D811D42F99D /* FIRConfiguration.h in Headers */, + 24EA40D936EC29376E681C41E68E8664 /* FIRConfigurationInternal.h in Headers */, + 86B8BF288312F0318C0D069D3FD0D0ED /* FIRDependency.h in Headers */, + CB12128F080101291E224B3091C696D7 /* FirebaseCore.h in Headers */, + 037EB8A9DABF4FDAC5B429B1A15B6E18 /* FirebaseCore-umbrella.h in Headers */, + 1BB615CDFB5FA1D38F49E757AD326403 /* FirebaseCoreInternal.h in Headers */, + 346D17FFD27BACCC84201FB599E04910 /* FIRFirebaseUserAgent.h in Headers */, + CFD7BCC70BA2D7A112DF87CC8A0E2621 /* FIRHeartbeatLogger.h in Headers */, + 1A489BD53A52433956CD9B21ACE04971 /* FIRLibrary.h in Headers */, + B7C36CA4F98AD5446DE6F8F0E60A1CE2 /* FIRLogger.h in Headers */, + CDF51BB2D8DDD5143D508CD8C66E76B8 /* FIRLoggerLevel.h in Headers */, + BD64038B193F6559C5A39AE5142296F7 /* FIROptions.h in Headers */, + 996D15BD575A804A99E050B681C08F38 /* FIROptionsInternal.h in Headers */, + 93415317A87C8D569C1F0FA3557F3C11 /* FIRVersion.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B0F91C7721C91FA75B031989D71FE23 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + A2A12185E9E1165D3593761FBC1C5C5F /* FIRAppInternal.h in Headers */, + F4EA10237210D16D24066CBA18DC8713 /* FIRComponent.h in Headers */, + DB5B0C8F049B2AF8553C4565ECBB3221 /* FIRComponentContainer.h in Headers */, + A34A76385D4414BB3007090AE6955DFE /* FIRComponentType.h in Headers */, + 3FB703A256519703177EC8EB1334E991 /* FIRCurrentDateProvider.h in Headers */, + E0BA9F9123D18022EA10BA2DB1757068 /* FIRDependency.h in Headers */, + 25E6BAB845B7F3DC6FEC1A5023644C34 /* FirebaseCoreInternal.h in Headers */, + 5BBD22AF1059269BC43EDF075ECE6406 /* FirebaseInstallations.h in Headers */, + 503063D4D411A3C0CCBF15CC14E048B0 /* FirebaseInstallations-umbrella.h in Headers */, + E0AC3898D7732FAD5B6081F410CE1CF9 /* FirebaseInstallationsInternal.h in Headers */, + A5611C2B60D19A01A35D0B795D104DCD /* FIRHeartbeatLogger.h in Headers */, + 52DBA511452DC665C02C38546E90D290 /* FIRInstallations.h in Headers */, + 0EA7754F7184C6AA03B1C22E54FE9A3C /* FIRInstallationsAPIService.h in Headers */, + 0A63944CC9F6F3BB72EB30CBC2E53457 /* FIRInstallationsAuthTokenResult.h in Headers */, + 8AB6112E62DF1F97AC2FF4B3CF2E92D8 /* FIRInstallationsAuthTokenResultInternal.h in Headers */, + 928636DE392A2592668AB49616E4FA07 /* FIRInstallationsBackoffController.h in Headers */, + 11A2AB5E67441BBF3D98B4CBAF439DA7 /* FIRInstallationsErrors.h in Headers */, + 2A5F9F84107D692A393457F5A79B6CFC /* FIRInstallationsErrorUtil.h in Headers */, + 16B05E7BFB1F2ED538AAED5247E263BA /* FIRInstallationsHTTPError.h in Headers */, + CD0E2DBE8F28F8D1D5D10F16D7A00F63 /* FIRInstallationsIDController.h in Headers */, + BFF03FA96140B5AC649C2BD02DE596BD /* FIRInstallationsIIDStore.h in Headers */, + 7104C97A514DFB3AA20BC595BA586E74 /* FIRInstallationsIIDTokenStore.h in Headers */, + BDAB010CAC043B15B6BEC882ADE47538 /* FIRInstallationsItem.h in Headers */, + 0C862A2FB61BF294B990C92D3D39EDB5 /* FIRInstallationsItem+RegisterInstallationAPI.h in Headers */, + 3EC815D5C5AD33607C81B8250C32D611 /* FIRInstallationsLogger.h in Headers */, + 3BEBD0E43705EFB4DF2D8C2A80B413D1 /* FIRInstallationsSingleOperationPromiseCache.h in Headers */, + B36F54FC2A5557A5A3EDA62C3204F818 /* FIRInstallationsStatus.h in Headers */, + 1E30147BC31330EDB52A8CBF4BA47DA1 /* FIRInstallationsStore.h in Headers */, + 619DC42D768882B852156984DE521225 /* FIRInstallationsStoredAuthToken.h in Headers */, + 2E73FC652C5267CE8132E7143EADA20D /* FIRInstallationsStoredItem.h in Headers */, + 3B82B056885EBDDF3353C29A20F2553B /* FIRLibrary.h in Headers */, + 9F5B3B58A35158B9687F3A9293E8DA8E /* FIRLogger.h in Headers */, + 1BC6D049D48A0F4D0429F41CB3AF7E0E /* FIROptionsInternal.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B1AC916C38231A8BD5E717A477D0ABA0 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 0B42662391E1F0B20862AD619625A34A /* ABTConditionalUserPropertyController.h in Headers */, + 0FB8B94B29A09F300D2A47AA6C362029 /* ABTConstants.h in Headers */, + 452BD48CFEDB75603E1DCADDD1C1C6F0 /* ABTExperimentPayload.h in Headers */, + 4CE9E79838F1A2E38395FF32B053B582 /* FIRAnalyticsInterop.h in Headers */, + 01080947AB08367F88AE23969144BD16 /* FIRAnalyticsInteropListener.h in Headers */, + 97DD20E649353DE7D33074543438D0FE /* FIRAppInternal.h in Headers */, + 1F83A6EEA5B5D0610425A09BD79A1BCE /* FIRComponent.h in Headers */, + 0BA30D76A9C94F8B1ABE3C5AA81128ED /* FIRComponentContainer.h in Headers */, + 17C3BD9EF58BA88ADFFB8C14346ACA3A /* FIRComponentType.h in Headers */, + 6029C05E1DAB4EC6FC7F82DBB9796FF2 /* FIRDependency.h in Headers */, + 6168BAF01AB3B54660F57ACD3290AE0F /* FirebaseABTesting.h in Headers */, + 2E80313FCD3EEEA68DA6F34E0416BBC9 /* FirebaseABTesting-umbrella.h in Headers */, + BF6EC2D659FFD114F8099F95181A2AEB /* FirebaseABTestingInternal.h in Headers */, + 6E73A2E14B1800D1D3EC46D4D9560823 /* FirebaseCoreInternal.h in Headers */, + C90466464C9DB45B03F726E0389B1524 /* FIRExperimentController.h in Headers */, + 4D7B1114E5F43E042AE48E1D6608B15B /* FIRHeartbeatLogger.h in Headers */, + 7C3806D3917DBC74D91E2D327AC3E66F /* FIRInteropEventNames.h in Headers */, + 8F94F3558D5B686DAFBA973B60C1B2A9 /* FIRInteropParameterNames.h in Headers */, + 0FB7E75647175C56A48237E7F7666D56 /* FIRLibrary.h in Headers */, + A566222F15526FBA76CA10F2FC6D802A /* FIRLifecycleEvents.h in Headers */, + 002E4A327A3CB44F4D16C0A226238A90 /* FIRLogger.h in Headers */, + 014B59D13FE778C995C7E06BA82823F3 /* FIROptionsInternal.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BFB79BCC2841F4F3B4ACE92EEF0F9124 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + B8D2D0DFAE7AD26E529972849964D74D /* FirebaseSharedSwift-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CE51C490BDF7EBC309F336CA1228D263 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + B7FC193A51569B977BB5C9EEE9D0CFE0 /* ABTExperimentPayload.h in Headers */, + 98F4DB88F9C58DAAC21DCCD25411E48A /* FIRAnalyticsInterop.h in Headers */, + C245F54DBA994B6AA16F4F1E9FD36256 /* FIRAnalyticsInteropListener.h in Headers */, + 9F5E26F9089A8BBBDB39B6F9303D6483 /* FIRAppInternal.h in Headers */, + 59B8FB4B3A535AEE9992E95DABDE052D /* FIRComponent.h in Headers */, + DF03D2792E54B7E3D0BD33C742A21EA7 /* FIRComponentContainer.h in Headers */, + 197BE4EF714B4E66AD0E6A22A626F765 /* FIRComponentType.h in Headers */, + 95A793820AE75639718FE3085EA9A6D5 /* FIRDependency.h in Headers */, + B5322FAE78BBCD4A8889E5182EB708C0 /* FirebaseABTestingInternal.h in Headers */, + F00678FAE83AD45D280DA59B3FAE1B79 /* FirebaseCoreInternal.h in Headers */, + 1334B9C4A6A8E74699F8B21A2657444E /* FirebaseInstallationsInternal.h in Headers */, + AAE0AF48937F401710EFDAF669CCBE6B /* FirebaseRemoteConfig.h in Headers */, + 47E92504DCF98D8F7CB7DB38EBA0A047 /* FirebaseRemoteConfig-umbrella.h in Headers */, + E971E1E6E1FE6C74F80303051F741096 /* FIRHeartbeatLogger.h in Headers */, + 24C51517170700E2BAA2677E4BA0FB6C /* FIRInteropEventNames.h in Headers */, + 8E6842275FCB472F515F9528F0365F16 /* FIRInteropParameterNames.h in Headers */, + ABBCC2BAB977D5AFD784D959F39E5382 /* FIRLibrary.h in Headers */, + 12D35D0F555699A4FD519C8579D6E2FE /* FIRLogger.h in Headers */, + F74B316FB409406995A7F37CE7DEE1D4 /* FIROptionsInternal.h in Headers */, + 6826C1FE06A215D2F6B8F51574FB1709 /* FIRRemoteConfig.h in Headers */, + 635C245F7FDB055D7BCB689F31EF04BC /* FIRRemoteConfig_Private.h in Headers */, + 981CB56D93FAF3DC8707FA0E35B4B310 /* FIRRemoteConfigComponent.h in Headers */, + 1792C6D8511CC67EF1FD8864BE80E311 /* RCNConfigConstants.h in Headers */, + 25AC76518081926C91722FE32C8E6E91 /* RCNConfigContent.h in Headers */, + 1E9AD700B357DCFA3E1E317B5490FEF0 /* RCNConfigDBManager.h in Headers */, + 20EB7353C65195AD8900D7EA4AC3D72E /* RCNConfigDefines.h in Headers */, + DA3D50737941CF3BB793F829A04B259B /* RCNConfigExperiment.h in Headers */, + 18993DAD06C256FBACD140FFF30A7223 /* RCNConfigFetch.h in Headers */, + 4120C92556C96D027AF77A1BF758F844 /* RCNConfigRealtime.h in Headers */, + C6656E6B25AF7D92BCA7ED357A317CFF /* RCNConfigSettings.h in Headers */, + 250FFF1BA8E20B668D2628E20D1DAA99 /* RCNConfigValue_Internal.h in Headers */, + B0AA56A7BA4557EF616346CE6CF37E8D /* RCNDevice.h in Headers */, + 8802FDF2420F8F1A2EE05CC8F1F86B91 /* RCNPersonalization.h in Headers */, + 0821509889AFAF943FE41ECA9AFA7CA1 /* RCNUserDefaultsManager.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D6294529BFCAF22FCB48428055A520B1 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + F0FE0939029DB44980E4992515EAE0C7 /* FirebaseCoreInternal-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F1F1B266B2974A7EEC1BE87BB6E0347E /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + B50F4DC2C07D8A33270EA188F0526734 /* GoogleUtilities-umbrella.h in Headers */, + 1187C0D8D69372171147A9F16A0AEAB9 /* GULAppDelegateSwizzler.h in Headers */, + 5CCB09383FE8A66A9D3237082E7BB297 /* GULAppDelegateSwizzler_Private.h in Headers */, + 02F16F9C7A20763496824FB3DECEEA5F /* GULAppEnvironmentUtil.h in Headers */, + 30E0DFE91FC8A124561506C723A2403C /* GULApplication.h in Headers */, + B254EF09E23C51171972082A0009D002 /* GULHeartbeatDateStorable.h in Headers */, + 3BF93076E8ABE2B97F4E027497E8F1D9 /* GULHeartbeatDateStorage.h in Headers */, + 3987D09E5123084EE5C490645C9CA8DE /* GULHeartbeatDateStorageUserDefaults.h in Headers */, + 87A6BC96D33D542F867E8433A393F8FF /* GULKeychainStorage.h in Headers */, + 072C74210202BF611391E7651910BF5F /* GULKeychainUtils.h in Headers */, + DBD30DC1722D92C82E21BC6BCC692BF2 /* GULLogger.h in Headers */, + D838A6D7510456D5B09DC1A635EFB4C3 /* GULLoggerCodes.h in Headers */, + F1E816465C3D3C871C582D66551F9B1E /* GULLoggerLevel.h in Headers */, + ED45843DF658E3B968B28FF4E239497D /* GULMutableDictionary.h in Headers */, + 17AD06278B2721840A94FD449A960503 /* GULNetwork.h in Headers */, + 84C26AA894C559C3E27DAC10EAD274F3 /* GULNetworkConstants.h in Headers */, + 01F6C082EC4E80AAEA6A7D8E2E1ED66F /* GULNetworkInfo.h in Headers */, + 03F75F13B17E635D2C9431C9DCA81D95 /* GULNetworkInternal.h in Headers */, + 5013C036BF99F09CDC5E52E846A3959B /* GULNetworkLoggerProtocol.h in Headers */, + D95F975AFEB7A4FF338B9D4627E65CB5 /* GULNetworkMessageCode.h in Headers */, + A7A2C5B7E0949A25B272EDAF2984A836 /* GULNetworkURLSession.h in Headers */, + EE04EF1645806C0E759BABA063E9B9B2 /* GULNSData+zlib.h in Headers */, + D1C88B402B77260D2EA25F86159A1A25 /* GULOriginalIMPConvenienceMacros.h in Headers */, + 65A8B640E3C161CB733FA87ECC087DC3 /* GULReachabilityChecker.h in Headers */, + 9093CC638BA2F194622C4F167A0A986C /* GULReachabilityChecker+Internal.h in Headers */, + 4F71CCF30BEAEF31781B41180EB6DBC6 /* GULReachabilityMessageCode.h in Headers */, + 02957B05E9F36148482D0F520B66E6A0 /* GULSceneDelegateSwizzler.h in Headers */, + B940ACBAB30D76C2ED49BE466EF88D5B /* GULSceneDelegateSwizzler_Private.h in Headers */, + 56996F206EBF485324F937A41EF6F1B9 /* GULSecureCoding.h in Headers */, + F0D69983AC6B8E8030E469B20F15A035 /* GULSwizzler.h in Headers */, + 98BCC34BD5FA508AB31593E96CF8DB10 /* GULURLSessionDataResponse.h in Headers */, + 09C139863044A20A7D7FD8193995541C /* GULUserDefaults.h in Headers */, + 53070110301B29EC210F0E24EAA65166 /* IsAppEncrypted.h in Headers */, + 4CAEB207FDC8F20F988669FDF167DC91 /* NSURLSession+GULPromises.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F87ABB56B2712571D91C0963C9FA34C5 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + DB0D5CAF12790F157CD3AD8A3F8A9834 /* Pods-TallPaper-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FE2B4261FC1DB17C10CA398676AF76C4 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 04914681DC621F7499CC6AE5FB64D8CB /* FirebaseRemoteConfigInterop-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - CD8E9F4C5B3F8681F98B33E18DC5C29F /* Pods-HD wallpaper */ = { + 1001C16510D946B47CFF8B19DBC0B787 /* FirebaseCore-FirebaseCore_Privacy */ = { isa = PBXNativeTarget; - buildConfigurationList = BDB3D85B698A0BE87C7F3D391EC964B8 /* Build configuration list for PBXNativeTarget "Pods-HD wallpaper" */; + buildConfigurationList = DB96948B15DF1A29204ECD6FBB3FDAC8 /* Build configuration list for PBXNativeTarget "FirebaseCore-FirebaseCore_Privacy" */; buildPhases = ( - 2F2E032924324BE1CD0AE7F16D24156D /* Headers */, - 1A09681F0C397CD33B6863E0726AC8D3 /* Sources */, - 0FC4ED0413E03C14B6BA2B68F0B82572 /* Frameworks */, - 485F47A6AF158A44FF7B101A4DDF80FA /* Resources */, + 025E644E9A07383329EB58F33012B8A6 /* Sources */, + 86DB900B69DBE26980A76BD3BA8E2D79 /* Frameworks */, + 999DEC30D4F32D295982DB51DB6426DC /* Resources */, ); buildRules = ( ); dependencies = ( ); - name = "Pods-HD wallpaper"; - productName = Pods_HD_wallpaper; - productReference = E707D19F3B4314DCCECC25261215E9EE /* Pods-HD wallpaper */; + name = "FirebaseCore-FirebaseCore_Privacy"; + productName = FirebaseCore_Privacy; + productReference = 8BB937B1C0DFFCF92F41861C2BC54DDA /* FirebaseCore-FirebaseCore_Privacy */; + productType = "com.apple.product-type.bundle"; + }; + 1BFBEDBF7E03729D43C96530EE190825 /* PromisesObjC-FBLPromises_Privacy */ = { + isa = PBXNativeTarget; + buildConfigurationList = DF54F4F48D5FB43AE838F00C69562C01 /* Build configuration list for PBXNativeTarget "PromisesObjC-FBLPromises_Privacy" */; + buildPhases = ( + 27C112DBCB5966CF03BBDE7D182B4D53 /* Sources */, + C3AA9C16BA9DDC01E2EEEECF3E56A700 /* Frameworks */, + 614ADD60FF8731478D133DD241333505 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "PromisesObjC-FBLPromises_Privacy"; + productName = FBLPromises_Privacy; + productReference = 3F238BB22C5201CE689CAF2F766AED95 /* PromisesObjC-FBLPromises_Privacy */; + productType = "com.apple.product-type.bundle"; + }; + 25E9E9A17BC3F670357D7385C521E48E /* FirebaseCoreInternal */ = { + isa = PBXNativeTarget; + buildConfigurationList = 59C8B1E1A6E8169BF54604D7DC38D8DF /* Build configuration list for PBXNativeTarget "FirebaseCoreInternal" */; + buildPhases = ( + D6294529BFCAF22FCB48428055A520B1 /* Headers */, + D35FFDBB016FB31347076B1775345C0C /* Sources */, + 96A116B8F4B32F63C36070D7974E82BF /* Frameworks */, + 89EBF14CD3510766ACB98A1DFEFEDCFA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 14C352D14522B8FFBE5605BECB5B2979 /* PBXTargetDependency */, + 8AFB3BDA0C62390379AC5CEAF8F16F3D /* PBXTargetDependency */, + ); + name = FirebaseCoreInternal; + productName = FirebaseCoreInternal; + productReference = 148D0F9E8C7373FEAF40D800FC5F1BAA /* FirebaseCoreInternal */; productType = "com.apple.product-type.framework"; }; + 2949783F7EDB27AD4666B5427B63DC79 /* FirebaseCoreInternal-FirebaseCoreInternal_Privacy */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2420DBFA283C8D72987D948D720026AB /* Build configuration list for PBXNativeTarget "FirebaseCoreInternal-FirebaseCoreInternal_Privacy" */; + buildPhases = ( + BCBB2B874D93477A41200C59F7612915 /* Sources */, + E777ED48436FB6FC3F9C286B98706D92 /* Frameworks */, + 40749592442914A3A583AA3A0FC7932B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "FirebaseCoreInternal-FirebaseCoreInternal_Privacy"; + productName = FirebaseCoreInternal_Privacy; + productReference = 4DB03FD262B678178A44272143846563 /* FirebaseCoreInternal-FirebaseCoreInternal_Privacy */; + productType = "com.apple.product-type.bundle"; + }; + 2BBF7206D7FAC92C82A042A99C4A98F8 /* PromisesObjC */ = { + isa = PBXNativeTarget; + buildConfigurationList = 13C0C3122A77F8F0F31DBB4A148C5E23 /* Build configuration list for PBXNativeTarget "PromisesObjC" */; + buildPhases = ( + 200759A6408E9F20065F3A1F75196691 /* Headers */, + 14B0CCD2467D7A63163832B6E2F0CC4D /* Sources */, + AE8D3B85B6DCC726B1E6EB39264991F0 /* Frameworks */, + 15B6249DC6EEA3057C4B49E33C84D923 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5116F6DE93D4F6ED4E17A32D891D8C2B /* PBXTargetDependency */, + ); + name = PromisesObjC; + productName = FBLPromises; + productReference = 3347A1AB6546F0A3977529B8F199DC41 /* PromisesObjC */; + productType = "com.apple.product-type.framework"; + }; + 328CC04F43300C6CAB81659260A3799D /* FirebaseRemoteConfigInterop */ = { + isa = PBXNativeTarget; + buildConfigurationList = C25B2784896EA6627D7C7E65609387B6 /* Build configuration list for PBXNativeTarget "FirebaseRemoteConfigInterop" */; + buildPhases = ( + FE2B4261FC1DB17C10CA398676AF76C4 /* Headers */, + 4CD5D9FAE85CCB839E4E41050861FB7B /* Sources */, + 580411DBDA000E517D949BCF8BE0B18B /* Frameworks */, + F18B60FDF7FFBC32C609CA39F6C6C5B1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = FirebaseRemoteConfigInterop; + productName = FirebaseRemoteConfigInterop; + productReference = 3CB3BCF1390F1406B03BC8DB4735D727 /* FirebaseRemoteConfigInterop */; + productType = "com.apple.product-type.framework"; + }; + 3EB14444A17F9D4F1F697F7C1FF32245 /* FirebaseInstallations-FirebaseInstallations_Privacy */ = { + isa = PBXNativeTarget; + buildConfigurationList = C95A64E102B99E1D38DF86F0DC4BC4DF /* Build configuration list for PBXNativeTarget "FirebaseInstallations-FirebaseInstallations_Privacy" */; + buildPhases = ( + 0C809A136F1D35B6D7C00513BEA729BC /* Sources */, + DB0C0623E1CF1D79BEB084BD89217422 /* Frameworks */, + 75D326BAC1B2F3A330DE7B24A72CEFAA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "FirebaseInstallations-FirebaseInstallations_Privacy"; + productName = FirebaseInstallations_Privacy; + productReference = 47C581450CDB4A6111CB97EEE0711A8C /* FirebaseInstallations-FirebaseInstallations_Privacy */; + productType = "com.apple.product-type.bundle"; + }; + 4402AFF83DBDC4DD07E198685FDC2DF2 /* FirebaseCore */ = { + isa = PBXNativeTarget; + buildConfigurationList = F29B3F5EBC81A1712BBEE1D60ADF3E89 /* Build configuration list for PBXNativeTarget "FirebaseCore" */; + buildPhases = ( + 29C3318D994534443B08EFEC6457EC40 /* Headers */, + 6CFBB73939D95DFFB2003A8A01839FF3 /* Sources */, + BE23B454B3E4E17F61E9319930B8097F /* Frameworks */, + FC510137C713E4C1E14D8F36BC784F3A /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + E10D6AEF53581CD520A644D6451C75E5 /* PBXTargetDependency */, + 543D1EEA9A05B1B6C086ED430485E911 /* PBXTargetDependency */, + EDD5EBFC7407BBE781857A003543C286 /* PBXTargetDependency */, + ); + name = FirebaseCore; + productName = FirebaseCore; + productReference = E2B63D462DB7F827C4B11FD51E4F8E2D /* FirebaseCore */; + productType = "com.apple.product-type.framework"; + }; + 51471EE35F2E9E19E51A74944E5ABB7F /* FirebaseRemoteConfig */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1BF7BF9AC1D4A689E82B20BAEBB160AA /* Build configuration list for PBXNativeTarget "FirebaseRemoteConfig" */; + buildPhases = ( + CE51C490BDF7EBC309F336CA1228D263 /* Headers */, + 948E09AE036CCF712199243B93074E41 /* Sources */, + 6D1A6D3F9005793C8BA47EC09F11CA0B /* Frameworks */, + 49E7E260891FC069643A91A9A280AA3D /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 398746AAFC91727467533D4A2340E94B /* PBXTargetDependency */, + F1E2523FB7E26C5383CD1976A5E4C7C0 /* PBXTargetDependency */, + 292CB2F3C662FED6FC3585461DE2386D /* PBXTargetDependency */, + B29CC0C48D85F007DFD8964C3AE75476 /* PBXTargetDependency */, + 04C5683ED27F80B37A1AF3927A8AF1DB /* PBXTargetDependency */, + 1A2DE80C47EA1680B22A5173C6000A66 /* PBXTargetDependency */, + C864FA594812EE03C711647D9D73650C /* PBXTargetDependency */, + ); + name = FirebaseRemoteConfig; + productName = FirebaseRemoteConfig; + productReference = AD776F1C94991D3E551CEAA515DB110A /* FirebaseRemoteConfig */; + productType = "com.apple.product-type.framework"; + }; + 55522A91938FF505CFEBEAD2DD85AE2D /* nanopb-nanopb_Privacy */ = { + isa = PBXNativeTarget; + buildConfigurationList = 47D214A835E066E643F53F997A46D018 /* Build configuration list for PBXNativeTarget "nanopb-nanopb_Privacy" */; + buildPhases = ( + 59501206ED4299C65458005370FBD413 /* Sources */, + EFA35509CD37400709F5024CE521F109 /* Frameworks */, + 27C2D70DFB7699695921D482ED59736E /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "nanopb-nanopb_Privacy"; + productName = nanopb_Privacy; + productReference = 3227F3FC45681D7CEE5D1355A532398A /* nanopb-nanopb_Privacy */; + productType = "com.apple.product-type.bundle"; + }; + 5FF1A58DEEC5DB749FCD6C120B97CC82 /* GoogleUtilities-GoogleUtilities_Privacy */ = { + isa = PBXNativeTarget; + buildConfigurationList = 22A01D8C10750D945F73A7EDD1351068 /* Build configuration list for PBXNativeTarget "GoogleUtilities-GoogleUtilities_Privacy" */; + buildPhases = ( + 002A758B73F0F25DA618C81AE7B47737 /* Sources */, + 425EB47BD11893928B2B68EA7595474B /* Frameworks */, + 94F19673D18210FC716FC66E1FE50786 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "GoogleUtilities-GoogleUtilities_Privacy"; + productName = GoogleUtilities_Privacy; + productReference = 44E291D18340EAC3F761346198515323 /* GoogleUtilities-GoogleUtilities_Privacy */; + productType = "com.apple.product-type.bundle"; + }; + 87803597EB3F20FC46472B85392EC4FD /* FirebaseInstallations */ = { + isa = PBXNativeTarget; + buildConfigurationList = EAEEC2C8228C14795FB4304F564F92EA /* Build configuration list for PBXNativeTarget "FirebaseInstallations" */; + buildPhases = ( + 4B0F91C7721C91FA75B031989D71FE23 /* Headers */, + CDE438FFB755F7A86B322321A94B025C /* Sources */, + 5EA365C8991970FE1F08D59B4D7949CC /* Frameworks */, + 3EB7DFE01B0958FE33A2AB19DE7B282E /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + DA47C4956B01D866D4E502CEF646CB46 /* PBXTargetDependency */, + 5B767F65C5B9D2B2FACEEB985B14027F /* PBXTargetDependency */, + 9D484A0E3ECC1AA530FFBDEDE7E588B2 /* PBXTargetDependency */, + E8F455A7FD924AA11068F0ED6FE736DD /* PBXTargetDependency */, + ); + name = FirebaseInstallations; + productName = FirebaseInstallations; + productReference = 13C8C8B254851998F9289F71229B28A2 /* FirebaseInstallations */; + productType = "com.apple.product-type.framework"; + }; + 8D7F5D5DD528D21A72DC87ADA5B12E2D /* GoogleUtilities */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6C57E918FF6EB5AC948A7B455A145C69 /* Build configuration list for PBXNativeTarget "GoogleUtilities" */; + buildPhases = ( + F1F1B266B2974A7EEC1BE87BB6E0347E /* Headers */, + E51402822A03141573E606368D7C253C /* Sources */, + 83E687FDB288231A011E95B87301CD46 /* Frameworks */, + A4C9BEB81339BFFE3D7D2AFEE8B727E9 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + D8C174FC418D3C1C67D13A999593D77B /* PBXTargetDependency */, + D4638B04CBDE95DC733CE2F51C3CD7CF /* PBXTargetDependency */, + ); + name = GoogleUtilities; + productName = GoogleUtilities; + productReference = B43874C6CBB50E7134FBEC24BABFE14F /* GoogleUtilities */; + productType = "com.apple.product-type.framework"; + }; + 8F68D031908A0059566798048C48F776 /* FirebaseABTesting */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3C703D607C67D3E76C417D44E6F824DF /* Build configuration list for PBXNativeTarget "FirebaseABTesting" */; + buildPhases = ( + B1AC916C38231A8BD5E717A477D0ABA0 /* Headers */, + 9440414775C332C52A59C66416725E15 /* Sources */, + 1BCEE596258863A4EA090C4C48692179 /* Frameworks */, + 5E7B1454ACE1E689886323A609C3763A /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 1B4A314ECB52C83607A8A0F9858E425C /* PBXTargetDependency */, + 12C1DF4DB55BA46E9142BA68B27732AF /* PBXTargetDependency */, + ); + name = FirebaseABTesting; + productName = FirebaseABTesting; + productReference = 7C3AE4425E7B08F16F1B4FD32951CA7F /* FirebaseABTesting */; + productType = "com.apple.product-type.framework"; + }; + 94706DD5BBE215339DF893D4434E1084 /* FirebaseSharedSwift */ = { + isa = PBXNativeTarget; + buildConfigurationList = C3E2F5B411EEC3A2309EF73E27DA5817 /* Build configuration list for PBXNativeTarget "FirebaseSharedSwift" */; + buildPhases = ( + BFB79BCC2841F4F3B4ACE92EEF0F9124 /* Headers */, + 88A64332BFB10CB8EF58B96AB8573E19 /* Sources */, + 2750492709CD6408547843A71B8D69DB /* Frameworks */, + 9A596F54025CAFD459382935B0637BAC /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = FirebaseSharedSwift; + productName = FirebaseSharedSwift; + productReference = 519172F62353C84795D05BA8A499936B /* FirebaseSharedSwift */; + productType = "com.apple.product-type.framework"; + }; + A9B0AE10478CAEDC7318BE4FE98EB9EB /* Pods-TallPaper */ = { + isa = PBXNativeTarget; + buildConfigurationList = A3715D5CAC4B91670C46A343F74E3561 /* Build configuration list for PBXNativeTarget "Pods-TallPaper" */; + buildPhases = ( + F87ABB56B2712571D91C0963C9FA34C5 /* Headers */, + C2E6DE4937CDB2367F24E31015777D54 /* Sources */, + 174C7953D00C8BD50BDF1694D1939E82 /* Frameworks */, + 7A879EE4B453E42A561EE6188701DEDC /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + D75504359000104CC0E433FBA226F6C2 /* PBXTargetDependency */, + 8E4FB243C1A99B992B43A6D63C4E9389 /* PBXTargetDependency */, + 72C0CE85C8805F049B6C9D871C67409F /* PBXTargetDependency */, + E446390ADCAE93489900CA6175BE03ED /* PBXTargetDependency */, + 9897B0527A75C95EFC897451B7B021A3 /* PBXTargetDependency */, + B35593402C1228676DAF3512F5B8473D /* PBXTargetDependency */, + 212AA6564C124386FBBFC864A7BEB652 /* PBXTargetDependency */, + B97CEBFB786A4C085DDB78B195F48505 /* PBXTargetDependency */, + 77AC8C3B8927ECDCE3BFE26AE8D7C7CF /* PBXTargetDependency */, + 4E63166588FAF0118840023BDBC17730 /* PBXTargetDependency */, + E33F565E56A9BB7B8FD75BEF5D8784D7 /* PBXTargetDependency */, + B99C7270E51C32780354FE49FA303F19 /* PBXTargetDependency */, + 454B74E7C145638BD704A566F20CBE38 /* PBXTargetDependency */, + ); + name = "Pods-TallPaper"; + productName = Pods_TallPaper; + productReference = B530EE4AE87824511A048DA41F2BD27A /* Pods-TallPaper */; + productType = "com.apple.product-type.framework"; + }; + C7B621349CB28ED0EBA4C3E416947AB6 /* FirebaseRemoteConfig-FirebaseRemoteConfig_Privacy */ = { + isa = PBXNativeTarget; + buildConfigurationList = 84E25780A03A38697B02AA5F3203B58D /* Build configuration list for PBXNativeTarget "FirebaseRemoteConfig-FirebaseRemoteConfig_Privacy" */; + buildPhases = ( + 377E771FF78545D9AB60C144317FD28D /* Sources */, + 781F16AC8C8D58000461057C6E2BB705 /* Frameworks */, + 516C216E7867D2AF59AF6BD9ED2491BF /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "FirebaseRemoteConfig-FirebaseRemoteConfig_Privacy"; + productName = FirebaseRemoteConfig_Privacy; + productReference = E75B0787FCDF53EA02071FEB9C2AE06A /* FirebaseRemoteConfig-FirebaseRemoteConfig_Privacy */; + productType = "com.apple.product-type.bundle"; + }; + D2B5E7DCCBBFB32341D857D01211A1A3 /* nanopb */ = { + isa = PBXNativeTarget; + buildConfigurationList = EE19EA06C95C29E2AD45DA4555E9EEC5 /* Build configuration list for PBXNativeTarget "nanopb" */; + buildPhases = ( + 0BA75D4D961131C3DE96FC8C17220B18 /* Headers */, + 28B1E2A1F1D557B7E6EA9C6395667AA7 /* Sources */, + 944FF9EE6C3A0AF20C8C3F13D9344FC0 /* Frameworks */, + AB4D6784CCD6D93B521FC9D612D06EF3 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 3AA9B141EBA112CD1FF5E5C2B5583E6F /* PBXTargetDependency */, + ); + name = nanopb; + productName = nanopb; + productReference = 06FC5C9CF96D60C50FCD47D339C91951 /* nanopb */; + productType = "com.apple.product-type.framework"; + }; + E9F5D289F4688880F8AEA528F4783976 /* FirebaseABTesting-FirebaseABTesting_Privacy */ = { + isa = PBXNativeTarget; + buildConfigurationList = E0021F85E3BC4A1C1514ED20731C442E /* Build configuration list for PBXNativeTarget "FirebaseABTesting-FirebaseABTesting_Privacy" */; + buildPhases = ( + ED56EBF50539B204C1670DFC355F9BFC /* Sources */, + 089A9012774DD24B758E1274541149BF /* Frameworks */, + 8587B9076FDE68D0FEBB02451B31EAC1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "FirebaseABTesting-FirebaseABTesting_Privacy"; + productName = FirebaseABTesting_Privacy; + productReference = EBC0124F859F5CDD9578E444B7412AC6 /* FirebaseABTesting-FirebaseABTesting_Privacy */; + productType = "com.apple.product-type.bundle"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -146,38 +2780,1292 @@ en, ); mainGroup = CF1408CF629C7361332E53B88F7BD30C; - productRefGroup = 07F789675B2818165881ED23AF0A24D2 /* Products */; + productRefGroup = B4D8B1C4140AE51C1D7646DD5E21226B /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - CD8E9F4C5B3F8681F98B33E18DC5C29F /* Pods-HD wallpaper */, + 072CEA044D2EF26F03496D5996BBF59F /* Firebase */, + 8F68D031908A0059566798048C48F776 /* FirebaseABTesting */, + E9F5D289F4688880F8AEA528F4783976 /* FirebaseABTesting-FirebaseABTesting_Privacy */, + C49E7A4D59E5C8BE8DE9FB1EFB150185 /* FirebaseAnalytics */, + 4402AFF83DBDC4DD07E198685FDC2DF2 /* FirebaseCore */, + 1001C16510D946B47CFF8B19DBC0B787 /* FirebaseCore-FirebaseCore_Privacy */, + 25E9E9A17BC3F670357D7385C521E48E /* FirebaseCoreInternal */, + 2949783F7EDB27AD4666B5427B63DC79 /* FirebaseCoreInternal-FirebaseCoreInternal_Privacy */, + 87803597EB3F20FC46472B85392EC4FD /* FirebaseInstallations */, + 3EB14444A17F9D4F1F697F7C1FF32245 /* FirebaseInstallations-FirebaseInstallations_Privacy */, + 51471EE35F2E9E19E51A74944E5ABB7F /* FirebaseRemoteConfig */, + C7B621349CB28ED0EBA4C3E416947AB6 /* FirebaseRemoteConfig-FirebaseRemoteConfig_Privacy */, + 328CC04F43300C6CAB81659260A3799D /* FirebaseRemoteConfigInterop */, + 94706DD5BBE215339DF893D4434E1084 /* FirebaseSharedSwift */, + B53D977A951AFC38B21751B706C1DF83 /* GoogleAppMeasurement */, + 8D7F5D5DD528D21A72DC87ADA5B12E2D /* GoogleUtilities */, + 5FF1A58DEEC5DB749FCD6C120B97CC82 /* GoogleUtilities-GoogleUtilities_Privacy */, + D2B5E7DCCBBFB32341D857D01211A1A3 /* nanopb */, + 55522A91938FF505CFEBEAD2DD85AE2D /* nanopb-nanopb_Privacy */, + A9B0AE10478CAEDC7318BE4FE98EB9EB /* Pods-TallPaper */, + 2BBF7206D7FAC92C82A042A99C4A98F8 /* PromisesObjC */, + 1BFBEDBF7E03729D43C96530EE190825 /* PromisesObjC-FBLPromises_Privacy */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - 485F47A6AF158A44FF7B101A4DDF80FA /* Resources */ = { + 15B6249DC6EEA3057C4B49E33C84D923 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7CAC6C750F0FD866960F2EA287FEE0E8 /* PromisesObjC-FBLPromises_Privacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 27C2D70DFB7699695921D482ED59736E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AC5D9019D657C5DFE041375928416970 /* PrivacyInfo.xcprivacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3EB7DFE01B0958FE33A2AB19DE7B282E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D9C9596E93439FF9D3B8AC079406C889 /* FirebaseInstallations-FirebaseInstallations_Privacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 40749592442914A3A583AA3A0FC7932B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 752CCCF6F24425B1B5AF180776639C8F /* PrivacyInfo.xcprivacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 49E7E260891FC069643A91A9A280AA3D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 82A3F699E1244A47A48903B10462C483 /* FirebaseRemoteConfig-FirebaseRemoteConfig_Privacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 516C216E7867D2AF59AF6BD9ED2491BF /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6D098ED385C81818E081BB4ACB3F08F6 /* PrivacyInfo.xcprivacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5E7B1454ACE1E689886323A609C3763A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4DE548D16C2ED9005D12CC6144DFA6A2 /* FirebaseABTesting-FirebaseABTesting_Privacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 614ADD60FF8731478D133DD241333505 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C8AAEA20390A2D089C96122F666A0F05 /* PrivacyInfo.xcprivacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 75D326BAC1B2F3A330DE7B24A72CEFAA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A96900969B4DD93F3CA898C4020B5A25 /* PrivacyInfo.xcprivacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7A879EE4B453E42A561EE6188701DEDC /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; + 8587B9076FDE68D0FEBB02451B31EAC1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7AC0142D7F858DE4B67276904397F482 /* PrivacyInfo.xcprivacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 89EBF14CD3510766ACB98A1DFEFEDCFA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8835DA541490CC3B33F51EF2A1D3F5A1 /* FirebaseCoreInternal-FirebaseCoreInternal_Privacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 94F19673D18210FC716FC66E1FE50786 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6AA982405AAD20B8FA6CFBFD7D486209 /* PrivacyInfo.xcprivacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 999DEC30D4F32D295982DB51DB6426DC /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 23719F5ABD7E5E38966B82FAF5656D0F /* PrivacyInfo.xcprivacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9A596F54025CAFD459382935B0637BAC /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A4C9BEB81339BFFE3D7D2AFEE8B727E9 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A65482320A15BD2D8BC34E0C7E45C32C /* GoogleUtilities-GoogleUtilities_Privacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AB4D6784CCD6D93B521FC9D612D06EF3 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FAEEEEB22A63428133C9D69418119A43 /* nanopb-nanopb_Privacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F18B60FDF7FFBC32C609CA39F6C6C5B1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FC510137C713E4C1E14D8F36BC784F3A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + AD2EC8DC4ABFC1C99A2C5150DDA5D70E /* FirebaseCore-FirebaseCore_Privacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + B82725F813044246C9CBD2EF41A0ECAF /* [CP] Copy XCFrameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks-input-files.xcfilelist", + ); + name = "[CP] Copy XCFrameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + EC57F3132A92F1704B35D2C5B32C64D9 /* [CP] Copy XCFrameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement-xcframeworks-input-files.xcfilelist", + ); + name = "[CP] Copy XCFrameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement-xcframeworks-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement-xcframeworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ - 1A09681F0C397CD33B6863E0726AC8D3 /* Sources */ = { + 002A758B73F0F25DA618C81AE7B47737 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 025E644E9A07383329EB58F33012B8A6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0C809A136F1D35B6D7C00513BEA729BC /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 14B0CCD2467D7A63163832B6E2F0CC4D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5973655F7EBDB83AF303F476E7C55157 /* FBLPromise.m in Sources */, + F3A5A0177DA043B370520334D484B83D /* FBLPromise+All.m in Sources */, + 672DDDE7DBD4EFF8357036DEBA0EFBC0 /* FBLPromise+Always.m in Sources */, + 72496DE8DCAF02B279C0E0792AEE398C /* FBLPromise+Any.m in Sources */, + 22A7845FA88AEB261651C57A150D7A06 /* FBLPromise+Async.m in Sources */, + A64A2A673CABF907CEB1627752509A27 /* FBLPromise+Await.m in Sources */, + FDB3FAC8CAA298F8E638D1B0B5E73DD6 /* FBLPromise+Catch.m in Sources */, + 97BB1C9234BCC0A9F40DF9B5B0439742 /* FBLPromise+Delay.m in Sources */, + 32C60E34AB6CA0D9E4BACC656A02525F /* FBLPromise+Do.m in Sources */, + BAC8ADFE352B585A8809A69152DB7A09 /* FBLPromise+Race.m in Sources */, + 8FEA3F31AE13E6091C45C33A854CF62D /* FBLPromise+Recover.m in Sources */, + 74081F542B64A38B39EA1346E138F933 /* FBLPromise+Reduce.m in Sources */, + 49FA4D2509EF4907230A2CA0CC16134A /* FBLPromise+Retry.m in Sources */, + A250E7BD7A742393573ED67256664322 /* FBLPromise+Testing.m in Sources */, + 1BBC5C2368E990779CEC13E0CE698058 /* FBLPromise+Then.m in Sources */, + 5701F6CC9D0D3D0675B40C02914442B1 /* FBLPromise+Timeout.m in Sources */, + 629D11E5D9046B8FB80C6C814192A28F /* FBLPromise+Validate.m in Sources */, + 11B6F16D57ABC141F6EF25010A8E1BEE /* FBLPromise+Wrap.m in Sources */, + E8E5C8BBD8B94C603912CEF6A984E292 /* FBLPromiseError.m in Sources */, + F6AD3A5D8A3C8499B8C9C18B17320E3A /* PromisesObjC-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 27C112DBCB5966CF03BBDE7D182B4D53 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 28B1E2A1F1D557B7E6EA9C6395667AA7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 557ED1CA94051856C92FFB5F85896FE6 /* nanopb-dummy.m in Sources */, + AB4461579566B0CEA2255E743823C9D4 /* pb_common.c in Sources */, + 618CFDC4CC93B88B788BDA1894884976 /* pb_decode.c in Sources */, + EB486F00D483C5DD151C2724316E3BAF /* pb_encode.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 377E771FF78545D9AB60C144317FD28D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4CD5D9FAE85CCB839E4E41050861FB7B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 648E136EA15B1689CD2BFE14069EF1B3 /* FirebaseRemoteConfigInterop-dummy.m in Sources */, + 55FBDB7F7C29F2363F1AE3B6DED07449 /* RemoteConfigConstants.swift in Sources */, + 838F47C14943DD453B90E52B9615C050 /* RemoteConfigInterop.swift in Sources */, + ADA7060BE42FC191AB4C76DBC920E168 /* RolloutAssignment.swift in Sources */, + D740B923690C7625A0A1FD365DED048C /* RolloutsStateSubscriber.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 59501206ED4299C65458005370FBD413 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6CFBB73939D95DFFB2003A8A01839FF3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4C3B8513C6C0BD42F6CBC837EC429DBC /* FIRAnalyticsConfiguration.m in Sources */, + 357DC605857D030BD54BC503421BEB4D /* FIRApp.m in Sources */, + 0FD802B43A35E41447F1B71A497D090F /* FIRBundleUtil.m in Sources */, + F83500E29BE9745AB16A0D80BCAB3DED /* FIRComponent.m in Sources */, + AD6871FCDC88B2AAD1B74DF690D59541 /* FIRComponentContainer.m in Sources */, + 059B07C3DEDB4EE0C32821FBCFFEA387 /* FIRComponentType.m in Sources */, + 69C92D56BDF88146A168DAB810E6FBBE /* FIRConfiguration.m in Sources */, + 2EDAC56F996DFF0E863359050DAF3E36 /* FIRDependency.m in Sources */, + 9118BC86E6B23F80844218DB19E824ED /* FirebaseCore-dummy.m in Sources */, + 56477103480E7B535B3855A1239B1124 /* FIRFirebaseUserAgent.m in Sources */, + 27AA7BE5357FB5A00F78424D1340BF2C /* FIRHeartbeatLogger.m in Sources */, + 324EF1B0910B956CCB4E0F82DBDF0797 /* FIRLogger.m in Sources */, + B76DF41921B90D311203DEB3858F29E8 /* FIROptions.m in Sources */, + A20CB02436409B5180B742C3487CB59A /* FIRVersion.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 88A64332BFB10CB8EF58B96AB8573E19 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B68303147CFA60059219EB7C3A3C9D64 /* FirebaseDataEncoder.swift in Sources */, + F65C2E1BE094262E7819BF79D69F6FEC /* FirebaseRemoteConfigValueDecoding.swift in Sources */, + 50DDCD88E26C61D7557E6D5595EA3351 /* FirebaseSharedSwift-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9440414775C332C52A59C66416725E15 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D808FD94A874D4D45793C05444120FB3 /* ABTConditionalUserPropertyController.m in Sources */, + B15AA88E5B9438ED215AD6FAA1CC7075 /* ABTExperimentPayload.m in Sources */, + 4B1D9CB7CB83021A706FC5FC731CA551 /* FirebaseABTesting-dummy.m in Sources */, + 7C3CABFBAB9CBA2E914D9452CA37197B /* FIRExperimentController.m in Sources */, + D2802874422630C0AA946A8ABC7D2289 /* FIRLifecycleEvents.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 948E09AE036CCF712199243B93074E41 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A84E754C7D9B7BFA2F3B02B40619CC87 /* Codable.swift in Sources */, + 19754842DC0D791C9E12C473444B14B6 /* FIRConfigValue.m in Sources */, + B1772E69A33CADF4339590E3C89A51F4 /* FirebaseRemoteConfig-dummy.m in Sources */, + FADB0173B4714D97704DC4B93AE2191C /* FirebaseRemoteConfigValueDecoderHelper.swift in Sources */, + 4AC11245E6B6573CC318C9102085C0E3 /* FIRRemoteConfig.m in Sources */, + 1366AD596ACDC5211422F1489C8C6579 /* FIRRemoteConfigComponent.m in Sources */, + 014A51D10A5E8B19B19B1E39AFC6CC7E /* FIRRemoteConfigUpdate.m in Sources */, + 5DF89FFB676DA8E2E76D397065AE9663 /* RCNConfigContent.m in Sources */, + 2376DF4DF42EB2D5791EC4E82BF818D7 /* RCNConfigDBManager.m in Sources */, + 03B92DAF7A6605A05A9E6464DD425DBB /* RCNConfigExperiment.m in Sources */, + 23E9269777AC1BF8044B3AD3EFF0750E /* RCNConfigFetch.m in Sources */, + DC95016776F4C4775BC83A5B9BBA67FF /* RCNConfigRealtime.m in Sources */, + 36FD69B6E2108E8F9375ABFD2867DD5B /* RCNConfigSettings.m in Sources */, + A9FB28CD29CFD806E77F4D23718252EA /* RCNConstants3P.m in Sources */, + 0310D0AAACDFA43D80CC48E7FD8BC830 /* RCNDevice.m in Sources */, + A0EBB3819B68180B49D8F8D93BA3975F /* RCNPersonalization.m in Sources */, + EA11597688903C5320AD86904A6E1928 /* RCNUserDefaultsManager.m in Sources */, + 72F0168B4185A0A3727E8E09213139CB /* RemoteConfigProperty.swift in Sources */, + C755818FF2D566A24463020C6C38BDC6 /* RemoteConfigValueObservable.swift in Sources */, + DD1235F0F860A6AA680D9EE0A57DA0F7 /* SPMSwiftHeaderWorkaround.swift in Sources */, + A2E4C1641A519E43A078374895FBBB98 /* Value.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BCBB2B874D93477A41200C59F7612915 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C2E6DE4937CDB2367F24E31015777D54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D30FD08897F3A30CB10471D4FF9C7EC2 /* Pods-TallPaper-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CDE438FFB755F7A86B322321A94B025C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 80326CDBC48B1A73EB9FB8D2C27EA74B /* FIRCurrentDateProvider.m in Sources */, + E84BD01ED4077B1640D9DB3AD895CBA3 /* FirebaseInstallations-dummy.m in Sources */, + 574A6495897B88B04CF915DE37312072 /* FIRInstallations.m in Sources */, + 72D2E4336EFDEFCDE0708A284C93D874 /* FIRInstallationsAPIService.m in Sources */, + 8728A7BFA216C50DA58F998A0F009FAC /* FIRInstallationsAuthTokenResult.m in Sources */, + 60516003FF3241145859BC05A6697D67 /* FIRInstallationsBackoffController.m in Sources */, + 5D2ED5A6F743E912A640F744CE331A3A /* FIRInstallationsErrorUtil.m in Sources */, + 593C81214C42B4B00CFCB24EC4ADD14F /* FIRInstallationsHTTPError.m in Sources */, + 46EDA447619C827F1E710C762A98C20F /* FIRInstallationsIDController.m in Sources */, + F426D94A9E79290D9AA64985A2589789 /* FIRInstallationsIIDStore.m in Sources */, + 3999EF5960E10C4219B6A0D1B95F268C /* FIRInstallationsIIDTokenStore.m in Sources */, + EAC2A886D88EEA6419C9C2950F6000A3 /* FIRInstallationsItem.m in Sources */, + 69868DADA44E53CE51042BDADCB10765 /* FIRInstallationsItem+RegisterInstallationAPI.m in Sources */, + AA72AD3F145E11FB00205BCBAF4F70A0 /* FIRInstallationsLogger.m in Sources */, + 77DAB8C1A6901060DDDE58E682735233 /* FIRInstallationsSingleOperationPromiseCache.m in Sources */, + CDAA53809FE4658AB62E6F6A8CF6A955 /* FIRInstallationsStore.m in Sources */, + 5CA8FEEDB54C293F4A74F580FF26E9B5 /* FIRInstallationsStoredAuthToken.m in Sources */, + 0F1F54BB51451311D842553F2606C5E6 /* FIRInstallationsStoredItem.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D35FFDBB016FB31347076B1775345C0C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1CD95F21E8C0DD476470B6D20C4A5ECD /* _ObjC_HeartbeatController.swift in Sources */, + 0CB6A0D1E953EDB1F4962DC56C23E288 /* _ObjC_HeartbeatsPayload.swift in Sources */, + EBE128E6F0CCC85440CEEF9B880FE73F /* FirebaseCoreInternal-dummy.m in Sources */, + 4B94C053073406FF1FCDED43F07E9092 /* Heartbeat.swift in Sources */, + 6BEDD7EED2AC8B76AE804DFA62841D3B /* HeartbeatController.swift in Sources */, + 560D0045B045EE16B370BBB060176A2E /* HeartbeatLoggingTestUtils.swift in Sources */, + DFFCF54CF20255E992DDCF41F73E33EB /* HeartbeatsBundle.swift in Sources */, + 9C5C32D7C6FB396A5EB18E18695F5C69 /* HeartbeatsPayload.swift in Sources */, + BE996023DD3BFB1B6ACA569102CA5584 /* HeartbeatStorage.swift in Sources */, + 2CE2FED50A50A7A9D8D990E935F12678 /* RingBuffer.swift in Sources */, + A300E387017BE7F2390B5E9612CB0DE4 /* Storage.swift in Sources */, + 4A5323703044C47F8A859F6C8103121C /* StorageFactory.swift in Sources */, + C7C78919F036C1FA7512B32BD3845694 /* WeakContainer.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E51402822A03141573E606368D7C253C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C0AEB9B2CC89EFFBCA8BD250CD2EDD56 /* GoogleUtilities-dummy.m in Sources */, + 286BCA33EB9D749D9D20BA6465837BAD /* GULAppDelegateSwizzler.m in Sources */, + 087ECD801CFD198243ED84F4B2BFD5D1 /* GULAppEnvironmentUtil.m in Sources */, + D8709F58EFA494EDF3B249214531FADC /* GULHeartbeatDateStorage.m in Sources */, + 8D97FDA2F690B52492945338C49D35E1 /* GULHeartbeatDateStorageUserDefaults.m in Sources */, + 4BBAF07A8197B54CA7665D7EDB6CAD61 /* GULKeychainStorage.m in Sources */, + 7DCF6508F810FC485A58ED8861939C89 /* GULKeychainUtils.m in Sources */, + 35FF4EAE2DE6D820314B27CD73C87423 /* GULLogger.m in Sources */, + 941FD9A53A9154E8BCD773F23E0CFB96 /* GULMutableDictionary.m in Sources */, + BABD7A92C6F68B2FFA6EEDDB31DB609C /* GULNetwork.m in Sources */, + AD5DF41E3B0B948D39237A5BB2D984F7 /* GULNetworkConstants.m in Sources */, + C15597EE7BE6CF4118F22F036FFB98BE /* GULNetworkInfo.m in Sources */, + 3FD4D9902B88B07E5905D92C5854EDD3 /* GULNetworkURLSession.m in Sources */, + 03D98F176B8F3123C881DC02EA547FBB /* GULNSData+zlib.m in Sources */, + F2D3FE6849FBB1C5C98B881E573FBBB3 /* GULReachabilityChecker.m in Sources */, + 53466019F0BC6E3BED9E1ED420F2CFCF /* GULSceneDelegateSwizzler.m in Sources */, + D5DB89F63CF0A8A18FE137E3DBB62D4A /* GULSecureCoding.m in Sources */, + 5308B4B1F4AD24CCB9D6D126C404AFF8 /* GULSwizzler.m in Sources */, + 79032BE000CEB45525B533AC5C035479 /* GULURLSessionDataResponse.m in Sources */, + B6B2F4FB00A438AB6A699CDFD6DA4D20 /* GULUserDefaults.m in Sources */, + 8FD0E1D5C2BB2195E79BC4D5AB72C450 /* IsAppEncrypted.m in Sources */, + E11B91D74B6E42A4B013F1CFD3D3F119 /* NSURLSession+GULPromises.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + ED56EBF50539B204C1670DFC355F9BFC /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 05FD1465944F134ABF7A9930D4CD3572 /* Pods-HD wallpaper-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 04C5683ED27F80B37A1AF3927A8AF1DB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseRemoteConfigInterop; + target = 328CC04F43300C6CAB81659260A3799D /* FirebaseRemoteConfigInterop */; + targetProxy = 1503E6F56D354428B148B3BBB051D738 /* PBXContainerItemProxy */; + }; + 119AE19212762697A6043151CF3C47B7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = nanopb; + target = D2B5E7DCCBBFB32341D857D01211A1A3 /* nanopb */; + targetProxy = EA34ADD006B1476EE422DFE42432FBD1 /* PBXContainerItemProxy */; + }; + 12C1DF4DB55BA46E9142BA68B27732AF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseCore; + target = 4402AFF83DBDC4DD07E198685FDC2DF2 /* FirebaseCore */; + targetProxy = A8848EF3927118035050B6F7396FB872 /* PBXContainerItemProxy */; + }; + 14C352D14522B8FFBE5605BECB5B2979 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "FirebaseCoreInternal-FirebaseCoreInternal_Privacy"; + target = 2949783F7EDB27AD4666B5427B63DC79 /* FirebaseCoreInternal-FirebaseCoreInternal_Privacy */; + targetProxy = 442DF15F710983695AB9CB115C0784A1 /* PBXContainerItemProxy */; + }; + 1A2DE80C47EA1680B22A5173C6000A66 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseSharedSwift; + target = 94706DD5BBE215339DF893D4434E1084 /* FirebaseSharedSwift */; + targetProxy = B703119491DFB27D9223BA2E79900887 /* PBXContainerItemProxy */; + }; + 1B4A314ECB52C83607A8A0F9858E425C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "FirebaseABTesting-FirebaseABTesting_Privacy"; + target = E9F5D289F4688880F8AEA528F4783976 /* FirebaseABTesting-FirebaseABTesting_Privacy */; + targetProxy = 7CB8E94492E7953D2AC2B8BD6F61C662 /* PBXContainerItemProxy */; + }; + 1F7B568D1965EE6C1B1EE4491FFB841B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = GoogleAppMeasurement; + target = B53D977A951AFC38B21751B706C1DF83 /* GoogleAppMeasurement */; + targetProxy = BED2A89948352F8B2C01A03D8161E15D /* PBXContainerItemProxy */; + }; + 212AA6564C124386FBBFC864A7BEB652 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseRemoteConfig; + target = 51471EE35F2E9E19E51A74944E5ABB7F /* FirebaseRemoteConfig */; + targetProxy = 0D860AB6942AA508FC7C0073DC2ADDC4 /* PBXContainerItemProxy */; + }; + 292CB2F3C662FED6FC3585461DE2386D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseInstallations; + target = 87803597EB3F20FC46472B85392EC4FD /* FirebaseInstallations */; + targetProxy = F9502B61921E53BF09F3FC0ED83B6CD6 /* PBXContainerItemProxy */; + }; + 398746AAFC91727467533D4A2340E94B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseABTesting; + target = 8F68D031908A0059566798048C48F776 /* FirebaseABTesting */; + targetProxy = B46B8910E9A0F50A4DCEC43C91553F54 /* PBXContainerItemProxy */; + }; + 3AA9B141EBA112CD1FF5E5C2B5583E6F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "nanopb-nanopb_Privacy"; + target = 55522A91938FF505CFEBEAD2DD85AE2D /* nanopb-nanopb_Privacy */; + targetProxy = 810E572A545C1D2DBB14727D74D6E9A3 /* PBXContainerItemProxy */; + }; + 3C59CC503E185A0918BA50B67B4C5871 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = GoogleUtilities; + target = 8D7F5D5DD528D21A72DC87ADA5B12E2D /* GoogleUtilities */; + targetProxy = 949DD4FCC278727B99CC98911ADBE73C /* PBXContainerItemProxy */; + }; + 454B74E7C145638BD704A566F20CBE38 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = nanopb; + target = D2B5E7DCCBBFB32341D857D01211A1A3 /* nanopb */; + targetProxy = 7312CE961258952B14B56854CC250D56 /* PBXContainerItemProxy */; + }; + 4D66D657EB58B5A47C67F6C942C9105F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseCore; + target = 4402AFF83DBDC4DD07E198685FDC2DF2 /* FirebaseCore */; + targetProxy = 97C4F13AA2985BD9D9577598788E1550 /* PBXContainerItemProxy */; + }; + 4E63166588FAF0118840023BDBC17730 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = GoogleAppMeasurement; + target = B53D977A951AFC38B21751B706C1DF83 /* GoogleAppMeasurement */; + targetProxy = E4689F6887BEF6932C075C938C4B2A40 /* PBXContainerItemProxy */; + }; + 5116F6DE93D4F6ED4E17A32D891D8C2B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "PromisesObjC-FBLPromises_Privacy"; + target = 1BFBEDBF7E03729D43C96530EE190825 /* PromisesObjC-FBLPromises_Privacy */; + targetProxy = 32C8AA9B091FEC1C555AC02739E998B0 /* PBXContainerItemProxy */; + }; + 543D1EEA9A05B1B6C086ED430485E911 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseCoreInternal; + target = 25E9E9A17BC3F670357D7385C521E48E /* FirebaseCoreInternal */; + targetProxy = EF2C4220D15ECAD4A347EBDA5C55A94C /* PBXContainerItemProxy */; + }; + 5504F5CCDA2C7DD64917C28D2AAF3C03 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseAnalytics; + target = C49E7A4D59E5C8BE8DE9FB1EFB150185 /* FirebaseAnalytics */; + targetProxy = 0FF7E72E45CB0340F82E7EA377DDCD6A /* PBXContainerItemProxy */; + }; + 5B767F65C5B9D2B2FACEEB985B14027F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "FirebaseInstallations-FirebaseInstallations_Privacy"; + target = 3EB14444A17F9D4F1F697F7C1FF32245 /* FirebaseInstallations-FirebaseInstallations_Privacy */; + targetProxy = 70A4665888585A341356023A8C1D7DF2 /* PBXContainerItemProxy */; + }; + 72C0CE85C8805F049B6C9D871C67409F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseAnalytics; + target = C49E7A4D59E5C8BE8DE9FB1EFB150185 /* FirebaseAnalytics */; + targetProxy = 152F093DB2B8DC111604E8D8B1DD4C04 /* PBXContainerItemProxy */; + }; + 77AC8C3B8927ECDCE3BFE26AE8D7C7CF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseSharedSwift; + target = 94706DD5BBE215339DF893D4434E1084 /* FirebaseSharedSwift */; + targetProxy = 9E8B23BDF693F044427951359FB201EE /* PBXContainerItemProxy */; + }; + 8AFB3BDA0C62390379AC5CEAF8F16F3D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = GoogleUtilities; + target = 8D7F5D5DD528D21A72DC87ADA5B12E2D /* GoogleUtilities */; + targetProxy = B6392751A6B18AC3E9E0523D7A71D924 /* PBXContainerItemProxy */; + }; + 8E4FB243C1A99B992B43A6D63C4E9389 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseABTesting; + target = 8F68D031908A0059566798048C48F776 /* FirebaseABTesting */; + targetProxy = 7F3934CE37EBC805566C0343C5AAD216 /* PBXContainerItemProxy */; + }; + 8F80413E521828C624F263B3595BCEEF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseInstallations; + target = 87803597EB3F20FC46472B85392EC4FD /* FirebaseInstallations */; + targetProxy = BA15A2694F4A203217DEF9FEDF62AB73 /* PBXContainerItemProxy */; + }; + 9897B0527A75C95EFC897451B7B021A3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseCoreInternal; + target = 25E9E9A17BC3F670357D7385C521E48E /* FirebaseCoreInternal */; + targetProxy = 2682C74FFD35473726B30A0FAB0876F7 /* PBXContainerItemProxy */; + }; + 9D484A0E3ECC1AA530FFBDEDE7E588B2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = GoogleUtilities; + target = 8D7F5D5DD528D21A72DC87ADA5B12E2D /* GoogleUtilities */; + targetProxy = FD3770C78E4F8B33613DC7B41452AB5A /* PBXContainerItemProxy */; + }; + AC3A40B2B4AF5C8BA73C61BA5E083D27 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = nanopb; + target = D2B5E7DCCBBFB32341D857D01211A1A3 /* nanopb */; + targetProxy = C6754D2B8C7AE5717C8F82883EE437A2 /* PBXContainerItemProxy */; + }; + B29CC0C48D85F007DFD8964C3AE75476 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "FirebaseRemoteConfig-FirebaseRemoteConfig_Privacy"; + target = C7B621349CB28ED0EBA4C3E416947AB6 /* FirebaseRemoteConfig-FirebaseRemoteConfig_Privacy */; + targetProxy = DEC6BF4C1423886E88E1748C33B55136 /* PBXContainerItemProxy */; + }; + B35593402C1228676DAF3512F5B8473D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseInstallations; + target = 87803597EB3F20FC46472B85392EC4FD /* FirebaseInstallations */; + targetProxy = CC5168CDA80D76FE411928416EA29ECA /* PBXContainerItemProxy */; + }; + B41BA038223454414C96FC1849286958 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = GoogleUtilities; + target = 8D7F5D5DD528D21A72DC87ADA5B12E2D /* GoogleUtilities */; + targetProxy = 9681F3A466FAEA2D485242C889D16173 /* PBXContainerItemProxy */; + }; + B97CEBFB786A4C085DDB78B195F48505 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseRemoteConfigInterop; + target = 328CC04F43300C6CAB81659260A3799D /* FirebaseRemoteConfigInterop */; + targetProxy = B35F65BE3D4B5256D6CFB33DE33929C5 /* PBXContainerItemProxy */; + }; + B99C7270E51C32780354FE49FA303F19 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PromisesObjC; + target = 2BBF7206D7FAC92C82A042A99C4A98F8 /* PromisesObjC */; + targetProxy = 081CF40DBBEB51B3F1D7EC7F8D7BF166 /* PBXContainerItemProxy */; + }; + C864FA594812EE03C711647D9D73650C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = GoogleUtilities; + target = 8D7F5D5DD528D21A72DC87ADA5B12E2D /* GoogleUtilities */; + targetProxy = 21F39E95BA677075F8EB4DCB42CBFD95 /* PBXContainerItemProxy */; + }; + D23980920D5AEB09BDA01D2F83A235F3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseCore; + target = 4402AFF83DBDC4DD07E198685FDC2DF2 /* FirebaseCore */; + targetProxy = BD94AE6BF3081863C9CE8BF10451D85D /* PBXContainerItemProxy */; + }; + D4638B04CBDE95DC733CE2F51C3CD7CF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PromisesObjC; + target = 2BBF7206D7FAC92C82A042A99C4A98F8 /* PromisesObjC */; + targetProxy = 45A1D9A21E0A7BED244127A2709B8AD7 /* PBXContainerItemProxy */; + }; + D75504359000104CC0E433FBA226F6C2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Firebase; + target = 072CEA044D2EF26F03496D5996BBF59F /* Firebase */; + targetProxy = AC4EDC404AE09AF4AD137D1C2C444D91 /* PBXContainerItemProxy */; + }; + D8C174FC418D3C1C67D13A999593D77B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "GoogleUtilities-GoogleUtilities_Privacy"; + target = 5FF1A58DEEC5DB749FCD6C120B97CC82 /* GoogleUtilities-GoogleUtilities_Privacy */; + targetProxy = 7E229544576078E2663FB7115D6BA2D7 /* PBXContainerItemProxy */; + }; + DA47C4956B01D866D4E502CEF646CB46 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseCore; + target = 4402AFF83DBDC4DD07E198685FDC2DF2 /* FirebaseCore */; + targetProxy = CD1003A3DC1C3B4A9FFB55030249A2FA /* PBXContainerItemProxy */; + }; + E10D6AEF53581CD520A644D6451C75E5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "FirebaseCore-FirebaseCore_Privacy"; + target = 1001C16510D946B47CFF8B19DBC0B787 /* FirebaseCore-FirebaseCore_Privacy */; + targetProxy = C07D7085FA2EF9F7F250A2792F7ED609 /* PBXContainerItemProxy */; + }; + E33F565E56A9BB7B8FD75BEF5D8784D7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = GoogleUtilities; + target = 8D7F5D5DD528D21A72DC87ADA5B12E2D /* GoogleUtilities */; + targetProxy = A09177654ADF7396E89786374177223E /* PBXContainerItemProxy */; + }; + E446390ADCAE93489900CA6175BE03ED /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseCore; + target = 4402AFF83DBDC4DD07E198685FDC2DF2 /* FirebaseCore */; + targetProxy = 87432F1B75017FCB8A9E80E9043CB0B4 /* PBXContainerItemProxy */; + }; + E8F455A7FD924AA11068F0ED6FE736DD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PromisesObjC; + target = 2BBF7206D7FAC92C82A042A99C4A98F8 /* PromisesObjC */; + targetProxy = 39D1346C189AA8F3A4B697C6F17A3A71 /* PBXContainerItemProxy */; + }; + EDD5EBFC7407BBE781857A003543C286 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = GoogleUtilities; + target = 8D7F5D5DD528D21A72DC87ADA5B12E2D /* GoogleUtilities */; + targetProxy = A0E8D0C6AF9DAA7396F1CFF4CD2B5DBB /* PBXContainerItemProxy */; + }; + F1E2523FB7E26C5383CD1976A5E4C7C0 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FirebaseCore; + target = 4402AFF83DBDC4DD07E198685FDC2DF2 /* FirebaseCore */; + targetProxy = B2DE9CCD596806BBAAFE458D5C9DBF80 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin XCBuildConfiguration section */ - 4BC7450F9457737EE3E637BA155B56F7 /* Debug */ = { + 04B9A4CC6A60FE8C0865617BAD99BCC2 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B3A907F7A54CD12D5B532362DD53ED4F /* Pods-TallPaper.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-TallPaper/Pods-TallPaper-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-TallPaper/Pods-TallPaper.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 05C6E7A558764E8AE1F7B218FC1DA1D6 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 05A0C6A166AB6A227A42FE62B5491689 /* PromisesObjC.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/PromisesObjC/PromisesObjC-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/PromisesObjC/PromisesObjC.modulemap"; + PRODUCT_MODULE_NAME = FBLPromises; + PRODUCT_NAME = FBLPromises; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 31A4AF50B74155FED1A16300CECAB85A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D45EDC5CDA793CACEAC775C09DCD8147 /* GoogleUtilities.release.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/GoogleUtilities"; + IBSC_MODULE = GoogleUtilities; + INFOPLIST_FILE = "Target Support Files/GoogleUtilities/ResourceBundle-GoogleUtilities_Privacy-GoogleUtilities-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = GoogleUtilities_Privacy; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 3319D00617F32B899503079D27DA5476 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B16BBE23543FAD12BB2BD35971F6DA1B /* Pods-TallPaper.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-TallPaper/Pods-TallPaper-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-TallPaper/Pods-TallPaper.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 39658B012E5129BFDA98DDE555231313 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = FB9620C9FFC61A502AFB127D5149EDCC /* FirebaseCoreInternal.release.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/FirebaseCoreInternal"; + IBSC_MODULE = FirebaseCoreInternal; + INFOPLIST_FILE = "Target Support Files/FirebaseCoreInternal/ResourceBundle-FirebaseCoreInternal_Privacy-FirebaseCoreInternal-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = FirebaseCoreInternal_Privacy; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 3CA7A11A608E34D02DE31273D2E51C0D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DCB1DF4DB075689625A34E2FF8A84C89 /* GoogleAppMeasurement.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_OBJC_WEAK = NO; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 3EB8C7DB159361702E691EE1255BFA2E /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E2252E0AFE170D46891542C10E59CEB0 /* FirebaseRemoteConfigInterop.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop.modulemap"; + PRODUCT_MODULE_NAME = FirebaseRemoteConfigInterop; + PRODUCT_NAME = FirebaseRemoteConfigInterop; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.3; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 3F91A4883AB22CD558443E212F4F2D3C /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 59B5796B0A4C9A227C8B300E065EDA13 /* FirebaseRemoteConfig.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig.modulemap"; + PRODUCT_MODULE_NAME = FirebaseRemoteConfig; + PRODUCT_NAME = FirebaseRemoteConfig; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.3; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 49679AFC5468C54E088385CCCF4172CA /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 499ADF1B3B37AD57C1A48C8AADD41D0B /* FirebaseCore.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/FirebaseCore/FirebaseCore-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/FirebaseCore/FirebaseCore.modulemap"; + PRODUCT_MODULE_NAME = FirebaseCore; + PRODUCT_NAME = FirebaseCore; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.3; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 4C4D110E4892E702A06A4FD202F5BEF2 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6DF900A74765E9831F99A4819F5414F7 /* FirebaseABTesting.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/FirebaseABTesting/FirebaseABTesting-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/FirebaseABTesting/FirebaseABTesting.modulemap"; + PRODUCT_MODULE_NAME = FirebaseABTesting; + PRODUCT_NAME = FirebaseABTesting; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.3; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 4ECB2F4439B8F80BD93EFE2CBD715105 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 088F19A523410C4D1489640C952BFF4E /* nanopb.release.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/nanopb"; + IBSC_MODULE = nanopb; + INFOPLIST_FILE = "Target Support Files/nanopb/ResourceBundle-nanopb_Privacy-nanopb-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = nanopb_Privacy; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 55AD6B91051EE6800B2C5B803DA760A2 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5F76D90C2948429C9CE7E3475DE0B924 /* FirebaseInstallations.debug.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/FirebaseInstallations"; + IBSC_MODULE = FirebaseInstallations; + INFOPLIST_FILE = "Target Support Files/FirebaseInstallations/ResourceBundle-FirebaseInstallations_Privacy-FirebaseInstallations-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = FirebaseInstallations_Privacy; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + 5BA1186032D2981C9B7A0D45FEF5317D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6D9A00D587445BCE41F470B03CFAB326 /* Firebase.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_OBJC_WEAK = NO; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5C3F8C16DA197B2FA3582E819525AC0F /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E90CD2DC1A9C50D83F61A8C480CBC447 /* FirebaseAnalytics.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_OBJC_WEAK = NO; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 65A3BFF4E685B0E795421D6910338B3D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2834B6BD9246A467EF26B83F6D9E3154 /* nanopb.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/nanopb/nanopb-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/nanopb/nanopb-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/nanopb/nanopb.modulemap"; + PRODUCT_MODULE_NAME = nanopb; + PRODUCT_NAME = nanopb; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 70FB0BA0DC10623690517C73A6FC8549 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = FF6FA42898B7D5C4D981D2EBA2C47BFB /* FirebaseCore.release.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/FirebaseCore"; + IBSC_MODULE = FirebaseCore; + INFOPLIST_FILE = "Target Support Files/FirebaseCore/ResourceBundle-FirebaseCore_Privacy-FirebaseCore-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = FirebaseCore_Privacy; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 732D32DF437FBC31D63A0ADA21588214 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 209B54CF7D994B06541AB454EE9CAA34 /* FirebaseABTesting.debug.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/FirebaseABTesting"; + IBSC_MODULE = FirebaseABTesting; + INFOPLIST_FILE = "Target Support Files/FirebaseABTesting/ResourceBundle-FirebaseABTesting_Privacy-FirebaseABTesting-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = FirebaseABTesting_Privacy; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + 760C7E3CDA5824E3536941FE1240F684 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9B3E3D3170028F2395F08A6CF1F5D821 /* FirebaseSharedSwift.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift.modulemap"; + PRODUCT_MODULE_NAME = FirebaseSharedSwift; + PRODUCT_NAME = FirebaseSharedSwift; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.3; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 78D506A4D5A317F018F5BA5F5EA7E6E6 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DAB1A6B8B900533E013246FF9E1B15FF /* FirebaseRemoteConfigInterop.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop.modulemap"; + PRODUCT_MODULE_NAME = FirebaseRemoteConfigInterop; + PRODUCT_NAME = FirebaseRemoteConfigInterop; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.3; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 864EEFCD74DF054D61738F0E5E360DE4 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 209B54CF7D994B06541AB454EE9CAA34 /* FirebaseABTesting.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/FirebaseABTesting/FirebaseABTesting-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/FirebaseABTesting/FirebaseABTesting.modulemap"; + PRODUCT_MODULE_NAME = FirebaseABTesting; + PRODUCT_NAME = FirebaseABTesting; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.3; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 8DE5143C03248BB6CD542DE3963D6F3A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -230,7 +4118,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -243,12 +4131,27 @@ }; name = Debug; }; - 5A2FD7EB3AEE0F000B95ACF158A0B552 /* Release */ = { + 8E719F1F08C4A795BBB6A0BFB80808D1 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A3FAA9E33EBDA1A67760BF69587CAB2B /* Pods-HD wallpaper.release.xcconfig */; + baseConfigurationReference = 499ADF1B3B37AD57C1A48C8AADD41D0B /* FirebaseCore.debug.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/FirebaseCore"; + IBSC_MODULE = FirebaseCore; + INFOPLIST_FILE = "Target Support Files/FirebaseCore/ResourceBundle-FirebaseCore_Privacy-FirebaseCore-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = FirebaseCore_Privacy; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + 92A837D6A2A8E692BCEE560455AE0FEA /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 088F19A523410C4D1489640C952BFF4E /* nanopb.release.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -257,23 +4160,21 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper-Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/nanopb/nanopb-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/nanopb/nanopb-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + MODULEMAP_FILE = "Target Support Files/nanopb/nanopb.modulemap"; + PRODUCT_MODULE_NAME = nanopb; + PRODUCT_NAME = nanopb; SDKROOT = iphoneos; SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -281,7 +4182,7 @@ }; name = Release; }; - 8B5A46FF8D3C1289CDEE3BAFACABCD2A /* Release */ = { + 9E406C6AAF85E580207CD97B0044DEAB /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -331,7 +4232,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -343,11 +4244,93 @@ }; name = Release; }; - D678F87B1CC0497096AED3515E838341 /* Debug */ = { + 9E63D666ED54521311F5B5C09EB95B4D /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 625A821940DC5522089C482A22E4EDD0 /* Pods-HD wallpaper.debug.xcconfig */; + baseConfigurationReference = 5BCF6CF17B85CFEE227E0466CB41E82D /* FirebaseAnalytics.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_OBJC_WEAK = NO; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 9FA96C4AEF038CD49167A6579C50E67B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6DF900A74765E9831F99A4819F5414F7 /* FirebaseABTesting.release.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/FirebaseABTesting"; + IBSC_MODULE = FirebaseABTesting; + INFOPLIST_FILE = "Target Support Files/FirebaseABTesting/ResourceBundle-FirebaseABTesting_Privacy-FirebaseABTesting-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = FirebaseABTesting_Privacy; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + AADFE565D33B0E774C0A9921DFFF80F0 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 13EB0519F4816AC5CD163BF70502E536 /* GoogleAppMeasurement.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_OBJC_WEAK = NO; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + AB3DCB20D56656C753CB7F4949F41483 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C267AF2E92505F6750EAA8C33424B4F6 /* PromisesObjC.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/PromisesObjC/PromisesObjC-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/PromisesObjC/PromisesObjC.modulemap"; + PRODUCT_MODULE_NAME = FBLPromises; + PRODUCT_NAME = FBLPromises; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + B55A70342E90060E1DF20619CA86FE4D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5F76D90C2948429C9CE7E3475DE0B924 /* FirebaseInstallations.debug.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -357,46 +4340,661 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper-Info.plist"; + INFOPLIST_FILE = "Target Support Files/FirebaseInstallations/FirebaseInstallations-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + MODULEMAP_FILE = "Target Support Files/FirebaseInstallations/FirebaseInstallations.modulemap"; + PRODUCT_MODULE_NAME = FirebaseInstallations; + PRODUCT_NAME = FirebaseInstallations; SDKROOT = iphoneos; SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.3; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; + B906626429B5C456DAA73C397217AAD5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 370761029B7BF9DB774682C5248D31FA /* GoogleUtilities.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/GoogleUtilities/GoogleUtilities-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/GoogleUtilities/GoogleUtilities.modulemap"; + PRODUCT_MODULE_NAME = GoogleUtilities; + PRODUCT_NAME = GoogleUtilities; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + BBA9E06AF54C8698690B29E5055C2647 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C267AF2E92505F6750EAA8C33424B4F6 /* PromisesObjC.debug.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/PromisesObjC"; + IBSC_MODULE = FBLPromises; + INFOPLIST_FILE = "Target Support Files/PromisesObjC/ResourceBundle-FBLPromises_Privacy-PromisesObjC-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = FBLPromises_Privacy; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + C1FFDBD94F162B8E42B45567B5CA5CA4 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = ABEE4483D32A73C25A946778F7E52969 /* Firebase.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_OBJC_WEAK = NO; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + C7F66ECB262AB5578208AEBE9F5640FF /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = FB9620C9FFC61A502AFB127D5149EDCC /* FirebaseCoreInternal.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal.modulemap"; + PRODUCT_MODULE_NAME = FirebaseCoreInternal; + PRODUCT_NAME = FirebaseCoreInternal; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.3; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + D4C0D05771C6E51D4B25D0EDE6094913 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = FDA3280B4DFDC7BC8325D81A6E655FB7 /* FirebaseRemoteConfig.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig.modulemap"; + PRODUCT_MODULE_NAME = FirebaseRemoteConfig; + PRODUCT_NAME = FirebaseRemoteConfig; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.3; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + D7539CEAAF158FFA98DE85554ABE948A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 117FB7DD9722C3296E517F8DA59AE404 /* FirebaseCoreInternal.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal.modulemap"; + PRODUCT_MODULE_NAME = FirebaseCoreInternal; + PRODUCT_NAME = FirebaseCoreInternal; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.3; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + DF2516F816F651753C2E4565468B1301 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2834B6BD9246A467EF26B83F6D9E3154 /* nanopb.debug.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/nanopb"; + IBSC_MODULE = nanopb; + INFOPLIST_FILE = "Target Support Files/nanopb/ResourceBundle-nanopb_Privacy-nanopb-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = nanopb_Privacy; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + DF4C2B6735B8370ADAD9120BB609B750 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 117FB7DD9722C3296E517F8DA59AE404 /* FirebaseCoreInternal.debug.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/FirebaseCoreInternal"; + IBSC_MODULE = FirebaseCoreInternal; + INFOPLIST_FILE = "Target Support Files/FirebaseCoreInternal/ResourceBundle-FirebaseCoreInternal_Privacy-FirebaseCoreInternal-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = FirebaseCoreInternal_Privacy; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + E1D8CA23D321853BC9B47E17378BF02C /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 59B5796B0A4C9A227C8B300E065EDA13 /* FirebaseRemoteConfig.release.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/FirebaseRemoteConfig"; + IBSC_MODULE = FirebaseRemoteConfig; + INFOPLIST_FILE = "Target Support Files/FirebaseRemoteConfig/ResourceBundle-FirebaseRemoteConfig_Privacy-FirebaseRemoteConfig-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = FirebaseRemoteConfig_Privacy; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + E2468A9EE981007D34A3E52C4C30CD40 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D45EDC5CDA793CACEAC775C09DCD8147 /* GoogleUtilities.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/GoogleUtilities/GoogleUtilities-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/GoogleUtilities/GoogleUtilities.modulemap"; + PRODUCT_MODULE_NAME = GoogleUtilities; + PRODUCT_NAME = GoogleUtilities; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + F01207357BF37E616D37FA8E51FF4332 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 05A0C6A166AB6A227A42FE62B5491689 /* PromisesObjC.release.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/PromisesObjC"; + IBSC_MODULE = FBLPromises; + INFOPLIST_FILE = "Target Support Files/PromisesObjC/ResourceBundle-FBLPromises_Privacy-PromisesObjC-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = FBLPromises_Privacy; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + F019DC5A4BAA91B94942619A22CEDEEF /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = FF6FA42898B7D5C4D981D2EBA2C47BFB /* FirebaseCore.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/FirebaseCore/FirebaseCore-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/FirebaseCore/FirebaseCore.modulemap"; + PRODUCT_MODULE_NAME = FirebaseCore; + PRODUCT_NAME = FirebaseCore; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.3; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + F27017493CBEB99BC7C7CC698D4CC305 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = FDA3280B4DFDC7BC8325D81A6E655FB7 /* FirebaseRemoteConfig.debug.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/FirebaseRemoteConfig"; + IBSC_MODULE = FirebaseRemoteConfig; + INFOPLIST_FILE = "Target Support Files/FirebaseRemoteConfig/ResourceBundle-FirebaseRemoteConfig_Privacy-FirebaseRemoteConfig-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = FirebaseRemoteConfig_Privacy; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + F44843D3C874E2B04B574CF31A05C881 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 500BF231A850BA165F5C4776F563AF37 /* FirebaseInstallations.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/FirebaseInstallations/FirebaseInstallations-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/FirebaseInstallations/FirebaseInstallations.modulemap"; + PRODUCT_MODULE_NAME = FirebaseInstallations; + PRODUCT_NAME = FirebaseInstallations; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.3; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + FA63A3482F1AB577A1550002D3A33866 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 500BF231A850BA165F5C4776F563AF37 /* FirebaseInstallations.release.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/FirebaseInstallations"; + IBSC_MODULE = FirebaseInstallations; + INFOPLIST_FILE = "Target Support Files/FirebaseInstallations/ResourceBundle-FirebaseInstallations_Privacy-FirebaseInstallations-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = FirebaseInstallations_Privacy; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + FC811A6E6FAF9F5FC6B24FA0B62EAF26 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 370761029B7BF9DB774682C5248D31FA /* GoogleUtilities.debug.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/GoogleUtilities"; + IBSC_MODULE = GoogleUtilities; + INFOPLIST_FILE = "Target Support Files/GoogleUtilities/ResourceBundle-GoogleUtilities_Privacy-GoogleUtilities-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = GoogleUtilities_Privacy; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + FD6953AD6A41AC7AF2BD7DE6430321D1 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C543619250755351CE882118D75DB383 /* FirebaseSharedSwift.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift.modulemap"; + PRODUCT_MODULE_NAME = FirebaseSharedSwift; + PRODUCT_NAME = FirebaseSharedSwift; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.3; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { + 13C0C3122A77F8F0F31DBB4A148C5E23 /* Build configuration list for PBXNativeTarget "PromisesObjC" */ = { isa = XCConfigurationList; buildConfigurations = ( - 4BC7450F9457737EE3E637BA155B56F7 /* Debug */, - 8B5A46FF8D3C1289CDEE3BAFACABCD2A /* Release */, + AB3DCB20D56656C753CB7F4949F41483 /* Debug */, + 05C6E7A558764E8AE1F7B218FC1DA1D6 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - BDB3D85B698A0BE87C7F3D391EC964B8 /* Build configuration list for PBXNativeTarget "Pods-HD wallpaper" */ = { + 1BF7BF9AC1D4A689E82B20BAEBB160AA /* Build configuration list for PBXNativeTarget "FirebaseRemoteConfig" */ = { isa = XCConfigurationList; buildConfigurations = ( - D678F87B1CC0497096AED3515E838341 /* Debug */, - 5A2FD7EB3AEE0F000B95ACF158A0B552 /* Release */, + D4C0D05771C6E51D4B25D0EDE6094913 /* Debug */, + 3F91A4883AB22CD558443E212F4F2D3C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 22A01D8C10750D945F73A7EDD1351068 /* Build configuration list for PBXNativeTarget "GoogleUtilities-GoogleUtilities_Privacy" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FC811A6E6FAF9F5FC6B24FA0B62EAF26 /* Debug */, + 31A4AF50B74155FED1A16300CECAB85A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2420DBFA283C8D72987D948D720026AB /* Build configuration list for PBXNativeTarget "FirebaseCoreInternal-FirebaseCoreInternal_Privacy" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DF4C2B6735B8370ADAD9120BB609B750 /* Debug */, + 39658B012E5129BFDA98DDE555231313 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3C703D607C67D3E76C417D44E6F824DF /* Build configuration list for PBXNativeTarget "FirebaseABTesting" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 864EEFCD74DF054D61738F0E5E360DE4 /* Debug */, + 4C4D110E4892E702A06A4FD202F5BEF2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 45F8006A959C88B6482BAFA1C0189E98 /* Build configuration list for PBXAggregateTarget "FirebaseAnalytics" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9E63D666ED54521311F5B5C09EB95B4D /* Debug */, + 5C3F8C16DA197B2FA3582E819525AC0F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 47D214A835E066E643F53F997A46D018 /* Build configuration list for PBXNativeTarget "nanopb-nanopb_Privacy" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DF2516F816F651753C2E4565468B1301 /* Debug */, + 4ECB2F4439B8F80BD93EFE2CBD715105 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8DE5143C03248BB6CD542DE3963D6F3A /* Debug */, + 9E406C6AAF85E580207CD97B0044DEAB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 59C8B1E1A6E8169BF54604D7DC38D8DF /* Build configuration list for PBXNativeTarget "FirebaseCoreInternal" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D7539CEAAF158FFA98DE85554ABE948A /* Debug */, + C7F66ECB262AB5578208AEBE9F5640FF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6C57E918FF6EB5AC948A7B455A145C69 /* Build configuration list for PBXNativeTarget "GoogleUtilities" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B906626429B5C456DAA73C397217AAD5 /* Debug */, + E2468A9EE981007D34A3E52C4C30CD40 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 84E25780A03A38697B02AA5F3203B58D /* Build configuration list for PBXNativeTarget "FirebaseRemoteConfig-FirebaseRemoteConfig_Privacy" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F27017493CBEB99BC7C7CC698D4CC305 /* Debug */, + E1D8CA23D321853BC9B47E17378BF02C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 899D32CA20311051D748DCDA67B8F798 /* Build configuration list for PBXAggregateTarget "GoogleAppMeasurement" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3CA7A11A608E34D02DE31273D2E51C0D /* Debug */, + AADFE565D33B0E774C0A9921DFFF80F0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A3715D5CAC4B91670C46A343F74E3561 /* Build configuration list for PBXNativeTarget "Pods-TallPaper" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 04B9A4CC6A60FE8C0865617BAD99BCC2 /* Debug */, + 3319D00617F32B899503079D27DA5476 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C25B2784896EA6627D7C7E65609387B6 /* Build configuration list for PBXNativeTarget "FirebaseRemoteConfigInterop" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 78D506A4D5A317F018F5BA5F5EA7E6E6 /* Debug */, + 3EB8C7DB159361702E691EE1255BFA2E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C3E2F5B411EEC3A2309EF73E27DA5817 /* Build configuration list for PBXNativeTarget "FirebaseSharedSwift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 760C7E3CDA5824E3536941FE1240F684 /* Debug */, + FD6953AD6A41AC7AF2BD7DE6430321D1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C6E4A38F24896DABC7A364E6DB2C7A7F /* Build configuration list for PBXAggregateTarget "Firebase" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C1FFDBD94F162B8E42B45567B5CA5CA4 /* Debug */, + 5BA1186032D2981C9B7A0D45FEF5317D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C95A64E102B99E1D38DF86F0DC4BC4DF /* Build configuration list for PBXNativeTarget "FirebaseInstallations-FirebaseInstallations_Privacy" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 55AD6B91051EE6800B2C5B803DA760A2 /* Debug */, + FA63A3482F1AB577A1550002D3A33866 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DB96948B15DF1A29204ECD6FBB3FDAC8 /* Build configuration list for PBXNativeTarget "FirebaseCore-FirebaseCore_Privacy" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8E719F1F08C4A795BBB6A0BFB80808D1 /* Debug */, + 70FB0BA0DC10623690517C73A6FC8549 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DF54F4F48D5FB43AE838F00C69562C01 /* Build configuration list for PBXNativeTarget "PromisesObjC-FBLPromises_Privacy" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BBA9E06AF54C8698690B29E5055C2647 /* Debug */, + F01207357BF37E616D37FA8E51FF4332 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E0021F85E3BC4A1C1514ED20731C442E /* Build configuration list for PBXNativeTarget "FirebaseABTesting-FirebaseABTesting_Privacy" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 732D32DF437FBC31D63A0ADA21588214 /* Debug */, + 9FA96C4AEF038CD49167A6579C50E67B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + EAEEC2C8228C14795FB4304F564F92EA /* Build configuration list for PBXNativeTarget "FirebaseInstallations" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B55A70342E90060E1DF20619CA86FE4D /* Debug */, + F44843D3C874E2B04B574CF31A05C881 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + EE19EA06C95C29E2AD45DA4555E9EEC5 /* Build configuration list for PBXNativeTarget "nanopb" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 65A3BFF4E685B0E795421D6910338B3D /* Debug */, + 92A837D6A2A8E692BCEE560455AE0FEA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F29B3F5EBC81A1712BBEE1D60ADF3E89 /* Build configuration list for PBXNativeTarget "FirebaseCore" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 49679AFC5468C54E088385CCCF4172CA /* Debug */, + F019DC5A4BAA91B94942619A22CEDEEF /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/Pods-HD wallpaper.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/Firebase.xcscheme similarity index 90% rename from Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/Pods-HD wallpaper.xcscheme rename to Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/Firebase.xcscheme index 9b5283e..8b3c425 100644 --- a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/Pods-HD wallpaper.xcscheme +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/Firebase.xcscheme @@ -14,9 +14,9 @@ buildForAnalyzing = "YES"> diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseABTesting-FirebaseABTesting_Privacy.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseABTesting-FirebaseABTesting_Privacy.xcscheme new file mode 100644 index 0000000..78755fa --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseABTesting-FirebaseABTesting_Privacy.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseABTesting.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseABTesting.xcscheme new file mode 100644 index 0000000..12e2081 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseABTesting.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseAnalytics.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseAnalytics.xcscheme new file mode 100644 index 0000000..4ef6a07 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseAnalytics.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseCore-FirebaseCore_Privacy.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseCore-FirebaseCore_Privacy.xcscheme new file mode 100644 index 0000000..15f9320 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseCore-FirebaseCore_Privacy.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseCore.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseCore.xcscheme new file mode 100644 index 0000000..a36829f --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseCore.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseCoreInternal-FirebaseCoreInternal_Privacy.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseCoreInternal-FirebaseCoreInternal_Privacy.xcscheme new file mode 100644 index 0000000..cf35a72 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseCoreInternal-FirebaseCoreInternal_Privacy.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseCoreInternal.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseCoreInternal.xcscheme new file mode 100644 index 0000000..3f22e05 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseCoreInternal.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseInstallations-FirebaseInstallations_Privacy.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseInstallations-FirebaseInstallations_Privacy.xcscheme new file mode 100644 index 0000000..abb8f0c --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseInstallations-FirebaseInstallations_Privacy.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseInstallations.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseInstallations.xcscheme new file mode 100644 index 0000000..81cf4f5 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseInstallations.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseRemoteConfig-FirebaseRemoteConfig_Privacy.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseRemoteConfig-FirebaseRemoteConfig_Privacy.xcscheme new file mode 100644 index 0000000..82bb77d --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseRemoteConfig-FirebaseRemoteConfig_Privacy.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseRemoteConfig.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseRemoteConfig.xcscheme new file mode 100644 index 0000000..8ba2d5f --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseRemoteConfig.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseRemoteConfigInterop.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseRemoteConfigInterop.xcscheme new file mode 100644 index 0000000..e1b41a8 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseRemoteConfigInterop.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseSharedSwift.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseSharedSwift.xcscheme new file mode 100644 index 0000000..c6adb45 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/FirebaseSharedSwift.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/GoogleAppMeasurement.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/GoogleAppMeasurement.xcscheme new file mode 100644 index 0000000..cf7db98 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/GoogleAppMeasurement.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/GoogleUtilities-GoogleUtilities_Privacy.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/GoogleUtilities-GoogleUtilities_Privacy.xcscheme new file mode 100644 index 0000000..e61fe15 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/GoogleUtilities-GoogleUtilities_Privacy.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/GoogleUtilities.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/GoogleUtilities.xcscheme new file mode 100644 index 0000000..4909ee5 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/GoogleUtilities.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/Pods-TallPaper.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/Pods-TallPaper.xcscheme new file mode 100644 index 0000000..d6556b4 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/Pods-TallPaper.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/PromisesObjC-FBLPromises_Privacy.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/PromisesObjC-FBLPromises_Privacy.xcscheme new file mode 100644 index 0000000..0d034a4 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/PromisesObjC-FBLPromises_Privacy.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/PromisesObjC.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/PromisesObjC.xcscheme new file mode 100644 index 0000000..91d9b1a --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/PromisesObjC.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/nanopb-nanopb_Privacy.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/nanopb-nanopb_Privacy.xcscheme new file mode 100644 index 0000000..373f771 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/nanopb-nanopb_Privacy.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/nanopb.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/nanopb.xcscheme new file mode 100644 index 0000000..6de6831 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/nanopb.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/xcschememanagement.plist b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/xcschememanagement.plist index 8199ca2..123ed26 100644 --- a/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Pods/Pods.xcodeproj/xcuserdata/aaa.xcuserdatad/xcschemes/xcschememanagement.plist @@ -4,12 +4,115 @@ SchemeUserState - Pods-HD wallpaper.xcscheme + Firebase.xcscheme + + isShown + + + FirebaseABTesting-FirebaseABTesting_Privacy.xcscheme + + isShown + + + FirebaseABTesting.xcscheme + + isShown + + + FirebaseAnalytics.xcscheme + + isShown + + + FirebaseCore-FirebaseCore_Privacy.xcscheme + + isShown + + + FirebaseCore.xcscheme + + isShown + + + FirebaseCoreInternal-FirebaseCoreInternal_Privacy.xcscheme + + isShown + + + FirebaseCoreInternal.xcscheme + + isShown + + + FirebaseInstallations-FirebaseInstallations_Privacy.xcscheme + + isShown + + + FirebaseInstallations.xcscheme + + isShown + + + FirebaseRemoteConfig-FirebaseRemoteConfig_Privacy.xcscheme + + isShown + + + FirebaseRemoteConfig.xcscheme + + isShown + + + FirebaseRemoteConfigInterop.xcscheme + + isShown + + + FirebaseSharedSwift.xcscheme + + isShown + + + GoogleAppMeasurement.xcscheme + + isShown + + + GoogleUtilities-GoogleUtilities_Privacy.xcscheme + + isShown + + + GoogleUtilities.xcscheme + + isShown + + + Pods-TallPaper.xcscheme + + isShown + + + PromisesObjC-FBLPromises_Privacy.xcscheme + + isShown + + + PromisesObjC.xcscheme + + isShown + + + nanopb-nanopb_Privacy.xcscheme + + isShown + + + nanopb.xcscheme isShown - orderHint - 0 SuppressBuildableAutocreation diff --git a/Pods/PromisesObjC/LICENSE b/Pods/PromisesObjC/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/Pods/PromisesObjC/LICENSE @@ -0,0 +1,202 @@ + + 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. diff --git a/Pods/PromisesObjC/README.md b/Pods/PromisesObjC/README.md new file mode 100644 index 0000000..e0e65b7 --- /dev/null +++ b/Pods/PromisesObjC/README.md @@ -0,0 +1,60 @@ +[![Apache +License](https://img.shields.io/github/license/google/promises.svg)](LICENSE) +[![Travis](https://api.travis-ci.org/google/promises.svg?branch=master)](https://travis-ci.org/google/promises) +[![Gitter Chat](https://badges.gitter.im/google/promises.svg)](https://gitter.im/google/promises) + +![Platforms](https://img.shields.io/badge/platforms-macOS%20%7C%20iOS%20%7C%20tvOS%20%7C%20watchOS-blue.svg?longCache=true&style=flat) +![Languages](https://img.shields.io/badge/languages-Swift%20%7C%20ObjC-orange.svg?longCache=true&style=flat) +![Package Managers](https://img.shields.io/badge/supports-Bazel%20%7C%20SwiftPM%20%7C%20CocoaPods%20%7C%20Carthage-yellow.svg?longCache=true&style=flat) + +# Promises + +Promises is a modern framework that provides a synchronization construct for +Objective-C and Swift to facilitate writing asynchronous code. + +* [Introduction](g3doc/index.md) + * [The problem with async + code](g3doc/index.md#the-problem-with-async-code) + * [Promises to the rescue](g3doc/index.md#promises-to-the-rescue) + * [What is a promise?](g3doc/index.md#what-is-a-promise) +* [Framework](g3doc/index.md#framework) + * [Features](g3doc/index.md#features) + * [Benchmark](g3doc/index.md#benchmark) +* [Getting started](g3doc/index.md#getting-started) + * [Add dependency](g3doc/index.md#add-dependency) + * [Import](g3doc/index.md#import) + * [Adopt](g3doc/index.md#adopt) +* [Basics](g3doc/index.md#basics) + * [Creating promises](g3doc/index.md#creating-promises) + * [Async](g3doc/index.md#async) + * [Do](g3doc/index.md#do) + * [Pending](g3doc/index.md#pending) + * [Resolved](g3doc/index.md#create-a-resolved-promise) + * [Observing fulfillment](g3doc/index.md#observing-fulfillment) + * [Then](g3doc/index.md#then) + * [Observing rejection](g3doc/index.md#observing-rejection) + * [Catch](g3doc/index.md#catch) +* [Extensions](g3doc/index.md#extensions) + * [All](g3doc/index.md#all) + * [Always](g3doc/index.md#always) + * [Any](g3doc/index.md#any) + * [AwaitPromise](g3doc/index.md#awaitpromise) + * [Delay](g3doc/index.md#delay) + * [Race](g3doc/index.md#race) + * [Recover](g3doc/index.md#recover) + * [Reduce](g3doc/index.md#reduce) + * [Retry](g3doc/index.md#retry) + * [Timeout](g3doc/index.md#timeout) + * [Validate](g3doc/index.md#validate) + * [Wrap](g3doc/index.md#wrap) +* [Advanced topics](g3doc/index.md#advanced-topics) + * [Default dispatch queue](g3doc/index.md#default-dispatch-queue) + * [Ownership and retain + cycles](g3doc/index.md#ownership-and-retain-cycles) + * [Testing](g3doc/index.md#testing) + * [Objective-C <-> Swift + interoperability](g3doc/index.md#objective-c---swift-interoperability) + * [Dot-syntax in Objective-C](g3doc/index.md#dot-syntax-in-objective-c) +* [Anti-patterns](g3doc/index.md#anti-patterns) + * [Broken chain](g3doc/index.md#broken-chain) + * [Nested promises](g3doc/index.md#nested-promises) diff --git a/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+All.m b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+All.m new file mode 100644 index 0000000..a9c7feb --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+All.m @@ -0,0 +1,89 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise+All.h" + +#import "FBLPromise+Async.h" +#import "FBLPromisePrivate.h" + +@implementation FBLPromise (AllAdditions) + ++ (FBLPromise *)all:(NSArray *)promises { + return [self onQueue:self.defaultDispatchQueue all:promises]; +} + ++ (FBLPromise *)onQueue:(dispatch_queue_t)queue all:(NSArray *)allPromises { + NSParameterAssert(queue); + NSParameterAssert(allPromises); + + if (allPromises.count == 0) { + return [[self alloc] initWithResolution:@[]]; + } + NSMutableArray *promises = [allPromises mutableCopy]; + return [self + onQueue:queue + async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) { + for (NSUInteger i = 0; i < promises.count; ++i) { + id promise = promises[i]; + if ([promise isKindOfClass:self]) { + continue; + } else if ([promise isKindOfClass:[NSError class]]) { + reject(promise); + return; + } else { + [promises replaceObjectAtIndex:i + withObject:[[self alloc] initWithResolution:promise]]; + } + } + for (FBLPromise *promise in promises) { + [promise observeOnQueue:queue + fulfill:^(id __unused _) { + // Wait until all are fulfilled. + for (FBLPromise *promise in promises) { + if (!promise.isFulfilled) { + return; + } + } + // If called multiple times, only the first one affects the result. + fulfill([promises valueForKey:NSStringFromSelector(@selector(value))]); + } + reject:^(NSError *error) { + reject(error); + }]; + } + }]; +} + +@end + +@implementation FBLPromise (DotSyntax_AllAdditions) + ++ (FBLPromise * (^)(NSArray *))all { + return ^(NSArray *promises) { + return [self all:promises]; + }; +} + ++ (FBLPromise * (^)(dispatch_queue_t, NSArray *))allOn { + return ^(dispatch_queue_t queue, NSArray *promises) { + return [self onQueue:queue all:promises]; + }; +} + +@end + +/** Stub used to force the linker to include the categories in this file. */ +void FBLIncludeAllCategory(void) {} diff --git a/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Always.m b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Always.m new file mode 100644 index 0000000..c4e9776 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Always.m @@ -0,0 +1,61 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise+Always.h" + +#import "FBLPromisePrivate.h" + +@implementation FBLPromise (AlwaysAdditions) + +- (FBLPromise *)always:(FBLPromiseAlwaysWorkBlock)work { + return [self onQueue:FBLPromise.defaultDispatchQueue always:work]; +} + +- (FBLPromise *)onQueue:(dispatch_queue_t)queue always:(FBLPromiseAlwaysWorkBlock)work { + NSParameterAssert(queue); + NSParameterAssert(work); + + return [self chainOnQueue:queue + chainedFulfill:^id(id value) { + work(); + return value; + } + chainedReject:^id(NSError *error) { + work(); + return error; + }]; +} + +@end + +@implementation FBLPromise (DotSyntax_AlwaysAdditions) + +- (FBLPromise * (^)(FBLPromiseAlwaysWorkBlock))always { + return ^(FBLPromiseAlwaysWorkBlock work) { + return [self always:work]; + }; +} + +- (FBLPromise * (^)(dispatch_queue_t, FBLPromiseAlwaysWorkBlock))alwaysOn { + return ^(dispatch_queue_t queue, FBLPromiseAlwaysWorkBlock work) { + return [self onQueue:queue always:work]; + }; +} + +@end + +/** Stub used to force the linker to include the categories in this file. */ +void FBLIncludeAlwaysCategory(void) {} diff --git a/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Any.m b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Any.m new file mode 100644 index 0000000..8454c34 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Any.m @@ -0,0 +1,115 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise+Any.h" + +#import "FBLPromise+Async.h" +#import "FBLPromisePrivate.h" + +static NSArray *FBLPromiseCombineValuesAndErrors(NSArray *promises) { + NSMutableArray *combinedValuesAndErrors = [[NSMutableArray alloc] init]; + for (FBLPromise *promise in promises) { + if (promise.isFulfilled) { + [combinedValuesAndErrors addObject:promise.value ?: [NSNull null]]; + continue; + } + if (promise.isRejected) { + [combinedValuesAndErrors addObject:promise.error]; + continue; + } + assert(!promise.isPending); + }; + return combinedValuesAndErrors; +} + +@implementation FBLPromise (AnyAdditions) + ++ (FBLPromise *)any:(NSArray *)promises { + return [self onQueue:FBLPromise.defaultDispatchQueue any:promises]; +} + ++ (FBLPromise *)onQueue:(dispatch_queue_t)queue any:(NSArray *)anyPromises { + NSParameterAssert(queue); + NSParameterAssert(anyPromises); + + if (anyPromises.count == 0) { + return [[self alloc] initWithResolution:@[]]; + } + NSMutableArray *promises = [anyPromises mutableCopy]; + return [self + onQueue:queue + async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) { + for (NSUInteger i = 0; i < promises.count; ++i) { + id promise = promises[i]; + if ([promise isKindOfClass:self]) { + continue; + } else { + [promises replaceObjectAtIndex:i + withObject:[[self alloc] initWithResolution:promise]]; + } + } + for (FBLPromise *promise in promises) { + [promise observeOnQueue:queue + fulfill:^(id __unused _) { + // Wait until all are resolved. + for (FBLPromise *promise in promises) { + if (promise.isPending) { + return; + } + } + // If called multiple times, only the first one affects the result. + fulfill(FBLPromiseCombineValuesAndErrors(promises)); + } + reject:^(NSError *error) { + BOOL atLeastOneIsFulfilled = NO; + for (FBLPromise *promise in promises) { + if (promise.isPending) { + return; + } + if (promise.isFulfilled) { + atLeastOneIsFulfilled = YES; + } + } + if (atLeastOneIsFulfilled) { + fulfill(FBLPromiseCombineValuesAndErrors(promises)); + } else { + reject(error); + } + }]; + } + }]; +} + +@end + +@implementation FBLPromise (DotSyntax_AnyAdditions) + ++ (FBLPromise * (^)(NSArray *))any { + return ^(NSArray *promises) { + return [self any:promises]; + }; +} + ++ (FBLPromise * (^)(dispatch_queue_t, NSArray *))anyOn { + return ^(dispatch_queue_t queue, NSArray *promises) { + return [self onQueue:queue any:promises]; + }; +} + +@end + +/** Stub used to force the linker to include the categories in this file. */ +void FBLIncludeAnyCategory(void) {} diff --git a/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Async.m b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Async.m new file mode 100644 index 0000000..c0a89d3 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Async.m @@ -0,0 +1,73 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise+Async.h" + +#import "FBLPromisePrivate.h" + +@implementation FBLPromise (AsyncAdditions) + ++ (instancetype)async:(FBLPromiseAsyncWorkBlock)work { + return [self onQueue:self.defaultDispatchQueue async:work]; +} + ++ (instancetype)onQueue:(dispatch_queue_t)queue async:(FBLPromiseAsyncWorkBlock)work { + NSParameterAssert(queue); + NSParameterAssert(work); + + FBLPromise *promise = [[self alloc] initPending]; + dispatch_group_async(FBLPromise.dispatchGroup, queue, ^{ + work( + ^(id __nullable value) { + if ([value isKindOfClass:[FBLPromise class]]) { + [(FBLPromise *)value observeOnQueue:queue + fulfill:^(id __nullable value) { + [promise fulfill:value]; + } + reject:^(NSError *error) { + [promise reject:error]; + }]; + } else { + [promise fulfill:value]; + } + }, + ^(NSError *error) { + [promise reject:error]; + }); + }); + return promise; +} + +@end + +@implementation FBLPromise (DotSyntax_AsyncAdditions) + ++ (FBLPromise* (^)(FBLPromiseAsyncWorkBlock))async { + return ^(FBLPromiseAsyncWorkBlock work) { + return [self async:work]; + }; +} + ++ (FBLPromise* (^)(dispatch_queue_t, FBLPromiseAsyncWorkBlock))asyncOn { + return ^(dispatch_queue_t queue, FBLPromiseAsyncWorkBlock work) { + return [self onQueue:queue async:work]; + }; +} + +@end + +/** Stub used to force the linker to include the categories in this file. */ +void FBLIncludeAsyncCategory(void) {} diff --git a/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Await.m b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Await.m new file mode 100644 index 0000000..0f86b2f --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Await.m @@ -0,0 +1,51 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise+Await.h" + +#import "FBLPromisePrivate.h" + +id __nullable FBLPromiseAwait(FBLPromise *promise, NSError **outError) { + assert(promise); + + static dispatch_once_t onceToken; + static dispatch_queue_t queue; + dispatch_once(&onceToken, ^{ + queue = dispatch_queue_create("com.google.FBLPromises.Await", DISPATCH_QUEUE_CONCURRENT); + }); + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + id __block resolution; + NSError __block *blockError; + [promise chainOnQueue:queue + chainedFulfill:^id(id value) { + resolution = value; + dispatch_semaphore_signal(semaphore); + return value; + } + chainedReject:^id(NSError *error) { + blockError = error; + dispatch_semaphore_signal(semaphore); + return error; + }]; + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); + if (outError) { + *outError = blockError; + } + return resolution; +} + +/** Stub used to force the linker to include the categories in this file. */ +void FBLIncludeAwaitCategory(void) {} diff --git a/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Catch.m b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Catch.m new file mode 100644 index 0000000..fff7690 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Catch.m @@ -0,0 +1,58 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise+Catch.h" + +#import "FBLPromisePrivate.h" + +@implementation FBLPromise (CatchAdditions) + +- (FBLPromise *)catch:(FBLPromiseCatchWorkBlock)reject { + return [self onQueue:FBLPromise.defaultDispatchQueue catch:reject]; +} + +- (FBLPromise *)onQueue:(dispatch_queue_t)queue catch:(FBLPromiseCatchWorkBlock)reject { + NSParameterAssert(queue); + NSParameterAssert(reject); + + return [self chainOnQueue:queue + chainedFulfill:nil + chainedReject:^id(NSError *error) { + reject(error); + return error; + }]; +} + +@end + +@implementation FBLPromise (DotSyntax_CatchAdditions) + +- (FBLPromise* (^)(FBLPromiseCatchWorkBlock))catch { + return ^(FBLPromiseCatchWorkBlock catch) { + return [self catch:catch]; + }; +} + +- (FBLPromise* (^)(dispatch_queue_t, FBLPromiseCatchWorkBlock))catchOn { + return ^(dispatch_queue_t queue, FBLPromiseCatchWorkBlock catch) { + return [self onQueue:queue catch:catch]; + }; +} + +@end + +/** Stub used to force the linker to include the categories in this file. */ +void FBLIncludeCatchCategory(void) {} diff --git a/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Delay.m b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Delay.m new file mode 100644 index 0000000..5aeeb1f --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Delay.m @@ -0,0 +1,62 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise+Delay.h" + +#import "FBLPromisePrivate.h" + +@implementation FBLPromise (DelayAdditions) + +- (FBLPromise *)delay:(NSTimeInterval)interval { + return [self onQueue:FBLPromise.defaultDispatchQueue delay:interval]; +} + +- (FBLPromise *)onQueue:(dispatch_queue_t)queue delay:(NSTimeInterval)interval { + NSParameterAssert(queue); + + FBLPromise *promise = [[[self class] alloc] initPending]; + [self observeOnQueue:queue + fulfill:^(id __nullable value) { + dispatch_after(dispatch_time(0, (int64_t)(interval * NSEC_PER_SEC)), queue, ^{ + [promise fulfill:value]; + }); + } + reject:^(NSError *error) { + [promise reject:error]; + }]; + return promise; +} + +@end + +@implementation FBLPromise (DotSyntax_DelayAdditions) + +- (FBLPromise * (^)(NSTimeInterval))delay { + return ^(NSTimeInterval interval) { + return [self delay:interval]; + }; +} + +- (FBLPromise * (^)(dispatch_queue_t, NSTimeInterval))delayOn { + return ^(dispatch_queue_t queue, NSTimeInterval interval) { + return [self onQueue:queue delay:interval]; + }; +} + +@end + +/** Stub used to force the linker to include the categories in this file. */ +void FBLIncludeDelayCategory(void) {} diff --git a/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Do.m b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Do.m new file mode 100644 index 0000000..9ae6033 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Do.m @@ -0,0 +1,62 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise+Do.h" + +#import "FBLPromisePrivate.h" + +@implementation FBLPromise (DoAdditions) + ++ (instancetype)do:(FBLPromiseDoWorkBlock)work { + return [self onQueue:self.defaultDispatchQueue do:work]; +} + ++ (instancetype)onQueue:(dispatch_queue_t)queue do:(FBLPromiseDoWorkBlock)work { + NSParameterAssert(queue); + NSParameterAssert(work); + + FBLPromise *promise = [[self alloc] initPending]; + dispatch_group_async(FBLPromise.dispatchGroup, queue, ^{ + id value = work(); + if ([value isKindOfClass:[FBLPromise class]]) { + [(FBLPromise *)value observeOnQueue:queue + fulfill:^(id __nullable value) { + [promise fulfill:value]; + } + reject:^(NSError *error) { + [promise reject:error]; + }]; + } else { + [promise fulfill:value]; + } + }); + return promise; +} + +@end + +@implementation FBLPromise (DotSyntax_DoAdditions) + ++ (FBLPromise* (^)(dispatch_queue_t, FBLPromiseDoWorkBlock))doOn { + return ^(dispatch_queue_t queue, FBLPromiseDoWorkBlock work) { + return [self onQueue:queue do:work]; + }; +} + +@end + +/** Stub used to force the linker to include the categories in this file. */ +void FBLIncludeDoCategory(void) {} diff --git a/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Race.m b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Race.m new file mode 100644 index 0000000..1672ac4 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Race.m @@ -0,0 +1,68 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise+Race.h" + +#import "FBLPromise+Async.h" +#import "FBLPromisePrivate.h" + +@implementation FBLPromise (RaceAdditions) + ++ (instancetype)race:(NSArray *)promises { + return [self onQueue:self.defaultDispatchQueue race:promises]; +} + ++ (instancetype)onQueue:(dispatch_queue_t)queue race:(NSArray *)racePromises { + NSParameterAssert(queue); + NSAssert(racePromises.count > 0, @"No promises to observe"); + + NSArray *promises = [racePromises copy]; + return [self onQueue:queue + async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) { + for (id promise in promises) { + if (![promise isKindOfClass:self]) { + fulfill(promise); + return; + } + } + // Subscribe all, but only the first one to resolve will change + // the resulting promise's state. + for (FBLPromise *promise in promises) { + [promise observeOnQueue:queue fulfill:fulfill reject:reject]; + } + }]; +} + +@end + +@implementation FBLPromise (DotSyntax_RaceAdditions) + ++ (FBLPromise * (^)(NSArray *))race { + return ^(NSArray *promises) { + return [self race:promises]; + }; +} + ++ (FBLPromise * (^)(dispatch_queue_t, NSArray *))raceOn { + return ^(dispatch_queue_t queue, NSArray *promises) { + return [self onQueue:queue race:promises]; + }; +} + +@end + +/** Stub used to force the linker to include the categories in this file. */ +void FBLIncludeRaceCategory(void) {} diff --git a/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Recover.m b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Recover.m new file mode 100644 index 0000000..50e337a --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Recover.m @@ -0,0 +1,57 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise+Recover.h" + +#import "FBLPromisePrivate.h" + +@implementation FBLPromise (RecoverAdditions) + +- (FBLPromise *)recover:(FBLPromiseRecoverWorkBlock)recovery { + return [self onQueue:FBLPromise.defaultDispatchQueue recover:recovery]; +} + +- (FBLPromise *)onQueue:(dispatch_queue_t)queue recover:(FBLPromiseRecoverWorkBlock)recovery { + NSParameterAssert(queue); + NSParameterAssert(recovery); + + return [self chainOnQueue:queue + chainedFulfill:nil + chainedReject:^id(NSError *error) { + return recovery(error); + }]; +} + +@end + +@implementation FBLPromise (DotSyntax_RecoverAdditions) + +- (FBLPromise * (^)(FBLPromiseRecoverWorkBlock))recover { + return ^(FBLPromiseRecoverWorkBlock recovery) { + return [self recover:recovery]; + }; +} + +- (FBLPromise * (^)(dispatch_queue_t, FBLPromiseRecoverWorkBlock))recoverOn { + return ^(dispatch_queue_t queue, FBLPromiseRecoverWorkBlock recovery) { + return [self onQueue:queue recover:recovery]; + }; +} + +@end + +/** Stub used to force the linker to include the categories in this file. */ +void FBLIncludeRecoverCategory(void) {} diff --git a/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Reduce.m b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Reduce.m new file mode 100644 index 0000000..f98cf69 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Reduce.m @@ -0,0 +1,64 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise+Reduce.h" + +#import "FBLPromisePrivate.h" + +@implementation FBLPromise (ReduceAdditions) + +- (FBLPromise *)reduce:(NSArray *)items combine:(FBLPromiseReducerBlock)reducer { + return [self onQueue:FBLPromise.defaultDispatchQueue reduce:items combine:reducer]; +} + +- (FBLPromise *)onQueue:(dispatch_queue_t)queue + reduce:(NSArray *)items + combine:(FBLPromiseReducerBlock)reducer { + NSParameterAssert(queue); + NSParameterAssert(items); + NSParameterAssert(reducer); + + FBLPromise *promise = self; + for (id item in items) { + promise = [promise chainOnQueue:queue + chainedFulfill:^id(id value) { + return reducer(value, item); + } + chainedReject:nil]; + } + return promise; +} + +@end + +@implementation FBLPromise (DotSyntax_ReduceAdditions) + +- (FBLPromise * (^)(NSArray *, FBLPromiseReducerBlock))reduce { + return ^(NSArray *items, FBLPromiseReducerBlock reducer) { + return [self reduce:items combine:reducer]; + }; +} + +- (FBLPromise * (^)(dispatch_queue_t, NSArray *, FBLPromiseReducerBlock))reduceOn { + return ^(dispatch_queue_t queue, NSArray *items, FBLPromiseReducerBlock reducer) { + return [self onQueue:queue reduce:items combine:reducer]; + }; +} + +@end + +/** Stub used to force the linker to include the categories in this file. */ +void FBLIncludeReduceCategory(void) {} diff --git a/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Retry.m b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Retry.m new file mode 100644 index 0000000..841be68 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Retry.m @@ -0,0 +1,131 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise+Retry.h" + +#import "FBLPromisePrivate.h" + +NSInteger const FBLPromiseRetryDefaultAttemptsCount = 1; +NSTimeInterval const FBLPromiseRetryDefaultDelayInterval = 1.0; + +static void FBLPromiseRetryAttempt(FBLPromise *promise, dispatch_queue_t queue, NSInteger count, + NSTimeInterval interval, FBLPromiseRetryPredicateBlock predicate, + FBLPromiseRetryWorkBlock work) { + __auto_type retrier = ^(id __nullable value) { + if ([value isKindOfClass:[NSError class]]) { + if (count <= 0 || (predicate && !predicate(count, value))) { + [promise reject:value]; + } else { + dispatch_after(dispatch_time(0, (int64_t)(interval * NSEC_PER_SEC)), queue, ^{ + FBLPromiseRetryAttempt(promise, queue, count - 1, interval, predicate, work); + }); + } + } else { + [promise fulfill:value]; + } + }; + id value = work(); + if ([value isKindOfClass:[FBLPromise class]]) { + [(FBLPromise *)value observeOnQueue:queue fulfill:retrier reject:retrier]; + } else { + retrier(value); + } +} + +@implementation FBLPromise (RetryAdditions) + ++ (instancetype)retry:(FBLPromiseRetryWorkBlock)work { + return [self onQueue:FBLPromise.defaultDispatchQueue retry:work]; +} + ++ (instancetype)onQueue:(dispatch_queue_t)queue retry:(FBLPromiseRetryWorkBlock)work { + return [self onQueue:queue attempts:FBLPromiseRetryDefaultAttemptsCount retry:work]; +} + ++ (instancetype)attempts:(NSInteger)count retry:(FBLPromiseRetryWorkBlock)work { + return [self onQueue:FBLPromise.defaultDispatchQueue attempts:count retry:work]; +} + ++ (instancetype)onQueue:(dispatch_queue_t)queue + attempts:(NSInteger)count + retry:(FBLPromiseRetryWorkBlock)work { + return [self onQueue:queue + attempts:count + delay:FBLPromiseRetryDefaultDelayInterval + condition:nil + retry:work]; +} + ++ (instancetype)attempts:(NSInteger)count + delay:(NSTimeInterval)interval + condition:(nullable FBLPromiseRetryPredicateBlock)predicate + retry:(FBLPromiseRetryWorkBlock)work { + return [self onQueue:FBLPromise.defaultDispatchQueue + attempts:count + delay:interval + condition:predicate + retry:work]; +} + ++ (instancetype)onQueue:(dispatch_queue_t)queue + attempts:(NSInteger)count + delay:(NSTimeInterval)interval + condition:(nullable FBLPromiseRetryPredicateBlock)predicate + retry:(FBLPromiseRetryWorkBlock)work { + NSParameterAssert(queue); + NSParameterAssert(work); + + FBLPromise *promise = [[self alloc] initPending]; + FBLPromiseRetryAttempt(promise, queue, count, interval, predicate, work); + return promise; +} + +@end + +@implementation FBLPromise (DotSyntax_RetryAdditions) + ++ (FBLPromise * (^)(FBLPromiseRetryWorkBlock))retry { + return ^id(FBLPromiseRetryWorkBlock work) { + return [self retry:work]; + }; +} + ++ (FBLPromise * (^)(dispatch_queue_t, FBLPromiseRetryWorkBlock))retryOn { + return ^id(dispatch_queue_t queue, FBLPromiseRetryWorkBlock work) { + return [self onQueue:queue retry:work]; + }; +} + ++ (FBLPromise * (^)(NSInteger, NSTimeInterval, FBLPromiseRetryPredicateBlock, + FBLPromiseRetryWorkBlock))retryAgain { + return ^id(NSInteger count, NSTimeInterval interval, FBLPromiseRetryPredicateBlock predicate, + FBLPromiseRetryWorkBlock work) { + return [self attempts:count delay:interval condition:predicate retry:work]; + }; +} + ++ (FBLPromise * (^)(dispatch_queue_t, NSInteger, NSTimeInterval, FBLPromiseRetryPredicateBlock, + FBLPromiseRetryWorkBlock))retryAgainOn { + return ^id(dispatch_queue_t queue, NSInteger count, NSTimeInterval interval, + FBLPromiseRetryPredicateBlock predicate, FBLPromiseRetryWorkBlock work) { + return [self onQueue:queue attempts:count delay:interval condition:predicate retry:work]; + }; +} + +@end + +/** Stub used to force the linker to include the categories in this file. */ +void FBLIncludeRetryCategory(void) {} diff --git a/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Testing.m b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Testing.m new file mode 100644 index 0000000..7d6b461 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Testing.m @@ -0,0 +1,58 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise+Testing.h" + +BOOL FBLWaitForPromisesWithTimeout(NSTimeInterval timeout) { + BOOL isTimedOut = NO; + NSDate *timeoutDate = [NSDate dateWithTimeIntervalSinceNow:timeout]; + static NSTimeInterval const minimalTimeout = 0.01; + static int64_t const minimalTimeToWait = (int64_t)(minimalTimeout * NSEC_PER_SEC); + dispatch_time_t waitTime = dispatch_time(DISPATCH_TIME_NOW, minimalTimeToWait); + dispatch_group_t dispatchGroup = FBLPromise.dispatchGroup; + NSRunLoop *runLoop = NSRunLoop.currentRunLoop; + while (dispatch_group_wait(dispatchGroup, waitTime)) { + isTimedOut = timeoutDate.timeIntervalSinceNow < 0.0; + if (isTimedOut) { + break; + } + [runLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:minimalTimeout]]; + } + return !isTimedOut; +} + +@implementation FBLPromise (TestingAdditions) + +// These properties are implemented in the FBLPromise class itself. +@dynamic isPending; +@dynamic isFulfilled; +@dynamic isRejected; +@dynamic value; +@dynamic error; + ++ (dispatch_group_t)dispatchGroup { + static dispatch_group_t gDispatchGroup; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + gDispatchGroup = dispatch_group_create(); + }); + return gDispatchGroup; +} + +@end + +/** Stub used to force the linker to include the categories in this file. */ +void FBLIncludeTestingCategory(void) {} diff --git a/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Then.m b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Then.m new file mode 100644 index 0000000..32df102 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Then.m @@ -0,0 +1,53 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise+Then.h" + +#import "FBLPromisePrivate.h" + +@implementation FBLPromise (ThenAdditions) + +- (FBLPromise *)then:(FBLPromiseThenWorkBlock)work { + return [self onQueue:FBLPromise.defaultDispatchQueue then:work]; +} + +- (FBLPromise *)onQueue:(dispatch_queue_t)queue then:(FBLPromiseThenWorkBlock)work { + NSParameterAssert(queue); + NSParameterAssert(work); + + return [self chainOnQueue:queue chainedFulfill:work chainedReject:nil]; +} + +@end + +@implementation FBLPromise (DotSyntax_ThenAdditions) + +- (FBLPromise* (^)(FBLPromiseThenWorkBlock))then { + return ^(FBLPromiseThenWorkBlock work) { + return [self then:work]; + }; +} + +- (FBLPromise* (^)(dispatch_queue_t, FBLPromiseThenWorkBlock))thenOn { + return ^(dispatch_queue_t queue, FBLPromiseThenWorkBlock work) { + return [self onQueue:queue then:work]; + }; +} + +@end + +/** Stub used to force the linker to include the categories in this file. */ +void FBLIncludeThenCategory(void) {} diff --git a/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Timeout.m b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Timeout.m new file mode 100644 index 0000000..91da9ff --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Timeout.m @@ -0,0 +1,67 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise+Timeout.h" + +#import "FBLPromisePrivate.h" + +@implementation FBLPromise (TimeoutAdditions) + +- (FBLPromise *)timeout:(NSTimeInterval)interval { + return [self onQueue:FBLPromise.defaultDispatchQueue timeout:interval]; +} + +- (FBLPromise *)onQueue:(dispatch_queue_t)queue timeout:(NSTimeInterval)interval { + NSParameterAssert(queue); + + FBLPromise *promise = [[[self class] alloc] initPending]; + [self observeOnQueue:queue + fulfill:^(id __nullable value) { + [promise fulfill:value]; + } + reject:^(NSError *error) { + [promise reject:error]; + }]; + FBLPromise* __weak weakPromise = promise; + dispatch_after(dispatch_time(0, (int64_t)(interval * NSEC_PER_SEC)), queue, ^{ + NSError *timedOutError = [[NSError alloc] initWithDomain:FBLPromiseErrorDomain + code:FBLPromiseErrorCodeTimedOut + userInfo:nil]; + [weakPromise reject:timedOutError]; + }); + return promise; +} + +@end + +@implementation FBLPromise (DotSyntax_TimeoutAdditions) + +- (FBLPromise* (^)(NSTimeInterval))timeout { + return ^(NSTimeInterval interval) { + return [self timeout:interval]; + }; +} + +- (FBLPromise* (^)(dispatch_queue_t, NSTimeInterval))timeoutOn { + return ^(dispatch_queue_t queue, NSTimeInterval interval) { + return [self onQueue:queue timeout:interval]; + }; +} + +@end + +/** Stub used to force the linker to include the categories in this file. */ +void FBLIncludeTimeoutCategory(void) {} diff --git a/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Validate.m b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Validate.m new file mode 100644 index 0000000..3520e24 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Validate.m @@ -0,0 +1,59 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise+Validate.h" + +#import "FBLPromisePrivate.h" + +@implementation FBLPromise (ValidateAdditions) + +- (FBLPromise*)validate:(FBLPromiseValidateWorkBlock)predicate { + return [self onQueue:FBLPromise.defaultDispatchQueue validate:predicate]; +} + +- (FBLPromise*)onQueue:(dispatch_queue_t)queue validate:(FBLPromiseValidateWorkBlock)predicate { + NSParameterAssert(queue); + NSParameterAssert(predicate); + + FBLPromiseChainedFulfillBlock chainedFulfill = ^id(id value) { + return predicate(value) ? value : + [[NSError alloc] initWithDomain:FBLPromiseErrorDomain + code:FBLPromiseErrorCodeValidationFailure + userInfo:nil]; + }; + return [self chainOnQueue:queue chainedFulfill:chainedFulfill chainedReject:nil]; +} + +@end + +@implementation FBLPromise (DotSyntax_ValidateAdditions) + +- (FBLPromise* (^)(FBLPromiseValidateWorkBlock))validate { + return ^(FBLPromiseValidateWorkBlock predicate) { + return [self validate:predicate]; + }; +} + +- (FBLPromise* (^)(dispatch_queue_t, FBLPromiseValidateWorkBlock))validateOn { + return ^(dispatch_queue_t queue, FBLPromiseValidateWorkBlock predicate) { + return [self onQueue:queue validate:predicate]; + }; +} + +@end + +/** Stub used to force the linker to include the categories in this file. */ +void FBLIncludeValidateCategory(void) {} diff --git a/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Wrap.m b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Wrap.m new file mode 100644 index 0000000..840bc16 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise+Wrap.m @@ -0,0 +1,423 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise+Wrap.h" + +#import "FBLPromise+Async.h" + +@implementation FBLPromise (WrapAdditions) + ++ (instancetype)wrapCompletion:(void (^)(FBLPromiseCompletion))work { + return [self onQueue:self.defaultDispatchQueue wrapCompletion:work]; +} + ++ (instancetype)onQueue:(dispatch_queue_t)queue + wrapCompletion:(void (^)(FBLPromiseCompletion))work { + NSParameterAssert(queue); + NSParameterAssert(work); + + return [self onQueue:queue + async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock __unused _) { + work(^{ + fulfill(nil); + }); + }]; +} + ++ (instancetype)wrapObjectCompletion:(void (^)(FBLPromiseObjectCompletion))work { + return [self onQueue:self.defaultDispatchQueue wrapObjectCompletion:work]; +} + ++ (instancetype)onQueue:(dispatch_queue_t)queue + wrapObjectCompletion:(void (^)(FBLPromiseObjectCompletion))work { + NSParameterAssert(queue); + NSParameterAssert(work); + + return [self onQueue:queue + async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock __unused _) { + work(^(id __nullable value) { + fulfill(value); + }); + }]; +} + ++ (instancetype)wrapErrorCompletion:(void (^)(FBLPromiseErrorCompletion))work { + return [self onQueue:self.defaultDispatchQueue wrapErrorCompletion:work]; +} + ++ (instancetype)onQueue:(dispatch_queue_t)queue + wrapErrorCompletion:(void (^)(FBLPromiseErrorCompletion))work { + NSParameterAssert(queue); + NSParameterAssert(work); + + return [self onQueue:queue + async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) { + work(^(NSError *__nullable error) { + if (error) { + reject(error); + } else { + fulfill(nil); + } + }); + }]; +} + ++ (instancetype)wrapObjectOrErrorCompletion:(void (^)(FBLPromiseObjectOrErrorCompletion))work { + return [self onQueue:self.defaultDispatchQueue wrapObjectOrErrorCompletion:work]; +} + ++ (instancetype)onQueue:(dispatch_queue_t)queue + wrapObjectOrErrorCompletion:(void (^)(FBLPromiseObjectOrErrorCompletion))work { + NSParameterAssert(queue); + NSParameterAssert(work); + + return [self onQueue:queue + async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) { + work(^(id __nullable value, NSError *__nullable error) { + if (error) { + reject(error); + } else { + fulfill(value); + } + }); + }]; +} + ++ (instancetype)wrapErrorOrObjectCompletion:(void (^)(FBLPromiseErrorOrObjectCompletion))work { + return [self onQueue:self.defaultDispatchQueue wrapErrorOrObjectCompletion:work]; +} + ++ (instancetype)onQueue:(dispatch_queue_t)queue + wrapErrorOrObjectCompletion:(void (^)(FBLPromiseErrorOrObjectCompletion))work { + NSParameterAssert(queue); + NSParameterAssert(work); + + return [self onQueue:queue + async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) { + work(^(NSError *__nullable error, id __nullable value) { + if (error) { + reject(error); + } else { + fulfill(value); + } + }); + }]; +} + ++ (FBLPromise *)wrap2ObjectsOrErrorCompletion: + (void (^)(FBLPromise2ObjectsOrErrorCompletion))work { + return [self onQueue:self.defaultDispatchQueue wrap2ObjectsOrErrorCompletion:work]; +} + ++ (FBLPromise *)onQueue:(dispatch_queue_t)queue + wrap2ObjectsOrErrorCompletion:(void (^)(FBLPromise2ObjectsOrErrorCompletion))work { + NSParameterAssert(queue); + NSParameterAssert(work); + + return [self onQueue:queue + async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) { + work(^(id __nullable value1, id __nullable value2, NSError *__nullable error) { + if (error) { + reject(error); + } else { + fulfill(@[ value1 ?: [NSNull null], value2 ?: [NSNull null] ]); + } + }); + }]; +} + ++ (FBLPromise *)wrapBoolCompletion:(void (^)(FBLPromiseBoolCompletion))work { + return [self onQueue:self.defaultDispatchQueue wrapBoolCompletion:work]; +} + ++ (FBLPromise *)onQueue:(dispatch_queue_t)queue + wrapBoolCompletion:(void (^)(FBLPromiseBoolCompletion))work { + NSParameterAssert(queue); + NSParameterAssert(work); + + return [self onQueue:queue + async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock __unused _) { + work(^(BOOL value) { + fulfill(@(value)); + }); + }]; +} + ++ (FBLPromise *)wrapBoolOrErrorCompletion: + (void (^)(FBLPromiseBoolOrErrorCompletion))work { + return [self onQueue:self.defaultDispatchQueue wrapBoolOrErrorCompletion:work]; +} + ++ (FBLPromise *)onQueue:(dispatch_queue_t)queue + wrapBoolOrErrorCompletion:(void (^)(FBLPromiseBoolOrErrorCompletion))work { + NSParameterAssert(queue); + NSParameterAssert(work); + + return [self onQueue:queue + async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) { + work(^(BOOL value, NSError *__nullable error) { + if (error) { + reject(error); + } else { + fulfill(@(value)); + } + }); + }]; +} + ++ (FBLPromise *)wrapIntegerCompletion:(void (^)(FBLPromiseIntegerCompletion))work { + return [self onQueue:self.defaultDispatchQueue wrapIntegerCompletion:work]; +} + ++ (FBLPromise *)onQueue:(dispatch_queue_t)queue + wrapIntegerCompletion:(void (^)(FBLPromiseIntegerCompletion))work { + NSParameterAssert(queue); + NSParameterAssert(work); + + return [self onQueue:queue + async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock __unused _) { + work(^(NSInteger value) { + fulfill(@(value)); + }); + }]; +} + ++ (FBLPromise *)wrapIntegerOrErrorCompletion: + (void (^)(FBLPromiseIntegerOrErrorCompletion))work { + return [self onQueue:self.defaultDispatchQueue wrapIntegerOrErrorCompletion:work]; +} + ++ (FBLPromise *)onQueue:(dispatch_queue_t)queue + wrapIntegerOrErrorCompletion:(void (^)(FBLPromiseIntegerOrErrorCompletion))work { + NSParameterAssert(queue); + NSParameterAssert(work); + + return [self onQueue:queue + async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) { + work(^(NSInteger value, NSError *__nullable error) { + if (error) { + reject(error); + } else { + fulfill(@(value)); + } + }); + }]; +} + ++ (FBLPromise *)wrapDoubleCompletion:(void (^)(FBLPromiseDoubleCompletion))work { + return [self onQueue:self.defaultDispatchQueue wrapDoubleCompletion:work]; +} + ++ (FBLPromise *)onQueue:(dispatch_queue_t)queue + wrapDoubleCompletion:(void (^)(FBLPromiseDoubleCompletion))work { + NSParameterAssert(queue); + NSParameterAssert(work); + + return [self onQueue:(dispatch_queue_t)queue + async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock __unused _) { + work(^(double value) { + fulfill(@(value)); + }); + }]; +} + ++ (FBLPromise *)wrapDoubleOrErrorCompletion: + (void (^)(FBLPromiseDoubleOrErrorCompletion))work { + return [self onQueue:self.defaultDispatchQueue wrapDoubleOrErrorCompletion:work]; +} + ++ (FBLPromise *)onQueue:(dispatch_queue_t)queue + wrapDoubleOrErrorCompletion:(void (^)(FBLPromiseDoubleOrErrorCompletion))work { + NSParameterAssert(queue); + NSParameterAssert(work); + + return [self onQueue:queue + async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) { + work(^(double value, NSError *__nullable error) { + if (error) { + reject(error); + } else { + fulfill(@(value)); + } + }); + }]; +} + +@end + +@implementation FBLPromise (DotSyntax_WrapAdditions) + ++ (FBLPromise * (^)(void (^)(FBLPromiseCompletion)))wrapCompletion { + return ^(void (^work)(FBLPromiseCompletion)) { + return [self wrapCompletion:work]; + }; +} + ++ (FBLPromise * (^)(dispatch_queue_t, void (^)(FBLPromiseCompletion)))wrapCompletionOn { + return ^(dispatch_queue_t queue, void (^work)(FBLPromiseCompletion)) { + return [self onQueue:queue wrapCompletion:work]; + }; +} + ++ (FBLPromise * (^)(void (^)(FBLPromiseObjectCompletion)))wrapObjectCompletion { + return ^(void (^work)(FBLPromiseObjectCompletion)) { + return [self wrapObjectCompletion:work]; + }; +} + ++ (FBLPromise * (^)(dispatch_queue_t, void (^)(FBLPromiseObjectCompletion)))wrapObjectCompletionOn { + return ^(dispatch_queue_t queue, void (^work)(FBLPromiseObjectCompletion)) { + return [self onQueue:queue wrapObjectCompletion:work]; + }; +} + ++ (FBLPromise * (^)(void (^)(FBLPromiseErrorCompletion)))wrapErrorCompletion { + return ^(void (^work)(FBLPromiseErrorCompletion)) { + return [self wrapErrorCompletion:work]; + }; +} + ++ (FBLPromise * (^)(dispatch_queue_t, void (^)(FBLPromiseErrorCompletion)))wrapErrorCompletionOn { + return ^(dispatch_queue_t queue, void (^work)(FBLPromiseErrorCompletion)) { + return [self onQueue:queue wrapErrorCompletion:work]; + }; +} + ++ (FBLPromise * (^)(void (^)(FBLPromiseObjectOrErrorCompletion)))wrapObjectOrErrorCompletion { + return ^(void (^work)(FBLPromiseObjectOrErrorCompletion)) { + return [self wrapObjectOrErrorCompletion:work]; + }; +} + ++ (FBLPromise * (^)(dispatch_queue_t, + void (^)(FBLPromiseObjectOrErrorCompletion)))wrapObjectOrErrorCompletionOn { + return ^(dispatch_queue_t queue, void (^work)(FBLPromiseObjectOrErrorCompletion)) { + return [self onQueue:queue wrapObjectOrErrorCompletion:work]; + }; +} + ++ (FBLPromise * (^)(void (^)(FBLPromiseErrorOrObjectCompletion)))wrapErrorOrObjectCompletion { + return ^(void (^work)(FBLPromiseErrorOrObjectCompletion)) { + return [self wrapErrorOrObjectCompletion:work]; + }; +} + ++ (FBLPromise * (^)(dispatch_queue_t, + void (^)(FBLPromiseErrorOrObjectCompletion)))wrapErrorOrObjectCompletionOn { + return ^(dispatch_queue_t queue, void (^work)(FBLPromiseErrorOrObjectCompletion)) { + return [self onQueue:queue wrapErrorOrObjectCompletion:work]; + }; +} + ++ (FBLPromise * (^)(void (^)(FBLPromise2ObjectsOrErrorCompletion))) + wrap2ObjectsOrErrorCompletion { + return ^(void (^work)(FBLPromise2ObjectsOrErrorCompletion)) { + return [self wrap2ObjectsOrErrorCompletion:work]; + }; +} + ++ (FBLPromise * (^)(dispatch_queue_t, void (^)(FBLPromise2ObjectsOrErrorCompletion))) + wrap2ObjectsOrErrorCompletionOn { + return ^(dispatch_queue_t queue, void (^work)(FBLPromise2ObjectsOrErrorCompletion)) { + return [self onQueue:queue wrap2ObjectsOrErrorCompletion:work]; + }; +} + ++ (FBLPromise * (^)(void (^)(FBLPromiseBoolCompletion)))wrapBoolCompletion { + return ^(void (^work)(FBLPromiseBoolCompletion)) { + return [self wrapBoolCompletion:work]; + }; +} + ++ (FBLPromise * (^)(dispatch_queue_t, + void (^)(FBLPromiseBoolCompletion)))wrapBoolCompletionOn { + return ^(dispatch_queue_t queue, void (^work)(FBLPromiseBoolCompletion)) { + return [self onQueue:queue wrapBoolCompletion:work]; + }; +} + ++ (FBLPromise * (^)(void (^)(FBLPromiseBoolOrErrorCompletion))) + wrapBoolOrErrorCompletion { + return ^(void (^work)(FBLPromiseBoolOrErrorCompletion)) { + return [self wrapBoolOrErrorCompletion:work]; + }; +} + ++ (FBLPromise * (^)(dispatch_queue_t, void (^)(FBLPromiseBoolOrErrorCompletion))) + wrapBoolOrErrorCompletionOn { + return ^(dispatch_queue_t queue, void (^work)(FBLPromiseBoolOrErrorCompletion)) { + return [self onQueue:queue wrapBoolOrErrorCompletion:work]; + }; +} + ++ (FBLPromise * (^)(void (^)(FBLPromiseIntegerCompletion)))wrapIntegerCompletion { + return ^(void (^work)(FBLPromiseIntegerCompletion)) { + return [self wrapIntegerCompletion:work]; + }; +} + ++ (FBLPromise * (^)(dispatch_queue_t, + void (^)(FBLPromiseIntegerCompletion)))wrapIntegerCompletionOn { + return ^(dispatch_queue_t queue, void (^work)(FBLPromiseIntegerCompletion)) { + return [self onQueue:queue wrapIntegerCompletion:work]; + }; +} + ++ (FBLPromise * (^)(void (^)(FBLPromiseIntegerOrErrorCompletion))) + wrapIntegerOrErrorCompletion { + return ^(void (^work)(FBLPromiseIntegerOrErrorCompletion)) { + return [self wrapIntegerOrErrorCompletion:work]; + }; +} + ++ (FBLPromise * (^)(dispatch_queue_t, void (^)(FBLPromiseIntegerOrErrorCompletion))) + wrapIntegerOrErrorCompletionOn { + return ^(dispatch_queue_t queue, void (^work)(FBLPromiseIntegerOrErrorCompletion)) { + return [self onQueue:queue wrapIntegerOrErrorCompletion:work]; + }; +} + ++ (FBLPromise * (^)(void (^)(FBLPromiseDoubleCompletion)))wrapDoubleCompletion { + return ^(void (^work)(FBLPromiseDoubleCompletion)) { + return [self wrapDoubleCompletion:work]; + }; +} + ++ (FBLPromise * (^)(dispatch_queue_t, + void (^)(FBLPromiseDoubleCompletion)))wrapDoubleCompletionOn { + return ^(dispatch_queue_t queue, void (^work)(FBLPromiseDoubleCompletion)) { + return [self onQueue:queue wrapDoubleCompletion:work]; + }; +} + ++ (FBLPromise * (^)(void (^)(FBLPromiseDoubleOrErrorCompletion))) + wrapDoubleOrErrorCompletion { + return ^(void (^work)(FBLPromiseDoubleOrErrorCompletion)) { + return [self wrapDoubleOrErrorCompletion:work]; + }; +} + ++ (FBLPromise * (^)(dispatch_queue_t, void (^)(FBLPromiseDoubleOrErrorCompletion))) + wrapDoubleOrErrorCompletionOn { + return ^(dispatch_queue_t queue, void (^work)(FBLPromiseDoubleOrErrorCompletion)) { + return [self onQueue:queue wrapDoubleOrErrorCompletion:work]; + }; +} + +@end + +/** Stub used to force the linker to include the categories in this file. */ +void FBLIncludeWrapCategory(void) {} diff --git a/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise.m b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise.m new file mode 100644 index 0000000..9a61ed2 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromise.m @@ -0,0 +1,346 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromisePrivate.h" + +/** All states a promise can be in. */ +typedef NS_ENUM(NSInteger, FBLPromiseState) { + FBLPromiseStatePending = 0, + FBLPromiseStateFulfilled, + FBLPromiseStateRejected, +}; + +typedef void (^FBLPromiseObserver)(FBLPromiseState state, id __nullable resolution); + +static dispatch_queue_t gFBLPromiseDefaultDispatchQueue; + +@implementation FBLPromise { + /** Current state of the promise. */ + FBLPromiseState _state; + /** + Set of arbitrary objects to keep strongly while the promise is pending. + Becomes nil after the promise has been resolved. + */ + NSMutableSet *__nullable _pendingObjects; + /** + Value to fulfill the promise with. + Can be nil if the promise is still pending, was resolved with nil or after it has been rejected. + */ + id __nullable _value; + /** + Error to reject the promise with. + Can be nil if the promise is still pending or after it has been fulfilled. + */ + NSError *__nullable _error; + /** List of observers to notify when the promise gets resolved. */ + NSMutableArray *_observers; +} + ++ (void)initialize { + if (self == [FBLPromise class]) { + gFBLPromiseDefaultDispatchQueue = dispatch_get_main_queue(); + } +} + ++ (dispatch_queue_t)defaultDispatchQueue { + @synchronized(self) { + return gFBLPromiseDefaultDispatchQueue; + } +} + ++ (void)setDefaultDispatchQueue:(dispatch_queue_t)queue { + NSParameterAssert(queue); + + @synchronized(self) { + gFBLPromiseDefaultDispatchQueue = queue; + } +} + ++ (instancetype)pendingPromise { + return [[self alloc] initPending]; +} + ++ (instancetype)resolvedWith:(nullable id)resolution { + return [[self alloc] initWithResolution:resolution]; +} + +- (void)fulfill:(nullable id)value { + if ([value isKindOfClass:[NSError class]]) { + [self reject:(NSError *)value]; + } else { + @synchronized(self) { + if (_state == FBLPromiseStatePending) { + _state = FBLPromiseStateFulfilled; + _value = value; + _pendingObjects = nil; + for (FBLPromiseObserver observer in _observers) { + observer(_state, _value); + } + _observers = nil; + dispatch_group_leave(FBLPromise.dispatchGroup); + } + } + } +} + +- (void)reject:(NSError *)error { + NSAssert([error isKindOfClass:[NSError class]], @"Invalid error type."); + + if (![error isKindOfClass:[NSError class]]) { + // Give up on invalid error type in Release mode. + @throw error; // NOLINT + } + @synchronized(self) { + if (_state == FBLPromiseStatePending) { + _state = FBLPromiseStateRejected; + _error = error; + _pendingObjects = nil; + for (FBLPromiseObserver observer in _observers) { + observer(_state, _error); + } + _observers = nil; + dispatch_group_leave(FBLPromise.dispatchGroup); + } + } +} + +#pragma mark - NSObject + +- (NSString *)description { + if (self.isFulfilled) { + return [NSString stringWithFormat:@"<%@ %p> Fulfilled: %@", NSStringFromClass([self class]), + self, self.value]; + } + if (self.isRejected) { + return [NSString stringWithFormat:@"<%@ %p> Rejected: %@", NSStringFromClass([self class]), + self, self.error]; + } + return [NSString stringWithFormat:@"<%@ %p> Pending", NSStringFromClass([self class]), self]; +} + +#pragma mark - Private + +- (instancetype)initPending { + self = [super init]; + if (self) { + dispatch_group_enter(FBLPromise.dispatchGroup); + } + return self; +} + +- (instancetype)initWithResolution:(nullable id)resolution { + self = [super init]; + if (self) { + if ([resolution isKindOfClass:[NSError class]]) { + _state = FBLPromiseStateRejected; + _error = (NSError *)resolution; + } else { + _state = FBLPromiseStateFulfilled; + _value = resolution; + } + } + return self; +} + +- (void)dealloc { + if (_state == FBLPromiseStatePending) { + dispatch_group_leave(FBLPromise.dispatchGroup); + } +} + +- (BOOL)isPending { + @synchronized(self) { + return _state == FBLPromiseStatePending; + } +} + +- (BOOL)isFulfilled { + @synchronized(self) { + return _state == FBLPromiseStateFulfilled; + } +} + +- (BOOL)isRejected { + @synchronized(self) { + return _state == FBLPromiseStateRejected; + } +} + +- (nullable id)value { + @synchronized(self) { + return _value; + } +} + +- (NSError *__nullable)error { + @synchronized(self) { + return _error; + } +} + +- (void)addPendingObject:(id)object { + NSParameterAssert(object); + + @synchronized(self) { + if (_state == FBLPromiseStatePending) { + if (!_pendingObjects) { + _pendingObjects = [[NSMutableSet alloc] init]; + } + [_pendingObjects addObject:object]; + } + } +} + +- (void)observeOnQueue:(dispatch_queue_t)queue + fulfill:(FBLPromiseOnFulfillBlock)onFulfill + reject:(FBLPromiseOnRejectBlock)onReject { + NSParameterAssert(queue); + NSParameterAssert(onFulfill); + NSParameterAssert(onReject); + + @synchronized(self) { + switch (_state) { + case FBLPromiseStatePending: { + if (!_observers) { + _observers = [[NSMutableArray alloc] init]; + } + [_observers addObject:^(FBLPromiseState state, id __nullable resolution) { + dispatch_group_async(FBLPromise.dispatchGroup, queue, ^{ + switch (state) { + case FBLPromiseStatePending: + break; + case FBLPromiseStateFulfilled: + onFulfill(resolution); + break; + case FBLPromiseStateRejected: + onReject(resolution); + break; + } + }); + }]; + break; + } + case FBLPromiseStateFulfilled: { + dispatch_group_async(FBLPromise.dispatchGroup, queue, ^{ + onFulfill(self->_value); + }); + break; + } + case FBLPromiseStateRejected: { + dispatch_group_async(FBLPromise.dispatchGroup, queue, ^{ + onReject(self->_error); + }); + break; + } + } + } +} + +- (FBLPromise *)chainOnQueue:(dispatch_queue_t)queue + chainedFulfill:(FBLPromiseChainedFulfillBlock)chainedFulfill + chainedReject:(FBLPromiseChainedRejectBlock)chainedReject { + NSParameterAssert(queue); + + FBLPromise *promise = [[[self class] alloc] initPending]; + __auto_type resolver = ^(id __nullable value) { + if ([value isKindOfClass:[FBLPromise class]]) { + [(FBLPromise *)value observeOnQueue:queue + fulfill:^(id __nullable value) { + [promise fulfill:value]; + } + reject:^(NSError *error) { + [promise reject:error]; + }]; + } else { + [promise fulfill:value]; + } + }; + [self observeOnQueue:queue + fulfill:^(id __nullable value) { + value = chainedFulfill ? chainedFulfill(value) : value; + resolver(value); + } + reject:^(NSError *error) { + id value = chainedReject ? chainedReject(error) : error; + resolver(value); + }]; + return promise; +} + +#pragma mark - Category linking workaround + +extern void FBLIncludeAllCategory(void); +extern void FBLIncludeAlwaysCategory(void); +extern void FBLIncludeAnyCategory(void); +extern void FBLIncludeAsyncCategory(void); +extern void FBLIncludeAwaitCategory(void); +extern void FBLIncludeCatchCategory(void); +extern void FBLIncludeDelayCategory(void); +extern void FBLIncludeDoCategory(void); +extern void FBLIncludeRaceCategory(void); +extern void FBLIncludeRecoverCategory(void); +extern void FBLIncludeReduceCategory(void); +extern void FBLIncludeRetryCategory(void); +extern void FBLIncludeTestingCategory(void); +extern void FBLIncludeThenCategory(void); +extern void FBLIncludeTimeoutCategory(void); +extern void FBLIncludeValidateCategory(void); +extern void FBLIncludeWrapCategory(void); + +/** + Does nothing when called, and not meant to be called. + + This method forces the linker to include all FBLPromise categories even if + users do not include the '-ObjC' linker flag in their projects. + */ ++ (void)noop { + FBLIncludeAllCategory(); + FBLIncludeAllCategory(); + FBLIncludeAlwaysCategory(); + FBLIncludeAnyCategory(); + FBLIncludeAsyncCategory(); + FBLIncludeAwaitCategory(); + FBLIncludeCatchCategory(); + FBLIncludeDelayCategory(); + FBLIncludeDoCategory(); + FBLIncludeRaceCategory(); + FBLIncludeRecoverCategory(); + FBLIncludeReduceCategory(); + FBLIncludeRetryCategory(); + FBLIncludeTestingCategory(); + FBLIncludeThenCategory(); + FBLIncludeTimeoutCategory(); + FBLIncludeValidateCategory(); + FBLIncludeWrapCategory(); +} + +@end + +@implementation FBLPromise (DotSyntaxAdditions) + ++ (FBLPromise * (^)(void))pending { + return ^(void) { + return [self pendingPromise]; + }; +} + ++ (FBLPromise * (^)(id __nullable))resolved { + return ^(id resolution) { + return [self resolvedWith:resolution]; + }; +} + +@end diff --git a/Pods/PromisesObjC/Sources/FBLPromises/FBLPromiseError.m b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromiseError.m new file mode 100644 index 0000000..1cc181a --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/FBLPromiseError.m @@ -0,0 +1,19 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromiseError.h" + +NSErrorDomain const FBLPromiseErrorDomain = @"com.google.FBLPromises.Error"; diff --git a/Pods/PromisesObjC/Sources/FBLPromises/Resources/PrivacyInfo.xcprivacy b/Pods/PromisesObjC/Sources/FBLPromises/Resources/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..5397adc --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/Resources/PrivacyInfo.xcprivacy @@ -0,0 +1,14 @@ + + + + + NSPrivacyAccessedAPITypes + + NSPrivacyCollectedDataTypes + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + + diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+All.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+All.h new file mode 100644 index 0000000..9c0090e --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+All.h @@ -0,0 +1,63 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FBLPromise(AllAdditions) + +/** + Wait until all of the given promises are fulfilled. + If one of the given promises is rejected, then the returned promise is rejected with same error. + If any other arbitrary value or `NSError` appears in the array instead of `FBLPromise`, + it's implicitly considered a pre-fulfilled or pre-rejected `FBLPromise` correspondingly. + Promises resolved with `nil` become `NSNull` instances in the resulting array. + + @param promises Promises to wait for. + @return Promise of an array containing the values of input promises in the same order. + */ ++ (FBLPromise *)all:(NSArray *)promises NS_SWIFT_UNAVAILABLE(""); + +/** + Wait until all of the given promises are fulfilled. + If one of the given promises is rejected, then the returned promise is rejected with same error. + If any other arbitrary value or `NSError` appears in the array instead of `FBLPromise`, + it's implicitly considered a pre-fulfilled or pre-rejected FBLPromise correspondingly. + Promises resolved with `nil` become `NSNull` instances in the resulting array. + + @param queue A queue to dispatch on. + @param promises Promises to wait for. + @return Promise of an array containing the values of input promises in the same order. + */ ++ (FBLPromise *)onQueue:(dispatch_queue_t)queue + all:(NSArray *)promises NS_REFINED_FOR_SWIFT; + +@end + +/** + Convenience dot-syntax wrappers for `FBLPromise` `all` operators. + Usage: FBLPromise.all(@[ ... ]) + */ +@interface FBLPromise(DotSyntax_AllAdditions) + ++ (FBLPromise * (^)(NSArray *))all FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise * (^)(dispatch_queue_t, NSArray *))allOn FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Always.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Always.h new file mode 100644 index 0000000..13000f5 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Always.h @@ -0,0 +1,54 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FBLPromise(AlwaysAdditions) + +typedef void (^FBLPromiseAlwaysWorkBlock)(void) NS_SWIFT_UNAVAILABLE(""); + +/** + @param work A block that always executes, no matter if the receiver is rejected or fulfilled. + @return A new pending promise to be resolved with same resolution as the receiver. + */ +- (FBLPromise *)always:(FBLPromiseAlwaysWorkBlock)work NS_SWIFT_UNAVAILABLE(""); + +/** + @param queue A queue to dispatch on. + @param work A block that always executes, no matter if the receiver is rejected or fulfilled. + @return A new pending promise to be resolved with same resolution as the receiver. + */ +- (FBLPromise *)onQueue:(dispatch_queue_t)queue + always:(FBLPromiseAlwaysWorkBlock)work NS_REFINED_FOR_SWIFT; + +@end + +/** + Convenience dot-syntax wrappers for `FBLPromise` `always` operators. + Usage: promise.always(^{...}) + */ +@interface FBLPromise(DotSyntax_AlwaysAdditions) + +- (FBLPromise* (^)(FBLPromiseAlwaysWorkBlock))always FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); +- (FBLPromise* (^)(dispatch_queue_t, FBLPromiseAlwaysWorkBlock))alwaysOn FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Any.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Any.h new file mode 100644 index 0000000..82875bf --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Any.h @@ -0,0 +1,69 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FBLPromise(AnyAdditions) + +/** + Waits until all of the given promises are either fulfilled or rejected. + If all promises are rejected, then the returned promise is rejected with same error + as the last one rejected. + If at least one of the promises is fulfilled, the resulting promise is fulfilled with an array of + values or `NSErrors`, matching the original order of fulfilled or rejected promises respectively. + If any other arbitrary value or `NSError` appears in the array instead of `FBLPromise`, + it's implicitly considered a pre-fulfilled or pre-rejected `FBLPromise` correspondingly. + Promises resolved with `nil` become `NSNull` instances in the resulting array. + + @param promises Promises to wait for. + @return Promise of array containing the values or `NSError`s of input promises in the same order. + */ ++ (FBLPromise *)any:(NSArray *)promises NS_SWIFT_UNAVAILABLE(""); + +/** + Waits until all of the given promises are either fulfilled or rejected. + If all promises are rejected, then the returned promise is rejected with same error + as the last one rejected. + If at least one of the promises is fulfilled, the resulting promise is fulfilled with an array of + values or `NSError`s, matching the original order of fulfilled or rejected promises respectively. + If any other arbitrary value or `NSError` appears in the array instead of `FBLPromise`, + it's implicitly considered a pre-fulfilled or pre-rejected `FBLPromise` correspondingly. + Promises resolved with `nil` become `NSNull` instances in the resulting array. + + @param queue A queue to dispatch on. + @param promises Promises to wait for. + @return Promise of array containing the values or `NSError`s of input promises in the same order. + */ ++ (FBLPromise *)onQueue:(dispatch_queue_t)queue + any:(NSArray *)promises NS_REFINED_FOR_SWIFT; + +@end + +/** + Convenience dot-syntax wrappers for `FBLPromise` `any` operators. + Usage: FBLPromise.any(@[ ... ]) + */ +@interface FBLPromise(DotSyntax_AnyAdditions) + ++ (FBLPromise * (^)(NSArray *))any FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise * (^)(dispatch_queue_t, NSArray *))anyOn FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Async.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Async.h new file mode 100644 index 0000000..0588a9e --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Async.h @@ -0,0 +1,60 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FBLPromise(AsyncAdditions) + +typedef void (^FBLPromiseFulfillBlock)(Value __nullable value) NS_SWIFT_UNAVAILABLE(""); +typedef void (^FBLPromiseRejectBlock)(NSError *error) NS_SWIFT_UNAVAILABLE(""); +typedef void (^FBLPromiseAsyncWorkBlock)(FBLPromiseFulfillBlock fulfill, + FBLPromiseRejectBlock reject) NS_SWIFT_UNAVAILABLE(""); + +/** + Creates a pending promise and executes `work` block asynchronously. + + @param work A block to perform any operations needed to resolve the promise. + @return A new pending promise. + */ ++ (instancetype)async:(FBLPromiseAsyncWorkBlock)work NS_SWIFT_UNAVAILABLE(""); + +/** + Creates a pending promise and executes `work` block asynchronously on the given queue. + + @param queue A queue to invoke the `work` block on. + @param work A block to perform any operations needed to resolve the promise. + @return A new pending promise. + */ ++ (instancetype)onQueue:(dispatch_queue_t)queue + async:(FBLPromiseAsyncWorkBlock)work NS_REFINED_FOR_SWIFT; + +@end + +/** + Convenience dot-syntax wrappers for `FBLPromise` `async` operators. + Usage: FBLPromise.async(^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) { ... }) + */ +@interface FBLPromise(DotSyntax_AsyncAdditions) + ++ (FBLPromise* (^)(FBLPromiseAsyncWorkBlock))async FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(dispatch_queue_t, FBLPromiseAsyncWorkBlock))asyncOn FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Await.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Await.h new file mode 100644 index 0000000..c97a1ba --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Await.h @@ -0,0 +1,32 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + Waits for promise resolution. The current thread blocks until the promise is resolved. + + @param promise Promise to wait for. + @param error Error the promise was rejected with, or `nil` if the promise was fulfilled. + @return Value the promise was fulfilled with. If the promise was rejected, the return value + is always `nil`, but the error out arg is not. + */ +FOUNDATION_EXTERN id __nullable FBLPromiseAwait(FBLPromise *promise, + NSError **error) NS_REFINED_FOR_SWIFT; + +NS_ASSUME_NONNULL_END diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Catch.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Catch.h new file mode 100644 index 0000000..a9ff170 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Catch.h @@ -0,0 +1,59 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FBLPromise(CatchAdditions) + +typedef void (^FBLPromiseCatchWorkBlock)(NSError *error) NS_SWIFT_UNAVAILABLE(""); + +/** + Creates a pending promise which eventually gets resolved with same resolution as the receiver. + If receiver is rejected, then `reject` block is executed asynchronously. + + @param reject A block to handle the error that receiver was rejected with. + @return A new pending promise. + */ +- (FBLPromise *)catch:(FBLPromiseCatchWorkBlock)reject NS_SWIFT_UNAVAILABLE(""); + +/** + Creates a pending promise which eventually gets resolved with same resolution as the receiver. + If receiver is rejected, then `reject` block is executed asynchronously on the given queue. + + @param queue A queue to invoke the `reject` block on. + @param reject A block to handle the error that receiver was rejected with. + @return A new pending promise. + */ +- (FBLPromise *)onQueue:(dispatch_queue_t)queue + catch:(FBLPromiseCatchWorkBlock)reject NS_REFINED_FOR_SWIFT; + +@end + +/** + Convenience dot-syntax wrappers for `FBLPromise` `catch` operators. + Usage: promise.catch(^(NSError *error) { ... }) + */ +@interface FBLPromise(DotSyntax_CatchAdditions) + +- (FBLPromise* (^)(FBLPromiseCatchWorkBlock))catch FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); +- (FBLPromise* (^)(dispatch_queue_t, FBLPromiseCatchWorkBlock))catchOn FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Delay.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Delay.h new file mode 100644 index 0000000..557df48 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Delay.h @@ -0,0 +1,59 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FBLPromise(DelayAdditions) + +/** + Creates a new pending promise that fulfills with the same value as `self` after the `delay`, or + rejects with the same error immediately. + + @param interval Time to wait in seconds. + @return A new pending promise that fulfills at least `delay` seconds later than `self`, or rejects + with the same error immediately. + */ +- (FBLPromise *)delay:(NSTimeInterval)interval NS_SWIFT_UNAVAILABLE(""); + +/** + Creates a new pending promise that fulfills with the same value as `self` after the `delay`, or + rejects with the same error immediately. + + @param queue A queue to dispatch on. + @param interval Time to wait in seconds. + @return A new pending promise that fulfills at least `delay` seconds later than `self`, or rejects + with the same error immediately. + */ +- (FBLPromise *)onQueue:(dispatch_queue_t)queue + delay:(NSTimeInterval)interval NS_REFINED_FOR_SWIFT; + +@end + +/** + Convenience dot-syntax wrappers for `FBLPromise` `delay` operators. + Usage: promise.delay(...) + */ +@interface FBLPromise(DotSyntax_DelayAdditions) + +- (FBLPromise * (^)(NSTimeInterval))delay FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); +- (FBLPromise * (^)(dispatch_queue_t, NSTimeInterval))delayOn FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Do.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Do.h new file mode 100644 index 0000000..6838e0a --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Do.h @@ -0,0 +1,55 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FBLPromise(DoAdditions) + +typedef id __nullable (^FBLPromiseDoWorkBlock)(void) NS_SWIFT_UNAVAILABLE(""); + +/** + Creates a pending promise and executes `work` block asynchronously. + + @param work A block that returns a value or an error used to resolve the promise. + @return A new pending promise. + */ ++ (instancetype)do:(FBLPromiseDoWorkBlock)work NS_SWIFT_UNAVAILABLE(""); + +/** + Creates a pending promise and executes `work` block asynchronously on the given queue. + + @param queue A queue to invoke the `work` block on. + @param work A block that returns a value or an error used to resolve the promise. + @return A new pending promise. + */ ++ (instancetype)onQueue:(dispatch_queue_t)queue do:(FBLPromiseDoWorkBlock)work NS_REFINED_FOR_SWIFT; + +@end + +/** + Convenience dot-syntax wrappers for `FBLPromise` `do` operators. + Usage: FBLPromise.doOn(queue, ^(NSError *error) { ... }) + */ +@interface FBLPromise(DotSyntax_DoAdditions) + ++ (FBLPromise * (^)(dispatch_queue_t, FBLPromiseDoWorkBlock))doOn FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Race.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Race.h new file mode 100644 index 0000000..2f67258 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Race.h @@ -0,0 +1,62 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FBLPromise(RaceAdditions) + +/** + Wait until any of the given promises are fulfilled. + If one of the promises is rejected, then the returned promise is rejected with same error. + If any other arbitrary value or `NSError` appears in the array instead of `FBLPromise`, + it's implicitly considered a pre-fulfilled or pre-rejected `FBLPromise` correspondingly. + + @param promises Promises to wait for. + @return A new pending promise to be resolved with the same resolution as the first promise, among + the given ones, which was resolved. + */ ++ (instancetype)race:(NSArray *)promises NS_SWIFT_UNAVAILABLE(""); + +/** + Wait until any of the given promises are fulfilled. + If one of the promises is rejected, then the returned promise is rejected with same error. + If any other arbitrary value or `NSError` appears in the array instead of `FBLPromise`, + it's implicitly considered a pre-fulfilled or pre-rejected `FBLPromise` correspondingly. + + @param queue A queue to dispatch on. + @param promises Promises to wait for. + @return A new pending promise to be resolved with the same resolution as the first promise, among + the given ones, which was resolved. + */ ++ (instancetype)onQueue:(dispatch_queue_t)queue race:(NSArray *)promises NS_REFINED_FOR_SWIFT; + +@end + +/** + Convenience dot-syntax wrappers for `FBLPromise` `race` operators. + Usage: FBLPromise.race(@[ ... ]) + */ +@interface FBLPromise(DotSyntax_RaceAdditions) + ++ (FBLPromise * (^)(NSArray *))race FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise * (^)(dispatch_queue_t, NSArray *))raceOn FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Recover.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Recover.h new file mode 100644 index 0000000..bb7df7e --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Recover.h @@ -0,0 +1,60 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FBLPromise(RecoverAdditions) + +typedef id __nullable (^FBLPromiseRecoverWorkBlock)(NSError *error) NS_SWIFT_UNAVAILABLE(""); + +/** + Provides a new promise to recover in case the receiver gets rejected. + + @param recovery A block to handle the error that the receiver was rejected with. + @return A new pending promise to use instead of the rejected one that gets resolved with resolution + returned from `recovery` block. + */ +- (FBLPromise *)recover:(FBLPromiseRecoverWorkBlock)recovery NS_SWIFT_UNAVAILABLE(""); + +/** + Provides a new promise to recover in case the receiver gets rejected. + + @param queue A queue to dispatch on. + @param recovery A block to handle the error that the receiver was rejected with. + @return A new pending promise to use instead of the rejected one that gets resolved with resolution + returned from `recovery` block. + */ +- (FBLPromise *)onQueue:(dispatch_queue_t)queue + recover:(FBLPromiseRecoverWorkBlock)recovery NS_REFINED_FOR_SWIFT; + +@end + +/** + Convenience dot-syntax wrappers for `FBLPromise` `recover` operators. + Usage: promise.recover(^id(NSError *error) {...}) + */ +@interface FBLPromise(DotSyntax_RecoverAdditions) + +- (FBLPromise * (^)(FBLPromiseRecoverWorkBlock))recover FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); +- (FBLPromise * (^)(dispatch_queue_t, FBLPromiseRecoverWorkBlock))recoverOn FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Reduce.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Reduce.h new file mode 100644 index 0000000..5bb1eee --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Reduce.h @@ -0,0 +1,71 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FBLPromise(ReduceAdditions) + +typedef id __nullable (^FBLPromiseReducerBlock)(Value __nullable partial, id next) + NS_SWIFT_UNAVAILABLE(""); + +/** + Sequentially reduces a collection of values to a single promise using a given combining block + and the value `self` resolves with as initial value. + + @param items An array of values to process in order. + @param reducer A block to combine an accumulating value and an element of the sequence into + the new accumulating value or a promise resolved with it, to be used in the next + call of the `reducer` or returned to the caller. + @return A new pending promise returned from the last `reducer` invocation. + Or `self` if `items` is empty. + */ +- (FBLPromise *)reduce:(NSArray *)items + combine:(FBLPromiseReducerBlock)reducer NS_SWIFT_UNAVAILABLE(""); + +/** + Sequentially reduces a collection of values to a single promise using a given combining block + and the value `self` resolves with as initial value. + + @param queue A queue to dispatch on. + @param items An array of values to process in order. + @param reducer A block to combine an accumulating value and an element of the sequence into + the new accumulating value or a promise resolved with it, to be used in the next + call of the `reducer` or returned to the caller. + @return A new pending promise returned from the last `reducer` invocation. + Or `self` if `items` is empty. + */ +- (FBLPromise *)onQueue:(dispatch_queue_t)queue + reduce:(NSArray *)items + combine:(FBLPromiseReducerBlock)reducer NS_SWIFT_UNAVAILABLE(""); + +@end + +/** + Convenience dot-syntax wrappers for `FBLPromise` `reduce` operators. + Usage: promise.reduce(values, ^id(id partial, id next) { ... }) + */ +@interface FBLPromise(DotSyntax_ReduceAdditions) + +- (FBLPromise * (^)(NSArray *, FBLPromiseReducerBlock))reduce FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); +- (FBLPromise * (^)(dispatch_queue_t, NSArray *, FBLPromiseReducerBlock))reduceOn + FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Retry.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Retry.h new file mode 100644 index 0000000..414a17a --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Retry.h @@ -0,0 +1,165 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise.h" + +NS_ASSUME_NONNULL_BEGIN + +/** The default number of retry attempts is 1. */ +FOUNDATION_EXTERN NSInteger const FBLPromiseRetryDefaultAttemptsCount NS_REFINED_FOR_SWIFT; + +/** The default delay interval before making a retry attempt is 1.0 second. */ +FOUNDATION_EXTERN NSTimeInterval const FBLPromiseRetryDefaultDelayInterval NS_REFINED_FOR_SWIFT; + +@interface FBLPromise(RetryAdditions) + +typedef id __nullable (^FBLPromiseRetryWorkBlock)(void) NS_SWIFT_UNAVAILABLE(""); +typedef BOOL (^FBLPromiseRetryPredicateBlock)(NSInteger, NSError *) NS_SWIFT_UNAVAILABLE(""); + +/** + Creates a pending promise that fulfills with the same value as the promise returned from `work` + block, which executes asynchronously, or rejects with the same error after all retry attempts have + been exhausted. Defaults to `FBLPromiseRetryDefaultAttemptsCount` attempt(s) on rejection where the + `work` block is retried after a delay of `FBLPromiseRetryDefaultDelayInterval` second(s). + + @param work A block that executes asynchronously on the default queue and returns a value or an + error used to resolve the promise. + @return A new pending promise that fulfills with the same value as the promise returned from `work` + block, or rejects with the same error after all retry attempts have been exhausted. + */ ++ (instancetype)retry:(FBLPromiseRetryWorkBlock)work NS_SWIFT_UNAVAILABLE(""); + +/** + Creates a pending promise that fulfills with the same value as the promise returned from `work` + block, which executes asynchronously on the given `queue`, or rejects with the same error after all + retry attempts have been exhausted. Defaults to `FBLPromiseRetryDefaultAttemptsCount` attempt(s) on + rejection where the `work` block is retried on the given `queue` after a delay of + `FBLPromiseRetryDefaultDelayInterval` second(s). + + @param queue A queue to invoke the `work` block on. + @param work A block that executes asynchronously on the given `queue` and returns a value or an + error used to resolve the promise. + @return A new pending promise that fulfills with the same value as the promise returned from `work` + block, or rejects with the same error after all retry attempts have been exhausted. + */ ++ (instancetype)onQueue:(dispatch_queue_t)queue + retry:(FBLPromiseRetryWorkBlock)work NS_SWIFT_UNAVAILABLE(""); + +/** + Creates a pending promise that fulfills with the same value as the promise returned from `work` + block, which executes asynchronously, or rejects with the same error after all retry attempts have + been exhausted. + + @param count Max number of retry attempts. The `work` block will be executed once if the specified + count is less than or equal to zero. + @param work A block that executes asynchronously on the default queue and returns a value or an + error used to resolve the promise. + @return A new pending promise that fulfills with the same value as the promise returned from `work` + block, or rejects with the same error after all retry attempts have been exhausted. + */ ++ (instancetype)attempts:(NSInteger)count + retry:(FBLPromiseRetryWorkBlock)work NS_SWIFT_UNAVAILABLE(""); + +/** + Creates a pending promise that fulfills with the same value as the promise returned from `work` + block, which executes asynchronously on the given `queue`, or rejects with the same error after all + retry attempts have been exhausted. + + @param queue A queue to invoke the `work` block on. + @param count Max number of retry attempts. The `work` block will be executed once if the specified + count is less than or equal to zero. + @param work A block that executes asynchronously on the given `queue` and returns a value or an + error used to resolve the promise. + @return A new pending promise that fulfills with the same value as the promise returned from `work` + block, or rejects with the same error after all retry attempts have been exhausted. + */ ++ (instancetype)onQueue:(dispatch_queue_t)queue + attempts:(NSInteger)count + retry:(FBLPromiseRetryWorkBlock)work NS_SWIFT_UNAVAILABLE(""); + +/** + Creates a pending promise that fulfills with the same value as the promise returned from `work` + block, which executes asynchronously, or rejects with the same error after all retry attempts have + been exhausted. On rejection, the `work` block is retried after the given delay `interval` and will + continue to retry until the number of specified attempts have been exhausted or will bail early if + the given condition is not met. + + @param count Max number of retry attempts. The `work` block will be executed once if the specified + count is less than or equal to zero. + @param interval Time to wait before the next retry attempt. + @param predicate Condition to check before the next retry attempt. The predicate block provides the + the number of remaining retry attempts and the error that the promise was rejected + with. + @param work A block that executes asynchronously on the default queue and returns a value or an + error used to resolve the promise. + @return A new pending promise that fulfills with the same value as the promise returned from `work` + block, or rejects with the same error after all retry attempts have been exhausted or if + the given condition is not met. + */ ++ (instancetype)attempts:(NSInteger)count + delay:(NSTimeInterval)interval + condition:(nullable FBLPromiseRetryPredicateBlock)predicate + retry:(FBLPromiseRetryWorkBlock)work NS_SWIFT_UNAVAILABLE(""); + +/** + Creates a pending promise that fulfills with the same value as the promise returned from `work` + block, which executes asynchronously on the given `queue`, or rejects with the same error after all + retry attempts have been exhausted. On rejection, the `work` block is retried after the given + delay `interval` and will continue to retry until the number of specified attempts have been + exhausted or will bail early if the given condition is not met. + + @param queue A queue to invoke the `work` block on. + @param count Max number of retry attempts. The `work` block will be executed once if the specified + count is less than or equal to zero. + @param interval Time to wait before the next retry attempt. + @param predicate Condition to check before the next retry attempt. The predicate block provides the + the number of remaining retry attempts and the error that the promise was rejected + with. + @param work A block that executes asynchronously on the given `queue` and returns a value or an + error used to resolve the promise. + @return A new pending promise that fulfills with the same value as the promise returned from `work` + block, or rejects with the same error after all retry attempts have been exhausted or if + the given condition is not met. + */ ++ (instancetype)onQueue:(dispatch_queue_t)queue + attempts:(NSInteger)count + delay:(NSTimeInterval)interval + condition:(nullable FBLPromiseRetryPredicateBlock)predicate + retry:(FBLPromiseRetryWorkBlock)work NS_REFINED_FOR_SWIFT; + +@end + +/** + Convenience dot-syntax wrappers for `FBLPromise+Retry` operators. + Usage: FBLPromise.retry(^id { ... }) + */ +@interface FBLPromise(DotSyntax_RetryAdditions) + ++ (FBLPromise * (^)(FBLPromiseRetryWorkBlock))retry FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise * (^)(dispatch_queue_t, FBLPromiseRetryWorkBlock))retryOn FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise * (^)(NSInteger, NSTimeInterval, FBLPromiseRetryPredicateBlock __nullable, + FBLPromiseRetryWorkBlock))retryAgain FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise * (^)(dispatch_queue_t, NSInteger, NSTimeInterval, + FBLPromiseRetryPredicateBlock __nullable, + FBLPromiseRetryWorkBlock))retryAgainOn FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Testing.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Testing.h new file mode 100644 index 0000000..8478ae2 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Testing.h @@ -0,0 +1,57 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + Waits for all scheduled promises blocks. + + @param timeout Maximum time to wait. + @return YES if all promises blocks have completed before the timeout and NO otherwise. + */ +FOUNDATION_EXTERN BOOL FBLWaitForPromisesWithTimeout(NSTimeInterval timeout) NS_REFINED_FOR_SWIFT; + +@interface FBLPromise(TestingAdditions) + +/** + Dispatch group for promises that is typically used to wait for all scheduled blocks. + */ +@property(class, nonatomic, readonly) dispatch_group_t dispatchGroup NS_REFINED_FOR_SWIFT; + +/** + Properties to get the current state of the promise. + */ +@property(nonatomic, readonly) BOOL isPending NS_REFINED_FOR_SWIFT; +@property(nonatomic, readonly) BOOL isFulfilled NS_REFINED_FOR_SWIFT; +@property(nonatomic, readonly) BOOL isRejected NS_REFINED_FOR_SWIFT; + +/** + Value the promise was fulfilled with. + Can be nil if the promise is still pending, was resolved with nil or after it has been rejected. + */ +@property(nonatomic, readonly, nullable) Value value NS_REFINED_FOR_SWIFT; + +/** + Error the promise was rejected with. + Can be nil if the promise is still pending or after it has been fulfilled. + */ +@property(nonatomic, readonly, nullable) NSError *error NS_REFINED_FOR_SWIFT; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Then.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Then.h new file mode 100644 index 0000000..32027e6 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Then.h @@ -0,0 +1,63 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FBLPromise(ThenAdditions) + +typedef id __nullable (^FBLPromiseThenWorkBlock)(Value __nullable value) NS_SWIFT_UNAVAILABLE(""); + +/** + Creates a pending promise which eventually gets resolved with resolution returned from `work` + block: either value, error or another promise. The `work` block is executed asynchronously only + when the receiver is fulfilled. If receiver is rejected, the returned promise is also rejected with + the same error. + + @param work A block to handle the value that receiver was fulfilled with. + @return A new pending promise to be resolved with resolution returned from the `work` block. + */ +- (FBLPromise *)then:(FBLPromiseThenWorkBlock)work NS_SWIFT_UNAVAILABLE(""); + +/** + Creates a pending promise which eventually gets resolved with resolution returned from `work` + block: either value, error or another promise. The `work` block is executed asynchronously when the + receiver is fulfilled. If receiver is rejected, the returned promise is also rejected with the same + error. + + @param queue A queue to invoke the `work` block on. + @param work A block to handle the value that receiver was fulfilled with. + @return A new pending promise to be resolved with resolution returned from the `work` block. + */ +- (FBLPromise *)onQueue:(dispatch_queue_t)queue + then:(FBLPromiseThenWorkBlock)work NS_REFINED_FOR_SWIFT; + +@end + +/** + Convenience dot-syntax wrappers for `FBLPromise` `then` operators. + Usage: promise.then(^id(id value) { ... }) + */ +@interface FBLPromise(DotSyntax_ThenAdditions) + +- (FBLPromise* (^)(FBLPromiseThenWorkBlock))then FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); +- (FBLPromise* (^)(dispatch_queue_t, FBLPromiseThenWorkBlock))thenOn FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Timeout.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Timeout.h new file mode 100644 index 0000000..184ba16 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Timeout.h @@ -0,0 +1,57 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FBLPromise(TimeoutAdditions) + +/** + Waits for a promise with the specified `timeout`. + + @param interval Time to wait in seconds. + @return A new pending promise that gets either resolved with same resolution as the receiver or + rejected with `FBLPromiseErrorCodeTimedOut` error code in `FBLPromiseErrorDomain`. + */ +- (FBLPromise *)timeout:(NSTimeInterval)interval NS_SWIFT_UNAVAILABLE(""); + +/** + Waits for a promise with the specified `timeout`. + + @param queue A queue to dispatch on. + @param interval Time to wait in seconds. + @return A new pending promise that gets either resolved with same resolution as the receiver or + rejected with `FBLPromiseErrorCodeTimedOut` error code in `FBLPromiseErrorDomain`. + */ +- (FBLPromise *)onQueue:(dispatch_queue_t)queue + timeout:(NSTimeInterval)interval NS_REFINED_FOR_SWIFT; + +@end + +/** + Convenience dot-syntax wrappers for `FBLPromise` `timeout` operators. + Usage: promise.timeout(...) + */ +@interface FBLPromise(DotSyntax_TimeoutAdditions) + +- (FBLPromise* (^)(NSTimeInterval))timeout FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); +- (FBLPromise* (^)(dispatch_queue_t, NSTimeInterval))timeoutOn FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Validate.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Validate.h new file mode 100644 index 0000000..9dfa2f1 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Validate.h @@ -0,0 +1,60 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FBLPromise(ValidateAdditions) + +typedef BOOL (^FBLPromiseValidateWorkBlock)(Value __nullable value) NS_SWIFT_UNAVAILABLE(""); + +/** + Validates a fulfilled value or rejects the value if it can not be validated. + + @param predicate An expression to validate. + @return A new pending promise that gets either resolved with same resolution as the receiver or + rejected with `FBLPromiseErrorCodeValidationFailure` error code in `FBLPromiseErrorDomain`. + */ +- (FBLPromise *)validate:(FBLPromiseValidateWorkBlock)predicate NS_SWIFT_UNAVAILABLE(""); + +/** + Validates a fulfilled value or rejects the value if it can not be validated. + + @param queue A queue to dispatch on. + @param predicate An expression to validate. + @return A new pending promise that gets either resolved with same resolution as the receiver or + rejected with `FBLPromiseErrorCodeValidationFailure` error code in `FBLPromiseErrorDomain`. + */ +- (FBLPromise *)onQueue:(dispatch_queue_t)queue + validate:(FBLPromiseValidateWorkBlock)predicate NS_REFINED_FOR_SWIFT; + +@end + +/** + Convenience dot-syntax wrappers for `FBLPromise` `validate` operators. + Usage: promise.validate(^BOOL(id value) { ... }) + */ +@interface FBLPromise(DotSyntax_ValidateAdditions) + +- (FBLPromise * (^)(FBLPromiseValidateWorkBlock))validate FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); +- (FBLPromise * (^)(dispatch_queue_t, FBLPromiseValidateWorkBlock))validateOn + FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Wrap.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Wrap.h new file mode 100644 index 0000000..664e1bb --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise+Wrap.h @@ -0,0 +1,316 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + Different types of completion handlers available to be wrapped with promise. + */ +typedef void (^FBLPromiseCompletion)(void) NS_SWIFT_UNAVAILABLE(""); +typedef void (^FBLPromiseObjectCompletion)(id __nullable) NS_SWIFT_UNAVAILABLE(""); +typedef void (^FBLPromiseErrorCompletion)(NSError* __nullable) NS_SWIFT_UNAVAILABLE(""); +typedef void (^FBLPromiseObjectOrErrorCompletion)(id __nullable, NSError* __nullable) + NS_SWIFT_UNAVAILABLE(""); +typedef void (^FBLPromiseErrorOrObjectCompletion)(NSError* __nullable, id __nullable) + NS_SWIFT_UNAVAILABLE(""); +typedef void (^FBLPromise2ObjectsOrErrorCompletion)(id __nullable, id __nullable, + NSError* __nullable) NS_SWIFT_UNAVAILABLE(""); +typedef void (^FBLPromiseBoolCompletion)(BOOL) NS_SWIFT_UNAVAILABLE(""); +typedef void (^FBLPromiseBoolOrErrorCompletion)(BOOL, NSError* __nullable) NS_SWIFT_UNAVAILABLE(""); +typedef void (^FBLPromiseIntegerCompletion)(NSInteger) NS_SWIFT_UNAVAILABLE(""); +typedef void (^FBLPromiseIntegerOrErrorCompletion)(NSInteger, NSError* __nullable) + NS_SWIFT_UNAVAILABLE(""); +typedef void (^FBLPromiseDoubleCompletion)(double) NS_SWIFT_UNAVAILABLE(""); +typedef void (^FBLPromiseDoubleOrErrorCompletion)(double, NSError* __nullable) + NS_SWIFT_UNAVAILABLE(""); + +/** + Provides an easy way to convert methods that use common callback patterns into promises. + */ +@interface FBLPromise(WrapAdditions) + +/** + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with `nil` when completion handler is invoked. + */ ++ (instancetype)wrapCompletion:(void (^)(FBLPromiseCompletion handler))work + NS_SWIFT_UNAVAILABLE(""); + +/** + @param queue A queue to invoke the `work` block on. + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with `nil` when completion handler is invoked. + */ ++ (instancetype)onQueue:(dispatch_queue_t)queue + wrapCompletion:(void (^)(FBLPromiseCompletion handler))work NS_SWIFT_UNAVAILABLE(""); + +/** + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an object provided by completion handler. + */ ++ (instancetype)wrapObjectCompletion:(void (^)(FBLPromiseObjectCompletion handler))work + NS_SWIFT_UNAVAILABLE(""); + +/** + @param queue A queue to invoke the `work` block on. + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an object provided by completion handler. + */ ++ (instancetype)onQueue:(dispatch_queue_t)queue + wrapObjectCompletion:(void (^)(FBLPromiseObjectCompletion handler))work + NS_SWIFT_UNAVAILABLE(""); + +/** + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an error provided by completion handler. + If error is `nil`, fulfills with `nil`, otherwise rejects with the error. + */ ++ (instancetype)wrapErrorCompletion:(void (^)(FBLPromiseErrorCompletion handler))work + NS_SWIFT_UNAVAILABLE(""); + +/** + @param queue A queue to invoke the `work` block on. + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an error provided by completion handler. + If error is `nil`, fulfills with `nil`, otherwise rejects with the error. + */ ++ (instancetype)onQueue:(dispatch_queue_t)queue + wrapErrorCompletion:(void (^)(FBLPromiseErrorCompletion handler))work NS_SWIFT_UNAVAILABLE(""); + +/** + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an object provided by completion handler if error is `nil`. + Otherwise, rejects with the error. + */ ++ (instancetype)wrapObjectOrErrorCompletion: + (void (^)(FBLPromiseObjectOrErrorCompletion handler))work NS_SWIFT_UNAVAILABLE(""); + +/** + @param queue A queue to invoke the `work` block on. + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an object provided by completion handler if error is `nil`. + Otherwise, rejects with the error. + */ ++ (instancetype)onQueue:(dispatch_queue_t)queue + wrapObjectOrErrorCompletion:(void (^)(FBLPromiseObjectOrErrorCompletion handler))work + NS_SWIFT_UNAVAILABLE(""); + +/** + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an error or object provided by completion handler. If error + is not `nil`, rejects with the error. + */ ++ (instancetype)wrapErrorOrObjectCompletion: + (void (^)(FBLPromiseErrorOrObjectCompletion handler))work NS_SWIFT_UNAVAILABLE(""); + +/** + @param queue A queue to invoke the `work` block on. + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an error or object provided by completion handler. If error + is not `nil`, rejects with the error. + */ ++ (instancetype)onQueue:(dispatch_queue_t)queue + wrapErrorOrObjectCompletion:(void (^)(FBLPromiseErrorOrObjectCompletion handler))work + NS_SWIFT_UNAVAILABLE(""); + +/** + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an array of objects provided by completion handler in order + if error is `nil`. Otherwise, rejects with the error. + */ ++ (FBLPromise*)wrap2ObjectsOrErrorCompletion: + (void (^)(FBLPromise2ObjectsOrErrorCompletion handler))work NS_SWIFT_UNAVAILABLE(""); + +/** + @param queue A queue to invoke the `work` block on. + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an array of objects provided by completion handler in order + if error is `nil`. Otherwise, rejects with the error. + */ ++ (FBLPromise*)onQueue:(dispatch_queue_t)queue + wrap2ObjectsOrErrorCompletion:(void (^)(FBLPromise2ObjectsOrErrorCompletion handler))work + NS_SWIFT_UNAVAILABLE(""); + +/** + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an `NSNumber` wrapping YES/NO. + */ ++ (FBLPromise*)wrapBoolCompletion:(void (^)(FBLPromiseBoolCompletion handler))work + NS_SWIFT_UNAVAILABLE(""); + +/** + @param queue A queue to invoke the `work` block on. + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an `NSNumber` wrapping YES/NO. + */ ++ (FBLPromise*)onQueue:(dispatch_queue_t)queue + wrapBoolCompletion:(void (^)(FBLPromiseBoolCompletion handler))work + NS_SWIFT_UNAVAILABLE(""); + +/** + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an `NSNumber` wrapping YES/NO when error is `nil`. + Otherwise rejects with the error. + */ ++ (FBLPromise*)wrapBoolOrErrorCompletion: + (void (^)(FBLPromiseBoolOrErrorCompletion handler))work NS_SWIFT_UNAVAILABLE(""); + +/** + @param queue A queue to invoke the `work` block on. + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an `NSNumber` wrapping YES/NO when error is `nil`. + Otherwise rejects with the error. + */ ++ (FBLPromise*)onQueue:(dispatch_queue_t)queue + wrapBoolOrErrorCompletion:(void (^)(FBLPromiseBoolOrErrorCompletion handler))work + NS_SWIFT_UNAVAILABLE(""); + +/** + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an `NSNumber` wrapping an integer. + */ ++ (FBLPromise*)wrapIntegerCompletion:(void (^)(FBLPromiseIntegerCompletion handler))work + NS_SWIFT_UNAVAILABLE(""); + +/** + @param queue A queue to invoke the `work` block on. + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an `NSNumber` wrapping an integer. + */ ++ (FBLPromise*)onQueue:(dispatch_queue_t)queue + wrapIntegerCompletion:(void (^)(FBLPromiseIntegerCompletion handler))work + NS_SWIFT_UNAVAILABLE(""); + +/** + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an `NSNumber` wrapping an integer when error is `nil`. + Otherwise rejects with the error. + */ ++ (FBLPromise*)wrapIntegerOrErrorCompletion: + (void (^)(FBLPromiseIntegerOrErrorCompletion handler))work NS_SWIFT_UNAVAILABLE(""); + +/** + @param queue A queue to invoke the `work` block on. + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an `NSNumber` wrapping an integer when error is `nil`. + Otherwise rejects with the error. + */ ++ (FBLPromise*)onQueue:(dispatch_queue_t)queue + wrapIntegerOrErrorCompletion:(void (^)(FBLPromiseIntegerOrErrorCompletion handler))work + NS_SWIFT_UNAVAILABLE(""); + +/** + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an `NSNumber` wrapping a double. + */ ++ (FBLPromise*)wrapDoubleCompletion:(void (^)(FBLPromiseDoubleCompletion handler))work + NS_SWIFT_UNAVAILABLE(""); + +/** + @param queue A queue to invoke the `work` block on. + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an `NSNumber` wrapping a double. + */ ++ (FBLPromise*)onQueue:(dispatch_queue_t)queue + wrapDoubleCompletion:(void (^)(FBLPromiseDoubleCompletion handler))work + NS_SWIFT_UNAVAILABLE(""); + +/** + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an `NSNumber` wrapping a double when error is `nil`. + Otherwise rejects with the error. + */ ++ (FBLPromise*)wrapDoubleOrErrorCompletion: + (void (^)(FBLPromiseDoubleOrErrorCompletion handler))work NS_SWIFT_UNAVAILABLE(""); + +/** + @param queue A queue to invoke the `work` block on. + @param work A block to perform any operations needed to resolve the promise. + @returns A promise that resolves with an `NSNumber` wrapping a double when error is `nil`. + Otherwise rejects with the error. + */ ++ (FBLPromise*)onQueue:(dispatch_queue_t)queue + wrapDoubleOrErrorCompletion:(void (^)(FBLPromiseDoubleOrErrorCompletion handler))work + NS_SWIFT_UNAVAILABLE(""); + +@end + +/** + Convenience dot-syntax wrappers for `FBLPromise` `wrap` operators. + Usage: FBLPromise.wrapCompletion(^(FBLPromiseCompletion handler) {...}) + */ +@interface FBLPromise(DotSyntax_WrapAdditions) + ++ (FBLPromise* (^)(void (^)(FBLPromiseCompletion)))wrapCompletion FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(dispatch_queue_t, void (^)(FBLPromiseCompletion)))wrapCompletionOn + FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(void (^)(FBLPromiseObjectCompletion)))wrapObjectCompletion + FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(dispatch_queue_t, void (^)(FBLPromiseObjectCompletion)))wrapObjectCompletionOn + FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(void (^)(FBLPromiseErrorCompletion)))wrapErrorCompletion FBL_PROMISES_DOT_SYNTAX + NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(dispatch_queue_t, void (^)(FBLPromiseErrorCompletion)))wrapErrorCompletionOn + FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(void (^)(FBLPromiseObjectOrErrorCompletion)))wrapObjectOrErrorCompletion + FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(dispatch_queue_t, + void (^)(FBLPromiseObjectOrErrorCompletion)))wrapObjectOrErrorCompletionOn + FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(void (^)(FBLPromiseErrorOrObjectCompletion)))wrapErrorOrObjectCompletion + FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(dispatch_queue_t, + void (^)(FBLPromiseErrorOrObjectCompletion)))wrapErrorOrObjectCompletionOn + FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(void (^)(FBLPromise2ObjectsOrErrorCompletion))) + wrap2ObjectsOrErrorCompletion FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(dispatch_queue_t, void (^)(FBLPromise2ObjectsOrErrorCompletion))) + wrap2ObjectsOrErrorCompletionOn FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(void (^)(FBLPromiseBoolCompletion)))wrapBoolCompletion + FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(dispatch_queue_t, + void (^)(FBLPromiseBoolCompletion)))wrapBoolCompletionOn + FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(void (^)(FBLPromiseBoolOrErrorCompletion)))wrapBoolOrErrorCompletion + FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(dispatch_queue_t, + void (^)(FBLPromiseBoolOrErrorCompletion)))wrapBoolOrErrorCompletionOn + FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(void (^)(FBLPromiseIntegerCompletion)))wrapIntegerCompletion + FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(dispatch_queue_t, + void (^)(FBLPromiseIntegerCompletion)))wrapIntegerCompletionOn + FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(void (^)(FBLPromiseIntegerOrErrorCompletion))) + wrapIntegerOrErrorCompletion FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(dispatch_queue_t, void (^)(FBLPromiseIntegerOrErrorCompletion))) + wrapIntegerOrErrorCompletionOn FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(void (^)(FBLPromiseDoubleCompletion)))wrapDoubleCompletion + FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(dispatch_queue_t, + void (^)(FBLPromiseDoubleCompletion)))wrapDoubleCompletionOn + FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(void (^)(FBLPromiseDoubleOrErrorCompletion))) + wrapDoubleOrErrorCompletion FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise* (^)(dispatch_queue_t, void (^)(FBLPromiseDoubleOrErrorCompletion))) + wrapDoubleOrErrorCompletionOn FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise.h new file mode 100644 index 0000000..98c813b --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromise.h @@ -0,0 +1,93 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromiseError.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + Promises synchronization construct in Objective-C. + */ +@interface FBLPromise<__covariant Value> : NSObject + +/** + Default dispatch queue used for `FBLPromise`, which is `main` if a queue is not specified. + */ +@property(class) dispatch_queue_t defaultDispatchQueue NS_REFINED_FOR_SWIFT; + +/** + Creates a pending promise. + */ ++ (instancetype)pendingPromise NS_REFINED_FOR_SWIFT; + +/** + Creates a resolved promise. + + @param resolution An object to resolve the promise with: either a value or an error. + @return A new resolved promise. + */ ++ (instancetype)resolvedWith:(nullable id)resolution NS_REFINED_FOR_SWIFT; + +/** + Synchronously fulfills the promise with a value. + + @param value An arbitrary value to fulfill the promise with, including `nil`. + */ +- (void)fulfill:(nullable Value)value NS_REFINED_FOR_SWIFT; + +/** + Synchronously rejects the promise with an error. + + @param error An error to reject the promise with. + */ +- (void)reject:(NSError *)error NS_REFINED_FOR_SWIFT; + ++ (instancetype)new NS_UNAVAILABLE; +- (instancetype)init NS_UNAVAILABLE; +@end + +@interface FBLPromise() + +/** + Adds an object to the set of pending objects to keep strongly while the promise is pending. + Used by the Swift wrappers to keep them alive until the underlying ObjC promise is resolved. + + @param object An object to add. + */ +- (void)addPendingObject:(id)object NS_REFINED_FOR_SWIFT; + +@end + +#ifdef FBL_PROMISES_DOT_SYNTAX_IS_DEPRECATED +#define FBL_PROMISES_DOT_SYNTAX __attribute__((deprecated)) +#else +#define FBL_PROMISES_DOT_SYNTAX +#endif + +@interface FBLPromise(DotSyntaxAdditions) + +/** + Convenience dot-syntax wrappers for FBLPromise. + Usage: FBLPromise.pending() + FBLPromise.resolved(value) + + */ ++ (FBLPromise * (^)(void))pending FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); ++ (FBLPromise * (^)(id __nullable))resolved FBL_PROMISES_DOT_SYNTAX NS_SWIFT_UNAVAILABLE(""); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromiseError.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromiseError.h new file mode 100644 index 0000000..d37af53 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromiseError.h @@ -0,0 +1,43 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 + +NS_ASSUME_NONNULL_BEGIN + +FOUNDATION_EXTERN NSErrorDomain const FBLPromiseErrorDomain NS_REFINED_FOR_SWIFT; + +/** + Possible error codes in `FBLPromiseErrorDomain`. + */ +typedef NS_ENUM(NSInteger, FBLPromiseErrorCode) { + /** Promise failed to resolve in time. */ + FBLPromiseErrorCodeTimedOut = 1, + /** Validation predicate returned false. */ + FBLPromiseErrorCodeValidationFailure = 2, +} NS_REFINED_FOR_SWIFT; + +NS_INLINE BOOL FBLPromiseErrorIsTimedOut(NSError *error) NS_SWIFT_UNAVAILABLE("") { + return error.domain == FBLPromiseErrorDomain && + error.code == FBLPromiseErrorCodeTimedOut; +} + +NS_INLINE BOOL FBLPromiseErrorIsValidationFailure(NSError *error) NS_SWIFT_UNAVAILABLE("") { + return error.domain == FBLPromiseErrorDomain && + error.code == FBLPromiseErrorCodeValidationFailure; +} + +NS_ASSUME_NONNULL_END diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromisePrivate.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromisePrivate.h new file mode 100644 index 0000000..7a132f2 --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromisePrivate.h @@ -0,0 +1,66 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise+Testing.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + Miscellaneous low-level private interfaces available to extend standard FBLPromise functionality. + */ +@interface FBLPromise() + +typedef void (^FBLPromiseOnFulfillBlock)(Value __nullable value) NS_SWIFT_UNAVAILABLE(""); +typedef void (^FBLPromiseOnRejectBlock)(NSError *error) NS_SWIFT_UNAVAILABLE(""); +typedef id __nullable (^__nullable FBLPromiseChainedFulfillBlock)(Value __nullable value) + NS_SWIFT_UNAVAILABLE(""); +typedef id __nullable (^__nullable FBLPromiseChainedRejectBlock)(NSError *error) + NS_SWIFT_UNAVAILABLE(""); + +/** + Creates a pending promise. + */ +- (instancetype)initPending NS_SWIFT_UNAVAILABLE(""); + +/** + Creates a resolved promise. + + @param resolution An object to resolve the promise with: either a value or an error. + @return A new resolved promise. + */ +- (instancetype)initWithResolution:(nullable id)resolution NS_SWIFT_UNAVAILABLE(""); + +/** + Invokes `fulfill` and `reject` blocks on `queue` when the receiver gets either fulfilled or + rejected respectively. + */ +- (void)observeOnQueue:(dispatch_queue_t)queue + fulfill:(FBLPromiseOnFulfillBlock)onFulfill + reject:(FBLPromiseOnRejectBlock)onReject NS_SWIFT_UNAVAILABLE(""); + +/** + Returns a new promise which gets resolved with the return value of `chainedFulfill` or + `chainedReject` blocks respectively. The blocks are invoked when the receiver gets either + fulfilled or rejected. If `nil` is passed to either block arg, the returned promise is resolved + with the same resolution as the receiver. + */ +- (FBLPromise *)chainOnQueue:(dispatch_queue_t)queue + chainedFulfill:(FBLPromiseChainedFulfillBlock)chainedFulfill + chainedReject:(FBLPromiseChainedRejectBlock)chainedReject NS_SWIFT_UNAVAILABLE(""); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromises.h b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromises.h new file mode 100644 index 0000000..2d90bad --- /dev/null +++ b/Pods/PromisesObjC/Sources/FBLPromises/include/FBLPromises.h @@ -0,0 +1,32 @@ +/** + Copyright 2018 Google Inc. All rights reserved. + + 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 "FBLPromise+All.h" +#import "FBLPromise+Always.h" +#import "FBLPromise+Any.h" +#import "FBLPromise+Async.h" +#import "FBLPromise+Await.h" +#import "FBLPromise+Catch.h" +#import "FBLPromise+Delay.h" +#import "FBLPromise+Do.h" +#import "FBLPromise+Race.h" +#import "FBLPromise+Recover.h" +#import "FBLPromise+Reduce.h" +#import "FBLPromise+Retry.h" +#import "FBLPromise+Then.h" +#import "FBLPromise+Timeout.h" +#import "FBLPromise+Validate.h" +#import "FBLPromise+Wrap.h" diff --git a/Pods/Target Support Files/Firebase/Firebase.debug.xcconfig b/Pods/Target Support Files/Firebase/Firebase.debug.xcconfig new file mode 100644 index 0000000..292e77c --- /dev/null +++ b/Pods/Target Support Files/Firebase/Firebase.debug.xcconfig @@ -0,0 +1,17 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Firebase +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" "${PODS_XCFRAMEWORKS_BUILD_DIR}/FirebaseAnalytics/WithoutAdIdSupport" "${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAppMeasurement/WithoutAdIdSupport" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Firebase" "${PODS_ROOT}/Headers/Public" +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "StoreKit" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/Firebase +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Firebase/Firebase.release.xcconfig b/Pods/Target Support Files/Firebase/Firebase.release.xcconfig new file mode 100644 index 0000000..292e77c --- /dev/null +++ b/Pods/Target Support Files/Firebase/Firebase.release.xcconfig @@ -0,0 +1,17 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Firebase +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" "${PODS_XCFRAMEWORKS_BUILD_DIR}/FirebaseAnalytics/WithoutAdIdSupport" "${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAppMeasurement/WithoutAdIdSupport" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Firebase" "${PODS_ROOT}/Headers/Public" +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "StoreKit" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/Firebase +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/FirebaseABTesting/FirebaseABTesting-Info.plist b/Pods/Target Support Files/FirebaseABTesting/FirebaseABTesting-Info.plist new file mode 100644 index 0000000..064f811 --- /dev/null +++ b/Pods/Target Support Files/FirebaseABTesting/FirebaseABTesting-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/FirebaseABTesting/FirebaseABTesting-dummy.m b/Pods/Target Support Files/FirebaseABTesting/FirebaseABTesting-dummy.m new file mode 100644 index 0000000..6b78697 --- /dev/null +++ b/Pods/Target Support Files/FirebaseABTesting/FirebaseABTesting-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_FirebaseABTesting : NSObject +@end +@implementation PodsDummy_FirebaseABTesting +@end diff --git a/Pods/Target Support Files/FirebaseABTesting/FirebaseABTesting-umbrella.h b/Pods/Target Support Files/FirebaseABTesting/FirebaseABTesting-umbrella.h new file mode 100644 index 0000000..6f49ae4 --- /dev/null +++ b/Pods/Target Support Files/FirebaseABTesting/FirebaseABTesting-umbrella.h @@ -0,0 +1,19 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "FirebaseABTesting.h" +#import "FIRExperimentController.h" +#import "FIRLifecycleEvents.h" + +FOUNDATION_EXPORT double FirebaseABTestingVersionNumber; +FOUNDATION_EXPORT const unsigned char FirebaseABTestingVersionString[]; + diff --git a/Pods/Target Support Files/FirebaseABTesting/FirebaseABTesting.debug.xcconfig b/Pods/Target Support Files/FirebaseABTesting/FirebaseABTesting.debug.xcconfig new file mode 100644 index 0000000..9e681f0 --- /dev/null +++ b/Pods/Target Support Files/FirebaseABTesting/FirebaseABTesting.debug.xcconfig @@ -0,0 +1,16 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseABTesting +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC" +GCC_C_LANGUAGE_STANDARD = c99 +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_TARGET_SRCROOT}" +OTHER_LDFLAGS = $(inherited) -framework "FirebaseCore" -framework "Foundation" -framework "UIKit" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseABTesting +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/FirebaseABTesting/FirebaseABTesting.modulemap b/Pods/Target Support Files/FirebaseABTesting/FirebaseABTesting.modulemap new file mode 100644 index 0000000..6531b1a --- /dev/null +++ b/Pods/Target Support Files/FirebaseABTesting/FirebaseABTesting.modulemap @@ -0,0 +1,6 @@ +framework module FirebaseABTesting { + umbrella header "FirebaseABTesting-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/FirebaseABTesting/FirebaseABTesting.release.xcconfig b/Pods/Target Support Files/FirebaseABTesting/FirebaseABTesting.release.xcconfig new file mode 100644 index 0000000..9e681f0 --- /dev/null +++ b/Pods/Target Support Files/FirebaseABTesting/FirebaseABTesting.release.xcconfig @@ -0,0 +1,16 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseABTesting +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC" +GCC_C_LANGUAGE_STANDARD = c99 +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_TARGET_SRCROOT}" +OTHER_LDFLAGS = $(inherited) -framework "FirebaseCore" -framework "Foundation" -framework "UIKit" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseABTesting +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/FirebaseABTesting/ResourceBundle-FirebaseABTesting_Privacy-FirebaseABTesting-Info.plist b/Pods/Target Support Files/FirebaseABTesting/ResourceBundle-FirebaseABTesting_Privacy-FirebaseABTesting-Info.plist new file mode 100644 index 0000000..3f8fb7d --- /dev/null +++ b/Pods/Target Support Files/FirebaseABTesting/ResourceBundle-FirebaseABTesting_Privacy-FirebaseABTesting-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks-input-files.xcfilelist b/Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks-input-files.xcfilelist new file mode 100644 index 0000000..09a3da3 --- /dev/null +++ b/Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks-input-files.xcfilelist @@ -0,0 +1,2 @@ +${PODS_ROOT}/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks.sh +${PODS_ROOT}/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework \ No newline at end of file diff --git a/Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks-output-files.xcfilelist b/Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks-output-files.xcfilelist new file mode 100644 index 0000000..1fd9cca --- /dev/null +++ b/Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks-output-files.xcfilelist @@ -0,0 +1 @@ +${PODS_XCFRAMEWORKS_BUILD_DIR}/FirebaseAnalytics/WithoutAdIdSupport/FirebaseAnalytics.framework \ No newline at end of file diff --git a/Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks.sh b/Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks.sh new file mode 100755 index 0000000..a654265 --- /dev/null +++ b/Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks.sh @@ -0,0 +1,145 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +function on_error { + echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" +} +trap 'on_error $LINENO' ERR + + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + + +variant_for_slice() +{ + case "$1" in + "FirebaseAnalytics.xcframework/ios-arm64") + echo "" + ;; + "FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst") + echo "maccatalyst" + ;; + "FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator") + echo "simulator" + ;; + "FirebaseAnalytics.xcframework/macos-arm64_x86_64") + echo "" + ;; + "FirebaseAnalytics.xcframework/tvos-arm64") + echo "" + ;; + "FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator") + echo "simulator" + ;; + esac +} + +archs_for_slice() +{ + case "$1" in + "FirebaseAnalytics.xcframework/ios-arm64") + echo "arm64" + ;; + "FirebaseAnalytics.xcframework/ios-arm64_x86_64-maccatalyst") + echo "arm64 x86_64" + ;; + "FirebaseAnalytics.xcframework/ios-arm64_x86_64-simulator") + echo "arm64 x86_64" + ;; + "FirebaseAnalytics.xcframework/macos-arm64_x86_64") + echo "arm64 x86_64" + ;; + "FirebaseAnalytics.xcframework/tvos-arm64") + echo "arm64" + ;; + "FirebaseAnalytics.xcframework/tvos-arm64_x86_64-simulator") + echo "arm64 x86_64" + ;; + esac +} + +copy_dir() +{ + local source="$1" + local destination="$2" + + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" \"${source}*\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" "${source}"/* "${destination}" +} + +SELECT_SLICE_RETVAL="" + +select_slice() { + local xcframework_name="$1" + xcframework_name="${xcframework_name##*/}" + local paths=("${@:2}") + # Locate the correct slice of the .xcframework for the current architectures + local target_path="" + + # Split archs on space so we can find a slice that has all the needed archs + local target_archs=$(echo $ARCHS | tr " " "\n") + + local target_variant="" + if [[ "$PLATFORM_NAME" == *"simulator" ]]; then + target_variant="simulator" + fi + if [[ ! -z ${EFFECTIVE_PLATFORM_NAME+x} && "$EFFECTIVE_PLATFORM_NAME" == *"maccatalyst" ]]; then + target_variant="maccatalyst" + fi + for i in ${!paths[@]}; do + local matched_all_archs="1" + local slice_archs="$(archs_for_slice "${xcframework_name}/${paths[$i]}")" + local slice_variant="$(variant_for_slice "${xcframework_name}/${paths[$i]}")" + for target_arch in $target_archs; do + if ! [[ "${slice_variant}" == "$target_variant" ]]; then + matched_all_archs="0" + break + fi + + if ! echo "${slice_archs}" | tr " " "\n" | grep -F -q -x "$target_arch"; then + matched_all_archs="0" + break + fi + done + + if [[ "$matched_all_archs" == "1" ]]; then + # Found a matching slice + echo "Selected xcframework slice ${paths[$i]}" + SELECT_SLICE_RETVAL=${paths[$i]} + break + fi + done +} + +install_xcframework() { + local basepath="$1" + local name="$2" + local package_type="$3" + local paths=("${@:4}") + + # Locate the correct slice of the .xcframework for the current architectures + select_slice "${basepath}" "${paths[@]}" + local target_path="$SELECT_SLICE_RETVAL" + if [[ -z "$target_path" ]]; then + echo "warning: [CP] $(basename ${basepath}): Unable to find matching slice in '${paths[@]}' for the current build architectures ($ARCHS) and platform (${EFFECTIVE_PLATFORM_NAME-${PLATFORM_NAME}})." + return + fi + local source="$basepath/$target_path" + + local destination="${PODS_XCFRAMEWORKS_BUILD_DIR}/${name}" + + if [ ! -d "$destination" ]; then + mkdir -p "$destination" + fi + + copy_dir "$source/" "$destination" + echo "Copied $source to $destination" +} + +install_xcframework "${PODS_ROOT}/FirebaseAnalytics/Frameworks/FirebaseAnalytics.xcframework" "FirebaseAnalytics/WithoutAdIdSupport" "framework" "ios-arm64" "ios-arm64_x86_64-maccatalyst" "ios-arm64_x86_64-simulator" + diff --git a/Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics.debug.xcconfig b/Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics.debug.xcconfig new file mode 100644 index 0000000..8f5f7f4 --- /dev/null +++ b/Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics.debug.xcconfig @@ -0,0 +1,16 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseAnalytics +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" "${PODS_XCFRAMEWORKS_BUILD_DIR}/FirebaseAnalytics/WithoutAdIdSupport" "${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAppMeasurement/WithoutAdIdSupport" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -l"c++" -l"sqlite3" -l"z" -framework "StoreKit" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseAnalytics +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics.release.xcconfig b/Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics.release.xcconfig new file mode 100644 index 0000000..8f5f7f4 --- /dev/null +++ b/Pods/Target Support Files/FirebaseAnalytics/FirebaseAnalytics.release.xcconfig @@ -0,0 +1,16 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseAnalytics +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" "${PODS_XCFRAMEWORKS_BUILD_DIR}/FirebaseAnalytics/WithoutAdIdSupport" "${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAppMeasurement/WithoutAdIdSupport" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -l"c++" -l"sqlite3" -l"z" -framework "StoreKit" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseAnalytics +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/FirebaseCore/FirebaseCore-Info.plist b/Pods/Target Support Files/FirebaseCore/FirebaseCore-Info.plist new file mode 100644 index 0000000..7452320 --- /dev/null +++ b/Pods/Target Support Files/FirebaseCore/FirebaseCore-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 10.28.1 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/FirebaseCore/FirebaseCore-dummy.m b/Pods/Target Support Files/FirebaseCore/FirebaseCore-dummy.m new file mode 100644 index 0000000..4f1eb27 --- /dev/null +++ b/Pods/Target Support Files/FirebaseCore/FirebaseCore-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_FirebaseCore : NSObject +@end +@implementation PodsDummy_FirebaseCore +@end diff --git a/Pods/Target Support Files/FirebaseCore/FirebaseCore-umbrella.h b/Pods/Target Support Files/FirebaseCore/FirebaseCore-umbrella.h new file mode 100644 index 0000000..0f96d94 --- /dev/null +++ b/Pods/Target Support Files/FirebaseCore/FirebaseCore-umbrella.h @@ -0,0 +1,22 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "FIRApp.h" +#import "FIRConfiguration.h" +#import "FirebaseCore.h" +#import "FIRLoggerLevel.h" +#import "FIROptions.h" +#import "FIRVersion.h" + +FOUNDATION_EXPORT double FirebaseCoreVersionNumber; +FOUNDATION_EXPORT const unsigned char FirebaseCoreVersionString[]; + diff --git a/Pods/Target Support Files/FirebaseCore/FirebaseCore.debug.xcconfig b/Pods/Target Support Files/FirebaseCore/FirebaseCore.debug.xcconfig new file mode 100644 index 0000000..2bf043a --- /dev/null +++ b/Pods/Target Support Files/FirebaseCore/FirebaseCore.debug.xcconfig @@ -0,0 +1,17 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC" +GCC_C_LANGUAGE_STANDARD = c99 +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 Firebase_VERSION=10.28.1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_TARGET_SRCROOT}" +OTHER_CFLAGS = $(inherited) -fno-autolink +OTHER_LDFLAGS = $(inherited) -framework "FirebaseCoreInternal" -framework "Foundation" -framework "GoogleUtilities" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseCore +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/FirebaseCore/FirebaseCore.modulemap b/Pods/Target Support Files/FirebaseCore/FirebaseCore.modulemap new file mode 100644 index 0000000..4c38b87 --- /dev/null +++ b/Pods/Target Support Files/FirebaseCore/FirebaseCore.modulemap @@ -0,0 +1,6 @@ +framework module FirebaseCore { + umbrella header "FirebaseCore-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/FirebaseCore/FirebaseCore.release.xcconfig b/Pods/Target Support Files/FirebaseCore/FirebaseCore.release.xcconfig new file mode 100644 index 0000000..2bf043a --- /dev/null +++ b/Pods/Target Support Files/FirebaseCore/FirebaseCore.release.xcconfig @@ -0,0 +1,17 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC" +GCC_C_LANGUAGE_STANDARD = c99 +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 Firebase_VERSION=10.28.1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_TARGET_SRCROOT}" +OTHER_CFLAGS = $(inherited) -fno-autolink +OTHER_LDFLAGS = $(inherited) -framework "FirebaseCoreInternal" -framework "Foundation" -framework "GoogleUtilities" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseCore +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/FirebaseCore/ResourceBundle-FirebaseCore_Privacy-FirebaseCore-Info.plist b/Pods/Target Support Files/FirebaseCore/ResourceBundle-FirebaseCore_Privacy-FirebaseCore-Info.plist new file mode 100644 index 0000000..f6631e5 --- /dev/null +++ b/Pods/Target Support Files/FirebaseCore/ResourceBundle-FirebaseCore_Privacy-FirebaseCore-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 10.28.1 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal-Info.plist b/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal-Info.plist new file mode 100644 index 0000000..064f811 --- /dev/null +++ b/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal-dummy.m b/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal-dummy.m new file mode 100644 index 0000000..1eb5767 --- /dev/null +++ b/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_FirebaseCoreInternal : NSObject +@end +@implementation PodsDummy_FirebaseCoreInternal +@end diff --git a/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal-prefix.pch b/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal-umbrella.h b/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal-umbrella.h new file mode 100644 index 0000000..559d38b --- /dev/null +++ b/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double FirebaseCoreInternalVersionNumber; +FOUNDATION_EXPORT const unsigned char FirebaseCoreInternalVersionString[]; + diff --git a/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal.debug.xcconfig b/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal.debug.xcconfig new file mode 100644 index 0000000..8f87c2f --- /dev/null +++ b/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal.debug.xcconfig @@ -0,0 +1,16 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "GoogleUtilities" -framework "Security" -framework "SystemConfiguration" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseCoreInternal +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal.modulemap b/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal.modulemap new file mode 100644 index 0000000..c5a589e --- /dev/null +++ b/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal.modulemap @@ -0,0 +1,6 @@ +framework module FirebaseCoreInternal { + umbrella header "FirebaseCoreInternal-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal.release.xcconfig b/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal.release.xcconfig new file mode 100644 index 0000000..8f87c2f --- /dev/null +++ b/Pods/Target Support Files/FirebaseCoreInternal/FirebaseCoreInternal.release.xcconfig @@ -0,0 +1,16 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "GoogleUtilities" -framework "Security" -framework "SystemConfiguration" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseCoreInternal +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/FirebaseCoreInternal/ResourceBundle-FirebaseCoreInternal_Privacy-FirebaseCoreInternal-Info.plist b/Pods/Target Support Files/FirebaseCoreInternal/ResourceBundle-FirebaseCoreInternal_Privacy-FirebaseCoreInternal-Info.plist new file mode 100644 index 0000000..3f8fb7d --- /dev/null +++ b/Pods/Target Support Files/FirebaseCoreInternal/ResourceBundle-FirebaseCoreInternal_Privacy-FirebaseCoreInternal-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations-Info.plist b/Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations-Info.plist new file mode 100644 index 0000000..064f811 --- /dev/null +++ b/Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations-dummy.m b/Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations-dummy.m new file mode 100644 index 0000000..ae19551 --- /dev/null +++ b/Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_FirebaseInstallations : NSObject +@end +@implementation PodsDummy_FirebaseInstallations +@end diff --git a/Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations-umbrella.h b/Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations-umbrella.h new file mode 100644 index 0000000..431ef45 --- /dev/null +++ b/Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations-umbrella.h @@ -0,0 +1,20 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "FirebaseInstallations.h" +#import "FIRInstallations.h" +#import "FIRInstallationsAuthTokenResult.h" +#import "FIRInstallationsErrors.h" + +FOUNDATION_EXPORT double FirebaseInstallationsVersionNumber; +FOUNDATION_EXPORT const unsigned char FirebaseInstallationsVersionString[]; + diff --git a/Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations.debug.xcconfig b/Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations.debug.xcconfig new file mode 100644 index 0000000..c878136 --- /dev/null +++ b/Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations.debug.xcconfig @@ -0,0 +1,16 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC" +GCC_C_LANGUAGE_STANDARD = c99 +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_TARGET_SRCROOT}" +OTHER_LDFLAGS = $(inherited) -framework "FBLPromises" -framework "FirebaseCore" -framework "Foundation" -framework "GoogleUtilities" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseInstallations +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations.modulemap b/Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations.modulemap new file mode 100644 index 0000000..f6e2a29 --- /dev/null +++ b/Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations.modulemap @@ -0,0 +1,6 @@ +framework module FirebaseInstallations { + umbrella header "FirebaseInstallations-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations.release.xcconfig b/Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations.release.xcconfig new file mode 100644 index 0000000..c878136 --- /dev/null +++ b/Pods/Target Support Files/FirebaseInstallations/FirebaseInstallations.release.xcconfig @@ -0,0 +1,16 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC" +GCC_C_LANGUAGE_STANDARD = c99 +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_TARGET_SRCROOT}" +OTHER_LDFLAGS = $(inherited) -framework "FBLPromises" -framework "FirebaseCore" -framework "Foundation" -framework "GoogleUtilities" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseInstallations +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/FirebaseInstallations/ResourceBundle-FirebaseInstallations_Privacy-FirebaseInstallations-Info.plist b/Pods/Target Support Files/FirebaseInstallations/ResourceBundle-FirebaseInstallations_Privacy-FirebaseInstallations-Info.plist new file mode 100644 index 0000000..3f8fb7d --- /dev/null +++ b/Pods/Target Support Files/FirebaseInstallations/ResourceBundle-FirebaseInstallations_Privacy-FirebaseInstallations-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig-Info.plist b/Pods/Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig-Info.plist new file mode 100644 index 0000000..064f811 --- /dev/null +++ b/Pods/Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig-dummy.m b/Pods/Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig-dummy.m new file mode 100644 index 0000000..641c58f --- /dev/null +++ b/Pods/Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_FirebaseRemoteConfig : NSObject +@end +@implementation PodsDummy_FirebaseRemoteConfig +@end diff --git a/Pods/Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig-umbrella.h b/Pods/Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig-umbrella.h new file mode 100644 index 0000000..a9a8d06 --- /dev/null +++ b/Pods/Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig-umbrella.h @@ -0,0 +1,18 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "FirebaseRemoteConfig.h" +#import "FIRRemoteConfig.h" + +FOUNDATION_EXPORT double FirebaseRemoteConfigVersionNumber; +FOUNDATION_EXPORT const unsigned char FirebaseRemoteConfigVersionString[]; + diff --git a/Pods/Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig.debug.xcconfig b/Pods/Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig.debug.xcconfig new file mode 100644 index 0000000..46794b2 --- /dev/null +++ b/Pods/Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig.debug.xcconfig @@ -0,0 +1,18 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseRemoteConfig +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseABTesting" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseRemoteConfigInterop" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseSharedSwift" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC" +GCC_C_LANGUAGE_STANDARD = c99 +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_TARGET_SRCROOT}" +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "FirebaseABTesting" -framework "FirebaseCore" -framework "FirebaseInstallations" -framework "FirebaseRemoteConfigInterop" -framework "FirebaseSharedSwift" -framework "Foundation" -framework "GoogleUtilities" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseRemoteConfig +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig.modulemap b/Pods/Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig.modulemap new file mode 100644 index 0000000..b6bcfa8 --- /dev/null +++ b/Pods/Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig.modulemap @@ -0,0 +1,6 @@ +framework module FirebaseRemoteConfig { + umbrella header "FirebaseRemoteConfig-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig.release.xcconfig b/Pods/Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig.release.xcconfig new file mode 100644 index 0000000..46794b2 --- /dev/null +++ b/Pods/Target Support Files/FirebaseRemoteConfig/FirebaseRemoteConfig.release.xcconfig @@ -0,0 +1,18 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseRemoteConfig +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseABTesting" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseRemoteConfigInterop" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseSharedSwift" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC" +GCC_C_LANGUAGE_STANDARD = c99 +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_TARGET_SRCROOT}" +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "FirebaseABTesting" -framework "FirebaseCore" -framework "FirebaseInstallations" -framework "FirebaseRemoteConfigInterop" -framework "FirebaseSharedSwift" -framework "Foundation" -framework "GoogleUtilities" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseRemoteConfig +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/FirebaseRemoteConfig/ResourceBundle-FirebaseRemoteConfig_Privacy-FirebaseRemoteConfig-Info.plist b/Pods/Target Support Files/FirebaseRemoteConfig/ResourceBundle-FirebaseRemoteConfig_Privacy-FirebaseRemoteConfig-Info.plist new file mode 100644 index 0000000..3f8fb7d --- /dev/null +++ b/Pods/Target Support Files/FirebaseRemoteConfig/ResourceBundle-FirebaseRemoteConfig_Privacy-FirebaseRemoteConfig-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop-Info.plist b/Pods/Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop-Info.plist new file mode 100644 index 0000000..064f811 --- /dev/null +++ b/Pods/Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop-dummy.m b/Pods/Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop-dummy.m new file mode 100644 index 0000000..5d07229 --- /dev/null +++ b/Pods/Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_FirebaseRemoteConfigInterop : NSObject +@end +@implementation PodsDummy_FirebaseRemoteConfigInterop +@end diff --git a/Pods/Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop-umbrella.h b/Pods/Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop-umbrella.h new file mode 100644 index 0000000..192520e --- /dev/null +++ b/Pods/Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double FirebaseRemoteConfigInteropVersionNumber; +FOUNDATION_EXPORT const unsigned char FirebaseRemoteConfigInteropVersionString[]; + diff --git a/Pods/Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop.debug.xcconfig b/Pods/Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop.debug.xcconfig new file mode 100644 index 0000000..9cec78a --- /dev/null +++ b/Pods/Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop.debug.xcconfig @@ -0,0 +1,14 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseRemoteConfigInterop +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseRemoteConfigInterop +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop.modulemap b/Pods/Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop.modulemap new file mode 100644 index 0000000..45f9a1a --- /dev/null +++ b/Pods/Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop.modulemap @@ -0,0 +1,6 @@ +framework module FirebaseRemoteConfigInterop { + umbrella header "FirebaseRemoteConfigInterop-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop.release.xcconfig b/Pods/Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop.release.xcconfig new file mode 100644 index 0000000..9cec78a --- /dev/null +++ b/Pods/Target Support Files/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop.release.xcconfig @@ -0,0 +1,14 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseRemoteConfigInterop +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseRemoteConfigInterop +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift-Info.plist b/Pods/Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift-Info.plist new file mode 100644 index 0000000..064f811 --- /dev/null +++ b/Pods/Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 10.28.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift-dummy.m b/Pods/Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift-dummy.m new file mode 100644 index 0000000..0e9c3a1 --- /dev/null +++ b/Pods/Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_FirebaseSharedSwift : NSObject +@end +@implementation PodsDummy_FirebaseSharedSwift +@end diff --git a/Pods/Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift-umbrella.h b/Pods/Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift-umbrella.h new file mode 100644 index 0000000..273677a --- /dev/null +++ b/Pods/Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double FirebaseSharedSwiftVersionNumber; +FOUNDATION_EXPORT const unsigned char FirebaseSharedSwiftVersionString[]; + diff --git a/Pods/Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift.debug.xcconfig b/Pods/Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift.debug.xcconfig new file mode 100644 index 0000000..df94f10 --- /dev/null +++ b/Pods/Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift.debug.xcconfig @@ -0,0 +1,14 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseSharedSwift +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseSharedSwift +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift.modulemap b/Pods/Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift.modulemap new file mode 100644 index 0000000..a4ee23b --- /dev/null +++ b/Pods/Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift.modulemap @@ -0,0 +1,6 @@ +framework module FirebaseSharedSwift { + umbrella header "FirebaseSharedSwift-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift.release.xcconfig b/Pods/Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift.release.xcconfig new file mode 100644 index 0000000..df94f10 --- /dev/null +++ b/Pods/Target Support Files/FirebaseSharedSwift/FirebaseSharedSwift.release.xcconfig @@ -0,0 +1,14 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseSharedSwift +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseSharedSwift +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement-xcframeworks-input-files.xcfilelist b/Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement-xcframeworks-input-files.xcfilelist new file mode 100644 index 0000000..e940d70 --- /dev/null +++ b/Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement-xcframeworks-input-files.xcfilelist @@ -0,0 +1,2 @@ +${PODS_ROOT}/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement-xcframeworks.sh +${PODS_ROOT}/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework \ No newline at end of file diff --git a/Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement-xcframeworks-output-files.xcfilelist b/Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement-xcframeworks-output-files.xcfilelist new file mode 100644 index 0000000..cb6b234 --- /dev/null +++ b/Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement-xcframeworks-output-files.xcfilelist @@ -0,0 +1 @@ +${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAppMeasurement/WithoutAdIdSupport/GoogleAppMeasurement.framework \ No newline at end of file diff --git a/Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement-xcframeworks.sh b/Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement-xcframeworks.sh new file mode 100755 index 0000000..5171a60 --- /dev/null +++ b/Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement-xcframeworks.sh @@ -0,0 +1,145 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +function on_error { + echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" +} +trap 'on_error $LINENO' ERR + + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + + +variant_for_slice() +{ + case "$1" in + "GoogleAppMeasurement.xcframework/ios-arm64") + echo "" + ;; + "GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst") + echo "maccatalyst" + ;; + "GoogleAppMeasurement.xcframework/ios-arm64_x86_64-simulator") + echo "simulator" + ;; + "GoogleAppMeasurement.xcframework/macos-arm64_x86_64") + echo "" + ;; + "GoogleAppMeasurement.xcframework/tvos-arm64") + echo "" + ;; + "GoogleAppMeasurement.xcframework/tvos-arm64_x86_64-simulator") + echo "simulator" + ;; + esac +} + +archs_for_slice() +{ + case "$1" in + "GoogleAppMeasurement.xcframework/ios-arm64") + echo "arm64" + ;; + "GoogleAppMeasurement.xcframework/ios-arm64_x86_64-maccatalyst") + echo "arm64 x86_64" + ;; + "GoogleAppMeasurement.xcframework/ios-arm64_x86_64-simulator") + echo "arm64 x86_64" + ;; + "GoogleAppMeasurement.xcframework/macos-arm64_x86_64") + echo "arm64 x86_64" + ;; + "GoogleAppMeasurement.xcframework/tvos-arm64") + echo "arm64" + ;; + "GoogleAppMeasurement.xcframework/tvos-arm64_x86_64-simulator") + echo "arm64 x86_64" + ;; + esac +} + +copy_dir() +{ + local source="$1" + local destination="$2" + + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" \"${source}*\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" "${source}"/* "${destination}" +} + +SELECT_SLICE_RETVAL="" + +select_slice() { + local xcframework_name="$1" + xcframework_name="${xcframework_name##*/}" + local paths=("${@:2}") + # Locate the correct slice of the .xcframework for the current architectures + local target_path="" + + # Split archs on space so we can find a slice that has all the needed archs + local target_archs=$(echo $ARCHS | tr " " "\n") + + local target_variant="" + if [[ "$PLATFORM_NAME" == *"simulator" ]]; then + target_variant="simulator" + fi + if [[ ! -z ${EFFECTIVE_PLATFORM_NAME+x} && "$EFFECTIVE_PLATFORM_NAME" == *"maccatalyst" ]]; then + target_variant="maccatalyst" + fi + for i in ${!paths[@]}; do + local matched_all_archs="1" + local slice_archs="$(archs_for_slice "${xcframework_name}/${paths[$i]}")" + local slice_variant="$(variant_for_slice "${xcframework_name}/${paths[$i]}")" + for target_arch in $target_archs; do + if ! [[ "${slice_variant}" == "$target_variant" ]]; then + matched_all_archs="0" + break + fi + + if ! echo "${slice_archs}" | tr " " "\n" | grep -F -q -x "$target_arch"; then + matched_all_archs="0" + break + fi + done + + if [[ "$matched_all_archs" == "1" ]]; then + # Found a matching slice + echo "Selected xcframework slice ${paths[$i]}" + SELECT_SLICE_RETVAL=${paths[$i]} + break + fi + done +} + +install_xcframework() { + local basepath="$1" + local name="$2" + local package_type="$3" + local paths=("${@:4}") + + # Locate the correct slice of the .xcframework for the current architectures + select_slice "${basepath}" "${paths[@]}" + local target_path="$SELECT_SLICE_RETVAL" + if [[ -z "$target_path" ]]; then + echo "warning: [CP] $(basename ${basepath}): Unable to find matching slice in '${paths[@]}' for the current build architectures ($ARCHS) and platform (${EFFECTIVE_PLATFORM_NAME-${PLATFORM_NAME}})." + return + fi + local source="$basepath/$target_path" + + local destination="${PODS_XCFRAMEWORKS_BUILD_DIR}/${name}" + + if [ ! -d "$destination" ]; then + mkdir -p "$destination" + fi + + copy_dir "$source/" "$destination" + echo "Copied $source to $destination" +} + +install_xcframework "${PODS_ROOT}/GoogleAppMeasurement/Frameworks/GoogleAppMeasurement.xcframework" "GoogleAppMeasurement/WithoutAdIdSupport" "framework" "ios-arm64" "ios-arm64_x86_64-maccatalyst" "ios-arm64_x86_64-simulator" + diff --git a/Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement.debug.xcconfig b/Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement.debug.xcconfig new file mode 100644 index 0000000..f124137 --- /dev/null +++ b/Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement.debug.xcconfig @@ -0,0 +1,14 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/GoogleAppMeasurement +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" "${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAppMeasurement/WithoutAdIdSupport" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = $(inherited) -l"c++" -l"sqlite3" -l"z" -framework "StoreKit" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/GoogleAppMeasurement +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement.release.xcconfig b/Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement.release.xcconfig new file mode 100644 index 0000000..f124137 --- /dev/null +++ b/Pods/Target Support Files/GoogleAppMeasurement/GoogleAppMeasurement.release.xcconfig @@ -0,0 +1,14 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/GoogleAppMeasurement +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" "${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAppMeasurement/WithoutAdIdSupport" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = $(inherited) -l"c++" -l"sqlite3" -l"z" -framework "StoreKit" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/GoogleAppMeasurement +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/GoogleUtilities/GoogleUtilities-Info.plist b/Pods/Target Support Files/GoogleUtilities/GoogleUtilities-Info.plist new file mode 100644 index 0000000..152a3f1 --- /dev/null +++ b/Pods/Target Support Files/GoogleUtilities/GoogleUtilities-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 7.13.3 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/GoogleUtilities/GoogleUtilities-dummy.m b/Pods/Target Support Files/GoogleUtilities/GoogleUtilities-dummy.m new file mode 100644 index 0000000..98ac4e9 --- /dev/null +++ b/Pods/Target Support Files/GoogleUtilities/GoogleUtilities-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_GoogleUtilities : NSObject +@end +@implementation PodsDummy_GoogleUtilities +@end diff --git a/Pods/Target Support Files/GoogleUtilities/GoogleUtilities-umbrella.h b/Pods/Target Support Files/GoogleUtilities/GoogleUtilities-umbrella.h new file mode 100644 index 0000000..94dd095 --- /dev/null +++ b/Pods/Target Support Files/GoogleUtilities/GoogleUtilities-umbrella.h @@ -0,0 +1,42 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "GULAppDelegateSwizzler.h" +#import "GULApplication.h" +#import "GULSceneDelegateSwizzler.h" +#import "GULAppEnvironmentUtil.h" +#import "GULHeartbeatDateStorable.h" +#import "GULHeartbeatDateStorage.h" +#import "GULHeartbeatDateStorageUserDefaults.h" +#import "GULKeychainStorage.h" +#import "GULKeychainUtils.h" +#import "GULNetworkInfo.h" +#import "GULSecureCoding.h" +#import "GULURLSessionDataResponse.h" +#import "NSURLSession+GULPromises.h" +#import "GULLogger.h" +#import "GULLoggerLevel.h" +#import "GULOriginalIMPConvenienceMacros.h" +#import "GULSwizzler.h" +#import "GULNSData+zlib.h" +#import "GULMutableDictionary.h" +#import "GULNetwork.h" +#import "GULNetworkConstants.h" +#import "GULNetworkLoggerProtocol.h" +#import "GULNetworkMessageCode.h" +#import "GULNetworkURLSession.h" +#import "GULReachabilityChecker.h" +#import "GULUserDefaults.h" + +FOUNDATION_EXPORT double GoogleUtilitiesVersionNumber; +FOUNDATION_EXPORT const unsigned char GoogleUtilitiesVersionString[]; + diff --git a/Pods/Target Support Files/GoogleUtilities/GoogleUtilities.debug.xcconfig b/Pods/Target Support Files/GoogleUtilities/GoogleUtilities.debug.xcconfig new file mode 100644 index 0000000..d3cff7f --- /dev/null +++ b/Pods/Target Support Files/GoogleUtilities/GoogleUtilities.debug.xcconfig @@ -0,0 +1,16 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC" +GCC_C_LANGUAGE_STANDARD = c99 +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_TARGET_SRCROOT}" +OTHER_LDFLAGS = $(inherited) -l"z" -framework "FBLPromises" -framework "Security" -framework "SystemConfiguration" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/GoogleUtilities +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/GoogleUtilities/GoogleUtilities.modulemap b/Pods/Target Support Files/GoogleUtilities/GoogleUtilities.modulemap new file mode 100644 index 0000000..491dd0a --- /dev/null +++ b/Pods/Target Support Files/GoogleUtilities/GoogleUtilities.modulemap @@ -0,0 +1,6 @@ +framework module GoogleUtilities { + umbrella header "GoogleUtilities-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/GoogleUtilities/GoogleUtilities.release.xcconfig b/Pods/Target Support Files/GoogleUtilities/GoogleUtilities.release.xcconfig new file mode 100644 index 0000000..d3cff7f --- /dev/null +++ b/Pods/Target Support Files/GoogleUtilities/GoogleUtilities.release.xcconfig @@ -0,0 +1,16 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC" +GCC_C_LANGUAGE_STANDARD = c99 +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_TARGET_SRCROOT}" +OTHER_LDFLAGS = $(inherited) -l"z" -framework "FBLPromises" -framework "Security" -framework "SystemConfiguration" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/GoogleUtilities +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/GoogleUtilities/ResourceBundle-GoogleUtilities_Privacy-GoogleUtilities-Info.plist b/Pods/Target Support Files/GoogleUtilities/ResourceBundle-GoogleUtilities_Privacy-GoogleUtilities-Info.plist new file mode 100644 index 0000000..4d66f4c --- /dev/null +++ b/Pods/Target Support Files/GoogleUtilities/ResourceBundle-GoogleUtilities_Privacy-GoogleUtilities-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 7.13.3 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper-acknowledgements.markdown b/Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper-acknowledgements.markdown deleted file mode 100644 index 102af75..0000000 --- a/Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper-acknowledgements.markdown +++ /dev/null @@ -1,3 +0,0 @@ -# Acknowledgements -This application makes use of the following third party libraries: -Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper-acknowledgements.plist b/Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper-acknowledgements.plist deleted file mode 100644 index 7acbad1..0000000 --- a/Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper-acknowledgements.plist +++ /dev/null @@ -1,29 +0,0 @@ - - - - - PreferenceSpecifiers - - - FooterText - This application makes use of the following third party libraries: - Title - Acknowledgements - Type - PSGroupSpecifier - - - FooterText - Generated by CocoaPods - https://cocoapods.org - Title - - Type - PSGroupSpecifier - - - StringsTable - Acknowledgements - Title - Acknowledgements - - diff --git a/Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper-dummy.m b/Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper-dummy.m deleted file mode 100644 index 058b1ab..0000000 --- a/Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper-dummy.m +++ /dev/null @@ -1,5 +0,0 @@ -#import -@interface PodsDummy_Pods_HD_wallpaper : NSObject -@end -@implementation PodsDummy_Pods_HD_wallpaper -@end diff --git a/Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper.modulemap b/Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper.modulemap deleted file mode 100644 index 468e2d6..0000000 --- a/Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper.modulemap +++ /dev/null @@ -1,6 +0,0 @@ -framework module Pods_HD_wallpaper { - umbrella header "Pods-HD wallpaper-umbrella.h" - - export * - module * { export * } -} diff --git a/Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper-Info.plist b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-Info.plist similarity index 100% rename from Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper-Info.plist rename to Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-Info.plist diff --git a/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-acknowledgements.markdown b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-acknowledgements.markdown new file mode 100644 index 0000000..9c71779 --- /dev/null +++ b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-acknowledgements.markdown @@ -0,0 +1,2327 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## Firebase + + + 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. + + +## FirebaseABTesting + + + 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. + + +## FirebaseAnalytics + +Copyright 2022 Google + +## FirebaseCore + + + 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. + + +## FirebaseCoreInternal + + + 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. + + +## FirebaseInstallations + + + 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. + + +## FirebaseRemoteConfig + + + 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. + + +## FirebaseRemoteConfigInterop + + + 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. + + +## FirebaseSharedSwift + + + 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. + + ## Runtime Library Exception to the Apache 2.0 License: ## + + + As an exception, if you use this Software to compile your source code and + portions of this Software are embedded into the binary product as a result, + you may redistribute such product without providing attribution as would + otherwise be required by Sections 4(a), 4(b) and 4(d) of the License. + + 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. + + +## GoogleAppMeasurement + +Copyright 2022 Google + +## GoogleUtilities + + + 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. + +================================================================================ + +Copyright (c) 2017 Landon J. Fuller +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. + + +## PromisesObjC + + + 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. + + +## nanopb + +Copyright (c) 2011 Petteri Aimonen + +This software is provided 'as-is', without any express or +implied warranty. In no event will the authors be held liable +for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you + must not claim that you wrote the original software. If you use + this software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and + must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source + distribution. + +Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-acknowledgements.plist b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-acknowledgements.plist new file mode 100644 index 0000000..43fd1e0 --- /dev/null +++ b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-acknowledgements.plist @@ -0,0 +1,2431 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + + 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. + + License + Apache-2.0 + Title + Firebase + Type + PSGroupSpecifier + + + FooterText + + 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. + + License + Apache-2.0 + Title + FirebaseABTesting + Type + PSGroupSpecifier + + + FooterText + Copyright 2022 Google + License + Copyright + Title + FirebaseAnalytics + Type + PSGroupSpecifier + + + FooterText + + 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. + + License + Apache-2.0 + Title + FirebaseCore + Type + PSGroupSpecifier + + + FooterText + + 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. + + License + Apache-2.0 + Title + FirebaseCoreInternal + Type + PSGroupSpecifier + + + FooterText + + 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. + + License + Apache-2.0 + Title + FirebaseInstallations + Type + PSGroupSpecifier + + + FooterText + + 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. + + License + Apache-2.0 + Title + FirebaseRemoteConfig + Type + PSGroupSpecifier + + + FooterText + + 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. + + License + Apache-2.0 + Title + FirebaseRemoteConfigInterop + Type + PSGroupSpecifier + + + FooterText + + 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. + + ## Runtime Library Exception to the Apache 2.0 License: ## + + + As an exception, if you use this Software to compile your source code and + portions of this Software are embedded into the binary product as a result, + you may redistribute such product without providing attribution as would + otherwise be required by Sections 4(a), 4(b) and 4(d) of the License. + + 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. + + License + Apache-2.0 + Title + FirebaseSharedSwift + Type + PSGroupSpecifier + + + FooterText + Copyright 2022 Google + License + Copyright + Title + GoogleAppMeasurement + Type + PSGroupSpecifier + + + FooterText + + 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. + +================================================================================ + +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. + + License + Apache-2.0 + Title + GoogleUtilities + Type + PSGroupSpecifier + + + FooterText + + 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. + + License + Apache-2.0 + Title + PromisesObjC + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2011 Petteri Aimonen <jpa at nanopb.mail.kapsi.fi> + +This software is provided 'as-is', without any express or +implied warranty. In no event will the authors be held liable +for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you + must not claim that you wrote the original software. If you use + this software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and + must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source + distribution. + + License + zlib + Title + nanopb + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-dummy.m b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-dummy.m new file mode 100644 index 0000000..10f11dc --- /dev/null +++ b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_TallPaper : NSObject +@end +@implementation PodsDummy_Pods_TallPaper +@end diff --git a/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-frameworks-Debug-input-files.xcfilelist b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-frameworks-Debug-input-files.xcfilelist new file mode 100644 index 0000000..6b9aa93 --- /dev/null +++ b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-frameworks-Debug-input-files.xcfilelist @@ -0,0 +1,11 @@ +${PODS_ROOT}/Target Support Files/Pods-TallPaper/Pods-TallPaper-frameworks.sh +${BUILT_PRODUCTS_DIR}/FirebaseABTesting/FirebaseABTesting.framework +${BUILT_PRODUCTS_DIR}/FirebaseCore/FirebaseCore.framework +${BUILT_PRODUCTS_DIR}/FirebaseCoreInternal/FirebaseCoreInternal.framework +${BUILT_PRODUCTS_DIR}/FirebaseInstallations/FirebaseInstallations.framework +${BUILT_PRODUCTS_DIR}/FirebaseRemoteConfig/FirebaseRemoteConfig.framework +${BUILT_PRODUCTS_DIR}/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop.framework +${BUILT_PRODUCTS_DIR}/FirebaseSharedSwift/FirebaseSharedSwift.framework +${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework +${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework +${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-frameworks-Debug-output-files.xcfilelist b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-frameworks-Debug-output-files.xcfilelist new file mode 100644 index 0000000..2cad325 --- /dev/null +++ b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-frameworks-Debug-output-files.xcfilelist @@ -0,0 +1,10 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseABTesting.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCore.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreInternal.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseInstallations.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseRemoteConfig.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseRemoteConfigInterop.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseSharedSwift.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBLPromises.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-frameworks-Release-input-files.xcfilelist b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-frameworks-Release-input-files.xcfilelist new file mode 100644 index 0000000..6b9aa93 --- /dev/null +++ b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-frameworks-Release-input-files.xcfilelist @@ -0,0 +1,11 @@ +${PODS_ROOT}/Target Support Files/Pods-TallPaper/Pods-TallPaper-frameworks.sh +${BUILT_PRODUCTS_DIR}/FirebaseABTesting/FirebaseABTesting.framework +${BUILT_PRODUCTS_DIR}/FirebaseCore/FirebaseCore.framework +${BUILT_PRODUCTS_DIR}/FirebaseCoreInternal/FirebaseCoreInternal.framework +${BUILT_PRODUCTS_DIR}/FirebaseInstallations/FirebaseInstallations.framework +${BUILT_PRODUCTS_DIR}/FirebaseRemoteConfig/FirebaseRemoteConfig.framework +${BUILT_PRODUCTS_DIR}/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop.framework +${BUILT_PRODUCTS_DIR}/FirebaseSharedSwift/FirebaseSharedSwift.framework +${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework +${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework +${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-frameworks-Release-output-files.xcfilelist b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-frameworks-Release-output-files.xcfilelist new file mode 100644 index 0000000..2cad325 --- /dev/null +++ b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-frameworks-Release-output-files.xcfilelist @@ -0,0 +1,10 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseABTesting.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCore.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseCoreInternal.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseInstallations.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseRemoteConfig.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseRemoteConfigInterop.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FirebaseSharedSwift.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBLPromises.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-frameworks.sh b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-frameworks.sh new file mode 100755 index 0000000..cc2cd7d --- /dev/null +++ b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-frameworks.sh @@ -0,0 +1,204 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +function on_error { + echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" +} +trap 'on_error $LINENO' ERR + +if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then + # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy + # frameworks to, so exit 0 (signalling the script phase was successful). + exit 0 +fi + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" +SWIFT_STDLIB_PATH="${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" +BCSYMBOLMAP_DIR="BCSymbolMaps" + + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +# Copies and strips a vendored framework +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink -f "${source}")" + fi + + if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then + # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied + find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do + echo "Installing $f" + install_bcsymbolmap "$f" "$destination" + rm "$f" + done + rmdir "${source}/${BCSYMBOLMAP_DIR}" + fi + + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + elif [ -L "${binary}" ]; then + echo "Destination binary is symlinked..." + dirname="$(dirname "${binary}")" + binary="${dirname}/$(readlink "${binary}")" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} +# Copies and strips a vendored dSYM +install_dsym() { + local source="$1" + warn_missing_arch=${2:-true} + if [ -r "$source" ]; then + # Copy the dSYM into the targets temp dir. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" + + local basename + basename="$(basename -s .dSYM "$source")" + binary_name="$(ls "$source/Contents/Resources/DWARF")" + binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" + + # Strip invalid architectures from the dSYM. + if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then + strip_invalid_archs "$binary" "$warn_missing_arch" + fi + if [[ $STRIP_BINARY_RETVAL == 0 ]]; then + # Move the stripped file into its final destination. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" + else + # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. + mkdir -p "${DWARF_DSYM_FOLDER_PATH}" + touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" + fi + fi +} + +# Used as a return value for each invocation of `strip_invalid_archs` function. +STRIP_BINARY_RETVAL=0 + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + warn_missing_arch=${2:-true} + # Get architectures for current target binary + binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" + # Intersect them with the architectures we are building for + intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" + # If there are no archs supported by this binary then warn the user + if [[ -z "$intersected_archs" ]]; then + if [[ "$warn_missing_arch" == "true" ]]; then + echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." + fi + STRIP_BINARY_RETVAL=1 + return + fi + stripped="" + for arch in $binary_archs; do + if ! [[ "${ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi + STRIP_BINARY_RETVAL=0 +} + +# Copies the bcsymbolmap files of a vendored framework +install_bcsymbolmap() { + local bcsymbolmap_path="$1" + local destination="${BUILT_PRODUCTS_DIR}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identity + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" + fi +} + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/FirebaseABTesting/FirebaseABTesting.framework" + install_framework "${BUILT_PRODUCTS_DIR}/FirebaseCore/FirebaseCore.framework" + install_framework "${BUILT_PRODUCTS_DIR}/FirebaseCoreInternal/FirebaseCoreInternal.framework" + install_framework "${BUILT_PRODUCTS_DIR}/FirebaseInstallations/FirebaseInstallations.framework" + install_framework "${BUILT_PRODUCTS_DIR}/FirebaseRemoteConfig/FirebaseRemoteConfig.framework" + install_framework "${BUILT_PRODUCTS_DIR}/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop.framework" + install_framework "${BUILT_PRODUCTS_DIR}/FirebaseSharedSwift/FirebaseSharedSwift.framework" + install_framework "${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework" + install_framework "${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework" + install_framework "${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework" +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/FirebaseABTesting/FirebaseABTesting.framework" + install_framework "${BUILT_PRODUCTS_DIR}/FirebaseCore/FirebaseCore.framework" + install_framework "${BUILT_PRODUCTS_DIR}/FirebaseCoreInternal/FirebaseCoreInternal.framework" + install_framework "${BUILT_PRODUCTS_DIR}/FirebaseInstallations/FirebaseInstallations.framework" + install_framework "${BUILT_PRODUCTS_DIR}/FirebaseRemoteConfig/FirebaseRemoteConfig.framework" + install_framework "${BUILT_PRODUCTS_DIR}/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop.framework" + install_framework "${BUILT_PRODUCTS_DIR}/FirebaseSharedSwift/FirebaseSharedSwift.framework" + install_framework "${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework" + install_framework "${BUILT_PRODUCTS_DIR}/PromisesObjC/FBLPromises.framework" + install_framework "${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework" +fi +if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + wait +fi diff --git a/Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper-umbrella.h b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-umbrella.h similarity index 60% rename from Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper-umbrella.h rename to Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-umbrella.h index 43289cf..eaa0876 100644 --- a/Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper-umbrella.h +++ b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper-umbrella.h @@ -11,6 +11,6 @@ #endif -FOUNDATION_EXPORT double Pods_HD_wallpaperVersionNumber; -FOUNDATION_EXPORT const unsigned char Pods_HD_wallpaperVersionString[]; +FOUNDATION_EXPORT double Pods_TallPaperVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_TallPaperVersionString[]; diff --git a/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper.debug.xcconfig b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper.debug.xcconfig new file mode 100644 index 0000000..724cfc9 --- /dev/null +++ b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +EMBEDDED_CONTENT_CONTAINS_SWIFT = YES +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseABTesting" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseRemoteConfig" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseRemoteConfigInterop" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseSharedSwift" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" "${PODS_XCFRAMEWORKS_BUILD_DIR}/FirebaseAnalytics/WithoutAdIdSupport" "${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAppMeasurement/WithoutAdIdSupport" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseABTesting/FirebaseABTesting.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal/FirebaseCoreInternal.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseRemoteConfig/FirebaseRemoteConfig.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseSharedSwift/FirebaseSharedSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb.framework/Headers" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources +LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -ObjC -l"c++" -l"sqlite3" -l"z" -framework "FBLPromises" -framework "FirebaseABTesting" -framework "FirebaseAnalytics" -framework "FirebaseCore" -framework "FirebaseCoreInternal" -framework "FirebaseInstallations" -framework "FirebaseRemoteConfig" -framework "FirebaseRemoteConfigInterop" -framework "FirebaseSharedSwift" -framework "Foundation" -framework "GoogleAppMeasurement" -framework "GoogleUtilities" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit" -framework "nanopb" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper.modulemap b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper.modulemap new file mode 100644 index 0000000..22dda95 --- /dev/null +++ b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper.modulemap @@ -0,0 +1,6 @@ +framework module Pods_TallPaper { + umbrella header "Pods-TallPaper-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper.release.xcconfig b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper.release.xcconfig new file mode 100644 index 0000000..724cfc9 --- /dev/null +++ b/Pods/Target Support Files/Pods-TallPaper/Pods-TallPaper.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +EMBEDDED_CONTENT_CONTAINS_SWIFT = YES +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseABTesting" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseRemoteConfig" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseRemoteConfigInterop" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseSharedSwift" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks" "${PODS_XCFRAMEWORKS_BUILD_DIR}/FirebaseAnalytics/WithoutAdIdSupport" "${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAppMeasurement/WithoutAdIdSupport" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseABTesting/FirebaseABTesting.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal/FirebaseCoreInternal.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseRemoteConfig/FirebaseRemoteConfig.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseRemoteConfigInterop/FirebaseRemoteConfigInterop.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseSharedSwift/FirebaseSharedSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb.framework/Headers" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" $(inherited) ${PODS_ROOT}/Firebase/CoreOnly/Sources +LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -ObjC -l"c++" -l"sqlite3" -l"z" -framework "FBLPromises" -framework "FirebaseABTesting" -framework "FirebaseAnalytics" -framework "FirebaseCore" -framework "FirebaseCoreInternal" -framework "FirebaseInstallations" -framework "FirebaseRemoteConfig" -framework "FirebaseRemoteConfigInterop" -framework "FirebaseSharedSwift" -framework "Foundation" -framework "GoogleAppMeasurement" -framework "GoogleUtilities" -framework "Security" -framework "StoreKit" -framework "SystemConfiguration" -framework "UIKit" -framework "nanopb" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/PromisesObjC/PromisesObjC-Info.plist b/Pods/Target Support Files/PromisesObjC/PromisesObjC-Info.plist new file mode 100644 index 0000000..2780533 --- /dev/null +++ b/Pods/Target Support Files/PromisesObjC/PromisesObjC-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.4.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/PromisesObjC/PromisesObjC-dummy.m b/Pods/Target Support Files/PromisesObjC/PromisesObjC-dummy.m new file mode 100644 index 0000000..ab1f210 --- /dev/null +++ b/Pods/Target Support Files/PromisesObjC/PromisesObjC-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_PromisesObjC : NSObject +@end +@implementation PodsDummy_PromisesObjC +@end diff --git a/Pods/Target Support Files/PromisesObjC/PromisesObjC-umbrella.h b/Pods/Target Support Files/PromisesObjC/PromisesObjC-umbrella.h new file mode 100644 index 0000000..5b014a8 --- /dev/null +++ b/Pods/Target Support Files/PromisesObjC/PromisesObjC-umbrella.h @@ -0,0 +1,36 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "FBLPromise+All.h" +#import "FBLPromise+Always.h" +#import "FBLPromise+Any.h" +#import "FBLPromise+Async.h" +#import "FBLPromise+Await.h" +#import "FBLPromise+Catch.h" +#import "FBLPromise+Delay.h" +#import "FBLPromise+Do.h" +#import "FBLPromise+Race.h" +#import "FBLPromise+Recover.h" +#import "FBLPromise+Reduce.h" +#import "FBLPromise+Retry.h" +#import "FBLPromise+Testing.h" +#import "FBLPromise+Then.h" +#import "FBLPromise+Timeout.h" +#import "FBLPromise+Validate.h" +#import "FBLPromise+Wrap.h" +#import "FBLPromise.h" +#import "FBLPromiseError.h" +#import "FBLPromises.h" + +FOUNDATION_EXPORT double FBLPromisesVersionNumber; +FOUNDATION_EXPORT const unsigned char FBLPromisesVersionString[]; + diff --git a/Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper.debug.xcconfig b/Pods/Target Support Files/PromisesObjC/PromisesObjC.debug.xcconfig similarity index 54% rename from Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper.debug.xcconfig rename to Pods/Target Support Files/PromisesObjC/PromisesObjC.debug.xcconfig index 26f2c77..132f10c 100644 --- a/Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper.debug.xcconfig +++ b/Pods/Target Support Files/PromisesObjC/PromisesObjC.debug.xcconfig @@ -1,8 +1,13 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC +DEFINES_MODULE = YES GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) -PODS_PODFILE_DIR_PATH = ${SRCROOT}/. -PODS_ROOT = ${SRCROOT}/Pods +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/PromisesObjC PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/PromisesObjC/PromisesObjC.modulemap b/Pods/Target Support Files/PromisesObjC/PromisesObjC.modulemap new file mode 100644 index 0000000..7d485cd --- /dev/null +++ b/Pods/Target Support Files/PromisesObjC/PromisesObjC.modulemap @@ -0,0 +1,6 @@ +framework module FBLPromises { + umbrella header "PromisesObjC-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper.release.xcconfig b/Pods/Target Support Files/PromisesObjC/PromisesObjC.release.xcconfig similarity index 54% rename from Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper.release.xcconfig rename to Pods/Target Support Files/PromisesObjC/PromisesObjC.release.xcconfig index 26f2c77..132f10c 100644 --- a/Pods/Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper.release.xcconfig +++ b/Pods/Target Support Files/PromisesObjC/PromisesObjC.release.xcconfig @@ -1,8 +1,13 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC +DEFINES_MODULE = YES GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) -PODS_PODFILE_DIR_PATH = ${SRCROOT}/. -PODS_ROOT = ${SRCROOT}/Pods +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/PromisesObjC PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/PromisesObjC/ResourceBundle-FBLPromises_Privacy-PromisesObjC-Info.plist b/Pods/Target Support Files/PromisesObjC/ResourceBundle-FBLPromises_Privacy-PromisesObjC-Info.plist new file mode 100644 index 0000000..1f1f0af --- /dev/null +++ b/Pods/Target Support Files/PromisesObjC/ResourceBundle-FBLPromises_Privacy-PromisesObjC-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 2.4.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/nanopb/ResourceBundle-nanopb_Privacy-nanopb-Info.plist b/Pods/Target Support Files/nanopb/ResourceBundle-nanopb_Privacy-nanopb-Info.plist new file mode 100644 index 0000000..e9256eb --- /dev/null +++ b/Pods/Target Support Files/nanopb/ResourceBundle-nanopb_Privacy-nanopb-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 2.30910.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/nanopb/nanopb-Info.plist b/Pods/Target Support Files/nanopb/nanopb-Info.plist new file mode 100644 index 0000000..f8f0733 --- /dev/null +++ b/Pods/Target Support Files/nanopb/nanopb-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.30910.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/nanopb/nanopb-dummy.m b/Pods/Target Support Files/nanopb/nanopb-dummy.m new file mode 100644 index 0000000..b3fa595 --- /dev/null +++ b/Pods/Target Support Files/nanopb/nanopb-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_nanopb : NSObject +@end +@implementation PodsDummy_nanopb +@end diff --git a/Pods/Target Support Files/nanopb/nanopb-prefix.pch b/Pods/Target Support Files/nanopb/nanopb-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/Pods/Target Support Files/nanopb/nanopb-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/nanopb/nanopb-umbrella.h b/Pods/Target Support Files/nanopb/nanopb-umbrella.h new file mode 100644 index 0000000..07e77b3 --- /dev/null +++ b/Pods/Target Support Files/nanopb/nanopb-umbrella.h @@ -0,0 +1,26 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "pb.h" +#import "pb_common.h" +#import "pb_decode.h" +#import "pb_encode.h" +#import "pb.h" +#import "pb_decode.h" +#import "pb_common.h" +#import "pb.h" +#import "pb_encode.h" +#import "pb_common.h" + +FOUNDATION_EXPORT double nanopbVersionNumber; +FOUNDATION_EXPORT const unsigned char nanopbVersionString[]; + diff --git a/Pods/Target Support Files/nanopb/nanopb.debug.xcconfig b/Pods/Target Support Files/nanopb/nanopb.debug.xcconfig new file mode 100644 index 0000000..b682973 --- /dev/null +++ b/Pods/Target Support Files/nanopb/nanopb.debug.xcconfig @@ -0,0 +1,12 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/nanopb +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/nanopb +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/nanopb/nanopb.modulemap b/Pods/Target Support Files/nanopb/nanopb.modulemap new file mode 100644 index 0000000..e8d4b53 --- /dev/null +++ b/Pods/Target Support Files/nanopb/nanopb.modulemap @@ -0,0 +1,6 @@ +framework module nanopb { + umbrella header "nanopb-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/nanopb/nanopb.release.xcconfig b/Pods/Target Support Files/nanopb/nanopb.release.xcconfig new file mode 100644 index 0000000..b682973 --- /dev/null +++ b/Pods/Target Support Files/nanopb/nanopb.release.xcconfig @@ -0,0 +1,12 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/nanopb +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 $(inherited) PB_FIELD_32BIT=1 PB_NO_PACKED_STRUCTS=1 PB_ENABLE_MALLOC=1 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/nanopb +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/nanopb/LICENSE.txt b/Pods/nanopb/LICENSE.txt new file mode 100644 index 0000000..d11c9af --- /dev/null +++ b/Pods/nanopb/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2011 Petteri Aimonen + +This software is provided 'as-is', without any express or +implied warranty. In no event will the authors be held liable +for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you + must not claim that you wrote the original software. If you use + this software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and + must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source + distribution. diff --git a/Pods/nanopb/README.md b/Pods/nanopb/README.md new file mode 100644 index 0000000..1a73cdd --- /dev/null +++ b/Pods/nanopb/README.md @@ -0,0 +1,71 @@ +Nanopb - Protocol Buffers for Embedded Systems +============================================== + +[![Build Status](https://travis-ci.org/nanopb/nanopb.svg?branch=master)](https://travis-ci.org/nanopb/nanopb) + +Nanopb is a small code-size Protocol Buffers implementation in ansi C. It is +especially suitable for use in microcontrollers, but fits any memory +restricted system. + +* **Homepage:** https://jpa.kapsi.fi/nanopb/ +* **Documentation:** https://jpa.kapsi.fi/nanopb/docs/ +* **Downloads:** https://jpa.kapsi.fi/nanopb/download/ +* **Forum:** https://groups.google.com/forum/#!forum/nanopb + + + +Using the nanopb library +------------------------ +To use the nanopb library, you need to do two things: + +1. Compile your .proto files for nanopb, using `protoc`. +2. Include *pb_encode.c*, *pb_decode.c* and *pb_common.c* in your project. + +The easiest way to get started is to study the project in "examples/simple". +It contains a Makefile, which should work directly under most Linux systems. +However, for any other kind of build system, see the manual steps in +README.txt in that folder. + + + +Using the Protocol Buffers compiler (protoc) +-------------------------------------------- +The nanopb generator is implemented as a plugin for the Google's own `protoc` +compiler. This has the advantage that there is no need to reimplement the +basic parsing of .proto files. However, it does mean that you need the +Google's protobuf library in order to run the generator. + +If you have downloaded a binary package for nanopb (either Windows, Linux or +Mac OS X version), the `protoc` binary is included in the 'generator-bin' +folder. In this case, you are ready to go. Simply run this command: + + generator-bin/protoc --nanopb_out=. myprotocol.proto + +However, if you are using a git checkout or a plain source distribution, you +need to provide your own version of `protoc` and the Google's protobuf library. +On Linux, the necessary packages are `protobuf-compiler` and `python-protobuf`. +On Windows, you can either build Google's protobuf library from source or use +one of the binary distributions of it. In either case, if you use a separate +`protoc`, you need to manually give the path to nanopb generator: + + protoc --plugin=protoc-gen-nanopb=nanopb/generator/protoc-gen-nanopb ... + + + +Running the tests +----------------- +If you want to perform further development of the nanopb core, or to verify +its functionality using your compiler and platform, you'll want to run the +test suite. The build rules for the test suite are implemented using Scons, +so you need to have that installed (ex: `sudo apt install scons` on Ubuntu). To run the tests: + + cd tests + scons + +This will show the progress of various test cases. If the output does not +end in an error, the test cases were successful. + +Note: Mac OS X by default aliases 'clang' as 'gcc', while not actually +supporting the same command line options as gcc does. To run tests on +Mac OS X, use: "scons CC=clang CXX=clang". Same way can be used to run +tests with different compilers on any platform. diff --git a/Pods/nanopb/pb.h b/Pods/nanopb/pb.h new file mode 100644 index 0000000..2bd4568 --- /dev/null +++ b/Pods/nanopb/pb.h @@ -0,0 +1,599 @@ +/* Common parts of the nanopb library. Most of these are quite low-level + * stuff. For the high-level interface, see pb_encode.h and pb_decode.h. + */ + +#ifndef PB_H_INCLUDED +#define PB_H_INCLUDED + +/***************************************************************** + * Nanopb compilation time options. You can change these here by * + * uncommenting the lines, or on the compiler command line. * + *****************************************************************/ + +/* Enable support for dynamically allocated fields */ +/* #define PB_ENABLE_MALLOC 1 */ + +/* Define this if your CPU / compiler combination does not support + * unaligned memory access to packed structures. */ +/* #define PB_NO_PACKED_STRUCTS 1 */ + +/* Increase the number of required fields that are tracked. + * A compiler warning will tell if you need this. */ +/* #define PB_MAX_REQUIRED_FIELDS 256 */ + +/* Add support for tag numbers > 255 and fields larger than 255 bytes. */ +/* #define PB_FIELD_16BIT 1 */ + +/* Add support for tag numbers > 65536 and fields larger than 65536 bytes. */ +/* #define PB_FIELD_32BIT 1 */ + +/* Disable support for error messages in order to save some code space. */ +/* #define PB_NO_ERRMSG 1 */ + +/* Disable support for custom streams (support only memory buffers). */ +/* #define PB_BUFFER_ONLY 1 */ + +/* Switch back to the old-style callback function signature. + * This was the default until nanopb-0.2.1. */ +/* #define PB_OLD_CALLBACK_STYLE */ + + +/* Don't encode scalar arrays as packed. This is only to be used when + * the decoder on the receiving side cannot process packed scalar arrays. + * Such example is older protobuf.js. */ +/* #define PB_ENCODE_ARRAYS_UNPACKED 1 */ + +/****************************************************************** + * You usually don't need to change anything below this line. * + * Feel free to look around and use the defined macros, though. * + ******************************************************************/ + + +/* Version of the nanopb library. Just in case you want to check it in + * your own program. */ +#define NANOPB_VERSION nanopb-0.3.9.10 + +/* Include all the system headers needed by nanopb. You will need the + * definitions of the following: + * - strlen, memcpy, memset functions + * - [u]int_least8_t, uint_fast8_t, [u]int_least16_t, [u]int32_t, [u]int64_t + * - size_t + * - bool + * + * If you don't have the standard header files, you can instead provide + * a custom header that defines or includes all this. In that case, + * define PB_SYSTEM_HEADER to the path of this file. + */ +#ifdef PB_SYSTEM_HEADER +#include PB_SYSTEM_HEADER +#else +#include +#include +#include +#include + +#ifdef PB_ENABLE_MALLOC +#include +#endif +#endif + +/* Macro for defining packed structures (compiler dependent). + * This just reduces memory requirements, but is not required. + */ +#if defined(PB_NO_PACKED_STRUCTS) + /* Disable struct packing */ +# define PB_PACKED_STRUCT_START +# define PB_PACKED_STRUCT_END +# define pb_packed +#elif defined(__GNUC__) || defined(__clang__) + /* For GCC and clang */ +# define PB_PACKED_STRUCT_START +# define PB_PACKED_STRUCT_END +# define pb_packed __attribute__((packed)) +#elif defined(__ICCARM__) || defined(__CC_ARM) + /* For IAR ARM and Keil MDK-ARM compilers */ +# define PB_PACKED_STRUCT_START _Pragma("pack(push, 1)") +# define PB_PACKED_STRUCT_END _Pragma("pack(pop)") +# define pb_packed +#elif defined(_MSC_VER) && (_MSC_VER >= 1500) + /* For Microsoft Visual C++ */ +# define PB_PACKED_STRUCT_START __pragma(pack(push, 1)) +# define PB_PACKED_STRUCT_END __pragma(pack(pop)) +# define pb_packed +#else + /* Unknown compiler */ +# define PB_PACKED_STRUCT_START +# define PB_PACKED_STRUCT_END +# define pb_packed +#endif + +/* Handly macro for suppressing unreferenced-parameter compiler warnings. */ +#ifndef PB_UNUSED +#define PB_UNUSED(x) (void)(x) +#endif + +/* Compile-time assertion, used for checking compatible compilation options. + * If this does not work properly on your compiler, use + * #define PB_NO_STATIC_ASSERT to disable it. + * + * But before doing that, check carefully the error message / place where it + * comes from to see if the error has a real cause. Unfortunately the error + * message is not always very clear to read, but you can see the reason better + * in the place where the PB_STATIC_ASSERT macro was called. + */ +#ifndef PB_NO_STATIC_ASSERT +#ifndef PB_STATIC_ASSERT +#define PB_STATIC_ASSERT(COND,MSG) typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1]; +#define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) +#define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) pb_static_assertion_##MSG##LINE##COUNTER +#endif +#else +#define PB_STATIC_ASSERT(COND,MSG) +#endif + +/* Number of required fields to keep track of. */ +#ifndef PB_MAX_REQUIRED_FIELDS +#define PB_MAX_REQUIRED_FIELDS 64 +#endif + +#if PB_MAX_REQUIRED_FIELDS < 64 +#error You should not lower PB_MAX_REQUIRED_FIELDS from the default value (64). +#endif + +/* List of possible field types. These are used in the autogenerated code. + * Least-significant 4 bits tell the scalar type + * Most-significant 4 bits specify repeated/required/packed etc. + */ + +typedef uint_least8_t pb_type_t; + +/**** Field data types ****/ + +/* Numeric types */ +#define PB_LTYPE_BOOL 0x00 /* bool */ +#define PB_LTYPE_VARINT 0x01 /* int32, int64, enum, bool */ +#define PB_LTYPE_UVARINT 0x02 /* uint32, uint64 */ +#define PB_LTYPE_SVARINT 0x03 /* sint32, sint64 */ +#define PB_LTYPE_FIXED32 0x04 /* fixed32, sfixed32, float */ +#define PB_LTYPE_FIXED64 0x05 /* fixed64, sfixed64, double */ + +/* Marker for last packable field type. */ +#define PB_LTYPE_LAST_PACKABLE 0x05 + +/* Byte array with pre-allocated buffer. + * data_size is the length of the allocated PB_BYTES_ARRAY structure. */ +#define PB_LTYPE_BYTES 0x06 + +/* String with pre-allocated buffer. + * data_size is the maximum length. */ +#define PB_LTYPE_STRING 0x07 + +/* Submessage + * submsg_fields is pointer to field descriptions */ +#define PB_LTYPE_SUBMESSAGE 0x08 + +/* Extension pseudo-field + * The field contains a pointer to pb_extension_t */ +#define PB_LTYPE_EXTENSION 0x09 + +/* Byte array with inline, pre-allocated byffer. + * data_size is the length of the inline, allocated buffer. + * This differs from PB_LTYPE_BYTES by defining the element as + * pb_byte_t[data_size] rather than pb_bytes_array_t. */ +#define PB_LTYPE_FIXED_LENGTH_BYTES 0x0A + +/* Number of declared LTYPES */ +#define PB_LTYPES_COUNT 0x0B +#define PB_LTYPE_MASK 0x0F + +/**** Field repetition rules ****/ + +#define PB_HTYPE_REQUIRED 0x00 +#define PB_HTYPE_OPTIONAL 0x10 +#define PB_HTYPE_REPEATED 0x20 +#define PB_HTYPE_ONEOF 0x30 +#define PB_HTYPE_MASK 0x30 + +/**** Field allocation types ****/ + +#define PB_ATYPE_STATIC 0x00 +#define PB_ATYPE_POINTER 0x80 +#define PB_ATYPE_CALLBACK 0x40 +#define PB_ATYPE_MASK 0xC0 + +#define PB_ATYPE(x) ((x) & PB_ATYPE_MASK) +#define PB_HTYPE(x) ((x) & PB_HTYPE_MASK) +#define PB_LTYPE(x) ((x) & PB_LTYPE_MASK) + +/* Data type used for storing sizes of struct fields + * and array counts. + */ +#if defined(PB_FIELD_32BIT) + typedef uint32_t pb_size_t; + typedef int32_t pb_ssize_t; +#elif defined(PB_FIELD_16BIT) + typedef uint_least16_t pb_size_t; + typedef int_least16_t pb_ssize_t; +#else + typedef uint_least8_t pb_size_t; + typedef int_least8_t pb_ssize_t; +#endif +#define PB_SIZE_MAX ((pb_size_t)-1) + +/* Data type for storing encoded data and other byte streams. + * This typedef exists to support platforms where uint8_t does not exist. + * You can regard it as equivalent on uint8_t on other platforms. + */ +typedef uint_least8_t pb_byte_t; + +/* This structure is used in auto-generated constants + * to specify struct fields. + * You can change field sizes if you need structures + * larger than 256 bytes or field tags larger than 256. + * The compiler should complain if your .proto has such + * structures. Fix that by defining PB_FIELD_16BIT or + * PB_FIELD_32BIT. + */ +PB_PACKED_STRUCT_START +typedef struct pb_field_s pb_field_t; +struct pb_field_s { + pb_size_t tag; + pb_type_t type; + pb_size_t data_offset; /* Offset of field data, relative to previous field. */ + pb_ssize_t size_offset; /* Offset of array size or has-boolean, relative to data */ + pb_size_t data_size; /* Data size in bytes for a single item */ + pb_size_t array_size; /* Maximum number of entries in array */ + + /* Field definitions for submessage + * OR default value for all other non-array, non-callback types + * If null, then field will zeroed. */ + const void *ptr; +} pb_packed; +PB_PACKED_STRUCT_END + +/* Make sure that the standard integer types are of the expected sizes. + * Otherwise fixed32/fixed64 fields can break. + * + * If you get errors here, it probably means that your stdint.h is not + * correct for your platform. + */ +#ifndef PB_WITHOUT_64BIT +PB_STATIC_ASSERT(sizeof(int64_t) == 2 * sizeof(int32_t), INT64_T_WRONG_SIZE) +PB_STATIC_ASSERT(sizeof(uint64_t) == 2 * sizeof(uint32_t), UINT64_T_WRONG_SIZE) +#endif + +/* This structure is used for 'bytes' arrays. + * It has the number of bytes in the beginning, and after that an array. + * Note that actual structs used will have a different length of bytes array. + */ +#define PB_BYTES_ARRAY_T(n) struct { pb_size_t size; pb_byte_t bytes[n]; } +#define PB_BYTES_ARRAY_T_ALLOCSIZE(n) ((size_t)n + offsetof(pb_bytes_array_t, bytes)) + +struct pb_bytes_array_s { + pb_size_t size; + pb_byte_t bytes[1]; +}; +typedef struct pb_bytes_array_s pb_bytes_array_t; + +/* This structure is used for giving the callback function. + * It is stored in the message structure and filled in by the method that + * calls pb_decode. + * + * The decoding callback will be given a limited-length stream + * If the wire type was string, the length is the length of the string. + * If the wire type was a varint/fixed32/fixed64, the length is the length + * of the actual value. + * The function may be called multiple times (especially for repeated types, + * but also otherwise if the message happens to contain the field multiple + * times.) + * + * The encoding callback will receive the actual output stream. + * It should write all the data in one call, including the field tag and + * wire type. It can write multiple fields. + * + * The callback can be null if you want to skip a field. + */ +typedef struct pb_istream_s pb_istream_t; +typedef struct pb_ostream_s pb_ostream_t; +typedef struct pb_callback_s pb_callback_t; +struct pb_callback_s { +#ifdef PB_OLD_CALLBACK_STYLE + /* Deprecated since nanopb-0.2.1 */ + union { + bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void *arg); + bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, const void *arg); + } funcs; +#else + /* New function signature, which allows modifying arg contents in callback. */ + union { + bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void **arg); + bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, void * const *arg); + } funcs; +#endif + + /* Free arg for use by callback */ + void *arg; +}; + +/* Wire types. Library user needs these only in encoder callbacks. */ +typedef enum { + PB_WT_VARINT = 0, + PB_WT_64BIT = 1, + PB_WT_STRING = 2, + PB_WT_32BIT = 5 +} pb_wire_type_t; + +/* Structure for defining the handling of unknown/extension fields. + * Usually the pb_extension_type_t structure is automatically generated, + * while the pb_extension_t structure is created by the user. However, + * if you want to catch all unknown fields, you can also create a custom + * pb_extension_type_t with your own callback. + */ +typedef struct pb_extension_type_s pb_extension_type_t; +typedef struct pb_extension_s pb_extension_t; +struct pb_extension_type_s { + /* Called for each unknown field in the message. + * If you handle the field, read off all of its data and return true. + * If you do not handle the field, do not read anything and return true. + * If you run into an error, return false. + * Set to NULL for default handler. + */ + bool (*decode)(pb_istream_t *stream, pb_extension_t *extension, + uint32_t tag, pb_wire_type_t wire_type); + + /* Called once after all regular fields have been encoded. + * If you have something to write, do so and return true. + * If you do not have anything to write, just return true. + * If you run into an error, return false. + * Set to NULL for default handler. + */ + bool (*encode)(pb_ostream_t *stream, const pb_extension_t *extension); + + /* Free field for use by the callback. */ + const void *arg; +}; + +struct pb_extension_s { + /* Type describing the extension field. Usually you'll initialize + * this to a pointer to the automatically generated structure. */ + const pb_extension_type_t *type; + + /* Destination for the decoded data. This must match the datatype + * of the extension field. */ + void *dest; + + /* Pointer to the next extension handler, or NULL. + * If this extension does not match a field, the next handler is + * automatically called. */ + pb_extension_t *next; + + /* The decoder sets this to true if the extension was found. + * Ignored for encoding. */ + bool found; +}; + +/* Memory allocation functions to use. You can define pb_realloc and + * pb_free to custom functions if you want. */ +#ifdef PB_ENABLE_MALLOC +# ifndef pb_realloc +# define pb_realloc(ptr, size) realloc(ptr, size) +# endif +# ifndef pb_free +# define pb_free(ptr) free(ptr) +# endif +#endif + +/* This is used to inform about need to regenerate .pb.h/.pb.c files. */ +#define PB_PROTO_HEADER_VERSION 30 + +/* These macros are used to declare pb_field_t's in the constant array. */ +/* Size of a structure member, in bytes. */ +#define pb_membersize(st, m) (sizeof ((st*)0)->m) +/* Number of entries in an array. */ +#define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0])) +/* Delta from start of one member to the start of another member. */ +#define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2)) +/* Marks the end of the field list */ +#define PB_LAST_FIELD {0,(pb_type_t) 0,0,0,0,0,0} + +/* Macros for filling in the data_offset field */ +/* data_offset for first field in a message */ +#define PB_DATAOFFSET_FIRST(st, m1, m2) (offsetof(st, m1)) +/* data_offset for subsequent fields */ +#define PB_DATAOFFSET_OTHER(st, m1, m2) (offsetof(st, m1) - offsetof(st, m2) - pb_membersize(st, m2)) +/* data offset for subsequent fields inside an union (oneof) */ +#define PB_DATAOFFSET_UNION(st, m1, m2) (PB_SIZE_MAX) +/* Choose first/other based on m1 == m2 (deprecated, remains for backwards compatibility) */ +#define PB_DATAOFFSET_CHOOSE(st, m1, m2) (int)(offsetof(st, m1) == offsetof(st, m2) \ + ? PB_DATAOFFSET_FIRST(st, m1, m2) \ + : PB_DATAOFFSET_OTHER(st, m1, m2)) + +/* Required fields are the simplest. They just have delta (padding) from + * previous field end, and the size of the field. Pointer is used for + * submessages and default values. + */ +#define PB_REQUIRED_STATIC(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_STATIC | PB_HTYPE_REQUIRED | ltype, \ + fd, 0, pb_membersize(st, m), 0, ptr} + +/* Optional fields add the delta to the has_ variable. */ +#define PB_OPTIONAL_STATIC(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | ltype, \ + fd, \ + pb_delta(st, has_ ## m, m), \ + pb_membersize(st, m), 0, ptr} + +#define PB_SINGULAR_STATIC(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_STATIC | PB_HTYPE_OPTIONAL | ltype, \ + fd, 0, pb_membersize(st, m), 0, ptr} + +/* Repeated fields have a _count field and also the maximum number of entries. */ +#define PB_REPEATED_STATIC(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_STATIC | PB_HTYPE_REPEATED | ltype, \ + fd, \ + pb_delta(st, m ## _count, m), \ + pb_membersize(st, m[0]), \ + pb_arraysize(st, m), ptr} + +/* Allocated fields carry the size of the actual data, not the pointer */ +#define PB_REQUIRED_POINTER(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_POINTER | PB_HTYPE_REQUIRED | ltype, \ + fd, 0, pb_membersize(st, m[0]), 0, ptr} + +/* Optional fields don't need a has_ variable, as information would be redundant */ +#define PB_OPTIONAL_POINTER(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_POINTER | PB_HTYPE_OPTIONAL | ltype, \ + fd, 0, pb_membersize(st, m[0]), 0, ptr} + +/* Same as optional fields*/ +#define PB_SINGULAR_POINTER(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_POINTER | PB_HTYPE_OPTIONAL | ltype, \ + fd, 0, pb_membersize(st, m[0]), 0, ptr} + +/* Repeated fields have a _count field and a pointer to array of pointers */ +#define PB_REPEATED_POINTER(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_POINTER | PB_HTYPE_REPEATED | ltype, \ + fd, pb_delta(st, m ## _count, m), \ + pb_membersize(st, m[0]), 0, ptr} + +/* Callbacks are much like required fields except with special datatype. */ +#define PB_REQUIRED_CALLBACK(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_CALLBACK | PB_HTYPE_REQUIRED | ltype, \ + fd, 0, pb_membersize(st, m), 0, ptr} + +#define PB_OPTIONAL_CALLBACK(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \ + fd, 0, pb_membersize(st, m), 0, ptr} + +#define PB_SINGULAR_CALLBACK(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_CALLBACK | PB_HTYPE_OPTIONAL | ltype, \ + fd, 0, pb_membersize(st, m), 0, ptr} + +#define PB_REPEATED_CALLBACK(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_CALLBACK | PB_HTYPE_REPEATED | ltype, \ + fd, 0, pb_membersize(st, m), 0, ptr} + +/* Optional extensions don't have the has_ field, as that would be redundant. + * Furthermore, the combination of OPTIONAL without has_ field is used + * for indicating proto3 style fields. Extensions exist in proto2 mode only, + * so they should be encoded according to proto2 rules. To avoid the conflict, + * extensions are marked as REQUIRED instead. + */ +#define PB_OPTEXT_STATIC(tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_STATIC | PB_HTYPE_REQUIRED | ltype, \ + 0, \ + 0, \ + pb_membersize(st, m), 0, ptr} + +#define PB_OPTEXT_POINTER(tag, st, m, fd, ltype, ptr) \ + PB_OPTIONAL_POINTER(tag, st, m, fd, ltype, ptr) + +#define PB_OPTEXT_CALLBACK(tag, st, m, fd, ltype, ptr) \ + PB_OPTIONAL_CALLBACK(tag, st, m, fd, ltype, ptr) + +/* The mapping from protobuf types to LTYPEs is done using these macros. */ +#define PB_LTYPE_MAP_BOOL PB_LTYPE_BOOL +#define PB_LTYPE_MAP_BYTES PB_LTYPE_BYTES +#define PB_LTYPE_MAP_DOUBLE PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_ENUM PB_LTYPE_VARINT +#define PB_LTYPE_MAP_UENUM PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_FIXED32 PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_FIXED64 PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_FLOAT PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_INT32 PB_LTYPE_VARINT +#define PB_LTYPE_MAP_INT64 PB_LTYPE_VARINT +#define PB_LTYPE_MAP_MESSAGE PB_LTYPE_SUBMESSAGE +#define PB_LTYPE_MAP_SFIXED32 PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_SFIXED64 PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_SINT32 PB_LTYPE_SVARINT +#define PB_LTYPE_MAP_SINT64 PB_LTYPE_SVARINT +#define PB_LTYPE_MAP_STRING PB_LTYPE_STRING +#define PB_LTYPE_MAP_UINT32 PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_UINT64 PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_EXTENSION PB_LTYPE_EXTENSION +#define PB_LTYPE_MAP_FIXED_LENGTH_BYTES PB_LTYPE_FIXED_LENGTH_BYTES + +/* This is the actual macro used in field descriptions. + * It takes these arguments: + * - Field tag number + * - Field type: BOOL, BYTES, DOUBLE, ENUM, UENUM, FIXED32, FIXED64, + * FLOAT, INT32, INT64, MESSAGE, SFIXED32, SFIXED64 + * SINT32, SINT64, STRING, UINT32, UINT64 or EXTENSION + * - Field rules: REQUIRED, OPTIONAL or REPEATED + * - Allocation: STATIC, CALLBACK or POINTER + * - Placement: FIRST or OTHER, depending on if this is the first field in structure. + * - Message name + * - Field name + * - Previous field name (or field name again for first field) + * - Pointer to default value or submsg fields. + */ + +#define PB_FIELD(tag, type, rules, allocation, placement, message, field, prevfield, ptr) \ + PB_ ## rules ## _ ## allocation(tag, message, field, \ + PB_DATAOFFSET_ ## placement(message, field, prevfield), \ + PB_LTYPE_MAP_ ## type, ptr) + +/* Field description for repeated static fixed count fields.*/ +#define PB_REPEATED_FIXED_COUNT(tag, type, placement, message, field, prevfield, ptr) \ + {tag, PB_ATYPE_STATIC | PB_HTYPE_REPEATED | PB_LTYPE_MAP_ ## type, \ + PB_DATAOFFSET_ ## placement(message, field, prevfield), \ + 0, \ + pb_membersize(message, field[0]), \ + pb_arraysize(message, field), ptr} + +/* Field description for oneof fields. This requires taking into account the + * union name also, that's why a separate set of macros is needed. + */ +#define PB_ONEOF_STATIC(u, tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_STATIC | PB_HTYPE_ONEOF | ltype, \ + fd, pb_delta(st, which_ ## u, u.m), \ + pb_membersize(st, u.m), 0, ptr} + +#define PB_ONEOF_POINTER(u, tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_POINTER | PB_HTYPE_ONEOF | ltype, \ + fd, pb_delta(st, which_ ## u, u.m), \ + pb_membersize(st, u.m[0]), 0, ptr} + +#define PB_ONEOF_FIELD(union_name, tag, type, rules, allocation, placement, message, field, prevfield, ptr) \ + PB_ONEOF_ ## allocation(union_name, tag, message, field, \ + PB_DATAOFFSET_ ## placement(message, union_name.field, prevfield), \ + PB_LTYPE_MAP_ ## type, ptr) + +#define PB_ANONYMOUS_ONEOF_STATIC(u, tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_STATIC | PB_HTYPE_ONEOF | ltype, \ + fd, pb_delta(st, which_ ## u, m), \ + pb_membersize(st, m), 0, ptr} + +#define PB_ANONYMOUS_ONEOF_POINTER(u, tag, st, m, fd, ltype, ptr) \ + {tag, PB_ATYPE_POINTER | PB_HTYPE_ONEOF | ltype, \ + fd, pb_delta(st, which_ ## u, m), \ + pb_membersize(st, m[0]), 0, ptr} + +#define PB_ANONYMOUS_ONEOF_FIELD(union_name, tag, type, rules, allocation, placement, message, field, prevfield, ptr) \ + PB_ANONYMOUS_ONEOF_ ## allocation(union_name, tag, message, field, \ + PB_DATAOFFSET_ ## placement(message, field, prevfield), \ + PB_LTYPE_MAP_ ## type, ptr) + +/* These macros are used for giving out error messages. + * They are mostly a debugging aid; the main error information + * is the true/false return value from functions. + * Some code space can be saved by disabling the error + * messages if not used. + * + * PB_SET_ERROR() sets the error message if none has been set yet. + * msg must be a constant string literal. + * PB_GET_ERROR() always returns a pointer to a string. + * PB_RETURN_ERROR() sets the error and returns false from current + * function. + */ +#ifdef PB_NO_ERRMSG +#define PB_SET_ERROR(stream, msg) PB_UNUSED(stream) +#define PB_GET_ERROR(stream) "(errmsg disabled)" +#else +#define PB_SET_ERROR(stream, msg) (stream->errmsg = (stream)->errmsg ? (stream)->errmsg : (msg)) +#define PB_GET_ERROR(stream) ((stream)->errmsg ? (stream)->errmsg : "(none)") +#endif + +#define PB_RETURN_ERROR(stream, msg) return PB_SET_ERROR(stream, msg), false + +#endif diff --git a/Pods/nanopb/pb_common.c b/Pods/nanopb/pb_common.c new file mode 100644 index 0000000..5799db2 --- /dev/null +++ b/Pods/nanopb/pb_common.c @@ -0,0 +1,106 @@ +/* pb_common.c: Common support functions for pb_encode.c and pb_decode.c. + * + * 2014 Petteri Aimonen + */ + +#include "pb_common.h" + +bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_field_t *fields, void *dest_struct) +{ + iter->start = fields; + iter->pos = fields; + iter->required_field_index = 0; + iter->dest_struct = dest_struct; + + if (!dest_struct) + { + iter->pData = NULL; + iter->pSize = NULL; + } + else + { + iter->pData = (char*)dest_struct + iter->pos->data_offset; + iter->pSize = (char*)iter->pData + iter->pos->size_offset; + } + + return (iter->pos->tag != 0); +} + +bool pb_field_iter_next(pb_field_iter_t *iter) +{ + const pb_field_t *prev_field = iter->pos; + + if (prev_field->tag == 0) + { + /* Handle empty message types, where the first field is already the terminator. + * In other cases, the iter->pos never points to the terminator. */ + return false; + } + + iter->pos++; + + if (iter->pos->tag == 0) + { + /* Wrapped back to beginning, reinitialize */ + (void)pb_field_iter_begin(iter, iter->start, iter->dest_struct); + return false; + } + else + { + /* Increment the pointers based on previous field size */ + size_t prev_size = prev_field->data_size; + + if (PB_HTYPE(prev_field->type) == PB_HTYPE_ONEOF && + PB_HTYPE(iter->pos->type) == PB_HTYPE_ONEOF && + iter->pos->data_offset == PB_SIZE_MAX) + { + /* Don't advance pointers inside unions */ + return true; + } + else if (PB_ATYPE(prev_field->type) == PB_ATYPE_STATIC && + PB_HTYPE(prev_field->type) == PB_HTYPE_REPEATED) + { + /* In static arrays, the data_size tells the size of a single entry and + * array_size is the number of entries */ + prev_size *= prev_field->array_size; + } + else if (PB_ATYPE(prev_field->type) == PB_ATYPE_POINTER) + { + /* Pointer fields always have a constant size in the main structure. + * The data_size only applies to the dynamically allocated area. */ + prev_size = sizeof(void*); + } + + if (PB_HTYPE(prev_field->type) == PB_HTYPE_REQUIRED) + { + /* Count the required fields, in order to check their presence in the + * decoder. */ + iter->required_field_index++; + } + + iter->pData = (char*)iter->pData + prev_size + iter->pos->data_offset; + iter->pSize = (char*)iter->pData + iter->pos->size_offset; + return true; + } +} + +bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag) +{ + const pb_field_t *start = iter->pos; + + do { + if (iter->pos->tag == tag && + PB_LTYPE(iter->pos->type) != PB_LTYPE_EXTENSION) + { + /* Found the wanted field */ + return true; + } + + (void)pb_field_iter_next(iter); + } while (iter->pos != start); + + /* Searched all the way back to start, and found nothing. */ + return false; +} + + diff --git a/Pods/nanopb/pb_common.h b/Pods/nanopb/pb_common.h new file mode 100644 index 0000000..60b3d37 --- /dev/null +++ b/Pods/nanopb/pb_common.h @@ -0,0 +1,42 @@ +/* pb_common.h: Common support functions for pb_encode.c and pb_decode.c. + * These functions are rarely needed by applications directly. + */ + +#ifndef PB_COMMON_H_INCLUDED +#define PB_COMMON_H_INCLUDED + +#include "pb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Iterator for pb_field_t list */ +struct pb_field_iter_s { + const pb_field_t *start; /* Start of the pb_field_t array */ + const pb_field_t *pos; /* Current position of the iterator */ + unsigned required_field_index; /* Zero-based index that counts only the required fields */ + void *dest_struct; /* Pointer to start of the structure */ + void *pData; /* Pointer to current field value */ + void *pSize; /* Pointer to count/has field */ +}; +typedef struct pb_field_iter_s pb_field_iter_t; + +/* Initialize the field iterator structure to beginning. + * Returns false if the message type is empty. */ +bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_field_t *fields, void *dest_struct); + +/* Advance the iterator to the next field. + * Returns false when the iterator wraps back to the first field. */ +bool pb_field_iter_next(pb_field_iter_t *iter); + +/* Advance the iterator until it points at a field with the given tag. + * Returns false if no such field exists. */ +bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif + diff --git a/Pods/nanopb/pb_decode.c b/Pods/nanopb/pb_decode.c new file mode 100644 index 0000000..ebf7e85 --- /dev/null +++ b/Pods/nanopb/pb_decode.c @@ -0,0 +1,1570 @@ +/* pb_decode.c -- decode a protobuf using minimal resources + * + * 2011 Petteri Aimonen + */ + +/* Use the GCC warn_unused_result attribute to check that all return values + * are propagated correctly. On other compilers and gcc before 3.4.0 just + * ignore the annotation. + */ +#if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) + #define checkreturn +#else + #define checkreturn __attribute__((warn_unused_result)) +#endif + +#include "pb.h" +#include "pb_decode.h" +#include "pb_common.h" + +/************************************** + * Declarations internal to this file * + **************************************/ + +typedef bool (*pb_decoder_t)(pb_istream_t *stream, const pb_field_t *field, void *dest) checkreturn; + +static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); +static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size); +static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter); +static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter); +static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter); +static void iter_from_extension(pb_field_iter_t *iter, pb_extension_t *extension); +static bool checkreturn default_extension_decoder(pb_istream_t *stream, pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type); +static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_field_iter_t *iter); +static bool checkreturn find_extension_field(pb_field_iter_t *iter); +static void pb_field_set_to_default(pb_field_iter_t *iter); +static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct); +static bool checkreturn pb_dec_bool(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof); +static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest); +static bool checkreturn pb_skip_varint(pb_istream_t *stream); +static bool checkreturn pb_skip_string(pb_istream_t *stream); + +#ifdef PB_ENABLE_MALLOC +static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size); +static bool checkreturn pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *iter); +static void pb_release_single_field(const pb_field_iter_t *iter); +#endif + +#ifdef PB_WITHOUT_64BIT +#define pb_int64_t int32_t +#define pb_uint64_t uint32_t +#else +#define pb_int64_t int64_t +#define pb_uint64_t uint64_t +#endif + +/* --- Function pointers to field decoders --- + * Order in the array must match pb_action_t LTYPE numbering. + */ +static const pb_decoder_t PB_DECODERS[PB_LTYPES_COUNT] = { + &pb_dec_bool, + &pb_dec_varint, + &pb_dec_uvarint, + &pb_dec_svarint, + &pb_dec_fixed32, + &pb_dec_fixed64, + + &pb_dec_bytes, + &pb_dec_string, + &pb_dec_submessage, + NULL, /* extensions */ + &pb_dec_fixed_length_bytes +}; + +/******************************* + * pb_istream_t implementation * + *******************************/ + +static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) +{ + size_t i; + const pb_byte_t *source = (const pb_byte_t*)stream->state; + stream->state = (pb_byte_t*)stream->state + count; + + if (buf != NULL) + { + for (i = 0; i < count; i++) + buf[i] = source[i]; + } + + return true; +} + +bool checkreturn pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) +{ + if (count == 0) + return true; + +#ifndef PB_BUFFER_ONLY + if (buf == NULL && stream->callback != buf_read) + { + /* Skip input bytes */ + pb_byte_t tmp[16]; + while (count > 16) + { + if (!pb_read(stream, tmp, 16)) + return false; + + count -= 16; + } + + return pb_read(stream, tmp, count); + } +#endif + + if (stream->bytes_left < count) + PB_RETURN_ERROR(stream, "end-of-stream"); + +#ifndef PB_BUFFER_ONLY + if (!stream->callback(stream, buf, count)) + PB_RETURN_ERROR(stream, "io error"); +#else + if (!buf_read(stream, buf, count)) + return false; +#endif + + stream->bytes_left -= count; + return true; +} + +/* Read a single byte from input stream. buf may not be NULL. + * This is an optimization for the varint decoding. */ +static bool checkreturn pb_readbyte(pb_istream_t *stream, pb_byte_t *buf) +{ + if (stream->bytes_left == 0) + PB_RETURN_ERROR(stream, "end-of-stream"); + +#ifndef PB_BUFFER_ONLY + if (!stream->callback(stream, buf, 1)) + PB_RETURN_ERROR(stream, "io error"); +#else + *buf = *(const pb_byte_t*)stream->state; + stream->state = (pb_byte_t*)stream->state + 1; +#endif + + stream->bytes_left--; + + return true; +} + +pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize) +{ + pb_istream_t stream; + /* Cast away the const from buf without a compiler error. We are + * careful to use it only in a const manner in the callbacks. + */ + union { + void *state; + const void *c_state; + } state; +#ifdef PB_BUFFER_ONLY + stream.callback = NULL; +#else + stream.callback = &buf_read; +#endif + state.c_state = buf; + stream.state = state.state; + stream.bytes_left = bufsize; +#ifndef PB_NO_ERRMSG + stream.errmsg = NULL; +#endif + return stream; +} + +/******************** + * Helper functions * + ********************/ + +static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof) +{ + pb_byte_t byte; + uint32_t result; + + if (!pb_readbyte(stream, &byte)) + { + if (stream->bytes_left == 0) + { + if (eof) + { + *eof = true; + } + } + + return false; + } + + if ((byte & 0x80) == 0) + { + /* Quick case, 1 byte value */ + result = byte; + } + else + { + /* Multibyte case */ + uint_fast8_t bitpos = 7; + result = byte & 0x7F; + + do + { + if (!pb_readbyte(stream, &byte)) + return false; + + if (bitpos >= 32) + { + /* Note: The varint could have trailing 0x80 bytes, or 0xFF for negative. */ + uint8_t sign_extension = (bitpos < 63) ? 0xFF : 0x01; + + if ((byte & 0x7F) != 0x00 && ((result >> 31) == 0 || byte != sign_extension)) + { + PB_RETURN_ERROR(stream, "varint overflow"); + } + } + else + { + result |= (uint32_t)(byte & 0x7F) << bitpos; + } + bitpos = (uint_fast8_t)(bitpos + 7); + } while (byte & 0x80); + + if (bitpos == 35 && (byte & 0x70) != 0) + { + /* The last byte was at bitpos=28, so only bottom 4 bits fit. */ + PB_RETURN_ERROR(stream, "varint overflow"); + } + } + + *dest = result; + return true; +} + +bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest) +{ + return pb_decode_varint32_eof(stream, dest, NULL); +} + +#ifndef PB_WITHOUT_64BIT +bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest) +{ + pb_byte_t byte; + uint_fast8_t bitpos = 0; + uint64_t result = 0; + + do + { + if (bitpos >= 64) + PB_RETURN_ERROR(stream, "varint overflow"); + + if (!pb_readbyte(stream, &byte)) + return false; + + result |= (uint64_t)(byte & 0x7F) << bitpos; + bitpos = (uint_fast8_t)(bitpos + 7); + } while (byte & 0x80); + + *dest = result; + return true; +} +#endif + +bool checkreturn pb_skip_varint(pb_istream_t *stream) +{ + pb_byte_t byte; + do + { + if (!pb_read(stream, &byte, 1)) + return false; + } while (byte & 0x80); + return true; +} + +bool checkreturn pb_skip_string(pb_istream_t *stream) +{ + uint32_t length; + if (!pb_decode_varint32(stream, &length)) + return false; + + return pb_read(stream, NULL, length); +} + +bool checkreturn pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof) +{ + uint32_t temp; + *eof = false; + *wire_type = (pb_wire_type_t) 0; + *tag = 0; + + if (!pb_decode_varint32_eof(stream, &temp, eof)) + { + return false; + } + + if (temp == 0) + { + *eof = true; /* Special feature: allow 0-terminated messages. */ + return false; + } + + *tag = temp >> 3; + *wire_type = (pb_wire_type_t)(temp & 7); + return true; +} + +bool checkreturn pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type) +{ + switch (wire_type) + { + case PB_WT_VARINT: return pb_skip_varint(stream); + case PB_WT_64BIT: return pb_read(stream, NULL, 8); + case PB_WT_STRING: return pb_skip_string(stream); + case PB_WT_32BIT: return pb_read(stream, NULL, 4); + default: PB_RETURN_ERROR(stream, "invalid wire_type"); + } +} + +/* Read a raw value to buffer, for the purpose of passing it to callback as + * a substream. Size is maximum size on call, and actual size on return. + */ +static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size) +{ + size_t max_size = *size; + switch (wire_type) + { + case PB_WT_VARINT: + *size = 0; + do + { + (*size)++; + if (*size > max_size) return false; + if (!pb_read(stream, buf, 1)) return false; + } while (*buf++ & 0x80); + return true; + + case PB_WT_64BIT: + *size = 8; + return pb_read(stream, buf, 8); + + case PB_WT_32BIT: + *size = 4; + return pb_read(stream, buf, 4); + + case PB_WT_STRING: + /* Calling read_raw_value with a PB_WT_STRING is an error. + * Explicitly handle this case and fallthrough to default to avoid + * compiler warnings. + */ + + default: PB_RETURN_ERROR(stream, "invalid wire_type"); + } +} + +/* Decode string length from stream and return a substream with limited length. + * Remember to close the substream using pb_close_string_substream(). + */ +bool checkreturn pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream) +{ + uint32_t size; + if (!pb_decode_varint32(stream, &size)) + return false; + + *substream = *stream; + if (substream->bytes_left < size) + PB_RETURN_ERROR(stream, "parent stream too short"); + + substream->bytes_left = size; + stream->bytes_left -= size; + return true; +} + +bool checkreturn pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream) +{ + if (substream->bytes_left) { + if (!pb_read(substream, NULL, substream->bytes_left)) + return false; + } + + stream->state = substream->state; + +#ifndef PB_NO_ERRMSG + stream->errmsg = substream->errmsg; +#endif + return true; +} + +/************************* + * Decode a single field * + *************************/ + +static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) +{ + pb_type_t type; + pb_decoder_t func; + + type = iter->pos->type; + func = PB_DECODERS[PB_LTYPE(type)]; + + switch (PB_HTYPE(type)) + { + case PB_HTYPE_REQUIRED: + return func(stream, iter->pos, iter->pData); + + case PB_HTYPE_OPTIONAL: + if (iter->pSize != iter->pData) + *(bool*)iter->pSize = true; + return func(stream, iter->pos, iter->pData); + + case PB_HTYPE_REPEATED: + if (wire_type == PB_WT_STRING + && PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE) + { + /* Packed array */ + bool status = true; + pb_size_t *size = (pb_size_t*)iter->pSize; + + pb_istream_t substream; + if (!pb_make_string_substream(stream, &substream)) + return false; + + while (substream.bytes_left > 0 && *size < iter->pos->array_size) + { + void *pItem = (char*)iter->pData + iter->pos->data_size * (*size); + if (!func(&substream, iter->pos, pItem)) + { + status = false; + break; + } + (*size)++; + } + + if (substream.bytes_left != 0) + PB_RETURN_ERROR(stream, "array overflow"); + if (!pb_close_string_substream(stream, &substream)) + return false; + + return status; + } + else + { + /* Repeated field */ + pb_size_t *size = (pb_size_t*)iter->pSize; + char *pItem = (char*)iter->pData + iter->pos->data_size * (*size); + + if ((*size)++ >= iter->pos->array_size) + PB_RETURN_ERROR(stream, "array overflow"); + + return func(stream, iter->pos, pItem); + } + + case PB_HTYPE_ONEOF: + if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE && + *(pb_size_t*)iter->pSize != iter->pos->tag) + { + /* We memset to zero so that any callbacks are set to NULL. + * This is because the callbacks might otherwise have values + * from some other union field. */ + memset(iter->pData, 0, iter->pos->data_size); + pb_message_set_to_defaults((const pb_field_t*)iter->pos->ptr, iter->pData); + } + *(pb_size_t*)iter->pSize = iter->pos->tag; + + return func(stream, iter->pos, iter->pData); + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +} + +#ifdef PB_ENABLE_MALLOC +/* Allocate storage for the field and store the pointer at iter->pData. + * array_size is the number of entries to reserve in an array. + * Zero size is not allowed, use pb_free() for releasing. + */ +static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size) +{ + void *ptr = *(void**)pData; + + if (data_size == 0 || array_size == 0) + PB_RETURN_ERROR(stream, "invalid size"); + +#ifdef __AVR__ + /* Workaround for AVR libc bug 53284: http://savannah.nongnu.org/bugs/?53284 + * Realloc to size of 1 byte can cause corruption of the malloc structures. + */ + if (data_size == 1 && array_size == 1) + { + data_size = 2; + } +#endif + + /* Check for multiplication overflows. + * This code avoids the costly division if the sizes are small enough. + * Multiplication is safe as long as only half of bits are set + * in either multiplicand. + */ + { + const size_t check_limit = (size_t)1 << (sizeof(size_t) * 4); + if (data_size >= check_limit || array_size >= check_limit) + { + const size_t size_max = (size_t)-1; + if (size_max / array_size < data_size) + { + PB_RETURN_ERROR(stream, "size too large"); + } + } + } + + /* Allocate new or expand previous allocation */ + /* Note: on failure the old pointer will remain in the structure, + * the message must be freed by caller also on error return. */ + ptr = pb_realloc(ptr, array_size * data_size); + if (ptr == NULL) + PB_RETURN_ERROR(stream, "realloc failed"); + + *(void**)pData = ptr; + return true; +} + +/* Clear a newly allocated item in case it contains a pointer, or is a submessage. */ +static void initialize_pointer_field(void *pItem, pb_field_iter_t *iter) +{ + if (PB_LTYPE(iter->pos->type) == PB_LTYPE_STRING || + PB_LTYPE(iter->pos->type) == PB_LTYPE_BYTES) + { + *(void**)pItem = NULL; + } + else if (PB_LTYPE(iter->pos->type) == PB_LTYPE_SUBMESSAGE) + { + /* We memset to zero so that any callbacks are set to NULL. + * Then set any default values. */ + memset(pItem, 0, iter->pos->data_size); + pb_message_set_to_defaults((const pb_field_t *) iter->pos->ptr, pItem); + } +} +#endif + +static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) +{ +#ifndef PB_ENABLE_MALLOC + PB_UNUSED(wire_type); + PB_UNUSED(iter); + PB_RETURN_ERROR(stream, "no malloc support"); +#else + pb_type_t type; + pb_decoder_t func; + + type = iter->pos->type; + func = PB_DECODERS[PB_LTYPE(type)]; + + switch (PB_HTYPE(type)) + { + case PB_HTYPE_REQUIRED: + case PB_HTYPE_OPTIONAL: + case PB_HTYPE_ONEOF: + if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE && + *(void**)iter->pData != NULL) + { + /* Duplicate field, have to release the old allocation first. */ + pb_release_single_field(iter); + } + + if (PB_HTYPE(type) == PB_HTYPE_ONEOF) + { + *(pb_size_t*)iter->pSize = iter->pos->tag; + } + + if (PB_LTYPE(type) == PB_LTYPE_STRING || + PB_LTYPE(type) == PB_LTYPE_BYTES) + { + return func(stream, iter->pos, iter->pData); + } + else + { + if (!allocate_field(stream, iter->pData, iter->pos->data_size, 1)) + return false; + + initialize_pointer_field(*(void**)iter->pData, iter); + return func(stream, iter->pos, *(void**)iter->pData); + } + + case PB_HTYPE_REPEATED: + if (wire_type == PB_WT_STRING + && PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE) + { + /* Packed array, multiple items come in at once. */ + bool status = true; + pb_size_t *size = (pb_size_t*)iter->pSize; + size_t allocated_size = *size; + void *pItem; + pb_istream_t substream; + + if (!pb_make_string_substream(stream, &substream)) + return false; + + while (substream.bytes_left) + { + if (*size == PB_SIZE_MAX) + { +#ifndef PB_NO_ERRMSG + stream->errmsg = "too many array entries"; +#endif + status = false; + break; + } + + if ((size_t)*size + 1 > allocated_size) + { + /* Allocate more storage. This tries to guess the + * number of remaining entries. Round the division + * upwards. */ + size_t remain = (substream.bytes_left - 1) / iter->pos->data_size + 1; + if (remain < PB_SIZE_MAX - allocated_size) + allocated_size += remain; + else + allocated_size += 1; + + if (!allocate_field(&substream, iter->pData, iter->pos->data_size, allocated_size)) + { + status = false; + break; + } + } + + /* Decode the array entry */ + pItem = *(char**)iter->pData + iter->pos->data_size * (*size); + if (pItem == NULL) + { + /* Shouldn't happen, but satisfies static analyzers */ + status = false; + break; + } + initialize_pointer_field(pItem, iter); + if (!func(&substream, iter->pos, pItem)) + { + status = false; + break; + } + + (*size)++; + } + if (!pb_close_string_substream(stream, &substream)) + return false; + + return status; + } + else + { + /* Normal repeated field, i.e. only one item at a time. */ + pb_size_t *size = (pb_size_t*)iter->pSize; + void *pItem; + + if (*size == PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "too many array entries"); + + if (!allocate_field(stream, iter->pData, iter->pos->data_size, (size_t)(*size + 1))) + return false; + + pItem = *(char**)iter->pData + iter->pos->data_size * (*size); + (*size)++; + initialize_pointer_field(pItem, iter); + return func(stream, iter->pos, pItem); + } + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +#endif +} + +static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) +{ + pb_callback_t *pCallback = (pb_callback_t*)iter->pData; +#ifdef PB_OLD_CALLBACK_STYLE + void *arg; +#else + void **arg; +#endif + + if (pCallback == NULL || pCallback->funcs.decode == NULL) + return pb_skip_field(stream, wire_type); + +#ifdef PB_OLD_CALLBACK_STYLE + arg = pCallback->arg; +#else + arg = &(pCallback->arg); +#endif + + if (wire_type == PB_WT_STRING) + { + pb_istream_t substream; + + if (!pb_make_string_substream(stream, &substream)) + return false; + + do + { + if (!pCallback->funcs.decode(&substream, iter->pos, arg)) + PB_RETURN_ERROR(stream, "callback failed"); + } while (substream.bytes_left); + + if (!pb_close_string_substream(stream, &substream)) + return false; + + return true; + } + else + { + /* Copy the single scalar value to stack. + * This is required so that we can limit the stream length, + * which in turn allows to use same callback for packed and + * not-packed fields. */ + pb_istream_t substream; + pb_byte_t buffer[10]; + size_t size = sizeof(buffer); + + if (!read_raw_value(stream, wire_type, buffer, &size)) + return false; + substream = pb_istream_from_buffer(buffer, size); + + return pCallback->funcs.decode(&substream, iter->pos, arg); + } +} + +static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter) +{ +#ifdef PB_ENABLE_MALLOC + /* When decoding an oneof field, check if there is old data that must be + * released first. */ + if (PB_HTYPE(iter->pos->type) == PB_HTYPE_ONEOF) + { + if (!pb_release_union_field(stream, iter)) + return false; + } +#endif + + switch (PB_ATYPE(iter->pos->type)) + { + case PB_ATYPE_STATIC: + return decode_static_field(stream, wire_type, iter); + + case PB_ATYPE_POINTER: + return decode_pointer_field(stream, wire_type, iter); + + case PB_ATYPE_CALLBACK: + return decode_callback_field(stream, wire_type, iter); + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +} + +static void iter_from_extension(pb_field_iter_t *iter, pb_extension_t *extension) +{ + /* Fake a field iterator for the extension field. + * It is not actually safe to advance this iterator, but decode_field + * will not even try to. */ + const pb_field_t *field = (const pb_field_t*)extension->type->arg; + (void)pb_field_iter_begin(iter, field, extension->dest); + iter->pData = extension->dest; + iter->pSize = &extension->found; + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { + /* For pointer extensions, the pointer is stored directly + * in the extension structure. This avoids having an extra + * indirection. */ + iter->pData = &extension->dest; + } +} + +/* Default handler for extension fields. Expects a pb_field_t structure + * in extension->type->arg. */ +static bool checkreturn default_extension_decoder(pb_istream_t *stream, + pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type) +{ + const pb_field_t *field = (const pb_field_t*)extension->type->arg; + pb_field_iter_t iter; + + if (field->tag != tag) + return true; + + iter_from_extension(&iter, extension); + extension->found = true; + return decode_field(stream, wire_type, &iter); +} + +/* Try to decode an unknown field as an extension field. Tries each extension + * decoder in turn, until one of them handles the field or loop ends. */ +static bool checkreturn decode_extension(pb_istream_t *stream, + uint32_t tag, pb_wire_type_t wire_type, pb_field_iter_t *iter) +{ + pb_extension_t *extension = *(pb_extension_t* const *)iter->pData; + size_t pos = stream->bytes_left; + + while (extension != NULL && pos == stream->bytes_left) + { + bool status; + if (extension->type->decode) + status = extension->type->decode(stream, extension, tag, wire_type); + else + status = default_extension_decoder(stream, extension, tag, wire_type); + + if (!status) + return false; + + extension = extension->next; + } + + return true; +} + +/* Step through the iterator until an extension field is found or until all + * entries have been checked. There can be only one extension field per + * message. Returns false if no extension field is found. */ +static bool checkreturn find_extension_field(pb_field_iter_t *iter) +{ + const pb_field_t *start = iter->pos; + + do { + if (PB_LTYPE(iter->pos->type) == PB_LTYPE_EXTENSION) + return true; + (void)pb_field_iter_next(iter); + } while (iter->pos != start); + + return false; +} + +/* Initialize message fields to default values, recursively */ +static void pb_field_set_to_default(pb_field_iter_t *iter) +{ + pb_type_t type; + type = iter->pos->type; + + if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) + { + pb_extension_t *ext = *(pb_extension_t* const *)iter->pData; + while (ext != NULL) + { + pb_field_iter_t ext_iter; + ext->found = false; + iter_from_extension(&ext_iter, ext); + pb_field_set_to_default(&ext_iter); + ext = ext->next; + } + } + else if (PB_ATYPE(type) == PB_ATYPE_STATIC) + { + bool init_data = true; + if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && iter->pSize != iter->pData) + { + /* Set has_field to false. Still initialize the optional field + * itself also. */ + *(bool*)iter->pSize = false; + } + else if (PB_HTYPE(type) == PB_HTYPE_REPEATED || + PB_HTYPE(type) == PB_HTYPE_ONEOF) + { + /* REPEATED: Set array count to 0, no need to initialize contents. + ONEOF: Set which_field to 0. */ + *(pb_size_t*)iter->pSize = 0; + init_data = false; + } + + if (init_data) + { + if (PB_LTYPE(iter->pos->type) == PB_LTYPE_SUBMESSAGE) + { + /* Initialize submessage to defaults */ + pb_message_set_to_defaults((const pb_field_t *) iter->pos->ptr, iter->pData); + } + else if (iter->pos->ptr != NULL) + { + /* Initialize to default value */ + memcpy(iter->pData, iter->pos->ptr, iter->pos->data_size); + } + else + { + /* Initialize to zeros */ + memset(iter->pData, 0, iter->pos->data_size); + } + } + } + else if (PB_ATYPE(type) == PB_ATYPE_POINTER) + { + /* Initialize the pointer to NULL. */ + *(void**)iter->pData = NULL; + + /* Initialize array count to 0. */ + if (PB_HTYPE(type) == PB_HTYPE_REPEATED || + PB_HTYPE(type) == PB_HTYPE_ONEOF) + { + *(pb_size_t*)iter->pSize = 0; + } + } + else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK) + { + /* Don't overwrite callback */ + } +} + +static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct) +{ + pb_field_iter_t iter; + + if (!pb_field_iter_begin(&iter, fields, dest_struct)) + return; /* Empty message type */ + + do + { + pb_field_set_to_default(&iter); + } while (pb_field_iter_next(&iter)); +} + +/********************* + * Decode all fields * + *********************/ + +bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) +{ + uint32_t fields_seen[(PB_MAX_REQUIRED_FIELDS + 31) / 32] = {0, 0}; + const uint32_t allbits = ~(uint32_t)0; + uint32_t extension_range_start = 0; + pb_field_iter_t iter; + + /* 'fixed_count_field' and 'fixed_count_size' track position of a repeated fixed + * count field. This can only handle _one_ repeated fixed count field that + * is unpacked and unordered among other (non repeated fixed count) fields. + */ + const pb_field_t *fixed_count_field = NULL; + pb_size_t fixed_count_size = 0; + + /* Return value ignored, as empty message types will be correctly handled by + * pb_field_iter_find() anyway. */ + (void)pb_field_iter_begin(&iter, fields, dest_struct); + + while (stream->bytes_left) + { + uint32_t tag; + pb_wire_type_t wire_type; + bool eof; + + if (!pb_decode_tag(stream, &wire_type, &tag, &eof)) + { + if (eof) + break; + else + return false; + } + + if (!pb_field_iter_find(&iter, tag)) + { + /* No match found, check if it matches an extension. */ + if (tag >= extension_range_start) + { + if (!find_extension_field(&iter)) + extension_range_start = (uint32_t)-1; + else + extension_range_start = iter.pos->tag; + + if (tag >= extension_range_start) + { + size_t pos = stream->bytes_left; + + if (!decode_extension(stream, tag, wire_type, &iter)) + return false; + + if (pos != stream->bytes_left) + { + /* The field was handled */ + continue; + } + } + } + + /* No match found, skip data */ + if (!pb_skip_field(stream, wire_type)) + return false; + continue; + } + + /* If a repeated fixed count field was found, get size from + * 'fixed_count_field' as there is no counter contained in the struct. + */ + if (PB_HTYPE(iter.pos->type) == PB_HTYPE_REPEATED + && iter.pSize == iter.pData) + { + if (fixed_count_field != iter.pos) { + /* If the new fixed count field does not match the previous one, + * check that the previous one is NULL or that it finished + * receiving all the expected data. + */ + if (fixed_count_field != NULL && + fixed_count_size != fixed_count_field->array_size) + { + PB_RETURN_ERROR(stream, "wrong size for fixed count field"); + } + + fixed_count_field = iter.pos; + fixed_count_size = 0; + } + + iter.pSize = &fixed_count_size; + } + + if (PB_HTYPE(iter.pos->type) == PB_HTYPE_REQUIRED + && iter.required_field_index < PB_MAX_REQUIRED_FIELDS) + { + uint32_t tmp = ((uint32_t)1 << (iter.required_field_index & 31)); + fields_seen[iter.required_field_index >> 5] |= tmp; + } + + if (!decode_field(stream, wire_type, &iter)) + return false; + } + + /* Check that all elements of the last decoded fixed count field were present. */ + if (fixed_count_field != NULL && + fixed_count_size != fixed_count_field->array_size) + { + PB_RETURN_ERROR(stream, "wrong size for fixed count field"); + } + + /* Check that all required fields were present. */ + { + /* First figure out the number of required fields by + * seeking to the end of the field array. Usually we + * are already close to end after decoding. + */ + unsigned req_field_count; + pb_type_t last_type; + unsigned i; + do { + req_field_count = iter.required_field_index; + last_type = iter.pos->type; + } while (pb_field_iter_next(&iter)); + + /* Fixup if last field was also required. */ + if (PB_HTYPE(last_type) == PB_HTYPE_REQUIRED && iter.pos->tag != 0) + req_field_count++; + + if (req_field_count > PB_MAX_REQUIRED_FIELDS) + req_field_count = PB_MAX_REQUIRED_FIELDS; + + if (req_field_count > 0) + { + /* Check the whole words */ + for (i = 0; i < (req_field_count >> 5); i++) + { + if (fields_seen[i] != allbits) + PB_RETURN_ERROR(stream, "missing required field"); + } + + /* Check the remaining bits (if any) */ + if ((req_field_count & 31) != 0) + { + if (fields_seen[req_field_count >> 5] != + (allbits >> (32 - (req_field_count & 31)))) + { + PB_RETURN_ERROR(stream, "missing required field"); + } + } + } + } + + return true; +} + +bool checkreturn pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) +{ + bool status; + pb_message_set_to_defaults(fields, dest_struct); + status = pb_decode_noinit(stream, fields, dest_struct); + +#ifdef PB_ENABLE_MALLOC + if (!status) + pb_release(fields, dest_struct); +#endif + + return status; +} + +bool pb_decode_delimited_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) +{ + pb_istream_t substream; + bool status; + + if (!pb_make_string_substream(stream, &substream)) + return false; + + status = pb_decode_noinit(&substream, fields, dest_struct); + + if (!pb_close_string_substream(stream, &substream)) + return false; + return status; +} + +bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) +{ + pb_istream_t substream; + bool status; + + if (!pb_make_string_substream(stream, &substream)) + return false; + + status = pb_decode(&substream, fields, dest_struct); + + if (!pb_close_string_substream(stream, &substream)) + return false; + return status; +} + +bool pb_decode_nullterminated(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct) +{ + /* This behaviour will be separated in nanopb-0.4.0, see issue #278. */ + return pb_decode(stream, fields, dest_struct); +} + +#ifdef PB_ENABLE_MALLOC +/* Given an oneof field, if there has already been a field inside this oneof, + * release it before overwriting with a different one. */ +static bool pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *iter) +{ + pb_size_t old_tag = *(pb_size_t*)iter->pSize; /* Previous which_ value */ + pb_size_t new_tag = iter->pos->tag; /* New which_ value */ + + if (old_tag == 0) + return true; /* Ok, no old data in union */ + + if (old_tag == new_tag) + return true; /* Ok, old data is of same type => merge */ + + /* Release old data. The find can fail if the message struct contains + * invalid data. */ + if (!pb_field_iter_find(iter, old_tag)) + PB_RETURN_ERROR(stream, "invalid union tag"); + + pb_release_single_field(iter); + + /* Restore iterator to where it should be. + * This shouldn't fail unless the pb_field_t structure is corrupted. */ + if (!pb_field_iter_find(iter, new_tag)) + PB_RETURN_ERROR(stream, "iterator error"); + + if (PB_ATYPE(iter->pos->type) == PB_ATYPE_POINTER) + { + /* Initialize the pointer to NULL to make sure it is valid + * even in case of error return. */ + *(void**)iter->pData = NULL; + } + + return true; +} + +static void pb_release_single_field(const pb_field_iter_t *iter) +{ + pb_type_t type; + type = iter->pos->type; + + if (PB_HTYPE(type) == PB_HTYPE_ONEOF) + { + if (*(pb_size_t*)iter->pSize != iter->pos->tag) + return; /* This is not the current field in the union */ + } + + /* Release anything contained inside an extension or submsg. + * This has to be done even if the submsg itself is statically + * allocated. */ + if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) + { + /* Release fields from all extensions in the linked list */ + pb_extension_t *ext = *(pb_extension_t**)iter->pData; + while (ext != NULL) + { + pb_field_iter_t ext_iter; + iter_from_extension(&ext_iter, ext); + pb_release_single_field(&ext_iter); + ext = ext->next; + } + } + else if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE && PB_ATYPE(type) != PB_ATYPE_CALLBACK) + { + /* Release fields in submessage or submsg array */ + void *pItem = iter->pData; + pb_size_t count = 1; + + if (PB_ATYPE(type) == PB_ATYPE_POINTER) + { + pItem = *(void**)iter->pData; + } + + if (PB_HTYPE(type) == PB_HTYPE_REPEATED) + { + if (PB_ATYPE(type) == PB_ATYPE_STATIC && iter->pSize == iter->pData) { + /* No _count field so use size of the array */ + count = iter->pos->array_size; + } else { + count = *(pb_size_t*)iter->pSize; + } + + if (PB_ATYPE(type) == PB_ATYPE_STATIC && count > iter->pos->array_size) + { + /* Protect against corrupted _count fields */ + count = iter->pos->array_size; + } + } + + if (pItem) + { + for (; count > 0; count--) + { + pb_release((const pb_field_t*)iter->pos->ptr, pItem); + pItem = (char*)pItem + iter->pos->data_size; + } + } + } + + if (PB_ATYPE(type) == PB_ATYPE_POINTER) + { + if (PB_HTYPE(type) == PB_HTYPE_REPEATED && + (PB_LTYPE(type) == PB_LTYPE_STRING || + PB_LTYPE(type) == PB_LTYPE_BYTES)) + { + /* Release entries in repeated string or bytes array */ + void **pItem = *(void***)iter->pData; + pb_size_t count = *(pb_size_t*)iter->pSize; + for (; count > 0; count--) + { + pb_free(*pItem); + *pItem++ = NULL; + } + } + + if (PB_HTYPE(type) == PB_HTYPE_REPEATED) + { + /* We are going to release the array, so set the size to 0 */ + *(pb_size_t*)iter->pSize = 0; + } + + /* Release main item */ + pb_free(*(void**)iter->pData); + *(void**)iter->pData = NULL; + } +} + +void pb_release(const pb_field_t fields[], void *dest_struct) +{ + pb_field_iter_t iter; + + if (!dest_struct) + return; /* Ignore NULL pointers, similar to free() */ + + if (!pb_field_iter_begin(&iter, fields, dest_struct)) + return; /* Empty message type */ + + do + { + pb_release_single_field(&iter); + } while (pb_field_iter_next(&iter)); +} +#endif + +/* Field decoders */ + +bool pb_decode_bool(pb_istream_t *stream, bool *dest) +{ + return pb_dec_bool(stream, NULL, (void*)dest); +} + +bool pb_decode_svarint(pb_istream_t *stream, pb_int64_t *dest) +{ + pb_uint64_t value; + if (!pb_decode_varint(stream, &value)) + return false; + + if (value & 1) + *dest = (pb_int64_t)(~(value >> 1)); + else + *dest = (pb_int64_t)(value >> 1); + + return true; +} + +bool pb_decode_fixed32(pb_istream_t *stream, void *dest) +{ + pb_byte_t bytes[4]; + + if (!pb_read(stream, bytes, 4)) + return false; + + *(uint32_t*)dest = ((uint32_t)bytes[0] << 0) | + ((uint32_t)bytes[1] << 8) | + ((uint32_t)bytes[2] << 16) | + ((uint32_t)bytes[3] << 24); + return true; +} + +#ifndef PB_WITHOUT_64BIT +bool pb_decode_fixed64(pb_istream_t *stream, void *dest) +{ + pb_byte_t bytes[8]; + + if (!pb_read(stream, bytes, 8)) + return false; + + *(uint64_t*)dest = ((uint64_t)bytes[0] << 0) | + ((uint64_t)bytes[1] << 8) | + ((uint64_t)bytes[2] << 16) | + ((uint64_t)bytes[3] << 24) | + ((uint64_t)bytes[4] << 32) | + ((uint64_t)bytes[5] << 40) | + ((uint64_t)bytes[6] << 48) | + ((uint64_t)bytes[7] << 56); + + return true; +} +#endif + +static bool checkreturn pb_dec_bool(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + uint32_t value; + PB_UNUSED(field); + if (!pb_decode_varint32(stream, &value)) + return false; + + *(bool*)dest = (value != 0); + return true; +} + +static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + pb_uint64_t value; + pb_int64_t svalue; + pb_int64_t clamped; + if (!pb_decode_varint(stream, &value)) + return false; + + /* See issue 97: Google's C++ protobuf allows negative varint values to + * be cast as int32_t, instead of the int64_t that should be used when + * encoding. Previous nanopb versions had a bug in encoding. In order to + * not break decoding of such messages, we cast <=32 bit fields to + * int32_t first to get the sign correct. + */ + if (field->data_size == sizeof(pb_int64_t)) + svalue = (pb_int64_t)value; + else + svalue = (int32_t)value; + + /* Cast to the proper field size, while checking for overflows */ + if (field->data_size == sizeof(pb_int64_t)) + clamped = *(pb_int64_t*)dest = svalue; + else if (field->data_size == sizeof(int32_t)) + clamped = *(int32_t*)dest = (int32_t)svalue; + else if (field->data_size == sizeof(int_least16_t)) + clamped = *(int_least16_t*)dest = (int_least16_t)svalue; + else if (field->data_size == sizeof(int_least8_t)) + clamped = *(int_least8_t*)dest = (int_least8_t)svalue; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + if (clamped != svalue) + PB_RETURN_ERROR(stream, "integer too large"); + + return true; +} + +static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + pb_uint64_t value, clamped; + if (!pb_decode_varint(stream, &value)) + return false; + + /* Cast to the proper field size, while checking for overflows */ + if (field->data_size == sizeof(pb_uint64_t)) + clamped = *(pb_uint64_t*)dest = value; + else if (field->data_size == sizeof(uint32_t)) + clamped = *(uint32_t*)dest = (uint32_t)value; + else if (field->data_size == sizeof(uint_least16_t)) + clamped = *(uint_least16_t*)dest = (uint_least16_t)value; + else if (field->data_size == sizeof(uint_least8_t)) + clamped = *(uint_least8_t*)dest = (uint_least8_t)value; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + if (clamped != value) + PB_RETURN_ERROR(stream, "integer too large"); + + return true; +} + +static bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + pb_int64_t value, clamped; + if (!pb_decode_svarint(stream, &value)) + return false; + + /* Cast to the proper field size, while checking for overflows */ + if (field->data_size == sizeof(pb_int64_t)) + clamped = *(pb_int64_t*)dest = value; + else if (field->data_size == sizeof(int32_t)) + clamped = *(int32_t*)dest = (int32_t)value; + else if (field->data_size == sizeof(int_least16_t)) + clamped = *(int_least16_t*)dest = (int_least16_t)value; + else if (field->data_size == sizeof(int_least8_t)) + clamped = *(int_least8_t*)dest = (int_least8_t)value; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + if (clamped != value) + PB_RETURN_ERROR(stream, "integer too large"); + + return true; +} + +static bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + PB_UNUSED(field); + return pb_decode_fixed32(stream, dest); +} + +static bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + PB_UNUSED(field); +#ifndef PB_WITHOUT_64BIT + return pb_decode_fixed64(stream, dest); +#else + PB_UNUSED(dest); + PB_RETURN_ERROR(stream, "no 64bit support"); +#endif +} + +static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + uint32_t size; + size_t alloc_size; + pb_bytes_array_t *bdest; + + if (!pb_decode_varint32(stream, &size)) + return false; + + if (size > PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "bytes overflow"); + + alloc_size = PB_BYTES_ARRAY_T_ALLOCSIZE(size); + if (size > alloc_size) + PB_RETURN_ERROR(stream, "size too large"); + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { +#ifndef PB_ENABLE_MALLOC + PB_RETURN_ERROR(stream, "no malloc support"); +#else + if (stream->bytes_left < size) + PB_RETURN_ERROR(stream, "end-of-stream"); + + if (!allocate_field(stream, dest, alloc_size, 1)) + return false; + bdest = *(pb_bytes_array_t**)dest; +#endif + } + else + { + if (alloc_size > field->data_size) + PB_RETURN_ERROR(stream, "bytes overflow"); + bdest = (pb_bytes_array_t*)dest; + } + + bdest->size = (pb_size_t)size; + return pb_read(stream, bdest->bytes, size); +} + +static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + uint32_t size; + size_t alloc_size; + bool status; + if (!pb_decode_varint32(stream, &size)) + return false; + + /* Space for null terminator */ + alloc_size = size + 1; + + if (alloc_size < size) + PB_RETURN_ERROR(stream, "size too large"); + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { +#ifndef PB_ENABLE_MALLOC + PB_RETURN_ERROR(stream, "no malloc support"); +#else + if (stream->bytes_left < size) + PB_RETURN_ERROR(stream, "end-of-stream"); + + if (!allocate_field(stream, dest, alloc_size, 1)) + return false; + dest = *(void**)dest; +#endif + } + else + { + if (alloc_size > field->data_size) + PB_RETURN_ERROR(stream, "string overflow"); + } + + status = pb_read(stream, (pb_byte_t*)dest, size); + *((pb_byte_t*)dest + size) = 0; + return status; +} + +static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + bool status; + pb_istream_t substream; + const pb_field_t* submsg_fields = (const pb_field_t*)field->ptr; + + if (!pb_make_string_substream(stream, &substream)) + return false; + + if (field->ptr == NULL) + PB_RETURN_ERROR(stream, "invalid field descriptor"); + + /* New array entries need to be initialized, while required and optional + * submessages have already been initialized in the top-level pb_decode. */ + if (PB_HTYPE(field->type) == PB_HTYPE_REPEATED) + status = pb_decode(&substream, submsg_fields, dest); + else + status = pb_decode_noinit(&substream, submsg_fields, dest); + + if (!pb_close_string_substream(stream, &substream)) + return false; + return status; +} + +static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest) +{ + uint32_t size; + + if (!pb_decode_varint32(stream, &size)) + return false; + + if (size > PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "bytes overflow"); + + if (size == 0) + { + /* As a special case, treat empty bytes string as all zeros for fixed_length_bytes. */ + memset(dest, 0, field->data_size); + return true; + } + + if (size != field->data_size) + PB_RETURN_ERROR(stream, "incorrect fixed length bytes size"); + + return pb_read(stream, (pb_byte_t*)dest, field->data_size); +} diff --git a/Pods/nanopb/pb_decode.h b/Pods/nanopb/pb_decode.h new file mode 100644 index 0000000..3577c20 --- /dev/null +++ b/Pods/nanopb/pb_decode.h @@ -0,0 +1,178 @@ +/* pb_decode.h: Functions to decode protocol buffers. Depends on pb_decode.c. + * The main function is pb_decode. You also need an input stream, and the + * field descriptions created by nanopb_generator.py. + */ + +#ifndef PB_DECODE_H_INCLUDED +#define PB_DECODE_H_INCLUDED + +#include "pb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Structure for defining custom input streams. You will need to provide + * a callback function to read the bytes from your storage, which can be + * for example a file or a network socket. + * + * The callback must conform to these rules: + * + * 1) Return false on IO errors. This will cause decoding to abort. + * 2) You can use state to store your own data (e.g. buffer pointer), + * and rely on pb_read to verify that no-body reads past bytes_left. + * 3) Your callback may be used with substreams, in which case bytes_left + * is different than from the main stream. Don't use bytes_left to compute + * any pointers. + */ +struct pb_istream_s +{ +#ifdef PB_BUFFER_ONLY + /* Callback pointer is not used in buffer-only configuration. + * Having an int pointer here allows binary compatibility but + * gives an error if someone tries to assign callback function. + */ + int *callback; +#else + bool (*callback)(pb_istream_t *stream, pb_byte_t *buf, size_t count); +#endif + + void *state; /* Free field for use by callback implementation */ + size_t bytes_left; + +#ifndef PB_NO_ERRMSG + const char *errmsg; +#endif +}; + +/*************************** + * Main decoding functions * + ***************************/ + +/* Decode a single protocol buffers message from input stream into a C structure. + * Returns true on success, false on any failure. + * The actual struct pointed to by dest must match the description in fields. + * Callback fields of the destination structure must be initialized by caller. + * All other fields will be initialized by this function. + * + * Example usage: + * MyMessage msg = {}; + * uint8_t buffer[64]; + * pb_istream_t stream; + * + * // ... read some data into buffer ... + * + * stream = pb_istream_from_buffer(buffer, count); + * pb_decode(&stream, MyMessage_fields, &msg); + */ +bool pb_decode(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); + +/* Same as pb_decode, except does not initialize the destination structure + * to default values. This is slightly faster if you need no default values + * and just do memset(struct, 0, sizeof(struct)) yourself. + * + * This can also be used for 'merging' two messages, i.e. update only the + * fields that exist in the new message. + * + * Note: If this function returns with an error, it will not release any + * dynamically allocated fields. You will need to call pb_release() yourself. + */ +bool pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); + +/* Same as pb_decode, except expects the stream to start with the message size + * encoded as varint. Corresponds to parseDelimitedFrom() in Google's + * protobuf API. + */ +bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); + +/* Same as pb_decode_delimited, except that it does not initialize the destination structure. + * See pb_decode_noinit + */ +bool pb_decode_delimited_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); + +/* Same as pb_decode, except allows the message to be terminated with a null byte. + * NOTE: Until nanopb-0.4.0, pb_decode() also allows null-termination. This behaviour + * is not supported in most other protobuf implementations, so pb_decode_delimited() + * is a better option for compatibility. + */ +bool pb_decode_nullterminated(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct); + +#ifdef PB_ENABLE_MALLOC +/* Release any allocated pointer fields. If you use dynamic allocation, you should + * call this for any successfully decoded message when you are done with it. If + * pb_decode() returns with an error, the message is already released. + */ +void pb_release(const pb_field_t fields[], void *dest_struct); +#endif + + +/************************************** + * Functions for manipulating streams * + **************************************/ + +/* Create an input stream for reading from a memory buffer. + * + * Alternatively, you can use a custom stream that reads directly from e.g. + * a file or a network socket. + */ +pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize); + +/* Function to read from a pb_istream_t. You can use this if you need to + * read some custom header data, or to read data in field callbacks. + */ +bool pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); + + +/************************************************ + * Helper functions for writing field callbacks * + ************************************************/ + +/* Decode the tag for the next field in the stream. Gives the wire type and + * field tag. At end of the message, returns false and sets eof to true. */ +bool pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof); + +/* Skip the field payload data, given the wire type. */ +bool pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type); + +/* Decode an integer in the varint format. This works for enum, int32, + * int64, uint32 and uint64 field types. */ +#ifndef PB_WITHOUT_64BIT +bool pb_decode_varint(pb_istream_t *stream, uint64_t *dest); +#else +#define pb_decode_varint pb_decode_varint32 +#endif + +/* Decode an integer in the varint format. This works for enum, int32, + * and uint32 field types. */ +bool pb_decode_varint32(pb_istream_t *stream, uint32_t *dest); + +/* Decode a bool value in varint format. */ +bool pb_decode_bool(pb_istream_t *stream, bool *dest); + +/* Decode an integer in the zig-zagged svarint format. This works for sint32 + * and sint64. */ +#ifndef PB_WITHOUT_64BIT +bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest); +#else +bool pb_decode_svarint(pb_istream_t *stream, int32_t *dest); +#endif + +/* Decode a fixed32, sfixed32 or float value. You need to pass a pointer to + * a 4-byte wide C variable. */ +bool pb_decode_fixed32(pb_istream_t *stream, void *dest); + +#ifndef PB_WITHOUT_64BIT +/* Decode a fixed64, sfixed64 or double value. You need to pass a pointer to + * a 8-byte wide C variable. */ +bool pb_decode_fixed64(pb_istream_t *stream, void *dest); +#endif + +/* Make a limited-length substream for reading a PB_WT_STRING field. */ +bool pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream); +bool pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/Pods/nanopb/pb_encode.c b/Pods/nanopb/pb_encode.c new file mode 100644 index 0000000..f6e60c4 --- /dev/null +++ b/Pods/nanopb/pb_encode.c @@ -0,0 +1,911 @@ +/* pb_encode.c -- encode a protobuf using minimal resources + * + * 2011 Petteri Aimonen + */ + +#include "pb.h" +#include "pb_encode.h" +#include "pb_common.h" + +/* Use the GCC warn_unused_result attribute to check that all return values + * are propagated correctly. On other compilers and gcc before 3.4.0 just + * ignore the annotation. + */ +#if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) + #define checkreturn +#else + #define checkreturn __attribute__((warn_unused_result)) +#endif + +/************************************** + * Declarations internal to this file * + **************************************/ +typedef bool (*pb_encoder_t)(pb_ostream_t *stream, const pb_field_t *field, const void *src) checkreturn; + +static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); +static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *field, const void *pData, size_t count, pb_encoder_t func); +static bool checkreturn encode_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData); +static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension); +static bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData); +static void *pb_const_cast(const void *p); +static bool checkreturn pb_enc_bool(pb_ostream_t *stream, const pb_field_t *field, const void *src); +static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src); +static bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src); +static bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src); +static bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, const void *src); +static bool checkreturn pb_enc_fixed64(pb_ostream_t *stream, const pb_field_t *field, const void *src); +static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src); +static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src); +static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src); +static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src); + +#ifdef PB_WITHOUT_64BIT +#define pb_int64_t int32_t +#define pb_uint64_t uint32_t + +static bool checkreturn pb_encode_negative_varint(pb_ostream_t *stream, pb_uint64_t value); +#else +#define pb_int64_t int64_t +#define pb_uint64_t uint64_t +#endif + +/* --- Function pointers to field encoders --- + * Order in the array must match pb_action_t LTYPE numbering. + */ +static const pb_encoder_t PB_ENCODERS[PB_LTYPES_COUNT] = { + &pb_enc_bool, + &pb_enc_varint, + &pb_enc_uvarint, + &pb_enc_svarint, + &pb_enc_fixed32, + &pb_enc_fixed64, + + &pb_enc_bytes, + &pb_enc_string, + &pb_enc_submessage, + NULL, /* extensions */ + &pb_enc_fixed_length_bytes +}; + +/******************************* + * pb_ostream_t implementation * + *******************************/ + +static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count) +{ + size_t i; + pb_byte_t *dest = (pb_byte_t*)stream->state; + stream->state = dest + count; + + for (i = 0; i < count; i++) + dest[i] = buf[i]; + + return true; +} + +pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize) +{ + pb_ostream_t stream; +#ifdef PB_BUFFER_ONLY + stream.callback = (void*)1; /* Just a marker value */ +#else + stream.callback = &buf_write; +#endif + stream.state = buf; + stream.max_size = bufsize; + stream.bytes_written = 0; +#ifndef PB_NO_ERRMSG + stream.errmsg = NULL; +#endif + return stream; +} + +bool checkreturn pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count) +{ + if (count > 0 && stream->callback != NULL) + { + if (stream->bytes_written + count < stream->bytes_written || + stream->bytes_written + count > stream->max_size) + { + PB_RETURN_ERROR(stream, "stream full"); + } + +#ifdef PB_BUFFER_ONLY + if (!buf_write(stream, buf, count)) + PB_RETURN_ERROR(stream, "io error"); +#else + if (!stream->callback(stream, buf, count)) + PB_RETURN_ERROR(stream, "io error"); +#endif + } + + stream->bytes_written += count; + return true; +} + +/************************* + * Encode a single field * + *************************/ + +/* Read a bool value without causing undefined behavior even if the value + * is invalid. See issue #434 and + * https://stackoverflow.com/questions/27661768/weird-results-for-conditional + */ +static bool safe_read_bool(const void *pSize) +{ + const char *p = (const char *)pSize; + size_t i; + for (i = 0; i < sizeof(bool); i++) + { + if (p[i] != 0) + return true; + } + return false; +} + +/* Encode a static array. Handles the size calculations and possible packing. */ +static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *field, + const void *pData, size_t count, pb_encoder_t func) +{ + size_t i; + const void *p; +#ifndef PB_ENCODE_ARRAYS_UNPACKED + size_t size; +#endif + + if (count == 0) + return true; + + if (PB_ATYPE(field->type) != PB_ATYPE_POINTER && count > field->array_size) + PB_RETURN_ERROR(stream, "array max size exceeded"); + +#ifndef PB_ENCODE_ARRAYS_UNPACKED + /* We always pack arrays if the datatype allows it. */ + if (PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) + { + if (!pb_encode_tag(stream, PB_WT_STRING, field->tag)) + return false; + + /* Determine the total size of packed array. */ + if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32) + { + size = 4 * count; + } + else if (PB_LTYPE(field->type) == PB_LTYPE_FIXED64) + { + size = 8 * count; + } + else + { + pb_ostream_t sizestream = PB_OSTREAM_SIZING; + p = pData; + for (i = 0; i < count; i++) + { + if (!func(&sizestream, field, p)) + return false; + p = (const char*)p + field->data_size; + } + size = sizestream.bytes_written; + } + + if (!pb_encode_varint(stream, (pb_uint64_t)size)) + return false; + + if (stream->callback == NULL) + return pb_write(stream, NULL, size); /* Just sizing.. */ + + /* Write the data */ + p = pData; + for (i = 0; i < count; i++) + { + if (!func(stream, field, p)) + return false; + p = (const char*)p + field->data_size; + } + } + else +#endif + { + p = pData; + for (i = 0; i < count; i++) + { + if (!pb_encode_tag_for_field(stream, field)) + return false; + + /* Normally the data is stored directly in the array entries, but + * for pointer-type string and bytes fields, the array entries are + * actually pointers themselves also. So we have to dereference once + * more to get to the actual data. */ + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER && + (PB_LTYPE(field->type) == PB_LTYPE_STRING || + PB_LTYPE(field->type) == PB_LTYPE_BYTES)) + { + if (!func(stream, field, *(const void* const*)p)) + return false; + } + else + { + if (!func(stream, field, p)) + return false; + } + p = (const char*)p + field->data_size; + } + } + + return true; +} + +/* In proto3, all fields are optional and are only encoded if their value is "non-zero". + * This function implements the check for the zero value. */ +static bool pb_check_proto3_default_value(const pb_field_t *field, const void *pData) +{ + pb_type_t type = field->type; + const void *pSize = (const char*)pData + field->size_offset; + + if (PB_HTYPE(type) == PB_HTYPE_REQUIRED) + { + /* Required proto2 fields inside proto3 submessage, pretty rare case */ + return false; + } + else if (PB_HTYPE(type) == PB_HTYPE_REPEATED) + { + /* Repeated fields inside proto3 submessage: present if count != 0 */ + if (field->size_offset != 0) + return *(const pb_size_t*)pSize == 0; + else if (PB_ATYPE(type) == PB_ATYPE_STATIC) + return false; /* Fixed length array */ + } + else if (PB_HTYPE(type) == PB_HTYPE_ONEOF) + { + /* Oneof fields */ + return *(const pb_size_t*)pSize == 0; + } + else if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && field->size_offset != 0) + { + /* Proto2 optional fields inside proto3 submessage */ + return safe_read_bool(pSize) == false; + } + + /* Rest is proto3 singular fields */ + + if (PB_ATYPE(type) == PB_ATYPE_STATIC) + { + if (PB_LTYPE(type) == PB_LTYPE_BYTES) + { + const pb_bytes_array_t *bytes = (const pb_bytes_array_t*)pData; + return bytes->size == 0; + } + else if (PB_LTYPE(type) == PB_LTYPE_STRING) + { + return *(const char*)pData == '\0'; + } + else if (PB_LTYPE(type) == PB_LTYPE_FIXED_LENGTH_BYTES) + { + /* Fixed length bytes is only empty if its length is fixed + * as 0. Which would be pretty strange, but we can check + * it anyway. */ + return field->data_size == 0; + } + else if (PB_LTYPE(type) == PB_LTYPE_SUBMESSAGE) + { + /* Check all fields in the submessage to find if any of them + * are non-zero. The comparison cannot be done byte-per-byte + * because the C struct may contain padding bytes that must + * be skipped. + */ + pb_field_iter_t iter; + if (pb_field_iter_begin(&iter, (const pb_field_t*)field->ptr, pb_const_cast(pData))) + { + do + { + if (!pb_check_proto3_default_value(iter.pos, iter.pData)) + { + return false; + } + } while (pb_field_iter_next(&iter)); + } + return true; + } + } + + /* Compares pointers to NULL in case of FT_POINTER */ + if (PB_ATYPE(type) == PB_ATYPE_POINTER && PB_LTYPE(type) > PB_LTYPE_LAST_PACKABLE) + { + return !*(const void**)((uintptr_t)pData); + } + + { + /* Catch-all branch that does byte-per-byte comparison for zero value. + * + * This is for all pointer fields, and for static PB_LTYPE_VARINT, + * UVARINT, SVARINT, FIXED32, FIXED64, EXTENSION fields, and also + * callback fields. These all have integer or pointer value which + * can be compared with 0. + */ + pb_size_t i; + const char *p = (const char*)pData; + for (i = 0; i < field->data_size; i++) + { + if (p[i] != 0) + { + return false; + } + } + + return true; + } +} + +/* Encode a field with static or pointer allocation, i.e. one whose data + * is available to the encoder directly. */ +static bool checkreturn encode_basic_field(pb_ostream_t *stream, + const pb_field_t *field, const void *pData) +{ + pb_encoder_t func; + bool implicit_has; + const void *pSize = &implicit_has; + + func = PB_ENCODERS[PB_LTYPE(field->type)]; + + if (field->size_offset) + { + /* Static optional, repeated or oneof field */ + pSize = (const char*)pData + field->size_offset; + } + else if (PB_HTYPE(field->type) == PB_HTYPE_OPTIONAL) + { + /* Proto3 style field, optional but without explicit has_ field. */ + implicit_has = !pb_check_proto3_default_value(field, pData); + } + else + { + /* Required field, always present */ + implicit_has = true; + } + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { + /* pData is a pointer to the field, which contains pointer to + * the data. If the 2nd pointer is NULL, it is interpreted as if + * the has_field was false. + */ + pData = *(const void* const*)pData; + implicit_has = (pData != NULL); + } + + switch (PB_HTYPE(field->type)) + { + case PB_HTYPE_REQUIRED: + if (!pData) + PB_RETURN_ERROR(stream, "missing required field"); + if (!pb_encode_tag_for_field(stream, field)) + return false; + if (!func(stream, field, pData)) + return false; + break; + + case PB_HTYPE_OPTIONAL: + if (safe_read_bool(pSize)) + { + if (!pb_encode_tag_for_field(stream, field)) + return false; + + if (!func(stream, field, pData)) + return false; + } + break; + + case PB_HTYPE_REPEATED: { + pb_size_t count; + if (field->size_offset != 0) { + count = *(const pb_size_t*)pSize; + } else { + count = field->array_size; + } + if (!encode_array(stream, field, pData, count, func)) + return false; + break; + } + + case PB_HTYPE_ONEOF: + if (*(const pb_size_t*)pSize == field->tag) + { + if (!pb_encode_tag_for_field(stream, field)) + return false; + + if (!func(stream, field, pData)) + return false; + } + break; + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } + + return true; +} + +/* Encode a field with callback semantics. This means that a user function is + * called to provide and encode the actual data. */ +static bool checkreturn encode_callback_field(pb_ostream_t *stream, + const pb_field_t *field, const void *pData) +{ + const pb_callback_t *callback = (const pb_callback_t*)pData; + +#ifdef PB_OLD_CALLBACK_STYLE + const void *arg = callback->arg; +#else + void * const *arg = &(callback->arg); +#endif + + if (callback->funcs.encode != NULL) + { + if (!callback->funcs.encode(stream, field, arg)) + PB_RETURN_ERROR(stream, "callback error"); + } + return true; +} + +/* Encode a single field of any callback or static type. */ +static bool checkreturn encode_field(pb_ostream_t *stream, + const pb_field_t *field, const void *pData) +{ + switch (PB_ATYPE(field->type)) + { + case PB_ATYPE_STATIC: + case PB_ATYPE_POINTER: + return encode_basic_field(stream, field, pData); + + case PB_ATYPE_CALLBACK: + return encode_callback_field(stream, field, pData); + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +} + +/* Default handler for extension fields. Expects to have a pb_field_t + * pointer in the extension->type->arg field. */ +static bool checkreturn default_extension_encoder(pb_ostream_t *stream, + const pb_extension_t *extension) +{ + const pb_field_t *field = (const pb_field_t*)extension->type->arg; + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { + /* For pointer extensions, the pointer is stored directly + * in the extension structure. This avoids having an extra + * indirection. */ + return encode_field(stream, field, &extension->dest); + } + else + { + return encode_field(stream, field, extension->dest); + } +} + +/* Walk through all the registered extensions and give them a chance + * to encode themselves. */ +static bool checkreturn encode_extension_field(pb_ostream_t *stream, + const pb_field_t *field, const void *pData) +{ + const pb_extension_t *extension = *(const pb_extension_t* const *)pData; + PB_UNUSED(field); + + while (extension) + { + bool status; + if (extension->type->encode) + status = extension->type->encode(stream, extension); + else + status = default_extension_encoder(stream, extension); + + if (!status) + return false; + + extension = extension->next; + } + + return true; +} + +/********************* + * Encode all fields * + *********************/ + +static void *pb_const_cast(const void *p) +{ + /* Note: this casts away const, in order to use the common field iterator + * logic for both encoding and decoding. */ + union { + void *p1; + const void *p2; + } t; + t.p2 = p; + return t.p1; +} + +bool checkreturn pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct) +{ + pb_field_iter_t iter; + if (!pb_field_iter_begin(&iter, fields, pb_const_cast(src_struct))) + return true; /* Empty message type */ + + do { + if (PB_LTYPE(iter.pos->type) == PB_LTYPE_EXTENSION) + { + /* Special case for the extension field placeholder */ + if (!encode_extension_field(stream, iter.pos, iter.pData)) + return false; + } + else + { + /* Regular field */ + if (!encode_field(stream, iter.pos, iter.pData)) + return false; + } + } while (pb_field_iter_next(&iter)); + + return true; +} + +bool pb_encode_delimited(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct) +{ + return pb_encode_submessage(stream, fields, src_struct); +} + +bool pb_encode_nullterminated(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct) +{ + const pb_byte_t zero = 0; + + if (!pb_encode(stream, fields, src_struct)) + return false; + + return pb_write(stream, &zero, 1); +} + +bool pb_get_encoded_size(size_t *size, const pb_field_t fields[], const void *src_struct) +{ + pb_ostream_t stream = PB_OSTREAM_SIZING; + + if (!pb_encode(&stream, fields, src_struct)) + return false; + + *size = stream.bytes_written; + return true; +} + +/******************** + * Helper functions * + ********************/ + +#ifdef PB_WITHOUT_64BIT +bool checkreturn pb_encode_negative_varint(pb_ostream_t *stream, pb_uint64_t value) +{ + pb_byte_t buffer[10]; + size_t i = 0; + size_t compensation = 32;/* we need to compensate 32 bits all set to 1 */ + + while (value) + { + buffer[i] = (pb_byte_t)((value & 0x7F) | 0x80); + value >>= 7; + if (compensation) + { + /* re-set all the compensation bits we can or need */ + size_t bits = compensation > 7 ? 7 : compensation; + value ^= (pb_uint64_t)((0xFFu >> (8 - bits)) << 25); /* set the number of bits needed on the lowest of the most significant 7 bits */ + compensation -= bits; + } + i++; + } + buffer[i - 1] &= 0x7F; /* Unset top bit on last byte */ + + return pb_write(stream, buffer, i); +} +#endif + +bool checkreturn pb_encode_varint(pb_ostream_t *stream, pb_uint64_t value) +{ + pb_byte_t buffer[10]; + size_t i = 0; + + if (value <= 0x7F) + { + pb_byte_t v = (pb_byte_t)value; + return pb_write(stream, &v, 1); + } + + while (value) + { + buffer[i] = (pb_byte_t)((value & 0x7F) | 0x80); + value >>= 7; + i++; + } + buffer[i-1] &= 0x7F; /* Unset top bit on last byte */ + + return pb_write(stream, buffer, i); +} + +bool checkreturn pb_encode_svarint(pb_ostream_t *stream, pb_int64_t value) +{ + pb_uint64_t zigzagged; + if (value < 0) + zigzagged = ~((pb_uint64_t)value << 1); + else + zigzagged = (pb_uint64_t)value << 1; + + return pb_encode_varint(stream, zigzagged); +} + +bool checkreturn pb_encode_fixed32(pb_ostream_t *stream, const void *value) +{ + uint32_t val = *(const uint32_t*)value; + pb_byte_t bytes[4]; + bytes[0] = (pb_byte_t)(val & 0xFF); + bytes[1] = (pb_byte_t)((val >> 8) & 0xFF); + bytes[2] = (pb_byte_t)((val >> 16) & 0xFF); + bytes[3] = (pb_byte_t)((val >> 24) & 0xFF); + return pb_write(stream, bytes, 4); +} + +#ifndef PB_WITHOUT_64BIT +bool checkreturn pb_encode_fixed64(pb_ostream_t *stream, const void *value) +{ + uint64_t val = *(const uint64_t*)value; + pb_byte_t bytes[8]; + bytes[0] = (pb_byte_t)(val & 0xFF); + bytes[1] = (pb_byte_t)((val >> 8) & 0xFF); + bytes[2] = (pb_byte_t)((val >> 16) & 0xFF); + bytes[3] = (pb_byte_t)((val >> 24) & 0xFF); + bytes[4] = (pb_byte_t)((val >> 32) & 0xFF); + bytes[5] = (pb_byte_t)((val >> 40) & 0xFF); + bytes[6] = (pb_byte_t)((val >> 48) & 0xFF); + bytes[7] = (pb_byte_t)((val >> 56) & 0xFF); + return pb_write(stream, bytes, 8); +} +#endif + +bool checkreturn pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number) +{ + pb_uint64_t tag = ((pb_uint64_t)field_number << 3) | wiretype; + return pb_encode_varint(stream, tag); +} + +bool checkreturn pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t *field) +{ + pb_wire_type_t wiretype; + switch (PB_LTYPE(field->type)) + { + case PB_LTYPE_BOOL: + case PB_LTYPE_VARINT: + case PB_LTYPE_UVARINT: + case PB_LTYPE_SVARINT: + wiretype = PB_WT_VARINT; + break; + + case PB_LTYPE_FIXED32: + wiretype = PB_WT_32BIT; + break; + + case PB_LTYPE_FIXED64: + wiretype = PB_WT_64BIT; + break; + + case PB_LTYPE_BYTES: + case PB_LTYPE_STRING: + case PB_LTYPE_SUBMESSAGE: + case PB_LTYPE_FIXED_LENGTH_BYTES: + wiretype = PB_WT_STRING; + break; + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } + + return pb_encode_tag(stream, wiretype, field->tag); +} + +bool checkreturn pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size) +{ + if (!pb_encode_varint(stream, (pb_uint64_t)size)) + return false; + + return pb_write(stream, buffer, size); +} + +bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct) +{ + /* First calculate the message size using a non-writing substream. */ + pb_ostream_t substream = PB_OSTREAM_SIZING; + size_t size; + bool status; + + if (!pb_encode(&substream, fields, src_struct)) + { +#ifndef PB_NO_ERRMSG + stream->errmsg = substream.errmsg; +#endif + return false; + } + + size = substream.bytes_written; + + if (!pb_encode_varint(stream, (pb_uint64_t)size)) + return false; + + if (stream->callback == NULL) + return pb_write(stream, NULL, size); /* Just sizing */ + + if (stream->bytes_written + size > stream->max_size) + PB_RETURN_ERROR(stream, "stream full"); + + /* Use a substream to verify that a callback doesn't write more than + * what it did the first time. */ + substream.callback = stream->callback; + substream.state = stream->state; + substream.max_size = size; + substream.bytes_written = 0; +#ifndef PB_NO_ERRMSG + substream.errmsg = NULL; +#endif + + status = pb_encode(&substream, fields, src_struct); + + stream->bytes_written += substream.bytes_written; + stream->state = substream.state; +#ifndef PB_NO_ERRMSG + stream->errmsg = substream.errmsg; +#endif + + if (substream.bytes_written != size) + PB_RETURN_ERROR(stream, "submsg size changed"); + + return status; +} + +/* Field encoders */ + +static bool checkreturn pb_enc_bool(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ + uint32_t value = safe_read_bool(src) ? 1 : 0; + PB_UNUSED(field); + return pb_encode_varint(stream, value); +} + +static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ + pb_int64_t value = 0; + + if (field->data_size == sizeof(int_least8_t)) + value = *(const int_least8_t*)src; + else if (field->data_size == sizeof(int_least16_t)) + value = *(const int_least16_t*)src; + else if (field->data_size == sizeof(int32_t)) + value = *(const int32_t*)src; + else if (field->data_size == sizeof(pb_int64_t)) + value = *(const pb_int64_t*)src; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + +#ifdef PB_WITHOUT_64BIT + if (value < 0) + return pb_encode_negative_varint(stream, (pb_uint64_t)value); + else +#endif + return pb_encode_varint(stream, (pb_uint64_t)value); +} + +static bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ + pb_uint64_t value = 0; + + if (field->data_size == sizeof(uint_least8_t)) + value = *(const uint_least8_t*)src; + else if (field->data_size == sizeof(uint_least16_t)) + value = *(const uint_least16_t*)src; + else if (field->data_size == sizeof(uint32_t)) + value = *(const uint32_t*)src; + else if (field->data_size == sizeof(pb_uint64_t)) + value = *(const pb_uint64_t*)src; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + return pb_encode_varint(stream, value); +} + +static bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ + pb_int64_t value = 0; + + if (field->data_size == sizeof(int_least8_t)) + value = *(const int_least8_t*)src; + else if (field->data_size == sizeof(int_least16_t)) + value = *(const int_least16_t*)src; + else if (field->data_size == sizeof(int32_t)) + value = *(const int32_t*)src; + else if (field->data_size == sizeof(pb_int64_t)) + value = *(const pb_int64_t*)src; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + return pb_encode_svarint(stream, value); +} + +static bool checkreturn pb_enc_fixed64(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ + PB_UNUSED(field); +#ifndef PB_WITHOUT_64BIT + return pb_encode_fixed64(stream, src); +#else + PB_UNUSED(src); + PB_RETURN_ERROR(stream, "no 64bit support"); +#endif +} + +static bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ + PB_UNUSED(field); + return pb_encode_fixed32(stream, src); +} + +static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ + const pb_bytes_array_t *bytes = NULL; + + bytes = (const pb_bytes_array_t*)src; + + if (src == NULL) + { + /* Treat null pointer as an empty bytes field */ + return pb_encode_string(stream, NULL, 0); + } + + if (PB_ATYPE(field->type) == PB_ATYPE_STATIC && + bytes->size > field->data_size - offsetof(pb_bytes_array_t, bytes)) + { + PB_RETURN_ERROR(stream, "bytes size exceeded"); + } + + return pb_encode_string(stream, bytes->bytes, bytes->size); +} + +static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ + size_t size = 0; + size_t max_size = field->data_size; + const char *p = (const char*)src; + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + max_size = (size_t)-1; + + if (src == NULL) + { + size = 0; /* Treat null pointer as an empty string */ + } + else + { + /* strnlen() is not always available, so just use a loop */ + while (size < max_size && *p != '\0') + { + size++; + p++; + } + } + + return pb_encode_string(stream, (const pb_byte_t*)src, size); +} + +static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ + if (field->ptr == NULL) + PB_RETURN_ERROR(stream, "invalid field descriptor"); + + return pb_encode_submessage(stream, (const pb_field_t*)field->ptr, src); +} + +static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src) +{ + return pb_encode_string(stream, (const pb_byte_t*)src, field->data_size); +} + diff --git a/Pods/nanopb/pb_encode.h b/Pods/nanopb/pb_encode.h new file mode 100644 index 0000000..b1d822f --- /dev/null +++ b/Pods/nanopb/pb_encode.h @@ -0,0 +1,170 @@ +/* pb_encode.h: Functions to encode protocol buffers. Depends on pb_encode.c. + * The main function is pb_encode. You also need an output stream, and the + * field descriptions created by nanopb_generator.py. + */ + +#ifndef PB_ENCODE_H_INCLUDED +#define PB_ENCODE_H_INCLUDED + +#include "pb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Structure for defining custom output streams. You will need to provide + * a callback function to write the bytes to your storage, which can be + * for example a file or a network socket. + * + * The callback must conform to these rules: + * + * 1) Return false on IO errors. This will cause encoding to abort. + * 2) You can use state to store your own data (e.g. buffer pointer). + * 3) pb_write will update bytes_written after your callback runs. + * 4) Substreams will modify max_size and bytes_written. Don't use them + * to calculate any pointers. + */ +struct pb_ostream_s +{ +#ifdef PB_BUFFER_ONLY + /* Callback pointer is not used in buffer-only configuration. + * Having an int pointer here allows binary compatibility but + * gives an error if someone tries to assign callback function. + * Also, NULL pointer marks a 'sizing stream' that does not + * write anything. + */ + int *callback; +#else + bool (*callback)(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); +#endif + void *state; /* Free field for use by callback implementation. */ + size_t max_size; /* Limit number of output bytes written (or use SIZE_MAX). */ + size_t bytes_written; /* Number of bytes written so far. */ + +#ifndef PB_NO_ERRMSG + const char *errmsg; +#endif +}; + +/*************************** + * Main encoding functions * + ***************************/ + +/* Encode a single protocol buffers message from C structure into a stream. + * Returns true on success, false on any failure. + * The actual struct pointed to by src_struct must match the description in fields. + * All required fields in the struct are assumed to have been filled in. + * + * Example usage: + * MyMessage msg = {}; + * uint8_t buffer[64]; + * pb_ostream_t stream; + * + * msg.field1 = 42; + * stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + * pb_encode(&stream, MyMessage_fields, &msg); + */ +bool pb_encode(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); + +/* Same as pb_encode, but prepends the length of the message as a varint. + * Corresponds to writeDelimitedTo() in Google's protobuf API. + */ +bool pb_encode_delimited(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); + +/* Same as pb_encode, but appends a null byte to the message for termination. + * NOTE: This behaviour is not supported in most other protobuf implementations, so pb_encode_delimited() + * is a better option for compatibility. + */ +bool pb_encode_nullterminated(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); + +/* Encode the message to get the size of the encoded data, but do not store + * the data. */ +bool pb_get_encoded_size(size_t *size, const pb_field_t fields[], const void *src_struct); + +/************************************** + * Functions for manipulating streams * + **************************************/ + +/* Create an output stream for writing into a memory buffer. + * The number of bytes written can be found in stream.bytes_written after + * encoding the message. + * + * Alternatively, you can use a custom stream that writes directly to e.g. + * a file or a network socket. + */ +pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize); + +/* Pseudo-stream for measuring the size of a message without actually storing + * the encoded data. + * + * Example usage: + * MyMessage msg = {}; + * pb_ostream_t stream = PB_OSTREAM_SIZING; + * pb_encode(&stream, MyMessage_fields, &msg); + * printf("Message size is %d\n", stream.bytes_written); + */ +#ifndef PB_NO_ERRMSG +#define PB_OSTREAM_SIZING {0,0,0,0,0} +#else +#define PB_OSTREAM_SIZING {0,0,0,0} +#endif + +/* Function to write into a pb_ostream_t stream. You can use this if you need + * to append or prepend some custom headers to the message. + */ +bool pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); + + +/************************************************ + * Helper functions for writing field callbacks * + ************************************************/ + +/* Encode field header based on type and field number defined in the field + * structure. Call this from the callback before writing out field contents. */ +bool pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t *field); + +/* Encode field header by manually specifying wire type. You need to use this + * if you want to write out packed arrays from a callback field. */ +bool pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number); + +/* Encode an integer in the varint format. + * This works for bool, enum, int32, int64, uint32 and uint64 field types. */ +#ifndef PB_WITHOUT_64BIT +bool pb_encode_varint(pb_ostream_t *stream, uint64_t value); +#else +bool pb_encode_varint(pb_ostream_t *stream, uint32_t value); +#endif + +/* Encode an integer in the zig-zagged svarint format. + * This works for sint32 and sint64. */ +#ifndef PB_WITHOUT_64BIT +bool pb_encode_svarint(pb_ostream_t *stream, int64_t value); +#else +bool pb_encode_svarint(pb_ostream_t *stream, int32_t value); +#endif + +/* Encode a string or bytes type field. For strings, pass strlen(s) as size. */ +bool pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size); + +/* Encode a fixed32, sfixed32 or float value. + * You need to pass a pointer to a 4-byte wide C variable. */ +bool pb_encode_fixed32(pb_ostream_t *stream, const void *value); + +#ifndef PB_WITHOUT_64BIT +/* Encode a fixed64, sfixed64 or double value. + * You need to pass a pointer to a 8-byte wide C variable. */ +bool pb_encode_fixed64(pb_ostream_t *stream, const void *value); +#endif + +/* Encode a submessage field. + * You need to pass the pb_field_t array and pointer to struct, just like + * with pb_encode(). This internally encodes the submessage twice, first to + * calculate message size and then to actually write it out. + */ +bool pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fields[], const void *src_struct); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/Pods/nanopb/spm_resources/PrivacyInfo.xcprivacy b/Pods/nanopb/spm_resources/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..72e00ac --- /dev/null +++ b/Pods/nanopb/spm_resources/PrivacyInfo.xcprivacy @@ -0,0 +1,15 @@ + + + + + NSPrivacyAccessedAPITypes + + NSPrivacyCollectedDataTypes + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + + + diff --git a/TallPaper.xcodeproj/project.pbxproj b/TallPaper.xcodeproj/project.pbxproj index 0880984..8da28d5 100644 --- a/TallPaper.xcodeproj/project.pbxproj +++ b/TallPaper.xcodeproj/project.pbxproj @@ -29,7 +29,7 @@ 0004D8932C363D5200B3E467 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0004D8922C363D5200B3E467 /* Localizable.strings */; }; 0004D8972C363D5800B3E467 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0004D8962C363D5800B3E467 /* InfoPlist.strings */; }; 0004D89C2C36443C00B3E467 /* AWM_NetManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0004D89B2C36443C00B3E467 /* AWM_NetManager.m */; }; - 0126BA97CEBE3D5058AF2043 /* Pods_HD_wallpaper.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18B9E38A7CF086ABC9920714 /* Pods_HD_wallpaper.framework */; }; + 00C5EEC72C52404B000553BF /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 00C5EEC62C52404B000553BF /* GoogleService-Info.plist */; }; 057AF7952BF1E86F00078C98 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 057AF7942BF1E86F00078C98 /* AppDelegate.m */; }; 057AF7A02BF1E87100078C98 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 057AF79F2BF1E87100078C98 /* Assets.xcassets */; }; 057AF7A32BF1E87100078C98 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 057AF7A12BF1E87100078C98 /* LaunchScreen.storyboard */; }; @@ -43,6 +43,7 @@ 057AF7C02BF209E100078C98 /* AWM_AllWallpaperViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 057AF7BF2BF209E100078C98 /* AWM_AllWallpaperViewController.m */; }; 057AF7C32BF20CF700078C98 /* AWM_DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 057AF7C22BF20CF700078C98 /* AWM_DetailViewController.m */; }; 05CC6FAC2C464CA40013KB00 /* CustomLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 75CC6FAB2C464CA40013FB06 /* CustomLabel.m */; }; + 650BB258597357B7AF970CB3 /* Pods_TallPaper.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7538E235FC6B7074F283038F /* Pods_TallPaper.framework */; }; 75CC6F9D2C4649C20013FB06 /* AWP_Color.m in Sources */ = {isa = PBXBuildFile; fileRef = 75CC6F9C2C4649C20013FB06 /* AWP_Color.m */; }; 75CC6FA02C464ABF0013FB06 /* CircularProgressView.m in Sources */ = {isa = PBXBuildFile; fileRef = 75CC6F9F2C464ABF0013FB06 /* CircularProgressView.m */; }; 75CC6FA32C464B310013FB06 /* CustomTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 75CC6FA22C464B310013FB06 /* CustomTextView.m */; }; @@ -90,6 +91,7 @@ 0004D89A2C36443C00B3E467 /* AWM_NetManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AWM_NetManager.h; sourceTree = ""; }; 0004D89B2C36443C00B3E467 /* AWM_NetManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AWM_NetManager.m; sourceTree = ""; }; 00218D932C4F807A00966466 /* PrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrefixHeader.pch; sourceTree = ""; }; + 00C5EEC62C52404B000553BF /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 041A9EAF08B4BEE8FF03DD23 /* Pods-HD wallpaper.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HD wallpaper.debug.xcconfig"; path = "Target Support Files/Pods-HD wallpaper/Pods-HD wallpaper.debug.xcconfig"; sourceTree = ""; }; 057AF7902BF1E86F00078C98 /* TallPaper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TallPaper.app; sourceTree = BUILT_PRODUCTS_DIR; }; 057AF7932BF1E86F00078C98 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; @@ -114,7 +116,9 @@ 057AF7BF2BF209E100078C98 /* AWM_AllWallpaperViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AWM_AllWallpaperViewController.m; sourceTree = ""; }; 057AF7C12BF20CF700078C98 /* AWM_DetailViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AWM_DetailViewController.h; sourceTree = ""; }; 057AF7C22BF20CF700078C98 /* AWM_DetailViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AWM_DetailViewController.m; sourceTree = ""; }; - 18B9E38A7CF086ABC9920714 /* Pods_HD_wallpaper.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_HD_wallpaper.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 6400D9E1665B36CDAB004CCA /* Pods-TallPaper.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TallPaper.debug.xcconfig"; path = "Target Support Files/Pods-TallPaper/Pods-TallPaper.debug.xcconfig"; sourceTree = ""; }; + 6494F8AC01693F32CAE5C66F /* Pods-TallPaper.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TallPaper.release.xcconfig"; path = "Target Support Files/Pods-TallPaper/Pods-TallPaper.release.xcconfig"; sourceTree = ""; }; + 7538E235FC6B7074F283038F /* Pods_TallPaper.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TallPaper.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 75CC6F9B2C4649C20013FB06 /* AWP_Color.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AWP_Color.h; sourceTree = ""; }; 75CC6F9C2C4649C20013FB06 /* AWP_Color.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AWP_Color.m; sourceTree = ""; }; 75CC6F9E2C464ABF0013FB06 /* CircularProgressView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CircularProgressView.h; sourceTree = ""; }; @@ -145,13 +149,13 @@ 0004D87D2C35300C00B3E467 /* SystemConfiguration.framework in Frameworks */, 0004D87F2C35301600B3E467 /* WebKit.framework in Frameworks */, 0004D8862C354B7700B3E467 /* AppLovinSDK.xcframework in Frameworks */, - 0126BA97CEBE3D5058AF2043 /* Pods_HD_wallpaper.framework in Frameworks */, 0004D8652C352F9800B3E467 /* AppTrackingTransparency.framework in Frameworks */, 0004D8692C352FAA00B3E467 /* AVFoundation.framework in Frameworks */, 0004D86B2C352FB100B3E467 /* CoreGraphics.framework in Frameworks */, 0004D8672C352FA200B3E467 /* AudioToolbox.framework in Frameworks */, 0004D8632C352F9100B3E467 /* AdSupport.framework in Frameworks */, 0004D8732C352FD300B3E467 /* Foundation.framework in Frameworks */, + 650BB258597357B7AF970CB3 /* Pods_TallPaper.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -205,6 +209,7 @@ 057AF7922BF1E86F00078C98 /* HDwallpaper */ = { isa = PBXGroup; children = ( + 00C5EEC62C52404B000553BF /* GoogleService-Info.plist */, 75CC6F9A2C46498C0013FB06 /* Tool */, 0004D8992C36442700B3E467 /* Net */, 0004D8822C35349200B3E467 /* WallPapaerADManager */, @@ -277,7 +282,7 @@ 0004D8662C352FA200B3E467 /* AudioToolbox.framework */, 0004D8642C352F9800B3E467 /* AppTrackingTransparency.framework */, 0004D8622C352F9100B3E467 /* AdSupport.framework */, - 18B9E38A7CF086ABC9920714 /* Pods_HD_wallpaper.framework */, + 7538E235FC6B7074F283038F /* Pods_TallPaper.framework */, ); name = Frameworks; sourceTree = ""; @@ -287,6 +292,8 @@ children = ( 041A9EAF08B4BEE8FF03DD23 /* Pods-HD wallpaper.debug.xcconfig */, 77C266AD32156D90D4CC96BA /* Pods-HD wallpaper.release.xcconfig */, + 6400D9E1665B36CDAB004CCA /* Pods-TallPaper.debug.xcconfig */, + 6494F8AC01693F32CAE5C66F /* Pods-TallPaper.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -303,6 +310,7 @@ 057AF78D2BF1E86F00078C98 /* Frameworks */, 057AF78E2BF1E86F00078C98 /* Resources */, 0004D8882C354B7700B3E467 /* Embed Frameworks */, + 58CC73BDB58E01C08E9A2D4F /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -354,6 +362,7 @@ files = ( 057AF7A32BF1E87100078C98 /* LaunchScreen.storyboard in Resources */, 0004D8972C363D5800B3E467 /* InfoPlist.strings in Resources */, + 00C5EEC72C52404B000553BF /* GoogleService-Info.plist in Resources */, 0004D8932C363D5200B3E467 /* Localizable.strings in Resources */, 057AF7A02BF1E87100078C98 /* Assets.xcassets in Resources */, ); @@ -362,6 +371,23 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 58CC73BDB58E01C08E9A2D4F /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-TallPaper/Pods-TallPaper-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-TallPaper/Pods-TallPaper-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-TallPaper/Pods-TallPaper-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; 93F27BB9030A668EE41A8F45 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -377,7 +403,7 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-HD wallpaper-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-TallPaper-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -563,7 +589,7 @@ }; 057AF7AA2BF1E87100078C98 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 041A9EAF08B4BEE8FF03DD23 /* Pods-HD wallpaper.debug.xcconfig */; + baseConfigurationReference = 6400D9E1665B36CDAB004CCA /* Pods-TallPaper.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; @@ -573,6 +599,7 @@ CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_TEAM = 8B4CW938L2; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 8B4CW938L2; + ENABLE_USER_SCRIPT_SANDBOXING = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/HDwallpaper", @@ -612,7 +639,7 @@ }; 057AF7AB2BF1E87100078C98 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 77C266AD32156D90D4CC96BA /* Pods-HD wallpaper.release.xcconfig */; + baseConfigurationReference = 6494F8AC01693F32CAE5C66F /* Pods-TallPaper.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; @@ -622,6 +649,7 @@ CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_TEAM = 8B4CW938L2; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 8B4CW938L2; + ENABLE_USER_SCRIPT_SANDBOXING = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/HDwallpaper", diff --git a/TallPaper.xcworkspace/contents.xcworkspacedata b/TallPaper.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..e4012b3 --- /dev/null +++ b/TallPaper.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + +