diff --git a/.github/workflows/abtesting.yml b/.github/workflows/abtesting.yml index dbd92e12b..7fc91ff89 100644 --- a/.github/workflows/abtesting.yml +++ b/.github/workflows/abtesting.yml @@ -1,8 +1,5 @@ name: A/B Testing -permissions: - contents: read - on: push: branches: [ main ] @@ -34,6 +31,31 @@ env: SAMPLE: ABTesting jobs: + cocoapods: + name: cocoapods + runs-on: macOS-15 + env: + SPM: false + TEST: true + steps: + - name: Checkout + uses: actions/checkout@master + - name: Setup + run: | + cd abtesting/LegacyABTestingQuickstart + gem install bundler + bundle install + gem install xcpretty + bundle exec pod install --repo-update + cd .. + ../scripts/install_prereqs/abtesting.sh + - name: Build Swift + run: ./scripts/test.sh + env: + LEGACY: true + SWIFT_SUFFIX: "" + OS: iOS + DEVICE: iPhone 16 spm: name: spm (Xcode ${{ matrix.xcode }} - ${{ matrix.os }}) runs-on: macOS-15 @@ -70,6 +92,7 @@ jobs: OS: ${{ matrix.os }} DEVICE: ${{ matrix.device }} TEST: ${{ matrix.test }} + DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer steps: - name: Checkout uses: actions/checkout@master diff --git a/.github/workflows/analytics.yml b/.github/workflows/analytics.yml index 13cd58278..e31a6576f 100644 --- a/.github/workflows/analytics.yml +++ b/.github/workflows/analytics.yml @@ -1,8 +1,5 @@ name: Analytics -permissions: - contents: read - on: push: branches: [ main ] @@ -30,8 +27,8 @@ env: secrets_passphrase: ${{ secrets.GHASECRETSGPGPASSPHRASE1 }} jobs: - spm: - name: spm (Xcode ${{ matrix.xcode }} - ${{ matrix.os }}) + cocoapods: + name: cocoapods - ${{ matrix.os }} runs-on: macOS-15 strategy: matrix: @@ -55,24 +52,28 @@ jobs: device: localhost scheme: AnalyticsExampleMac test: true - env: - SPM: true + SPM: false + LEGACY: false OS: ${{ matrix.os }} DEVICE: ${{ matrix.device }} - SCHEME: ${{ matrix.scheme || 'AnalyticsExample' }} - DIR: analytics + SCHEME: ${{ matrix.scheme }} + DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer steps: - name: Checkout uses: actions/checkout@master - - name: Xcode - run: sudo xcode-select -s /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer - name: Setup run: | cd analytics + gem install bundler + bundle install gem install xcpretty + bundle exec pod install --repo-update ../scripts/install_prereqs/analytics.sh - name: Build Swift run: ./scripts/test.sh env: TEST: ${{ matrix.test }} + SWIFT_SUFFIX: "" + + #TODO: Add `spm` job. diff --git a/.github/workflows/authentication.yml b/.github/workflows/authentication.yml index 884ff76d0..2a43a46a6 100644 --- a/.github/workflows/authentication.yml +++ b/.github/workflows/authentication.yml @@ -1,8 +1,5 @@ name: Authentication -permissions: - contents: read - on: push: branches: [ main ] @@ -30,25 +27,27 @@ env: secrets_passphrase: ${{ secrets.GHASECRETSGPGPASSPHRASE1 }} jobs: - spm: + cocoapods: + name: cocoapods runs-on: macOS-15 env: + SPM: false + LEGACY: false OS: iOS - SETUP: authentication - SPM: true - DIR: authentication DEVICE: iPhone 16 TEST: false - SCHEME: AuthenticationExample steps: - name: Checkout uses: actions/checkout@master - - name: Xcode - run: sudo xcode-select -s /Applications/Xcode_16.4.app/Contents/Developer - name: Setup run: | + cd authentication + gem install bundler + bundle install gem install xcpretty - cd $SETUP - ../scripts/install_prereqs/${SETUP}.sh - - name: Build and Test SwiftUI (${OS}) + bundle exec pod install --repo-update + ../scripts/install_prereqs/authentication.sh + - name: Build Swift run: ./scripts/test.sh + env: + SWIFT_SUFFIX: "" diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index d6d92e2a8..c6e040f20 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -1,8 +1,5 @@ name: check -permissions: - contents: read - on: pull_request: push: diff --git a/.github/workflows/config.yml b/.github/workflows/config.yml index 74e769fa8..f14ee86d5 100644 --- a/.github/workflows/config.yml +++ b/.github/workflows/config.yml @@ -1,8 +1,5 @@ name: Remote Config -permissions: - contents: read - on: push: branches: [ main ] @@ -30,14 +27,13 @@ env: secrets_passphrase: ${{ secrets.GHASECRETSGPGPASSPHRASE1 }} jobs: - spm: + cocoapods: + name: cocoapods runs-on: macOS-15 env: - OS: iOS - DEVICE: iPhone 16 - DIR: config - SPM: true - SCHEME: ConfigExample + SPM: false + LEGACY: false + SWIFT_SUFFIX: "" TEST: true steps: - name: Checkout @@ -45,7 +41,14 @@ jobs: - name: Setup run: | cd config + gem install bundler + bundle install + gem install xcpretty + bundle exec pod install --repo-update ../scripts/install_prereqs/config.sh xcrun simctl boot "iPhone 16" - name: Build Swift run: ./scripts/test.sh + env: + OS: iOS + DEVICE: iPhone 16 diff --git a/.github/workflows/crashlytics.yml b/.github/workflows/crashlytics.yml index 905d27fcf..e4b788785 100644 --- a/.github/workflows/crashlytics.yml +++ b/.github/workflows/crashlytics.yml @@ -1,8 +1,5 @@ name: Crashlytics -permissions: - contents: read - on: push: branches: [ main ] @@ -30,6 +27,31 @@ env: secrets_passphrase: ${{ secrets.GHASECRETSGPGPASSPHRASE1 }} jobs: + cocoapods: + name: cocoapods + runs-on: macOS-15 + env: + SPM: false + LEGACY: true + OS: iOS + DEVICE: iPhone 16 + TEST: true + steps: + - name: Checkout + uses: actions/checkout@master + - name: Setup + run: | + cd crashlytics/LegacyCrashlyticsQuickstart + gem install bundler + bundle install + gem install xcpretty + bundle exec pod install --repo-update + cd .. + ../scripts/install_prereqs/crashlytics.sh + - name: Build Swift + run: ./scripts/test.sh + env: + SWIFT_SUFFIX: Swift spm: name: spm (Xcode ${{ matrix.xcode }} - ${{ matrix.os }}) runs-on: macOS-15 @@ -57,6 +79,7 @@ jobs: OS: ${{ matrix.os }} DEVICE: ${{ matrix.device }} TEST: ${{ matrix.test }} + DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer steps: - name: Checkout uses: actions/checkout@master diff --git a/.github/workflows/database.yml b/.github/workflows/database.yml index 2bffc89b8..acf22c313 100644 --- a/.github/workflows/database.yml +++ b/.github/workflows/database.yml @@ -1,8 +1,5 @@ name: Database -permissions: - contents: read - on: push: branches: [ main ] @@ -30,27 +27,30 @@ env: secrets_passphrase: ${{ secrets.GHASECRETSGPGPASSPHRASE1 }} jobs: - spm-buildonly: - name: spm (non-SwiftUI) + cocoapods: + name: cocoapods runs-on: macOS-15 env: + SPM: false + LEGACY: false OS: iOS - SPM: true - DIR: database DEVICE: iPhone 16 TEST: false - SCHEME: DatabaseExample steps: - name: Checkout uses: actions/checkout@master - name: Setup run: | - gem install xcpretty cd database + gem install bundler + bundle install + gem install xcpretty + bundle exec pod install --repo-update ../scripts/install_prereqs/database.sh - name: Build Swift run: ./scripts/test.sh - + env: + SWIFT_SUFFIX: Swift spm: name: spm (Xcode ${{ matrix.xcode }} - ${{ matrix.os }}) runs-on: macOS-15 @@ -75,6 +75,7 @@ jobs: OS: ${{ matrix.os }} DEVICE: ${{ matrix.device }} TEST: ${{ matrix.test }} + DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer steps: - name: Checkout uses: actions/checkout@master diff --git a/.github/workflows/firebaseai.yml b/.github/workflows/firebaseai.yml index ea807fc9b..65378ba39 100644 --- a/.github/workflows/firebaseai.yml +++ b/.github/workflows/firebaseai.yml @@ -42,11 +42,11 @@ jobs: OS: ${{ matrix.platform }} DEVICE: ${{ matrix.device }} TEST: false + XCODE_VERSION: ${{ matrix.xcode }} + DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer steps: - name: Checkout uses: actions/checkout@master - - name: Xcode - run: sudo xcode-select -s /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer - name: Setup run: | gem install xcpretty diff --git a/.github/workflows/firestore.yml b/.github/workflows/firestore.yml index 3fe2865c6..9ab5536d3 100644 --- a/.github/workflows/firestore.yml +++ b/.github/workflows/firestore.yml @@ -1,8 +1,5 @@ name: Firestore -permissions: - contents: read - on: push: branches: [ main ] @@ -30,22 +27,27 @@ env: secrets_passphrase: ${{ secrets.GHASECRETSGPGPASSPHRASE1 }} jobs: - spm: + cocoapods: + name: cocoapods runs-on: macOS-15 env: - SPM: true + SPM: false + LEGACY: false OS: iOS - DIR: firestore DEVICE: iPhone 16 TEST: false - SCHEME: FirestoreExample steps: - name: Checkout uses: actions/checkout@master - name: Setup run: | cd firestore + gem install bundler + bundle install gem install xcpretty + bundle exec pod install --repo-update ../scripts/install_prereqs/firestore.sh - name: Build run: ./scripts/test.sh + env: + SWIFT_SUFFIX: "" diff --git a/.github/workflows/functions.yml b/.github/workflows/functions.yml index e8b3a626e..93c0ea57e 100644 --- a/.github/workflows/functions.yml +++ b/.github/workflows/functions.yml @@ -1,8 +1,5 @@ name: Functions -permissions: - contents: read - on: push: branches: [ main ] @@ -51,6 +48,8 @@ jobs: OS: ${{ matrix.os }} DEVICE: ${{ matrix.device }} TEST: false + XCODE_VERSION: ${{ matrix.xcode }} + DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer steps: - name: Checkout uses: actions/checkout@master diff --git a/.github/workflows/inappmessaging.yml b/.github/workflows/inappmessaging.yml index 0844d4c71..cf824f9c0 100644 --- a/.github/workflows/inappmessaging.yml +++ b/.github/workflows/inappmessaging.yml @@ -1,8 +1,5 @@ name: InAppMessaging -permissions: - contents: read - on: push: branches: [ main ] @@ -30,23 +27,31 @@ env: secrets_passphrase: ${{ secrets.GHASECRETSGPGPASSPHRASE1 }} jobs: - spm: + cocoapods: + name: cocoapods runs-on: macOS-15 env: - SPM: true - DIR: inappmessaging + SPM: false + LEGACY: false OS: iOS DEVICE: iPhone 16 - TEST: false + TEST: true steps: - name: Checkout uses: actions/checkout@master - name: Setup run: | cd inappmessaging + gem install bundler + bundle install gem install xcpretty + bundle exec pod install --repo-update ../scripts/install_prereqs/inappmessaging.sh + - name: Build ObjC + run: ./scripts/test.sh + env: + SWIFT_SUFFIX: "" - name: Build Swift run: ./scripts/test.sh env: - SCHEME: InAppMessagingExample + SWIFT_SUFFIX: Swift diff --git a/.github/workflows/installations.yml b/.github/workflows/installations.yml index 4ba87fcca..37f281558 100644 --- a/.github/workflows/installations.yml +++ b/.github/workflows/installations.yml @@ -1,8 +1,5 @@ name: Installations -permissions: - contents: read - on: push: branches: [ main ] @@ -30,23 +27,31 @@ env: secrets_passphrase: ${{ secrets.GHASECRETSGPGPASSPHRASE1 }} jobs: - spm: + cocoapods: + name: cocoapods runs-on: macOS-15 env: - SPM: true + SPM: false + LEGACY: false OS: iOS DEVICE: iPhone 16 TEST: true - DIR: installations steps: - name: Checkout uses: actions/checkout@master - name: Setup run: | cd installations + gem install bundler + bundle install gem install xcpretty + bundle exec pod install --repo-update ../scripts/install_prereqs/installations.sh - name: Build ObjC run: ./scripts/test.sh env: - SCHEME: InstallationsExample + SWIFT_SUFFIX: "" + - name: Build Swift + run: ./scripts/test.sh + env: + SWIFT_SUFFIX: Swift diff --git a/.github/workflows/messaging.yml b/.github/workflows/messaging.yml index ac8ea65cc..0186e8858 100644 --- a/.github/workflows/messaging.yml +++ b/.github/workflows/messaging.yml @@ -1,8 +1,5 @@ name: Messaging -permissions: - contents: read - on: push: branches: [ main ] @@ -30,23 +27,31 @@ env: secrets_passphrase: ${{ secrets.GHASECRETSGPGPASSPHRASE1 }} jobs: - spm: + cocoapods: + name: cocoapods runs-on: macOS-15 env: - SPM: true + SPM: false + LEGACY: false OS: iOS DEVICE: iPhone 16 TEST: false - DIR: messaging steps: - name: Checkout uses: actions/checkout@master - name: Setup run: | cd messaging + gem install bundler + bundle install gem install xcpretty + bundle exec pod install --repo-update ../scripts/install_prereqs/messaging.sh - - name: Build + - name: Build ObjC + run: ./scripts/test.sh + env: + SWIFT_SUFFIX: "" + - name: Build Swift run: ./scripts/test.sh env: - SCHEME: MessagingExample + SWIFT_SUFFIX: Swift diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index 87e80fb11..1c014a33e 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -1,8 +1,5 @@ name: Performance -permissions: - contents: read - on: push: branches: [ main ] @@ -34,27 +31,30 @@ env: secrets_passphrase: ${{ secrets.GHASECRETSGPGPASSPHRASE1 }} jobs: - spm-buildonly: - name: spm + cocoapods: + name: cocoapods runs-on: macOS-15 env: - SPM: true + SPM: false + LEGACY: false OS: iOS DEVICE: iPhone 16 TEST: true - DIR: performance - SCHEME: PerformanceExample steps: - name: Checkout uses: actions/checkout@master - name: Setup run: | cd performance + gem install bundler + bundle install gem install xcpretty + bundle exec pod install --repo-update ../scripts/install_prereqs/performance.sh - name: Build Swift run: ./scripts/test.sh - + env: + SWIFT_SUFFIX: Swift spm: name: spm (Xcode ${{ matrix.xcode }} - ${{ matrix.os }}) runs-on: macOS-15 @@ -76,6 +76,8 @@ jobs: OS: ${{ matrix.os }} DEVICE: ${{ matrix.device }} TEST: ${{ matrix.test }} + XCODE_VERSION: ${{ matrix.xcode }} + DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer steps: - name: Checkout uses: actions/checkout@master diff --git a/.github/workflows/storage.yml b/.github/workflows/storage.yml index a15217d78..2cefc3bcb 100644 --- a/.github/workflows/storage.yml +++ b/.github/workflows/storage.yml @@ -1,8 +1,5 @@ name: Storage -permissions: - contents: read - on: push: branches: [ main ] @@ -30,6 +27,32 @@ env: secrets_passphrase: ${{ secrets.GHASECRETSGPGPASSPHRASE1 }} jobs: + cocoapods: + name: cocoapods + runs-on: macOS-15 + env: + SPM: false + LEGACY: true + OS: iOS + DEVICE: iPhone 16 + TEST: true + steps: + - name: Checkout + uses: actions/checkout@master + - name: Setup + run: | + cd storage/LegacyStorageQuickstart + gem install bundler + bundle install + gem install xcpretty + bundle exec pod install --repo-update + cd .. + ../scripts/install_prereqs/storage.sh + - name: Build Swift + run: ./scripts/test.sh + env: + SWIFT_SUFFIX: Swift + spm: name: spm (Xcode ${{ matrix.xcode }} - ${{ matrix.os }}) runs-on: macOS-15 @@ -47,10 +70,12 @@ jobs: env: SETUP: storage SPM: true - DIR: storage + DIR: storage/StorageExample OS: ${{ matrix.os }} DEVICE: ${{ matrix.device }} TEST: false + XCODE_VERSION: ${{ matrix.xcode }} + DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer steps: - name: Checkout uses: actions/checkout@master diff --git a/abtesting/ABTestingExample.xcodeproj/project.pbxproj b/abtesting/ABTestingExample.xcodeproj/project.pbxproj index 78c66e53f..d11f50b22 100644 --- a/abtesting/ABTestingExample.xcodeproj/project.pbxproj +++ b/abtesting/ABTestingExample.xcodeproj/project.pbxproj @@ -266,9 +266,9 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 4125B7C6268E2E7C00232B67 /* ABTestingExample */ = { + 4125B7C6268E2E7C00232B67 /* ABTestingExample (iOS) */ = { isa = PBXNativeTarget; - buildConfigurationList = 4125B7EA268E2E7C00232B67 /* Build configuration list for PBXNativeTarget "ABTestingExample" */; + buildConfigurationList = 4125B7EA268E2E7C00232B67 /* Build configuration list for PBXNativeTarget "ABTestingExample (iOS)" */; buildPhases = ( 4125B7C3268E2E7C00232B67 /* Sources */, 4125B7C4268E2E7C00232B67 /* Frameworks */, @@ -278,7 +278,7 @@ ); dependencies = ( ); - name = ABTestingExample; + name = "ABTestingExample (iOS)"; packageProductDependencies = ( 4125B7F9268E319D00232B67 /* FirebaseInstallations */, 4125B7FB268E319D00232B67 /* FirebaseRemoteConfig */, @@ -544,7 +544,7 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 4125B7C6268E2E7C00232B67 /* ABTestingExample */, + 4125B7C6268E2E7C00232B67 /* ABTestingExample (iOS) */, 4125B7D1268E2E7C00232B67 /* Tests (iOS) */, 4174272226D89C7E00966D7D /* ABTestingExample (tvOS) */, 4174273926D89E1B00966D7D /* Tests (tvOS) */, @@ -740,7 +740,7 @@ /* Begin PBXTargetDependency section */ 4125B7D4268E2E7C00232B67 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4125B7C6268E2E7C00232B67 /* ABTestingExample */; + target = 4125B7C6268E2E7C00232B67 /* ABTestingExample (iOS) */; targetProxy = 4125B7D3268E2E7C00232B67 /* PBXContainerItemProxy */; }; 41394CE826DF75D200C54DAE /* PBXTargetDependency */ = { @@ -965,7 +965,7 @@ SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = ABTestingExample; + TEST_TARGET_NAME = "ABTestingExample (iOS)"; }; name = Debug; }; @@ -987,7 +987,7 @@ SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = ABTestingExample; + TEST_TARGET_NAME = "ABTestingExample (iOS)"; VALIDATE_PRODUCT = YES; }; name = Release; @@ -1423,7 +1423,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4125B7EA268E2E7C00232B67 /* Build configuration list for PBXNativeTarget "ABTestingExample" */ = { + 4125B7EA268E2E7C00232B67 /* Build configuration list for PBXNativeTarget "ABTestingExample (iOS)" */ = { isa = XCConfigurationList; buildConfigurations = ( 4125B7EB268E2E7C00232B67 /* Debug */, diff --git a/abtesting/ABTestingExample.xcodeproj/xcshareddata/xcschemes/ABTestingExample.xcscheme b/abtesting/ABTestingExample.xcodeproj/xcshareddata/xcschemes/ABTestingExample (iOS).xcscheme similarity index 95% rename from abtesting/ABTestingExample.xcodeproj/xcshareddata/xcschemes/ABTestingExample.xcscheme rename to abtesting/ABTestingExample.xcodeproj/xcshareddata/xcschemes/ABTestingExample (iOS).xcscheme index 4c7ab6260..422ab68f9 100644 --- a/abtesting/ABTestingExample.xcodeproj/xcshareddata/xcschemes/ABTestingExample.xcscheme +++ b/abtesting/ABTestingExample.xcodeproj/xcshareddata/xcschemes/ABTestingExample (iOS).xcscheme @@ -16,7 +16,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "4125B7C6268E2E7C00232B67" BuildableName = "ABTestingExample.app" - BlueprintName = "ABTestingExample" + BlueprintName = "ABTestingExample (iOS)" ReferencedContainer = "container:ABTestingExample.xcodeproj"> @@ -61,7 +61,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "4125B7C6268E2E7C00232B67" BuildableName = "ABTestingExample.app" - BlueprintName = "ABTestingExample" + BlueprintName = "ABTestingExample (iOS)" ReferencedContainer = "container:ABTestingExample.xcodeproj"> @@ -78,7 +78,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "4125B7C6268E2E7C00232B67" BuildableName = "ABTestingExample.app" - BlueprintName = "ABTestingExample" + BlueprintName = "ABTestingExample (iOS)" ReferencedContainer = "container:ABTestingExample.xcodeproj"> diff --git a/abtesting/ABTestingExample.xcodeproj/xcshareddata/xcschemes/ABTestingExample (watchOS).xcscheme b/abtesting/ABTestingExample.xcodeproj/xcshareddata/xcschemes/ABTestingExample (watchOS).xcscheme index 397c90246..480442a1f 100644 --- a/abtesting/ABTestingExample.xcodeproj/xcshareddata/xcschemes/ABTestingExample (watchOS).xcscheme +++ b/abtesting/ABTestingExample.xcodeproj/xcshareddata/xcschemes/ABTestingExample (watchOS).xcscheme @@ -30,7 +30,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "4125B7C6268E2E7C00232B67" BuildableName = "ABTestingExample.app" - BlueprintName = "ABTestingExample" + BlueprintName = "ABTestingExample (iOS)" ReferencedContainer = "container:ABTestingExample.xcodeproj"> diff --git a/abtesting/LegacyABTestingQuickstart/ABTestingExample.xcodeproj/project.pbxproj b/abtesting/LegacyABTestingQuickstart/ABTestingExample.xcodeproj/project.pbxproj new file mode 100644 index 000000000..c34abf47f --- /dev/null +++ b/abtesting/LegacyABTestingQuickstart/ABTestingExample.xcodeproj/project.pbxproj @@ -0,0 +1,590 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 10B92C9F202E3603008DBD68 /* ABTestingExampleUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10B92C9E202E3603008DBD68 /* ABTestingExampleUITests.swift */; }; + 29E0D31D0ECE9DE41F33C00A /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = EBCA43177E99956B67580EEC /* GoogleService-Info.plist */; }; + 8DFFBF9E1F9E6C5200C3483E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DFFBF9D1F9E6C5200C3483E /* AppDelegate.swift */; }; + 8DFFBFA01F9E6C5200C3483E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DFFBF9F1F9E6C5200C3483E /* ViewController.swift */; }; + 8DFFBFA31F9E6C5200C3483E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8DFFBFA11F9E6C5200C3483E /* Main.storyboard */; }; + 8DFFBFA51F9E6C5200C3483E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8DFFBFA41F9E6C5200C3483E /* Assets.xcassets */; }; + 8DFFBFA81F9E6C5200C3483E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8DFFBFA61F9E6C5200C3483E /* LaunchScreen.storyboard */; }; + 8DFFBFB31F9E6C5200C3483E /* ABTestingExampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DFFBFB21F9E6C5200C3483E /* ABTestingExampleTests.swift */; }; + 9014CF21F4720D01EBB1E21A /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = EBCA43177E99956B67580EEC /* GoogleService-Info.plist */; }; + C2B56E8E65745789367E0646 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = EBCA43177E99956B67580EEC /* GoogleService-Info.plist */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 10B92CA1202E3603008DBD68 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8DFFBF921F9E6C5200C3483E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8DFFBF991F9E6C5200C3483E; + remoteInfo = ABTestingExample; + }; + 8DFFBFAF1F9E6C5200C3483E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8DFFBF921F9E6C5200C3483E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8DFFBF991F9E6C5200C3483E; + remoteInfo = ABTestingExample; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 10B92C9C202E3603008DBD68 /* ABTestingExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ABTestingExampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 10B92C9E202E3603008DBD68 /* ABTestingExampleUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ABTestingExampleUITests.swift; sourceTree = ""; }; + 10B92CA0202E3603008DBD68 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8DFFBF9A1F9E6C5200C3483E /* ABTestingExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ABTestingExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 8DFFBF9D1F9E6C5200C3483E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 8DFFBF9F1F9E6C5200C3483E /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 8DFFBFA21F9E6C5200C3483E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 8DFFBFA41F9E6C5200C3483E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 8DFFBFA71F9E6C5200C3483E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 8DFFBFA91F9E6C5200C3483E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8DFFBFAE1F9E6C5200C3483E /* ABTestingExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ABTestingExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 8DFFBFB21F9E6C5200C3483E /* ABTestingExampleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ABTestingExampleTests.swift; sourceTree = ""; }; + 8DFFBFB41F9E6C5200C3483E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + EBCA43177E99956B67580EEC /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "../GoogleService-Info.plist"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 10B92C99202E3603008DBD68 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DFFBF971F9E6C5200C3483E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DFFBFAB1F9E6C5200C3483E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 10B92C9D202E3603008DBD68 /* ABTestingExampleUITests */ = { + isa = PBXGroup; + children = ( + 10B92C9E202E3603008DBD68 /* ABTestingExampleUITests.swift */, + 10B92CA0202E3603008DBD68 /* Info.plist */, + ); + path = ABTestingExampleUITests; + sourceTree = ""; + }; + 8DFFBF911F9E6C5200C3483E = { + isa = PBXGroup; + children = ( + 8DFFBF9C1F9E6C5200C3483E /* ABTestingExample */, + 8DFFBFB11F9E6C5200C3483E /* ABTestingExampleTests */, + 10B92C9D202E3603008DBD68 /* ABTestingExampleUITests */, + 8DFFBF9B1F9E6C5200C3483E /* Products */, + EBCA43177E99956B67580EEC /* GoogleService-Info.plist */, + ); + sourceTree = ""; + }; + 8DFFBF9B1F9E6C5200C3483E /* Products */ = { + isa = PBXGroup; + children = ( + 8DFFBF9A1F9E6C5200C3483E /* ABTestingExample.app */, + 8DFFBFAE1F9E6C5200C3483E /* ABTestingExampleTests.xctest */, + 10B92C9C202E3603008DBD68 /* ABTestingExampleUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 8DFFBF9C1F9E6C5200C3483E /* ABTestingExample */ = { + isa = PBXGroup; + children = ( + 8DFFBF9D1F9E6C5200C3483E /* AppDelegate.swift */, + 8DFFBF9F1F9E6C5200C3483E /* ViewController.swift */, + 8DFFBFA11F9E6C5200C3483E /* Main.storyboard */, + 8DFFBFA41F9E6C5200C3483E /* Assets.xcassets */, + 8DFFBFA61F9E6C5200C3483E /* LaunchScreen.storyboard */, + 8DFFBFA91F9E6C5200C3483E /* Info.plist */, + ); + path = ABTestingExample; + sourceTree = ""; + }; + 8DFFBFB11F9E6C5200C3483E /* ABTestingExampleTests */ = { + isa = PBXGroup; + children = ( + 8DFFBFB21F9E6C5200C3483E /* ABTestingExampleTests.swift */, + 8DFFBFB41F9E6C5200C3483E /* Info.plist */, + ); + path = ABTestingExampleTests; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 10B92C9B202E3603008DBD68 /* ABTestingExampleUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 10B92CA5202E3603008DBD68 /* Build configuration list for PBXNativeTarget "ABTestingExampleUITests" */; + buildPhases = ( + 10B92C98202E3603008DBD68 /* Sources */, + 10B92C99202E3603008DBD68 /* Frameworks */, + 10B92C9A202E3603008DBD68 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 10B92CA2202E3603008DBD68 /* PBXTargetDependency */, + ); + name = ABTestingExampleUITests; + productName = ABTestingExampleUITests; + productReference = 10B92C9C202E3603008DBD68 /* ABTestingExampleUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + 8DFFBF991F9E6C5200C3483E /* ABTestingExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8DFFBFB71F9E6C5200C3483E /* Build configuration list for PBXNativeTarget "ABTestingExample" */; + buildPhases = ( + 8DFFBF961F9E6C5200C3483E /* Sources */, + 8DFFBF971F9E6C5200C3483E /* Frameworks */, + 8DFFBF981F9E6C5200C3483E /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ABTestingExample; + productName = ABTestingExample; + productReference = 8DFFBF9A1F9E6C5200C3483E /* ABTestingExample.app */; + productType = "com.apple.product-type.application"; + }; + 8DFFBFAD1F9E6C5200C3483E /* ABTestingExampleTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8DFFBFBA1F9E6C5200C3483E /* Build configuration list for PBXNativeTarget "ABTestingExampleTests" */; + buildPhases = ( + 8DFFBFAA1F9E6C5200C3483E /* Sources */, + 8DFFBFAB1F9E6C5200C3483E /* Frameworks */, + 8DFFBFAC1F9E6C5200C3483E /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 8DFFBFB01F9E6C5200C3483E /* PBXTargetDependency */, + ); + name = ABTestingExampleTests; + productName = ABTestingExampleTests; + productReference = 8DFFBFAE1F9E6C5200C3483E /* ABTestingExampleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 8DFFBF921F9E6C5200C3483E /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1110; + ORGANIZATIONNAME = Firebase; + TargetAttributes = { + 10B92C9B202E3603008DBD68 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1110; + ProvisioningStyle = Automatic; + TestTargetID = 8DFFBF991F9E6C5200C3483E; + }; + 8DFFBF991F9E6C5200C3483E = { + CreatedOnToolsVersion = 8.3.3; + LastSwiftMigration = 1110; + ProvisioningStyle = Automatic; + }; + 8DFFBFAD1F9E6C5200C3483E = { + CreatedOnToolsVersion = 8.3.3; + LastSwiftMigration = 1110; + ProvisioningStyle = Automatic; + TestTargetID = 8DFFBF991F9E6C5200C3483E; + }; + }; + }; + buildConfigurationList = 8DFFBF951F9E6C5200C3483E /* Build configuration list for PBXProject "ABTestingExample" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 8DFFBF911F9E6C5200C3483E; + productRefGroup = 8DFFBF9B1F9E6C5200C3483E /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8DFFBF991F9E6C5200C3483E /* ABTestingExample */, + 8DFFBFAD1F9E6C5200C3483E /* ABTestingExampleTests */, + 10B92C9B202E3603008DBD68 /* ABTestingExampleUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 10B92C9A202E3603008DBD68 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DFFBF981F9E6C5200C3483E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8DFFBFA81F9E6C5200C3483E /* LaunchScreen.storyboard in Resources */, + 8DFFBFA51F9E6C5200C3483E /* Assets.xcassets in Resources */, + 8DFFBFA31F9E6C5200C3483E /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DFFBFAC1F9E6C5200C3483E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 10B92C98202E3603008DBD68 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 10B92C9F202E3603008DBD68 /* ABTestingExampleUITests.swift in Sources */, + 9014CF21F4720D01EBB1E21A /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DFFBF961F9E6C5200C3483E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8DFFBFA01F9E6C5200C3483E /* ViewController.swift in Sources */, + 8DFFBF9E1F9E6C5200C3483E /* AppDelegate.swift in Sources */, + C2B56E8E65745789367E0646 /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DFFBFAA1F9E6C5200C3483E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8DFFBFB31F9E6C5200C3483E /* ABTestingExampleTests.swift in Sources */, + 29E0D31D0ECE9DE41F33C00A /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 10B92CA2202E3603008DBD68 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8DFFBF991F9E6C5200C3483E /* ABTestingExample */; + targetProxy = 10B92CA1202E3603008DBD68 /* PBXContainerItemProxy */; + }; + 8DFFBFB01F9E6C5200C3483E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8DFFBF991F9E6C5200C3483E /* ABTestingExample */; + targetProxy = 8DFFBFAF1F9E6C5200C3483E /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 8DFFBFA11F9E6C5200C3483E /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 8DFFBFA21F9E6C5200C3483E /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 8DFFBFA61F9E6C5200C3483E /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 8DFFBFA71F9E6C5200C3483E /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 10B92CA3202E3603008DBD68 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = ABTestingExampleUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.firebase.ABTestingExample.ABTestingExampleUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = ABTestingExample; + }; + name = Debug; + }; + 10B92CA4202E3603008DBD68 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = ABTestingExampleUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.firebase.ABTestingExample.ABTestingExampleUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = ABTestingExample; + }; + name = Release; + }; + 8DFFBFB51F9E6C5200C3483E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 8DFFBFB61F9E6C5200C3483E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 8DFFBFB81F9E6C5200C3483E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = ABTestingExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks $(PODS_CONFIGURATION_BUILD_DIR)/GoogleToolboxForMac $(PODS_CONFIGURATION_BUILD_DIR)/nanopb $(PODS_CONFIGURATION_BUILD_DIR)/Protobuf"; + PRODUCT_BUNDLE_IDENTIFIER = com.firebase.ABTestingExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 8DFFBFB91F9E6C5200C3483E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + INFOPLIST_FILE = ABTestingExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks $(PODS_CONFIGURATION_BUILD_DIR)/GoogleToolboxForMac $(PODS_CONFIGURATION_BUILD_DIR)/nanopb $(PODS_CONFIGURATION_BUILD_DIR)/Protobuf"; + PRODUCT_BUNDLE_IDENTIFIER = com.firebase.ABTestingExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 8DFFBFBB1F9E6C5200C3483E /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + INFOPLIST_FILE = ABTestingExampleTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.firebase.ABTestingExampleTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ABTestingExample.app/ABTestingExample"; + }; + name = Debug; + }; + 8DFFBFBC1F9E6C5200C3483E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + INFOPLIST_FILE = ABTestingExampleTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.firebase.ABTestingExampleTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ABTestingExample.app/ABTestingExample"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 10B92CA5202E3603008DBD68 /* Build configuration list for PBXNativeTarget "ABTestingExampleUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 10B92CA3202E3603008DBD68 /* Debug */, + 10B92CA4202E3603008DBD68 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8DFFBF951F9E6C5200C3483E /* Build configuration list for PBXProject "ABTestingExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8DFFBFB51F9E6C5200C3483E /* Debug */, + 8DFFBFB61F9E6C5200C3483E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8DFFBFB71F9E6C5200C3483E /* Build configuration list for PBXNativeTarget "ABTestingExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8DFFBFB81F9E6C5200C3483E /* Debug */, + 8DFFBFB91F9E6C5200C3483E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8DFFBFBA1F9E6C5200C3483E /* Build configuration list for PBXNativeTarget "ABTestingExampleTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8DFFBFBB1F9E6C5200C3483E /* Debug */, + 8DFFBFBC1F9E6C5200C3483E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 8DFFBF921F9E6C5200C3483E /* Project object */; +} diff --git a/abtesting/LegacyABTestingQuickstart/ABTestingExample/AppDelegate.swift b/abtesting/LegacyABTestingQuickstart/ABTestingExample/AppDelegate.swift new file mode 100644 index 000000000..18d472591 --- /dev/null +++ b/abtesting/LegacyABTestingQuickstart/ABTestingExample/AppDelegate.swift @@ -0,0 +1,30 @@ +// +// Copyright (c) Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import FirebaseCore +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? + + func application(_ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication + .LaunchOptionsKey: Any]?) -> Bool { + FirebaseApp.configure() + return true + } +} diff --git a/abtesting/LegacyABTestingQuickstart/ABTestingExample/Assets.xcassets/AppIcon.appiconset/Contents.json b/abtesting/LegacyABTestingQuickstart/ABTestingExample/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..36d2c80d8 --- /dev/null +++ b/abtesting/LegacyABTestingQuickstart/ABTestingExample/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/abtesting/LegacyABTestingQuickstart/ABTestingExample/Base.lproj/LaunchScreen.storyboard b/abtesting/LegacyABTestingQuickstart/ABTestingExample/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 000000000..fdf3f97d1 --- /dev/null +++ b/abtesting/LegacyABTestingQuickstart/ABTestingExample/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/abtesting/LegacyABTestingQuickstart/ABTestingExample/Base.lproj/Main.storyboard b/abtesting/LegacyABTestingQuickstart/ABTestingExample/Base.lproj/Main.storyboard new file mode 100644 index 000000000..46d947ee8 --- /dev/null +++ b/abtesting/LegacyABTestingQuickstart/ABTestingExample/Base.lproj/Main.storyboard @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/abtesting/LegacyABTestingQuickstart/ABTestingExample/Info.plist b/abtesting/LegacyABTestingQuickstart/ABTestingExample/Info.plist new file mode 100644 index 000000000..d05247386 --- /dev/null +++ b/abtesting/LegacyABTestingQuickstart/ABTestingExample/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/abtesting/LegacyABTestingQuickstart/ABTestingExample/ViewController.swift b/abtesting/LegacyABTestingQuickstart/ABTestingExample/ViewController.swift new file mode 100644 index 000000000..e9f4c5ad5 --- /dev/null +++ b/abtesting/LegacyABTestingQuickstart/ABTestingExample/ViewController.swift @@ -0,0 +1,185 @@ +// +// Copyright (c) Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import FirebaseRemoteConfig +import FirebaseInstallations +import UIKit + +enum ColorScheme { + case light + case dark +} + +extension RemoteConfigFetchStatus { + var debugDescription: String { + switch self { + case .failure: + return "failure" + case .noFetchYet: + return "pending" + case .success: + return "success" + case .throttled: + return "throttled" + } + } +} + +class ViewController: UIViewController, UITableViewDataSource { + @IBOutlet var tableView: UITableView! + + var colorScheme: ColorScheme = .light { + didSet { + switchToColorScheme(colorScheme) + } + } + + override func viewDidLoad() { + super.viewDidLoad() + tableView.dataSource = self + tableView.tableFooterView = UIView() + + #if DEBUG + NotificationCenter.default.addObserver(self, + selector: #selector(printInstallationsID), + name: .InstallationIDDidChange, + object: nil) + #endif + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + RemoteConfig.remoteConfig().fetch(withExpirationDuration: 0) { status, error in + if let error = error { + print("Error fetching config: \(error)") + } + print("Config fetch completed with status: \(status.debugDescription)") + self.setAppearance() + } + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + setAppearance() + } + + func setAppearance() { + RemoteConfig.remoteConfig().activate { activated, error in + let configValue = RemoteConfig.remoteConfig()["color_scheme"] + print("Config value: \(configValue.stringValue ?? "null")") + DispatchQueue.main.async { + if configValue.stringValue == "dark" { + self.colorScheme = .dark + } else { + self.colorScheme = .light + } + } + } + } + + @objc func printInstallationsID() { + #if DEBUG + Installations.installations().authTokenForcingRefresh(true) { token, error in + if let error = error { + print("Error fetching token: \(error)") + return + } + guard let token = token else { return } + print("Installation auth token: \(token.authToken)") + } + Installations.installations().installationID { identifier, error in + if let error = error { + print("Error fetching installations ID: \(error)") + } else if let identifier = identifier { + print("Remote installations ID: \(identifier)") + } + } + #endif + } + + deinit { + NotificationCenter.default.removeObserver(self) + } + + // MARK: - UI Colors + + func switchToColorScheme(_ scheme: ColorScheme) { + switch scheme { + case .light: + navigationController?.navigationBar.barTintColor = ViewController.lightColors.primary + navigationController?.navigationBar.barStyle = .default + navigationController?.navigationBar.titleTextAttributes = [ + NSAttributedString.Key.foregroundColor: UIColor.black, + ] + tableView.separatorColor = .gray + tableView.backgroundColor = UIColor(red: 0.94, green: 0.94, blue: 0.94, alpha: 1) + + case .dark: + navigationController?.navigationBar.barTintColor = ViewController.darkColors.primary + navigationController?.navigationBar.barStyle = .black + navigationController?.navigationBar.titleTextAttributes = [ + NSAttributedString.Key.foregroundColor: UIColor.white, + ] + tableView.separatorColor = .lightGray + tableView.backgroundColor = ViewController.darkColors.secondary + } + + tableView.reloadData() + } + + static let darkColors = ( + primary: UIColor(red: 0x61 / 0xFF, green: 0x61 / 0xFF, blue: 0x61 / 0xFF, alpha: 1), + secondary: UIColor(red: 0x42 / 0xFF, green: 0x42 / 0xFF, blue: 0x42 / 0xFF, alpha: 1) + ) + + static let lightColors = ( + primary: UIColor(red: 0xFF / 0xFF, green: 0xC1 / 0xFF, blue: 0x07 / 0xFF, alpha: 1), + secondary: UIColor(red: 0xFF / 0xFF, green: 0xC1 / 0xFF, blue: 0x07 / 0xFF, alpha: 1) + ) + + // MARK: - UITableViewDataSource + + let data = [ + ("Getting Started with Firebase", "An Introduction to Firebase"), + ("Google Firestore", "Powerful Querying and Automatic Scaling"), + ("Analytics", "Simple App Insights"), + ("Remote Config", "Parameterize App Behavior"), + ] + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return data.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "GenericSubtitleCell", for: indexPath) + cell.textLabel?.text = data[indexPath.row].0 + cell.detailTextLabel?.text = data[indexPath.row].1 + cell.detailTextLabel?.alpha = 0.8 + + switch colorScheme { + case .light: + cell.backgroundColor = UIColor(red: 0.99, green: 0.99, blue: 0.99, alpha: 1) + cell.textLabel?.textColor = .black + cell.detailTextLabel?.textColor = .black + case .dark: + cell.backgroundColor = ViewController.darkColors.secondary + cell.textLabel?.textColor = .white + cell.detailTextLabel?.textColor = .white + } + + return cell + } +} diff --git a/abtesting/LegacyABTestingQuickstart/ABTestingExampleTests/ABTestingExampleTests.swift b/abtesting/LegacyABTestingQuickstart/ABTestingExampleTests/ABTestingExampleTests.swift new file mode 100644 index 000000000..b22d8c6fc --- /dev/null +++ b/abtesting/LegacyABTestingQuickstart/ABTestingExampleTests/ABTestingExampleTests.swift @@ -0,0 +1,20 @@ +// +// Copyright (c) Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import XCTest +@testable import ABTestingExample + +class ABTestingExampleTests: XCTestCase {} diff --git a/abtesting/LegacyABTestingQuickstart/ABTestingExampleTests/Info.plist b/abtesting/LegacyABTestingQuickstart/ABTestingExampleTests/Info.plist new file mode 100644 index 000000000..6c6c23c43 --- /dev/null +++ b/abtesting/LegacyABTestingQuickstart/ABTestingExampleTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/abtesting/LegacyABTestingQuickstart/ABTestingExampleUITests/ABTestingExampleUITests.swift b/abtesting/LegacyABTestingQuickstart/ABTestingExampleUITests/ABTestingExampleUITests.swift new file mode 100644 index 000000000..c02c9b1c9 --- /dev/null +++ b/abtesting/LegacyABTestingQuickstart/ABTestingExampleUITests/ABTestingExampleUITests.swift @@ -0,0 +1,31 @@ +// Copyright 2019 Google +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import XCTest + +class ABTestingExampleUITests: XCTestCase { + override func setUp() { + super.setUp() + XCUIApplication().launch() + } + + override func tearDown() { + super.tearDown() + } + + func testExample() { + XCTAssertTrue(XCUIApplication().navigationBars["Firenotes"].exists, + "Firenotes is missing from the navigation bar") + } +} diff --git a/abtesting/LegacyABTestingQuickstart/ABTestingExampleUITests/Info.plist b/abtesting/LegacyABTestingQuickstart/ABTestingExampleUITests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/abtesting/LegacyABTestingQuickstart/ABTestingExampleUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/abtesting/LegacyABTestingQuickstart/Podfile b/abtesting/LegacyABTestingQuickstart/Podfile new file mode 100644 index 000000000..1fc057a62 --- /dev/null +++ b/abtesting/LegacyABTestingQuickstart/Podfile @@ -0,0 +1,14 @@ +platform :ios, '15.0' + +target 'ABTestingExample' do + use_frameworks! + + pod 'FirebaseAnalytics' + pod 'FirebaseRemoteConfig' + + target 'ABTestingExampleTests' do + inherit! :search_paths + # Pods for testing + end + +end diff --git a/abtesting/LegacyABTestingQuickstart/Podfile.lock b/abtesting/LegacyABTestingQuickstart/Podfile.lock new file mode 100644 index 000000000..5f41cf7cb --- /dev/null +++ b/abtesting/LegacyABTestingQuickstart/Podfile.lock @@ -0,0 +1,141 @@ +PODS: + - FirebaseABTesting (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseAnalytics (12.6.0): + - FirebaseAnalytics/Default (= 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseAnalytics/Default (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleAppMeasurement/Default (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseCore (12.6.0): + - FirebaseCoreInternal (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreInternal (12.6.0): + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseInstallations (12.6.0): + - FirebaseCore (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - PromisesObjC (~> 2.4) + - FirebaseRemoteConfig (12.6.0): + - FirebaseABTesting (~> 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - FirebaseRemoteConfigInterop (~> 12.6.0) + - FirebaseSharedSwift (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseRemoteConfigInterop (12.6.0) + - FirebaseSharedSwift (12.6.0) + - GoogleAdsOnDeviceConversion (3.2.0): + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Core (12.6.0): + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Default (12.6.0): + - GoogleAdsOnDeviceConversion (~> 3.2.0) + - GoogleAppMeasurement/Core (= 12.6.0) + - GoogleAppMeasurement/IdentitySupport (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/IdentitySupport (12.6.0): + - GoogleAppMeasurement/Core (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleUtilities/AppDelegateSwizzler (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Privacy + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - GoogleUtilities/MethodSwizzler (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/Network (8.1.0): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Privacy + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (8.1.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/Reachability (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/UserDefaults (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - nanopb (3.30910.0): + - nanopb/decode (= 3.30910.0) + - nanopb/encode (= 3.30910.0) + - nanopb/decode (3.30910.0) + - nanopb/encode (3.30910.0) + - PromisesObjC (2.4.0) + +DEPENDENCIES: + - FirebaseAnalytics + - FirebaseRemoteConfig + +SPEC REPOS: + trunk: + - FirebaseABTesting + - FirebaseAnalytics + - FirebaseCore + - FirebaseCoreInternal + - FirebaseInstallations + - FirebaseRemoteConfig + - FirebaseRemoteConfigInterop + - FirebaseSharedSwift + - GoogleAdsOnDeviceConversion + - GoogleAppMeasurement + - GoogleUtilities + - nanopb + - PromisesObjC + +SPEC CHECKSUMS: + FirebaseABTesting: 119f0a2b2e68b1ae05d248c5adb2455f148f20c1 + FirebaseAnalytics: d0a97a0db6425e5a5d966340b87f92ca7b13a557 + FirebaseCore: 0e38ad5d62d980a47a64b8e9301ffa311457be04 + FirebaseCoreInternal: 69bf1306a05b8ac43004f6cc1f804bb7b05b229e + FirebaseInstallations: 631b38da2e11a83daa4bfb482f79d286a5dfa7ad + FirebaseRemoteConfig: c5dfe22828a7ae7673d16224ea92743687e993df + FirebaseRemoteConfigInterop: 3443b8cb8fffd76bb3e03b2a84bfd3db952fcda4 + FirebaseSharedSwift: 79f27fff0addd15c3de19b87fba426f3cc2c964f + GoogleAdsOnDeviceConversion: d68c69dd9581a0f5da02617b6f377e5be483970f + GoogleAppMeasurement: 3bf40aff49a601af5da1c3345702fcb4991d35ee + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + +PODFILE CHECKSUM: 46f08f1667aa6efa2162f0fe0fe92bd33c239dd7 + +COCOAPODS: 1.16.2 diff --git a/abtesting/LegacyABTestingQuickstart/README.md b/abtesting/LegacyABTestingQuickstart/README.md new file mode 100644 index 000000000..804da9970 --- /dev/null +++ b/abtesting/LegacyABTestingQuickstart/README.md @@ -0,0 +1,25 @@ +A/B Testing +======== + +Firebase A/B Testing leverages Remote Config to automatically trial new app +behaviors and exports the experiment results into Firebase Analytics. This +sample demonstrates using an A/B test to test multiple color schemes within +an app. + +## Quickstart Setup + +In Firebase Console, create a new A/B test with any name. In step two under +'Variants', click the 'Add Parameter' button and create a parameter named +`color_scheme`. Set its default value in the control group to `default` and +its value in 'Variant A' to `dark`. In the third step, select any goal metric. + +Verify the following two flows: + +Test on device: +Run the sample and copy the printed remote installations ID or the installation auth token from Xcode's console +into the 'Manage test devices' section in Firebase Console (click into details +in 'Experiment Overview' when experiment is in Draft status). + +Published experiment: +Run the experiment at a high percentage and reinstall the app until your app +instance is in the A/B test. diff --git a/abtesting/README.md b/abtesting/README.md index 647d6488b..b71399756 100644 --- a/abtesting/README.md +++ b/abtesting/README.md @@ -9,6 +9,9 @@ multiple color schemes within an app. See [OUTLINE.md](OUTLINE.md) for information on the design of the app, screenshots, and symbol references. +To view the older Objective-C and Swift quickstarts, view the +[LegacyABTestingQuickstart](LegacyABTestingQuickstart) directory. + ## Getting Started - [Add Firebase to your iOS Project](https://firebase.google.com/docs/ios/setup) diff --git a/abtesting/Shared/AppConfig.swift b/abtesting/Shared/AppConfig.swift index e7241f3b9..b180eefe9 100644 --- a/abtesting/Shared/AppConfig.swift +++ b/abtesting/Shared/AppConfig.swift @@ -22,7 +22,7 @@ class AppConfig: ObservableObject { @Published var colorScheme: ColorScheme init() { - let value = RemoteConfig.remoteConfig()["color_scheme"].stringValue ?? "light" + let value = RemoteConfig.remoteConfig()["color_scheme"].stringValue ?? "nil" colorScheme = ColorScheme(value) #if !targetEnvironment(macCatalyst) && DEBUG NotificationCenter.default.addObserver(self, @@ -38,13 +38,13 @@ class AppConfig: ObservableObject { func updateFromRemoteConfig() { let remoteConfig = RemoteConfig.remoteConfig() - let oldValue = remoteConfig["color_scheme"].stringValue ?? "light" + let oldValue = remoteConfig["color_scheme"].stringValue ?? "nil" remoteConfig.fetchAndActivate { status, error in print("Fetch-and-activate completed with status: \(status.debugDescription)") if let error = error { print("Error fetching and activating config: \(error)") } else { - let newValue = remoteConfig["color_scheme"].stringValue ?? "light" + let newValue = remoteConfig["color_scheme"].stringValue ?? "nil" if newValue != oldValue { print("Remote Config changed to: \(newValue)") DispatchQueue.main.async { self.colorScheme = ColorScheme(newValue) } @@ -59,11 +59,11 @@ class AppConfig: ObservableObject { @available(iOS 15, tvOS 15, macOS 12, watchOS 8, *) func updateFromRemoteConfigAsync() async { let remoteConfig = RemoteConfig.remoteConfig() - let oldValue = remoteConfig["color_scheme"].stringValue ?? "light" + let oldValue = remoteConfig["color_scheme"].stringValue ?? "nil" do { let status = try await remoteConfig.fetchAndActivate() print("Fetch-and-activate completed with status: \(status.debugDescription)") - let newValue = remoteConfig["color_scheme"].stringValue ?? "light" + let newValue = remoteConfig["color_scheme"].stringValue ?? "nil" if newValue != oldValue { print("Remote Config changed to: \(newValue)") Task.detached { @MainActor in self.colorScheme = ColorScheme(newValue) } diff --git a/analytics/AnalyticsExample.xcodeproj/project.pbxproj b/analytics/AnalyticsExample.xcodeproj/project.pbxproj index 96688d2e9..a67bb6157 100644 --- a/analytics/AnalyticsExample.xcodeproj/project.pbxproj +++ b/analytics/AnalyticsExample.xcodeproj/project.pbxproj @@ -3,13 +3,10 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 51; objects = { /* Begin PBXBuildFile section */ - 8D7951DB2D39BE24000FD694 /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 8D7951DA2D39BE24000FD694 /* FirebaseAnalytics */; }; - 8D7951DD2D39BE29000FD694 /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 8D7951DC2D39BE29000FD694 /* FirebaseAnalytics */; }; - 8D7951DF2D39BE2E000FD694 /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 8D7951DE2D39BE2E000FD694 /* FirebaseAnalytics */; }; EA11716F24C6AB3D0085BD17 /* BlogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA11716E24C6AB3D0085BD17 /* BlogViewController.swift */; }; EA5C0BC624C5D2060010FDF6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5C0BC524C5D2060010FDF6 /* AppDelegate.swift */; }; EA5C0BC824C5D2060010FDF6 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5C0BC724C5D2060010FDF6 /* SceneDelegate.swift */; }; @@ -91,7 +88,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8D7951DB2D39BE24000FD694 /* FirebaseAnalytics in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -106,7 +102,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8D7951DD2D39BE29000FD694 /* FirebaseAnalytics in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -121,7 +116,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8D7951DF2D39BE2E000FD694 /* FirebaseAnalytics in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -135,11 +129,11 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 8D7951D92D39BE24000FD694 /* Frameworks */ = { + 2B283AC81B12C877411DB212 /* Pods */ = { isa = PBXGroup; children = ( ); - name = Frameworks; + path = Pods; sourceTree = ""; }; EA5C0BB924C5D2060010FDF6 = { @@ -153,8 +147,8 @@ EDF987902715E41D008840FA /* AnalyticsExampleMac */, EDF987A22715E421008840FA /* AnalyticsExampleMacTests */, EA5C0BC324C5D2060010FDF6 /* Products */, + 2B283AC81B12C877411DB212 /* Pods */, EDF987FB2719C791008840FA /* GoogleService-Info.plist */, - 8D7951D92D39BE24000FD694 /* Frameworks */, ); sourceTree = ""; }; @@ -395,9 +389,6 @@ Base, ); mainGroup = EA5C0BB924C5D2060010FDF6; - packageReferences = ( - 8D7951D82D39BE12000FD694 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, - ); productRefGroup = EA5C0BC324C5D2060010FDF6 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -1061,35 +1052,6 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ - -/* Begin XCRemoteSwiftPackageReference section */ - 8D7951D82D39BE12000FD694 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/firebase/firebase-ios-sdk"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 11.7.0; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 8D7951DA2D39BE24000FD694 /* FirebaseAnalytics */ = { - isa = XCSwiftPackageProductDependency; - package = 8D7951D82D39BE12000FD694 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = FirebaseAnalytics; - }; - 8D7951DC2D39BE29000FD694 /* FirebaseAnalytics */ = { - isa = XCSwiftPackageProductDependency; - package = 8D7951D82D39BE12000FD694 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = FirebaseAnalytics; - }; - 8D7951DE2D39BE2E000FD694 /* FirebaseAnalytics */ = { - isa = XCSwiftPackageProductDependency; - package = 8D7951D82D39BE12000FD694 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = FirebaseAnalytics; - }; -/* End XCSwiftPackageProductDependency section */ }; rootObject = EA5C0BBA24C5D2060010FDF6 /* Project object */; } diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExample.xcodeproj/project.pbxproj b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample.xcodeproj/project.pbxproj new file mode 100644 index 000000000..0b02995aa --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample.xcodeproj/project.pbxproj @@ -0,0 +1,917 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 107346D920315877004A66D1 /* AnalyticsExampleSwiftUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 107346D820315877004A66D1 /* AnalyticsExampleSwiftUITests.swift */; }; + 107347FF20333AD6004A66D1 /* AnalyticsExampleUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 107347FE20333AD6004A66D1 /* AnalyticsExampleUITests.m */; }; + 15D22729762E9C62A1777AEF /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = B719D0274FAE0575DEFC2BC2 /* GoogleService-Info.plist */; }; + 37C41742C3050BBAA05AEB2F /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = B719D0274FAE0575DEFC2BC2 /* GoogleService-Info.plist */; }; + 4109F1E5F3ED7CC121BC3AEC /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = B719D0274FAE0575DEFC2BC2 /* GoogleService-Info.plist */; }; + 5F3B16801AFC453200860007 /* CircleImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F3B167F1AFC453200860007 /* CircleImageView.m */; }; + 5F3B16811AFC453200860007 /* CircleImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F3B167F1AFC453200860007 /* CircleImageView.m */; }; + 5F5A53521ADE670C00F81DF0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53511ADE670C00F81DF0 /* main.m */; }; + 5F5A53551ADE670C00F81DF0 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */; }; + 5F5A53581ADE670C00F81DF0 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53571ADE670C00F81DF0 /* ViewController.m */; }; + 5F5A535B1ADE670C00F81DF0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5F5A53591ADE670C00F81DF0 /* Main.storyboard */; }; + 5F5A537E1ADE67D500F81DF0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */; }; + 5F5A53801ADE67D500F81DF0 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A537F1ADE67D500F81DF0 /* ViewController.swift */; }; + 5F5A539C1ADE69AA00F81DF0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5F5A53591ADE670C00F81DF0 /* Main.storyboard */; }; + 5F99610A1AE0CF4F0034F503 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961061AE0CF4F0034F503 /* Images.xcassets */; }; + 5F99610B1AE0CF4F0034F503 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961061AE0CF4F0034F503 /* Images.xcassets */; }; + 5F99610C1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */; }; + 5F99610D1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */; }; + 5FC04A7F1AF1DCAA00F787CA /* PatternTabBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FC04A7E1AF1DCAA00F787CA /* PatternTabBarController.m */; }; + 5FC04A811AF1DF8300F787CA /* PatternTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FC04A801AF1DF8300F787CA /* PatternTabBarController.swift */; }; + 5FC7AD8E1B0D446A004E3100 /* LogWrapper.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5FC7AD8D1B0D446A004E3100 /* LogWrapper.mm */; }; + 5FDE05641B0DAD5C0037B82F /* AppTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FDE05631B0DAD5C0037B82F /* AppTests.m */; }; + AD7774A577C995CEC721FBA9 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = B719D0274FAE0575DEFC2BC2 /* GoogleService-Info.plist */; }; + E735D5D1655322FCC076AC05 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = B719D0274FAE0575DEFC2BC2 /* GoogleService-Info.plist */; }; + EF01600C1BD07C1F00F8DA01 /* AnalyticsImages.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EF01600B1BD07C1F00F8DA01 /* AnalyticsImages.xcassets */; }; + EF01600D1BD07C1F00F8DA01 /* AnalyticsImages.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EF01600B1BD07C1F00F8DA01 /* AnalyticsImages.xcassets */; }; + EFB6C1B61C6524F4007CCA78 /* FoodPickerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EFB6C1B51C6524F4007CCA78 /* FoodPickerViewController.m */; }; + EFB6C1BA1C656D38007CCA78 /* FoodPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFB6C1B91C656D38007CCA78 /* FoodPickerViewController.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 107346DB20315877004A66D1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5F5A53781ADE67D500F81DF0; + remoteInfo = AnalyticsExampleSwift; + }; + 1073480120333AD6004A66D1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5F5A534B1ADE670C00F81DF0; + remoteInfo = AnalyticsExample; + }; + 5FC7AD881B0D4106004E3100 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5F5A534B1ADE670C00F81DF0; + remoteInfo = AnalyticsExample; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 107346D620315877004A66D1 /* AnalyticsExampleSwiftUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AnalyticsExampleSwiftUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 107346D820315877004A66D1 /* AnalyticsExampleSwiftUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsExampleSwiftUITests.swift; sourceTree = ""; }; + 107346DA20315877004A66D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 107347FC20333AD6004A66D1 /* AnalyticsExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AnalyticsExampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 107347FE20333AD6004A66D1 /* AnalyticsExampleUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AnalyticsExampleUITests.m; sourceTree = ""; }; + 1073480020333AD6004A66D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5F3B167E1AFC453200860007 /* CircleImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CircleImageView.h; sourceTree = ""; }; + 5F3B167F1AFC453200860007 /* CircleImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CircleImageView.m; sourceTree = ""; }; + 5F5A534C1ADE670C00F81DF0 /* AnalyticsExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AnalyticsExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5F5A53501ADE670C00F81DF0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5F5A53511ADE670C00F81DF0 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 5F5A53531ADE670C00F81DF0 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 5F5A53561ADE670C00F81DF0 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + 5F5A53571ADE670C00F81DF0 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 5F5A535A1ADE670C00F81DF0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 5F5A53791ADE67D500F81DF0 /* AnalyticsExampleSwift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AnalyticsExampleSwift.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 5F5A537F1ADE67D500F81DF0 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 5F9961061AE0CF4F0034F503 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LaunchScreen.xib; sourceTree = ""; }; + 5FC04A7D1AF1DCAA00F787CA /* PatternTabBarController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PatternTabBarController.h; sourceTree = ""; }; + 5FC04A7E1AF1DCAA00F787CA /* PatternTabBarController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PatternTabBarController.m; sourceTree = ""; }; + 5FC04A801AF1DF8300F787CA /* PatternTabBarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PatternTabBarController.swift; sourceTree = ""; }; + 5FC7AD821B0D4106004E3100 /* AnalyticsExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AnalyticsExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5FC7AD8D1B0D446A004E3100 /* LogWrapper.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LogWrapper.mm; sourceTree = ""; }; + 5FC7AD8F1B0D44B9004E3100 /* LogWrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LogWrapper.h; sourceTree = ""; }; + 5FDE05631B0DAD5C0037B82F /* AppTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppTests.m; sourceTree = ""; }; + B719D0274FAE0575DEFC2BC2 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "../GoogleService-Info.plist"; sourceTree = ""; }; + EF01600B1BD07C1F00F8DA01 /* AnalyticsImages.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = AnalyticsImages.xcassets; sourceTree = ""; }; + EFB6C1B41C6524F4007CCA78 /* FoodPickerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FoodPickerViewController.h; sourceTree = ""; }; + EFB6C1B51C6524F4007CCA78 /* FoodPickerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FoodPickerViewController.m; sourceTree = ""; }; + EFB6C1B91C656D38007CCA78 /* FoodPickerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FoodPickerViewController.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 107346D320315877004A66D1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 107347F920333AD6004A66D1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53491ADE670C00F81DF0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53761ADE67D500F81DF0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FC7AD7F1B0D4106004E3100 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 107346D720315877004A66D1 /* AnalyticsExampleSwiftUITests */ = { + isa = PBXGroup; + children = ( + 107346D820315877004A66D1 /* AnalyticsExampleSwiftUITests.swift */, + 107346DA20315877004A66D1 /* Info.plist */, + ); + path = AnalyticsExampleSwiftUITests; + sourceTree = ""; + }; + 107347FD20333AD6004A66D1 /* AnalyticsExampleUITests */ = { + isa = PBXGroup; + children = ( + 107347FE20333AD6004A66D1 /* AnalyticsExampleUITests.m */, + 1073480020333AD6004A66D1 /* Info.plist */, + ); + path = AnalyticsExampleUITests; + sourceTree = ""; + }; + 5F5A53431ADE670C00F81DF0 = { + isa = PBXGroup; + children = ( + 5F5A534E1ADE670C00F81DF0 /* AnalyticsExample */, + 5F5A537A1ADE67D500F81DF0 /* AnalyticsExampleSwift */, + 5FC7AD831B0D4106004E3100 /* AnalyticsExampleTests */, + 107346D720315877004A66D1 /* AnalyticsExampleSwiftUITests */, + 107347FD20333AD6004A66D1 /* AnalyticsExampleUITests */, + 5F5A534D1ADE670C00F81DF0 /* Products */, + 5F9961041AE0CF4F0034F503 /* Shared */, + 5FC29E541AE9255700668C8D /* Images */, + B719D0274FAE0575DEFC2BC2 /* GoogleService-Info.plist */, + ); + sourceTree = ""; + }; + 5F5A534D1ADE670C00F81DF0 /* Products */ = { + isa = PBXGroup; + children = ( + 5F5A534C1ADE670C00F81DF0 /* AnalyticsExample.app */, + 5F5A53791ADE67D500F81DF0 /* AnalyticsExampleSwift.app */, + 5FC7AD821B0D4106004E3100 /* AnalyticsExampleTests.xctest */, + 107346D620315877004A66D1 /* AnalyticsExampleSwiftUITests.xctest */, + 107347FC20333AD6004A66D1 /* AnalyticsExampleUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 5F5A534E1ADE670C00F81DF0 /* AnalyticsExample */ = { + isa = PBXGroup; + children = ( + 5F5A53531ADE670C00F81DF0 /* AppDelegate.h */, + 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */, + EFB6C1B41C6524F4007CCA78 /* FoodPickerViewController.h */, + EFB6C1B51C6524F4007CCA78 /* FoodPickerViewController.m */, + 5FC04A7D1AF1DCAA00F787CA /* PatternTabBarController.h */, + 5FC04A7E1AF1DCAA00F787CA /* PatternTabBarController.m */, + 5F5A53561ADE670C00F81DF0 /* ViewController.h */, + 5F5A53571ADE670C00F81DF0 /* ViewController.m */, + 5F5A534F1ADE670C00F81DF0 /* Supporting Files */, + ); + path = AnalyticsExample; + sourceTree = ""; + }; + 5F5A534F1ADE670C00F81DF0 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 5F3B167E1AFC453200860007 /* CircleImageView.h */, + 5F3B167F1AFC453200860007 /* CircleImageView.m */, + 5F5A53511ADE670C00F81DF0 /* main.m */, + 5F5A53501ADE670C00F81DF0 /* Info.plist */, + 5F5A53591ADE670C00F81DF0 /* Main.storyboard */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 5F5A537A1ADE67D500F81DF0 /* AnalyticsExampleSwift */ = { + isa = PBXGroup; + children = ( + 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */, + EFB6C1B91C656D38007CCA78 /* FoodPickerViewController.swift */, + 5FC04A801AF1DF8300F787CA /* PatternTabBarController.swift */, + 5F5A537F1ADE67D500F81DF0 /* ViewController.swift */, + ); + path = AnalyticsExampleSwift; + sourceTree = ""; + }; + 5F9961041AE0CF4F0034F503 /* Shared */ = { + isa = PBXGroup; + children = ( + 5F9961061AE0CF4F0034F503 /* Images.xcassets */, + 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */, + ); + name = Shared; + path = ../../shared; + sourceTree = ""; + }; + 5FC29E541AE9255700668C8D /* Images */ = { + isa = PBXGroup; + children = ( + EF01600B1BD07C1F00F8DA01 /* AnalyticsImages.xcassets */, + ); + path = Images; + sourceTree = ""; + }; + 5FC7AD831B0D4106004E3100 /* AnalyticsExampleTests */ = { + isa = PBXGroup; + children = ( + 5FDE05631B0DAD5C0037B82F /* AppTests.m */, + 5FC7AD8D1B0D446A004E3100 /* LogWrapper.mm */, + 5FC7AD8F1B0D44B9004E3100 /* LogWrapper.h */, + ); + path = AnalyticsExampleTests; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 107346D520315877004A66D1 /* AnalyticsExampleSwiftUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 107346DD20315877004A66D1 /* Build configuration list for PBXNativeTarget "AnalyticsExampleSwiftUITests" */; + buildPhases = ( + 107346D220315877004A66D1 /* Sources */, + 107346D320315877004A66D1 /* Frameworks */, + 107346D420315877004A66D1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 107346DC20315877004A66D1 /* PBXTargetDependency */, + ); + name = AnalyticsExampleSwiftUITests; + productName = AnalyticsExampleSwiftUITests; + productReference = 107346D620315877004A66D1 /* AnalyticsExampleSwiftUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + 107347FB20333AD6004A66D1 /* AnalyticsExampleUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1073480320333AD7004A66D1 /* Build configuration list for PBXNativeTarget "AnalyticsExampleUITests" */; + buildPhases = ( + 107347F820333AD6004A66D1 /* Sources */, + 107347F920333AD6004A66D1 /* Frameworks */, + 107347FA20333AD6004A66D1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 1073480220333AD6004A66D1 /* PBXTargetDependency */, + ); + name = AnalyticsExampleUITests; + productName = AnalyticsExampleUITests; + productReference = 107347FC20333AD6004A66D1 /* AnalyticsExampleUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + 5F5A534B1ADE670C00F81DF0 /* AnalyticsExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5F5A536F1ADE670C00F81DF0 /* Build configuration list for PBXNativeTarget "AnalyticsExample" */; + buildPhases = ( + 5F5A53481ADE670C00F81DF0 /* Sources */, + 5F5A53491ADE670C00F81DF0 /* Frameworks */, + 5F5A534A1ADE670C00F81DF0 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AnalyticsExample; + productName = AnalyticsExample; + productReference = 5F5A534C1ADE670C00F81DF0 /* AnalyticsExample.app */; + productType = "com.apple.product-type.application"; + }; + 5F5A53781ADE67D500F81DF0 /* AnalyticsExampleSwift */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5F5A53991ADE67D500F81DF0 /* Build configuration list for PBXNativeTarget "AnalyticsExampleSwift" */; + buildPhases = ( + 5F5A53751ADE67D500F81DF0 /* Sources */, + 5F5A53761ADE67D500F81DF0 /* Frameworks */, + 5F5A53771ADE67D500F81DF0 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AnalyticsExampleSwift; + productName = AnalyticsExampleSwift; + productReference = 5F5A53791ADE67D500F81DF0 /* AnalyticsExampleSwift.app */; + productType = "com.apple.product-type.application"; + }; + 5FC7AD811B0D4106004E3100 /* AnalyticsExampleTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5FC7AD8C1B0D4106004E3100 /* Build configuration list for PBXNativeTarget "AnalyticsExampleTests" */; + buildPhases = ( + 5FC7AD7E1B0D4106004E3100 /* Sources */, + 5FC7AD7F1B0D4106004E3100 /* Frameworks */, + 5FC7AD801B0D4106004E3100 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5FC7AD891B0D4106004E3100 /* PBXTargetDependency */, + ); + name = AnalyticsExampleTests; + productName = AnalyticsExampleTests; + productReference = 5FC7AD821B0D4106004E3100 /* AnalyticsExampleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5F5A53441ADE670C00F81DF0 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 0930; + ORGANIZATIONNAME = "Google Inc."; + TargetAttributes = { + 107346D520315877004A66D1 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1110; + ProvisioningStyle = Automatic; + TestTargetID = 5F5A53781ADE67D500F81DF0; + }; + 107347FB20333AD6004A66D1 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Automatic; + TestTargetID = 5F5A534B1ADE670C00F81DF0; + }; + 5F5A534B1ADE670C00F81DF0 = { + CreatedOnToolsVersion = 6.3; + LastSwiftMigration = 0800; + ProvisioningStyle = Automatic; + }; + 5F5A53781ADE67D500F81DF0 = { + CreatedOnToolsVersion = 6.3; + LastSwiftMigration = 1110; + ProvisioningStyle = Automatic; + }; + 5FC7AD811B0D4106004E3100 = { + CreatedOnToolsVersion = 6.3.2; + LastSwiftMigration = ""; + ProvisioningStyle = Automatic; + TestTargetID = 5F5A534B1ADE670C00F81DF0; + }; + }; + }; + buildConfigurationList = 5F5A53471ADE670C00F81DF0 /* Build configuration list for PBXProject "AnalyticsExample" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 5F5A53431ADE670C00F81DF0; + productRefGroup = 5F5A534D1ADE670C00F81DF0 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5F5A534B1ADE670C00F81DF0 /* AnalyticsExample */, + 5F5A53781ADE67D500F81DF0 /* AnalyticsExampleSwift */, + 5FC7AD811B0D4106004E3100 /* AnalyticsExampleTests */, + 107346D520315877004A66D1 /* AnalyticsExampleSwiftUITests */, + 107347FB20333AD6004A66D1 /* AnalyticsExampleUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 107346D420315877004A66D1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 107347FA20333AD6004A66D1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A534A1ADE670C00F81DF0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F99610C1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */, + 5F99610A1AE0CF4F0034F503 /* Images.xcassets in Resources */, + EF01600C1BD07C1F00F8DA01 /* AnalyticsImages.xcassets in Resources */, + 5F5A535B1ADE670C00F81DF0 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53771ADE67D500F81DF0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F99610D1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */, + EF01600D1BD07C1F00F8DA01 /* AnalyticsImages.xcassets in Resources */, + 5F5A539C1ADE69AA00F81DF0 /* Main.storyboard in Resources */, + 5F99610B1AE0CF4F0034F503 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FC7AD801B0D4106004E3100 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 107346D220315877004A66D1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 107346D920315877004A66D1 /* AnalyticsExampleSwiftUITests.swift in Sources */, + 15D22729762E9C62A1777AEF /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 107347F820333AD6004A66D1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 107347FF20333AD6004A66D1 /* AnalyticsExampleUITests.m in Sources */, + 4109F1E5F3ED7CC121BC3AEC /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53481ADE670C00F81DF0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F5A53581ADE670C00F81DF0 /* ViewController.m in Sources */, + 5F5A53551ADE670C00F81DF0 /* AppDelegate.m in Sources */, + 5FC04A7F1AF1DCAA00F787CA /* PatternTabBarController.m in Sources */, + 5F3B16801AFC453200860007 /* CircleImageView.m in Sources */, + EFB6C1B61C6524F4007CCA78 /* FoodPickerViewController.m in Sources */, + 5F5A53521ADE670C00F81DF0 /* main.m in Sources */, + 37C41742C3050BBAA05AEB2F /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53751ADE67D500F81DF0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F3B16811AFC453200860007 /* CircleImageView.m in Sources */, + 5FC04A811AF1DF8300F787CA /* PatternTabBarController.swift in Sources */, + 5F5A53801ADE67D500F81DF0 /* ViewController.swift in Sources */, + EFB6C1BA1C656D38007CCA78 /* FoodPickerViewController.swift in Sources */, + 5F5A537E1ADE67D500F81DF0 /* AppDelegate.swift in Sources */, + AD7774A577C995CEC721FBA9 /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FC7AD7E1B0D4106004E3100 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5FC7AD8E1B0D446A004E3100 /* LogWrapper.mm in Sources */, + 5FDE05641B0DAD5C0037B82F /* AppTests.m in Sources */, + E735D5D1655322FCC076AC05 /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 107346DC20315877004A66D1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5F5A53781ADE67D500F81DF0 /* AnalyticsExampleSwift */; + targetProxy = 107346DB20315877004A66D1 /* PBXContainerItemProxy */; + }; + 1073480220333AD6004A66D1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5F5A534B1ADE670C00F81DF0 /* AnalyticsExample */; + targetProxy = 1073480120333AD6004A66D1 /* PBXContainerItemProxy */; + }; + 5FC7AD891B0D4106004E3100 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5F5A534B1ADE670C00F81DF0 /* AnalyticsExample */; + targetProxy = 5FC7AD881B0D4106004E3100 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 5F5A53591ADE670C00F81DF0 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5F5A535A1ADE670C00F81DF0 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 107346DE20315877004A66D1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = AnalyticsExampleSwiftUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.AnalyticsExampleSwiftUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = AnalyticsExampleSwift; + }; + name = Debug; + }; + 107346DF20315877004A66D1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = AnalyticsExampleSwiftUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.AnalyticsExampleSwiftUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = AnalyticsExampleSwift; + }; + name = Release; + }; + 1073480420333AD7004A66D1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = AnalyticsExampleUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.AnalyticsExampleUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = AnalyticsExample; + }; + name = Debug; + }; + 1073480520333AD7004A66D1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = AnalyticsExampleUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.AnalyticsExampleUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = AnalyticsExample; + }; + name = Release; + }; + 1073F3B81DA830C500C3EDCB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + INFOPLIST_FILE = "$(SRCROOT)/AnalyticsExample/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.AnalyticsExample; + PRODUCT_NAME = AnalyticsExampleSwift; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 5F5A536D1ADE670C00F81DF0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5F5A536E1ADE670C00F81DF0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5F5A53701ADE670C00F81DF0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = AnalyticsExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.AnalyticsExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + }; + name = Debug; + }; + 5F5A53711ADE670C00F81DF0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = AnalyticsExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.AnalyticsExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + }; + name = Release; + }; + 5F5A53961ADE67D500F81DF0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = "$(SRCROOT)/AnalyticsExample/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.AnalyticsExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 5FC7AD8A1B0D4106004E3100 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + AnalyticsExample, + ); + INFOPLIST_FILE = AnalyticsExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AnalyticsExample.app/AnalyticsExample"; + }; + name = Debug; + }; + 5FC7AD8B1B0D4106004E3100 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + AnalyticsExample, + ); + INFOPLIST_FILE = AnalyticsExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AnalyticsExample.app/AnalyticsExample"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 107346DD20315877004A66D1 /* Build configuration list for PBXNativeTarget "AnalyticsExampleSwiftUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 107346DE20315877004A66D1 /* Debug */, + 107346DF20315877004A66D1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1073480320333AD7004A66D1 /* Build configuration list for PBXNativeTarget "AnalyticsExampleUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1073480420333AD7004A66D1 /* Debug */, + 1073480520333AD7004A66D1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5F5A53471ADE670C00F81DF0 /* Build configuration list for PBXProject "AnalyticsExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5F5A536D1ADE670C00F81DF0 /* Debug */, + 5F5A536E1ADE670C00F81DF0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5F5A536F1ADE670C00F81DF0 /* Build configuration list for PBXNativeTarget "AnalyticsExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5F5A53701ADE670C00F81DF0 /* Debug */, + 5F5A53711ADE670C00F81DF0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5F5A53991ADE67D500F81DF0 /* Build configuration list for PBXNativeTarget "AnalyticsExampleSwift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5F5A53961ADE67D500F81DF0 /* Release */, + 1073F3B81DA830C500C3EDCB /* Debug */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5FC7AD8C1B0D4106004E3100 /* Build configuration list for PBXNativeTarget "AnalyticsExampleTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5FC7AD8A1B0D4106004E3100 /* Debug */, + 5FC7AD8B1B0D4106004E3100 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5F5A53441ADE670C00F81DF0 /* Project object */; +} diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExample.xcodeproj/xcshareddata/xcschemes/AnalyticsExample.xcscheme b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample.xcodeproj/xcshareddata/xcschemes/AnalyticsExample.xcscheme new file mode 100644 index 000000000..70d6d152c --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample.xcodeproj/xcshareddata/xcschemes/AnalyticsExample.xcscheme @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExample.xcodeproj/xcshareddata/xcschemes/AnalyticsExampleSwift.xcscheme b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample.xcodeproj/xcshareddata/xcschemes/AnalyticsExampleSwift.xcscheme new file mode 100644 index 000000000..cf9dc012f --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample.xcodeproj/xcshareddata/xcschemes/AnalyticsExampleSwift.xcscheme @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/AppDelegate.h b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/AppDelegate.h new file mode 100644 index 000000000..498396760 --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/AppDelegate.h @@ -0,0 +1,23 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import UIKit; + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + +@end diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/AppDelegate.m b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/AppDelegate.m new file mode 100644 index 000000000..3814a0d6b --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/AppDelegate.m @@ -0,0 +1,39 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +// For more information on setting up and running this sample code, see +// https://firebase.google.com/docs/analytics/ios/start +// + +#import "AppDelegate.h" + +@import FirebaseCore; + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // [START configure] + [FIRApp configure]; + // [END configure] + + // Set a white background so that patterns are showcased. + self.window.backgroundColor = [UIColor whiteColor]; + + return YES; +} + +@end diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/Base.lproj/Main.storyboard b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/Base.lproj/Main.storyboard new file mode 100644 index 000000000..53add7abb --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/Base.lproj/Main.storyboard @@ -0,0 +1,284 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/CircleImageView.h b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/CircleImageView.h new file mode 100644 index 000000000..cc22e3937 --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/CircleImageView.h @@ -0,0 +1,27 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import UIKit; + +/** + * CircleImageView is a UIImageView subclass that renders an image inside a + * circle that has a drop shadow. It should be given equal width and height. + * + * This is shared between the Objective-C and Swift versions of the samples. + */ +IB_DESIGNABLE +@interface CircleImageView : UIImageView +@end diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/CircleImageView.m b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/CircleImageView.m new file mode 100644 index 000000000..876e892e5 --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/CircleImageView.m @@ -0,0 +1,59 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "CircleImageView.h" + +@implementation CircleImageView + +- (instancetype)initWithFrame:(CGRect)frame { + if ((self = [super initWithFrame:frame])) { + [self sharedInit]; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if ((self = [super initWithCoder:aDecoder])) { + [self sharedInit]; + } + return self; +} + +- (void)sharedInit { + self.backgroundColor = [UIColor whiteColor]; + super.contentMode = UIViewContentModeCenter; + + CALayer *layer = super.layer; + layer.shadowOffset = CGSizeMake(0, 2); + layer.shadowOpacity = 0.25; + layer.shadowColor = [UIColor grayColor].CGColor; + layer.shadowRadius = 4.0; + layer.shadowOffset = CGSizeMake(0, 2); +} + +- (void)layoutSubviews { + [super layoutSubviews]; + + CGSize size = self.bounds.size; + CGFloat dim = MAX(size.width, size.height); + self.layer.cornerRadius = dim / 2; +} + +- (void)setContentMode:(UIViewContentMode)contentMode { + // ignore +} + +@end diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/FoodPickerViewController.h b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/FoodPickerViewController.h new file mode 100644 index 000000000..30bcfeed5 --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/FoodPickerViewController.h @@ -0,0 +1,26 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +// For more information on setting up and running this sample code, see +// https://firebase.google.com/docs/analytics/ios/start +// + +@import UIKit; + +@interface FoodPickerViewController : UIViewController + +@end diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/FoodPickerViewController.m b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/FoodPickerViewController.m new file mode 100644 index 000000000..f00e95538 --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/FoodPickerViewController.m @@ -0,0 +1,69 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +// For more information on setting up and running this sample code, see +// https://firebase.google.com/docs/analytics/ios/start +// + +#import "FoodPickerViewController.h" + +@import FirebaseAnalytics; + +@interface FoodPickerViewController () +@property (nonatomic, strong) NSArray *foodStuffs; +@end + +@implementation FoodPickerViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + self.foodStuffs = @[ + @"Hot Dogs", + @"Hamburger", + @"Pizza" + ]; +} + + +- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row + inComponent:(NSInteger)component { + NSString *food = self.foodStuffs[row]; + + [[NSUserDefaults standardUserDefaults] setObject:food forKey:@"favorite_food"]; + + // [START user_property] + [FIRAnalytics setUserPropertyString:food forName:@"favorite_food"]; + // [END user_property] + + [self performSegueWithIdentifier:@"goToShareScreen" sender:self]; +} + +- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { + return 1; +} + +- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { + return self.foodStuffs.count; +} + +- (NSString *)pickerView:(UIPickerView *)pickerView + titleForRow:(NSInteger)row + forComponent:(NSInteger)component { + return self.foodStuffs[row]; +} + +@end diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/Info.plist b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/Info.plist new file mode 100644 index 000000000..d67c8fe8a --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/Info.plist @@ -0,0 +1,51 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIcons + + CFBundleIcons~ipad + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0.1 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/PatternTabBarController.h b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/PatternTabBarController.h new file mode 100644 index 000000000..e2d5a4117 --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/PatternTabBarController.h @@ -0,0 +1,28 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import UIKit; + +/** + * PatternTabBarController exists as a subclass of UITabBarConttroller that + * supports a 'share' action. This will trigger a custom event to Analytics and + * display a dialog. + */ +@interface PatternTabBarController : UITabBarController + +- (IBAction)didTapShare:(id)sender; + +@end diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/PatternTabBarController.m b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/PatternTabBarController.m new file mode 100644 index 000000000..1602ef01e --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/PatternTabBarController.m @@ -0,0 +1,71 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +// For more information on setting up and running this sample code, see +// https://firebase.google.com/docs/analytics/ios/start +// + +#import "PatternTabBarController.h" + +@import FirebaseAnalytics; + +@implementation PatternTabBarController + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + // For first run, ask for the user's favorite food. + if (![self getUserFavoriteFood]) { + [self askForFavoriteFood]; + } +} + +- (void)didTapShare:(id)sender { + NSString *name = [NSString stringWithFormat:@"Pattern~%@", self.selectedViewController.title]; + NSString *text = [NSString stringWithFormat:@"I'd love you to hear about %@", name]; + + // [START custom_event_objc] + [FIRAnalytics logEventWithName:@"share_image" + parameters:@{ + @"name": name, + @"full_text": text + }]; + // [END custom_event_objc] + + NSString *title = [NSString stringWithFormat:@"Share: %@", + self.selectedViewController.title]; + NSString *message = + @"Share event sent to Analytics; actual share not implemented in this quickstart"; + + UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]; + [alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:nil]]; + [self presentViewController:alert animated:true completion:nil]; +} + +- (NSString *)getUserFavoriteFood { + return [[NSUserDefaults standardUserDefaults] stringForKey:@"favorite_food"]; +} + +- (void)askForFavoriteFood { + [self performSegueWithIdentifier:@"pickFavoriteFood" sender:self]; +} + +-(IBAction)unwindToHome:(UIStoryboardSegue *)segue { + UINavigationController *nc = self.navigationController; + [nc dismissViewControllerAnimated:YES completion: nil]; +} + +@end diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/ViewController.h b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/ViewController.h new file mode 100644 index 000000000..327d97a4a --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/ViewController.h @@ -0,0 +1,20 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import UIKit; + +@interface ViewController : UIViewController +@end diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/ViewController.m b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/ViewController.m new file mode 100644 index 000000000..cefbafc05 --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/ViewController.m @@ -0,0 +1,55 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +// For more information on setting up and running this sample code, see +// https://firebase.google.com/docs/analytics/ios/start +// + +#import "ViewController.h" + +@import FirebaseAnalytics; + +@implementation ViewController + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + + [self recordScreenView]; + + // [START custom_event_objc] + [FIRAnalytics logEventWithName:kFIREventSelectContent + parameters:@{ + kFIRParameterItemID:[NSString stringWithFormat:@"id-%@", self.title], + kFIRParameterItemName:self.title, + kFIRParameterContentType:@"image" + }]; + // [END custom_event_objc] +} + +// Manually record "screen views" as user selects tabs. +- (void)recordScreenView { + // These strings must be <= 36 characters long in order for setScreenName:screenClass: to succeed. + NSString *screenName = self.title; + NSString *screenClass = [self.classForCoder description]; + + // [START set_current_screen] + [FIRAnalytics logEventWithName:kFIREventScreenView + parameters:@{kFIRParameterScreenClass: screenClass, + kFIRParameterScreenName: screenName}]; + // [END set_current_screen] +} + +@end diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/main.m b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/main.m new file mode 100644 index 000000000..8218f2256 --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExample/main.m @@ -0,0 +1,24 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleSwift/AppDelegate.swift b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleSwift/AppDelegate.swift new file mode 100644 index 000000000..d778168de --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleSwift/AppDelegate.swift @@ -0,0 +1,36 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit +import FirebaseCore + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? + + func application(_ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication + .LaunchOptionsKey: Any]?) -> Bool { + // [START tracker_swift] + FirebaseApp.configure() + // [END tracker_swift] + + // Set a white background so that patterns are showcased. + window?.backgroundColor = .white + + return true + } +} diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleSwift/FoodPickerViewController.swift b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleSwift/FoodPickerViewController.swift new file mode 100644 index 000000000..166868902 --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleSwift/FoodPickerViewController.swift @@ -0,0 +1,52 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +// For more information on setting up and running this sample code, see +// https://firebase.google.com/docs/analytics/ios/start +// + +import UIKit +import FirebaseAnalytics + +@objc(FoodPickerViewController) // match the ObjC symbol name inside Storyboard +class FoodPickerViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource { + let foodStuffs = ["Hot Dogs", "Hamburger", "Pizza"] + + func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { + let food = foodStuffs[row] + UserDefaults.standard.set(food, forKey: "favorite_food") + + // [START user_property] + Analytics.setUserProperty(food, forName: "favorite_food") + // [END user_property] + + performSegue(withIdentifier: "goToShareScreen", sender: self) + } + + func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { + return foodStuffs.count + } + + func numberOfComponents(in pickerView: UIPickerView) -> Int { + return 1 + } + + func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, + forComponent component: Int) -> String? { + return foodStuffs[row] + } +} diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleSwift/PatternTabBarController.swift b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleSwift/PatternTabBarController.swift new file mode 100644 index 000000000..6cb099f70 --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleSwift/PatternTabBarController.swift @@ -0,0 +1,65 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit +import FirebaseAnalytics + +/** + * PatternTabBarController exists as a subclass of UITabBarConttroller that + * supports a 'share' action. This will trigger a custom event to Analytics and + * display a dialog. + */ +@objc(PatternTabBarController) // match the ObjC symbol name inside Storyboard +class PatternTabBarController: UITabBarController { + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + if getUserFavoriteFood() == nil { + askForFavoriteFood() + } + } + + @IBAction func didTapShare(_ sender: AnyObject) { + let name = "Pattern~\(selectedViewController!.title!)", + text = "I'd love you to hear about\(name)" + + // [START custom_event_swift] + Analytics.logEvent("share_image", parameters: [ + "name": name as NSObject, + "full_text": text as NSObject, + ]) + // [END custom_event_swift] + + let title = "Share: \(selectedViewController!.title!)", + message = "Share event sent to Analytics; actual share not implemented in this quickstart", + alert = UIAlertController(title: title, message: message, preferredStyle: .alert) + alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil)) + present(alert, animated: true, completion: nil) + } + + @IBAction func unwindToHome(_ segue: UIStoryboardSegue?) { + if let nc = navigationController { + nc.dismiss(animated: true, completion: nil) + } + } + + func getUserFavoriteFood() -> String? { + return UserDefaults.standard.string(forKey: "favorite_food") + } + + func askForFavoriteFood() { + performSegue(withIdentifier: "pickFavoriteFood", sender: self) + } +} diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleSwift/ViewController.swift b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleSwift/ViewController.swift new file mode 100644 index 000000000..21e24f1da --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleSwift/ViewController.swift @@ -0,0 +1,49 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit +import FirebaseAnalytics + +@objc(ViewController) // match the ObjC symbol name inside Storyboard +class ViewController: UIViewController { + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + recordScreenView() + + // [START custom_event_swift] + Analytics.logEvent(AnalyticsEventSelectContent, parameters: [ + AnalyticsParameterItemID: "id-\(title!)", + AnalyticsParameterItemName: title!, + AnalyticsParameterContentType: "cont", + ]) + // [END custom_event_swift] + } + + func recordScreenView() { + // These strings must be <= 36 characters long in order for setScreenName:screenClass: to succeed. + guard let screenName = title else { + return + } + let screenClass = classForCoder.description() + + // [START set_current_screen] + Analytics.logEvent(AnalyticsEventScreenView, + parameters: [AnalyticsParameterScreenName: screenName, + AnalyticsParameterScreenClass: screenClass]) + // [END set_current_screen] + } +} diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleSwiftUITests/AnalyticsExampleSwiftUITests.swift b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleSwiftUITests/AnalyticsExampleSwiftUITests.swift new file mode 100644 index 000000000..d7a5b5d7f --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleSwiftUITests/AnalyticsExampleSwiftUITests.swift @@ -0,0 +1,42 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import XCTest + +class AnalyticsExampleSwiftUITests: XCTestCase { + override func setUp() { + super.setUp() + + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. + XCUIApplication().launch() + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } +} diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleSwiftUITests/Info.plist b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleSwiftUITests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleSwiftUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleTests/AppTests.m b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleTests/AppTests.m new file mode 100644 index 000000000..d94992a3a --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleTests/AppTests.m @@ -0,0 +1,88 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +@import FirebaseCore; + +#import "LogWrapper.h" + +static NSString * const kSearchTerm = @" Measurement data sent to network. "; + +@interface AppTests : XCTestCase +@end + +@implementation AppTests { + LogWrapper *_logWrapper; + UITabBarController *_patternsController; +} + +- (void)setUp { + _logWrapper = [[LogWrapper alloc] init]; + + [[FIRConfiguration sharedInstance] setLoggerLevel:FIRLoggerLevelDebug]; + + UIWindow *window = [UIApplication sharedApplication].keyWindow; + UIViewController *rootViewController = window.rootViewController; + for (UIViewController *candidate in rootViewController.childViewControllers) { + if ([candidate isKindOfClass:[UITabBarController class]]) { + _patternsController = (UITabBarController *)candidate; + break; + } + } +} + +- (void)tearDown { + _logWrapper = nil; +} + +// This test passes when run in Xcode but fails when run via the command line. +// It's disabled to avoid failures in Travis. +- (void)disabled_testLogs { + XCTestExpectation *expectation = + [self expectationWithDescription:@"Send event inside logs"]; + [_logWrapper lines]; // force clear + + // Trigger a new, different tab to be shown. + XCTAssertEqual(_patternsController.selectedIndex, 0, + @"Expected left-most index to be initially selected"); + _patternsController.selectedIndex = 2; + + // Check the logs constantly until a send message is found. + NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.1 + target:self + selector:@selector(checkTimer:) + userInfo:expectation + repeats:YES]; + [self waitForExpectationsWithTimeout:30.0 handler:nil]; + [timer invalidate]; +} + +- (void)checkTimer:(NSTimer *)timer { + XCTestExpectation *expectation = timer.userInfo; + NSArray *lines = [_logWrapper lines]; + + for (NSString *line in lines) { + if ([line containsString:kSearchTerm]) { + [expectation fulfill]; + break; + } + } + +} + +@end diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleTests/LogWrapper.h b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleTests/LogWrapper.h new file mode 100644 index 000000000..edb675ddb --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleTests/LogWrapper.h @@ -0,0 +1,32 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +/** + * LogWrapper replaces the current stderr, matched to its lifetime. Any lines written to stderr + * during this time can be retrieved by the -lines method. + */ +@interface LogWrapper : NSObject + +/** + * Returns any lines (as NSString instances) written since LogWrapper was created, or the last + * call to this method. This may return a nil/empty array if nothing was written. + */ +- (NSArray *)lines; + +@end + diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleTests/LogWrapper.mm b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleTests/LogWrapper.mm new file mode 100644 index 000000000..fad99a398 --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleTests/LogWrapper.mm @@ -0,0 +1,65 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "LogWrapper.h" + +#include +#include + +#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) + +@implementation LogWrapper { + char _tempLogFile[64]; + NSFileHandle *_handle; + int _dupFd; +} + +- (instancetype)init { + if ((self = [super init])) { + _dupFd = dup(fileno(stderr)); + + snprintf(_tempLogFile, ARRAYSIZE(_tempLogFile), "/tmp/objc-logwrapper.XXXXXX"); + int fd = mkstemp(_tempLogFile); + + NSLog(@"LogWrapper writing to: %s", _tempLogFile); + + freopen(_tempLogFile, "w+", stderr); + _handle = [[NSFileHandle alloc] initWithFileDescriptor:fd closeOnDealloc:YES]; + } + return self; +} + +- (void)dealloc { + unlink(_tempLogFile); + NSLog(@"~LogWrapper removed: %s", _tempLogFile); + + dup2(_dupFd, fileno(stderr)); + close(_dupFd); +} + +- (NSArray *)lines { + NSData *data = [_handle readDataToEndOfFile]; + [_handle seekToFileOffset:data.length]; + + if (data == nil || !data.bytes) { + return nil; + } + + NSString *allData = [NSString stringWithUTF8String:(const char *)[data bytes]]; + return [allData componentsSeparatedByString:@"\n"]; +} + +@end diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleUITests/AnalyticsExampleUITests.m b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleUITests/AnalyticsExampleUITests.m new file mode 100644 index 000000000..421b42c96 --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleUITests/AnalyticsExampleUITests.m @@ -0,0 +1,68 @@ +// +// Copyright (c) 2019 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +static NSTimeInterval const defaultTimeout = 10; + +@interface AnalyticsUITest : XCTestCase +@end + +@implementation AnalyticsUITest { + XCUIApplication *_app; +} + +- (void)setUp { + [super setUp]; + _app = [[XCUIApplication alloc] init]; + [_app launch]; +} + +- (void)testVerifyAppLaunched { + NSArray *tapArray = @[ @"A", @"B", @"C", @"D" ]; + + FIRWaitForVisible(_app.staticTexts[@"Pick Your Favorite Food!"]); + [[_app.pickerWheels firstMatch] adjustToPickerWheelValue:@"Pizza"]; + + // Tap on each tab + for (NSString *tap_label in tapArray) { + [_app.buttons[tap_label] tap]; + } + + // Share + [_app.buttons[@"Share"] tap]; + FIRWaitForVisible([_app.alerts firstMatch]); + XCTAssertTrue(_app.alerts[@"Share: D"].exists); +} + +static void FIRWaitForVisibleWithTimeout(XCUIElement *element, NSUInteger timeout) { + NSPredicate *visible = [NSPredicate predicateWithFormat:@"exists == true"]; + FIRWaitForPredicateWithTimeout(visible, element, timeout); +} + +static void FIRWaitForVisible(XCUIElement *element) { + FIRWaitForVisibleWithTimeout(element, defaultTimeout); +} + +static void FIRWaitForPredicateWithTimeout(NSPredicate *predicate, XCUIElement *element, + NSUInteger timeout) { + XCTestExpectation *expectation = + [[XCTNSPredicateExpectation alloc] initWithPredicate:predicate object:element]; + NSArray *expectationArray = @[ expectation ]; + (void)[XCTWaiter waitForExpectations:expectationArray timeout:timeout]; +} + +@end diff --git a/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleUITests/Info.plist b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleUITests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/AnalyticsExampleUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/inappmessaging/InAppMessagingExample/Assets.xcassets/Contents.json b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/Contents.json similarity index 100% rename from inappmessaging/InAppMessagingExample/Assets.xcassets/Contents.json rename to analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/Contents.json diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/favorite.imageset/Contents.json b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/favorite.imageset/Contents.json new file mode 100644 index 000000000..884f47ee2 --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/favorite.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "favorite.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "favorite_2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "favorite_3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/favorite.imageset/favorite.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/favorite.imageset/favorite.png new file mode 100644 index 000000000..1e218a2ef Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/favorite.imageset/favorite.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/favorite.imageset/favorite_2x.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/favorite.imageset/favorite_2x.png new file mode 100644 index 000000000..e0c2dc11b Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/favorite.imageset/favorite_2x.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/favorite.imageset/favorite_3x.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/favorite.imageset/favorite_3x.png new file mode 100644 index 000000000..5b7ad85f6 Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/favorite.imageset/favorite_3x.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/flash_on.imageset/Contents.json b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/flash_on.imageset/Contents.json new file mode 100644 index 000000000..f33be7358 --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/flash_on.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "flash_on.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "flash_on_2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "flash_on_3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/flash_on.imageset/flash_on.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/flash_on.imageset/flash_on.png new file mode 100644 index 000000000..296155f69 Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/flash_on.imageset/flash_on.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/flash_on.imageset/flash_on_2x.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/flash_on.imageset/flash_on_2x.png new file mode 100644 index 000000000..001245a80 Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/flash_on.imageset/flash_on_2x.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/flash_on.imageset/flash_on_3x.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/flash_on.imageset/flash_on_3x.png new file mode 100644 index 000000000..9fd808759 Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/flash_on.imageset/flash_on_3x.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-favorite.imageset/Contents.json b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-favorite.imageset/Contents.json new file mode 100644 index 000000000..7dd9947de --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-favorite.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon-favorite.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "icon-favorite_2x-1.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "icon-favorite_3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-favorite.imageset/icon-favorite.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-favorite.imageset/icon-favorite.png new file mode 100644 index 000000000..914ded97a Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-favorite.imageset/icon-favorite.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-favorite.imageset/icon-favorite_2x-1.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-favorite.imageset/icon-favorite_2x-1.png new file mode 100644 index 000000000..5ad2ce11f Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-favorite.imageset/icon-favorite_2x-1.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-favorite.imageset/icon-favorite_3x.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-favorite.imageset/icon-favorite_3x.png new file mode 100644 index 000000000..f89f87390 Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-favorite.imageset/icon-favorite_3x.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-flash_on.imageset/Contents.json b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-flash_on.imageset/Contents.json new file mode 100644 index 000000000..610bf3634 --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-flash_on.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon-flash_on.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "icon-flash_on_2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "icon-flash_on_3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-flash_on.imageset/icon-flash_on.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-flash_on.imageset/icon-flash_on.png new file mode 100644 index 000000000..407f4b93a Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-flash_on.imageset/icon-flash_on.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-flash_on.imageset/icon-flash_on_2x.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-flash_on.imageset/icon-flash_on_2x.png new file mode 100644 index 000000000..df0f2a1fa Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-flash_on.imageset/icon-flash_on_2x.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-flash_on.imageset/icon-flash_on_3x.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-flash_on.imageset/icon-flash_on_3x.png new file mode 100644 index 000000000..978d2afc7 Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-flash_on.imageset/icon-flash_on_3x.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-tag_faces.imageset/Contents.json b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-tag_faces.imageset/Contents.json new file mode 100644 index 000000000..6fe161ff3 --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-tag_faces.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon-tag_faces.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "icon-tag_faces_2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "icon-tag_faces_3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-tag_faces.imageset/icon-tag_faces.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-tag_faces.imageset/icon-tag_faces.png new file mode 100644 index 000000000..f89c7adee Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-tag_faces.imageset/icon-tag_faces.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-tag_faces.imageset/icon-tag_faces_2x.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-tag_faces.imageset/icon-tag_faces_2x.png new file mode 100644 index 000000000..25c5a36a0 Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-tag_faces.imageset/icon-tag_faces_2x.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-tag_faces.imageset/icon-tag_faces_3x.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-tag_faces.imageset/icon-tag_faces_3x.png new file mode 100644 index 000000000..ad9110471 Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-tag_faces.imageset/icon-tag_faces_3x.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-wb_incandescent.imageset/Contents.json b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-wb_incandescent.imageset/Contents.json new file mode 100644 index 000000000..4678d64da --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-wb_incandescent.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon-wb_incandescent.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "icon-wb_incandescent_2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "icon-wb_incandescent_3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-wb_incandescent.imageset/icon-wb_incandescent.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-wb_incandescent.imageset/icon-wb_incandescent.png new file mode 100644 index 000000000..900cf2b3b Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-wb_incandescent.imageset/icon-wb_incandescent.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-wb_incandescent.imageset/icon-wb_incandescent_2x.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-wb_incandescent.imageset/icon-wb_incandescent_2x.png new file mode 100644 index 000000000..82c7aa990 Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-wb_incandescent.imageset/icon-wb_incandescent_2x.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-wb_incandescent.imageset/icon-wb_incandescent_3x.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-wb_incandescent.imageset/icon-wb_incandescent_3x.png new file mode 100644 index 000000000..b9f7b1bef Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/icon-wb_incandescent.imageset/icon-wb_incandescent_3x.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/tag_faces.imageset/Contents.json b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/tag_faces.imageset/Contents.json new file mode 100644 index 000000000..5699db3df --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/tag_faces.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "tag_faces.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "tag_faces_2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "tag_faces_3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/tag_faces.imageset/tag_faces.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/tag_faces.imageset/tag_faces.png new file mode 100644 index 000000000..7c77eb0e4 Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/tag_faces.imageset/tag_faces.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/tag_faces.imageset/tag_faces_2x.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/tag_faces.imageset/tag_faces_2x.png new file mode 100644 index 000000000..4e6b1252c Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/tag_faces.imageset/tag_faces_2x.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/tag_faces.imageset/tag_faces_3x.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/tag_faces.imageset/tag_faces_3x.png new file mode 100644 index 000000000..cdc2978bf Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/tag_faces.imageset/tag_faces_3x.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/wb_incandescent.imageset/Contents.json b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/wb_incandescent.imageset/Contents.json new file mode 100644 index 000000000..16b6cd6bf --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/wb_incandescent.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "wb_incandescent.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "wb_incandescent_2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "wb_incandescent_3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/wb_incandescent.imageset/wb_incandescent.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/wb_incandescent.imageset/wb_incandescent.png new file mode 100644 index 000000000..a1c45ab14 Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/wb_incandescent.imageset/wb_incandescent.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/wb_incandescent.imageset/wb_incandescent_2x.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/wb_incandescent.imageset/wb_incandescent_2x.png new file mode 100644 index 000000000..183bee973 Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/wb_incandescent.imageset/wb_incandescent_2x.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/wb_incandescent.imageset/wb_incandescent_3x.png b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/wb_incandescent.imageset/wb_incandescent_3x.png new file mode 100644 index 000000000..210496e30 Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Images/AnalyticsImages.xcassets/wb_incandescent.imageset/wb_incandescent_3x.png differ diff --git a/analytics/LegacyAnalyticsQuickstart/Podfile b/analytics/LegacyAnalyticsQuickstart/Podfile new file mode 100644 index 000000000..d429f7f37 --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/Podfile @@ -0,0 +1,16 @@ +# AnalyticsExample + +use_frameworks! +platform :ios, '15.0' + +target 'AnalyticsExample' do + pod 'FirebaseAnalytics' + + target 'AnalyticsExampleTests' do + inherit! :search_paths + end +end + +target 'AnalyticsExampleSwift' do + pod 'FirebaseAnalytics' +end diff --git a/analytics/LegacyAnalyticsQuickstart/Podfile.lock b/analytics/LegacyAnalyticsQuickstart/Podfile.lock new file mode 100644 index 000000000..36b0b4788 --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/Podfile.lock @@ -0,0 +1,120 @@ +PODS: + - FirebaseAnalytics (12.6.0): + - FirebaseAnalytics/Default (= 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseAnalytics/Default (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleAppMeasurement/Default (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseCore (12.6.0): + - FirebaseCoreInternal (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreInternal (12.6.0): + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseInstallations (12.6.0): + - FirebaseCore (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - PromisesObjC (~> 2.4) + - GoogleAdsOnDeviceConversion (3.2.0): + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Core (12.6.0): + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Default (12.6.0): + - GoogleAdsOnDeviceConversion (~> 3.2.0) + - GoogleAppMeasurement/Core (= 12.6.0) + - GoogleAppMeasurement/IdentitySupport (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/IdentitySupport (12.6.0): + - GoogleAppMeasurement/Core (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleUtilities/AppDelegateSwizzler (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Privacy + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - GoogleUtilities/MethodSwizzler (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/Network (8.1.0): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Privacy + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (8.1.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/Reachability (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/UserDefaults (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - nanopb (3.30910.0): + - nanopb/decode (= 3.30910.0) + - nanopb/encode (= 3.30910.0) + - nanopb/decode (3.30910.0) + - nanopb/encode (3.30910.0) + - PromisesObjC (2.4.0) + +DEPENDENCIES: + - FirebaseAnalytics + +SPEC REPOS: + trunk: + - FirebaseAnalytics + - FirebaseCore + - FirebaseCoreInternal + - FirebaseInstallations + - GoogleAdsOnDeviceConversion + - GoogleAppMeasurement + - GoogleUtilities + - nanopb + - PromisesObjC + +SPEC CHECKSUMS: + FirebaseAnalytics: d0a97a0db6425e5a5d966340b87f92ca7b13a557 + FirebaseCore: 0e38ad5d62d980a47a64b8e9301ffa311457be04 + FirebaseCoreInternal: 69bf1306a05b8ac43004f6cc1f804bb7b05b229e + FirebaseInstallations: 631b38da2e11a83daa4bfb482f79d286a5dfa7ad + GoogleAdsOnDeviceConversion: d68c69dd9581a0f5da02617b6f377e5be483970f + GoogleAppMeasurement: 3bf40aff49a601af5da1c3345702fcb4991d35ee + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + +PODFILE CHECKSUM: 9092820812ba08f8312f6f0c9577dd8d312ea8b3 + +COCOAPODS: 1.16.2 diff --git a/analytics/LegacyAnalyticsQuickstart/README.md b/analytics/LegacyAnalyticsQuickstart/README.md new file mode 100644 index 000000000..82b77f2bf --- /dev/null +++ b/analytics/LegacyAnalyticsQuickstart/README.md @@ -0,0 +1,43 @@ +Google Analytics for Firebase Quickstart +=========================== + +Google Analytics for Firebase iOS Quickstart app demonstrates collecting app usage analytics via the +Analytics API. + +Introduction +------------ + +- [Read more about Google Analytics for Firebase](https://firebase.google.com/docs/analytics) + +Getting Started +--------------- + +- [Add Firebase to your iOS Project](https://firebase.google.com/docs/ios/setup). +- Run the sample on your iOS device or emulator. + +Note: You will need Swift 3.0 to run the Swift version of this quickstart. + +Support +------- + +- [Firebase Support](https://firebase.google.com/support/) + +License +------- + +Copyright 2015 Google, Inc. + +Licensed to the Apache Software Foundation (ASF) under one or more contributor +license agreements. See the NOTICE file distributed with this work for +additional information regarding copyright ownership. The ASF licenses this +file to you under the Apache License, Version 2.0 (the "License"); you may not +use this file except in compliance with the License. You may obtain a copy of +the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +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/analytics/LegacyAnalyticsQuickstart/Screenshot/analytics-sample.png b/analytics/LegacyAnalyticsQuickstart/Screenshot/analytics-sample.png new file mode 100644 index 000000000..c3af67900 Binary files /dev/null and b/analytics/LegacyAnalyticsQuickstart/Screenshot/analytics-sample.png differ diff --git a/analytics/Podfile b/analytics/Podfile new file mode 100644 index 000000000..704c43b98 --- /dev/null +++ b/analytics/Podfile @@ -0,0 +1,57 @@ +# Common pods +pod 'FirebaseAnalytics' + +target 'AnalyticsExample' do + platform :ios, '15.0' + + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + + target 'AnalyticsExampleTests' do + inherit! :search_paths + # Pods for testing + end + +end + +target 'AnalyticsExampleMac' do + platform :macos, '11.0' + + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + + target 'AnalyticsExampleMacTests' do + inherit! :search_paths + # Pods for testing + end +end + + +target 'AnalyticsExampleTV' do + platform :tvos, '15.0' + + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + + target 'AnalyticsExampleTVTests' do + inherit! :search_paths + # Pods for testing + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + if target.name == "Pods-AnalyticsExample" + puts "Updating #{target.name} to include GoogleAdsOnDeviceConversion for iPhone only" + target.build_configurations.each do |config| + xcconfig_path = config.base_configuration_reference.real_path + xcconfig = File.read(xcconfig_path) + xcconfig =~ /OTHER_LDFLAGS = (.+)/ + other_ld_flags = "#{$1}" + xcconfig.sub!('-framework "GoogleAdsOnDeviceConversion"', '') + new_xcconfig = xcconfig + "OTHER_LDFLAGS[sdk=iphone*] = #{other_ld_flags}" + File.open(xcconfig_path, "w") { |file| file << new_xcconfig } + end + end + end +end diff --git a/analytics/Podfile.lock b/analytics/Podfile.lock new file mode 100644 index 000000000..054e62dae --- /dev/null +++ b/analytics/Podfile.lock @@ -0,0 +1,120 @@ +PODS: + - FirebaseAnalytics (12.6.0): + - FirebaseAnalytics/Default (= 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseAnalytics/Default (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleAppMeasurement/Default (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseCore (12.6.0): + - FirebaseCoreInternal (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreInternal (12.6.0): + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseInstallations (12.6.0): + - FirebaseCore (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - PromisesObjC (~> 2.4) + - GoogleAdsOnDeviceConversion (3.2.0): + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Core (12.6.0): + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Default (12.6.0): + - GoogleAdsOnDeviceConversion (~> 3.2.0) + - GoogleAppMeasurement/Core (= 12.6.0) + - GoogleAppMeasurement/IdentitySupport (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/IdentitySupport (12.6.0): + - GoogleAppMeasurement/Core (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleUtilities/AppDelegateSwizzler (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Privacy + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - GoogleUtilities/MethodSwizzler (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/Network (8.1.0): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Privacy + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (8.1.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/Reachability (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/UserDefaults (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - nanopb (3.30910.0): + - nanopb/decode (= 3.30910.0) + - nanopb/encode (= 3.30910.0) + - nanopb/decode (3.30910.0) + - nanopb/encode (3.30910.0) + - PromisesObjC (2.4.0) + +DEPENDENCIES: + - FirebaseAnalytics + +SPEC REPOS: + trunk: + - FirebaseAnalytics + - FirebaseCore + - FirebaseCoreInternal + - FirebaseInstallations + - GoogleAdsOnDeviceConversion + - GoogleAppMeasurement + - GoogleUtilities + - nanopb + - PromisesObjC + +SPEC CHECKSUMS: + FirebaseAnalytics: d0a97a0db6425e5a5d966340b87f92ca7b13a557 + FirebaseCore: 0e38ad5d62d980a47a64b8e9301ffa311457be04 + FirebaseCoreInternal: 69bf1306a05b8ac43004f6cc1f804bb7b05b229e + FirebaseInstallations: 631b38da2e11a83daa4bfb482f79d286a5dfa7ad + GoogleAdsOnDeviceConversion: d68c69dd9581a0f5da02617b6f377e5be483970f + GoogleAppMeasurement: 3bf40aff49a601af5da1c3345702fcb4991d35ee + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + +PODFILE CHECKSUM: 6097b0ced448df423a1a885a6de5c1c6b63e4559 + +COCOAPODS: 1.16.2 diff --git a/analytics/README.md b/analytics/README.md index 882c54c39..d1a8ee820 100644 --- a/analytics/README.md +++ b/analytics/README.md @@ -5,7 +5,12 @@ Analytics can provide insight on app usage and user engagement. You can read mor about Google Analytics for Firebase [here](https://firebase.google.com/docs/analytics)! The iOS, iPadOS, and Catalyst versions are powered by UIKit. The tvOS and macOS -versions are powered by SwiftUI. +versions are powered by SwiftUI. Note that Catalyst, macOS, and tvOS support for Google +Analytics for Firebase are in beta as of version 8.9.0. + +To view the older Objective-C and Swift quickstarts, view the +[`LegacyAnalyticsQuickstart`](https://github.com/firebase/quickstart-ios/blob/main/analytics/LegacyAnalyticsQuickstart) +directory. ## Getting Started diff --git a/appdistribution/AppDistributionExample.xcodeproj/project.pbxproj b/appdistribution/AppDistributionExample.xcodeproj/project.pbxproj index cbf24951d..d89c720a8 100644 --- a/appdistribution/AppDistributionExample.xcodeproj/project.pbxproj +++ b/appdistribution/AppDistributionExample.xcodeproj/project.pbxproj @@ -3,15 +3,13 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 51; objects = { /* Begin PBXBuildFile section */ 1E5FA399E68EEC6A1CC9D4F9 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 7B7A16FC609E3AE1BA2F8E93 /* GoogleService-Info.plist */; }; 4C5B56DE60EC55CE980B3E35 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 7B7A16FC609E3AE1BA2F8E93 /* GoogleService-Info.plist */; }; 64A8AA8B04202E42604E1B50 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 7B7A16FC609E3AE1BA2F8E93 /* GoogleService-Info.plist */; }; - 8D7951E32D3B02BA000FD694 /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 8D7951E22D3B02BA000FD694 /* FirebaseAnalytics */; }; - 8D7951E52D3B02BA000FD694 /* FirebaseAppDistribution-Beta in Frameworks */ = {isa = PBXBuildFile; productRef = 8D7951E42D3B02BA000FD694 /* FirebaseAppDistribution-Beta */; }; EA5C0BC624C5D2060010FDF6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5C0BC524C5D2060010FDF6 /* AppDelegate.swift */; }; EA5C0BC824C5D2060010FDF6 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5C0BC724C5D2060010FDF6 /* SceneDelegate.swift */; }; EA5C0BCA24C5D2060010FDF6 /* AppDistributionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5C0BC924C5D2060010FDF6 /* AppDistributionViewController.swift */; }; @@ -60,8 +58,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8D7951E32D3B02BA000FD694 /* FirebaseAnalytics in Frameworks */, - 8D7951E52D3B02BA000FD694 /* FirebaseAppDistribution-Beta in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -82,11 +78,11 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 8D7951E12D3B02BA000FD694 /* Frameworks */ = { + 2B283AC81B12C877411DB212 /* Pods */ = { isa = PBXGroup; children = ( ); - name = Frameworks; + path = Pods; sourceTree = ""; }; EA5C0BB924C5D2060010FDF6 = { @@ -96,8 +92,8 @@ EA5C0BDB24C5D2070010FDF6 /* AppDistributionTests */, EA5C0BE624C5D2070010FDF6 /* AppDistributionUITests */, EA5C0BC324C5D2060010FDF6 /* Products */, + 2B283AC81B12C877411DB212 /* Pods */, 7B7A16FC609E3AE1BA2F8E93 /* GoogleService-Info.plist */, - 8D7951E12D3B02BA000FD694 /* Frameworks */, ); sourceTree = ""; }; @@ -229,9 +225,6 @@ Base, ); mainGroup = EA5C0BB924C5D2060010FDF6; - packageReferences = ( - 8D7951E02D3B0248000FD694 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, - ); productRefGroup = EA5C0BC324C5D2060010FDF6 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -606,30 +599,6 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ - -/* Begin XCRemoteSwiftPackageReference section */ - 8D7951E02D3B0248000FD694 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/firebase/firebase-ios-sdk"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 11.7.0; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 8D7951E22D3B02BA000FD694 /* FirebaseAnalytics */ = { - isa = XCSwiftPackageProductDependency; - package = 8D7951E02D3B0248000FD694 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = FirebaseAnalytics; - }; - 8D7951E42D3B02BA000FD694 /* FirebaseAppDistribution-Beta */ = { - isa = XCSwiftPackageProductDependency; - package = 8D7951E02D3B0248000FD694 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = "FirebaseAppDistribution-Beta"; - }; -/* End XCSwiftPackageProductDependency section */ }; rootObject = EA5C0BBA24C5D2060010FDF6 /* Project object */; } diff --git a/appdistribution/Podfile b/appdistribution/Podfile new file mode 100644 index 000000000..0347f4e07 --- /dev/null +++ b/appdistribution/Podfile @@ -0,0 +1,21 @@ +# Uncomment the next line to define a global platform for your project + platform :ios, '15.0' + +target 'AppDistributionExample' do + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + + # Pods for AppDistributionExample + pod 'FirebaseAnalytics' + pod 'FirebaseAppDistribution', "> 8.11-beta" + + target 'AppDistributionExampleTests' do + inherit! :search_paths + # Pods for testing + end + + target 'AppDistributionExampleUITests' do + # Pods for testing + end + +end diff --git a/appdistribution/Podfile.lock b/appdistribution/Podfile.lock new file mode 100644 index 000000000..f7010a2fe --- /dev/null +++ b/appdistribution/Podfile.lock @@ -0,0 +1,128 @@ +PODS: + - FirebaseAnalytics (12.6.0): + - FirebaseAnalytics/Default (= 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseAnalytics/Default (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleAppMeasurement/Default (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseAppDistribution (12.6.0-beta): + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - FirebaseCore (12.6.0): + - FirebaseCoreInternal (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreInternal (12.6.0): + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseInstallations (12.6.0): + - FirebaseCore (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - PromisesObjC (~> 2.4) + - GoogleAdsOnDeviceConversion (3.2.0): + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Core (12.6.0): + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Default (12.6.0): + - GoogleAdsOnDeviceConversion (~> 3.2.0) + - GoogleAppMeasurement/Core (= 12.6.0) + - GoogleAppMeasurement/IdentitySupport (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/IdentitySupport (12.6.0): + - GoogleAppMeasurement/Core (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleUtilities/AppDelegateSwizzler (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Privacy + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - GoogleUtilities/MethodSwizzler (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/Network (8.1.0): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Privacy + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (8.1.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/Reachability (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/UserDefaults (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - nanopb (3.30910.0): + - nanopb/decode (= 3.30910.0) + - nanopb/encode (= 3.30910.0) + - nanopb/decode (3.30910.0) + - nanopb/encode (3.30910.0) + - PromisesObjC (2.4.0) + +DEPENDENCIES: + - FirebaseAnalytics + - FirebaseAppDistribution (> 8.11-beta) + +SPEC REPOS: + trunk: + - FirebaseAnalytics + - FirebaseAppDistribution + - FirebaseCore + - FirebaseCoreInternal + - FirebaseInstallations + - GoogleAdsOnDeviceConversion + - GoogleAppMeasurement + - GoogleUtilities + - nanopb + - PromisesObjC + +SPEC CHECKSUMS: + FirebaseAnalytics: d0a97a0db6425e5a5d966340b87f92ca7b13a557 + FirebaseAppDistribution: d5c3be8ef1008b08921abcc511bdfa3560e9b1eb + FirebaseCore: 0e38ad5d62d980a47a64b8e9301ffa311457be04 + FirebaseCoreInternal: 69bf1306a05b8ac43004f6cc1f804bb7b05b229e + FirebaseInstallations: 631b38da2e11a83daa4bfb482f79d286a5dfa7ad + GoogleAdsOnDeviceConversion: d68c69dd9581a0f5da02617b6f377e5be483970f + GoogleAppMeasurement: 3bf40aff49a601af5da1c3345702fcb4991d35ee + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + +PODFILE CHECKSUM: 4d5d808ee055d454499eb2db56646a731a1474d8 + +COCOAPODS: 1.16.2 diff --git a/authentication/AuthenticationExample.xcodeproj/project.pbxproj b/authentication/AuthenticationExample.xcodeproj/project.pbxproj index 06d89c491..6dc1c7b57 100644 --- a/authentication/AuthenticationExample.xcodeproj/project.pbxproj +++ b/authentication/AuthenticationExample.xcodeproj/project.pbxproj @@ -3,14 +3,11 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 50; objects = { /* Begin PBXBuildFile section */ 8848765129D314A400780FA6 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 8848764F29D3149200780FA6 /* GoogleService-Info.plist */; }; - 8D00BB692D3B068100F6F6DD /* FacebookLogin in Frameworks */ = {isa = PBXBuildFile; productRef = 8D00BB682D3B068100F6F6DD /* FacebookLogin */; }; - 8D7951EB2D3B039D000FD694 /* FirebaseAuth in Frameworks */ = {isa = PBXBuildFile; productRef = 8D7951EA2D3B039D000FD694 /* FirebaseAuth */; }; - 8D7951EF2D3B03BA000FD694 /* GoogleSignIn in Frameworks */ = {isa = PBXBuildFile; productRef = 8D7951EE2D3B03BA000FD694 /* GoogleSignIn */; }; EA02F68524A000E00079D000 /* UserActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA02F68424A000E00079D000 /* UserActions.swift */; }; EA02F68D24A063E90079D000 /* LoginDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA02F68C24A063E90079D000 /* LoginDelegate.swift */; }; EA062D5D24A0FEB6006714D3 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = EA062D5C24A0FEB6006714D3 /* README.md */; }; @@ -100,9 +97,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8D7951EB2D3B039D000FD694 /* FirebaseAuth in Frameworks */, - 8D7951EF2D3B03BA000FD694 /* GoogleSignIn in Frameworks */, - 8D00BB692D3B068100F6F6DD /* FacebookLogin in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -123,11 +117,11 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 8D7951E92D3B039D000FD694 /* Frameworks */ = { + CE54897B57069002714B8FA5 /* Pods */ = { isa = PBXGroup; children = ( ); - name = Frameworks; + path = Pods; sourceTree = ""; }; EA02F68E24A0714B0079D000 /* OtherAuthMethodControllers */ = { @@ -208,8 +202,8 @@ EAE4CBC324855E3A00245E92 /* AuthenticationExample */, EAE4CBDA24855E3E00245E92 /* AuthenticationExampleTests */, EAE4CBE524855E3E00245E92 /* AuthenticationExampleUITests */, - 8D7951E92D3B039D000FD694 /* Frameworks */, EAE4CBC224855E3A00245E92 /* Products */, + CE54897B57069002714B8FA5 /* Pods */, ); sourceTree = ""; }; @@ -322,9 +316,8 @@ EAE4CBB924855E3A00245E92 /* Project object */ = { isa = PBXProject; attributes = { - BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 1130; - LastUpgradeCheck = 1610; + LastUpgradeCheck = 1130; ORGANIZATIONNAME = Firebase; TargetAttributes = { EAE4CBC024855E3A00245E92 = { @@ -349,11 +342,6 @@ Base, ); mainGroup = EAE4CBB824855E3A00245E92; - packageReferences = ( - 8D7951E62D3B034C000FD694 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, - 8D7951E72D3B037B000FD694 /* XCRemoteSwiftPackageReference "GoogleSignIn-iOS" */, - 8D00BB672D3B067500F6F6DD /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */, - ); productRefGroup = EAE4CBC224855E3A00245E92 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -481,7 +469,6 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -492,7 +479,6 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -514,7 +500,6 @@ SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 6.0; }; name = Debug; }; @@ -544,7 +529,6 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -555,7 +539,6 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -570,7 +553,6 @@ SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; - SWIFT_VERSION = 6.0; VALIDATE_PRODUCT = YES; }; name = Release; @@ -593,7 +575,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.AuthenticationExample; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 6.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; }; name = Debug; @@ -616,7 +598,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.AuthenticationExample; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 6.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; }; name = Release; @@ -624,6 +606,7 @@ EAE4CBEF24855E3E00245E92 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; BUNDLE_LOADER = "$(TEST_HOST)"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; @@ -637,7 +620,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.google.AuthenticationExampleTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 6.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AuthenticationExample.app/AuthenticationExample"; }; @@ -646,6 +629,7 @@ EAE4CBF024855E3E00245E92 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; BUNDLE_LOADER = "$(TEST_HOST)"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; @@ -659,7 +643,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.google.AuthenticationExampleTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 6.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AuthenticationExample.app/AuthenticationExample"; }; @@ -668,6 +652,7 @@ EAE4CBF224855E3E00245E92 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = AuthenticationExampleUITests/Info.plist; @@ -679,7 +664,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.google.AuthenticationExampleUITests; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; - SWIFT_VERSION = 6.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; TEST_TARGET_NAME = AuthenticationExample; }; @@ -688,6 +673,7 @@ EAE4CBF324855E3E00245E92 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = AuthenticationExampleUITests/Info.plist; @@ -699,7 +685,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.google.AuthenticationExampleUITests; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; - SWIFT_VERSION = 6.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; TEST_TARGET_NAME = AuthenticationExample; }; @@ -745,51 +731,6 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ - -/* Begin XCRemoteSwiftPackageReference section */ - 8D00BB672D3B067500F6F6DD /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/facebook/facebook-ios-sdk.git"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 18.0.0; - }; - }; - 8D7951E62D3B034C000FD694 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/firebase/firebase-ios-sdk"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 11.7.0; - }; - }; - 8D7951E72D3B037B000FD694 /* XCRemoteSwiftPackageReference "GoogleSignIn-iOS" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/google/GoogleSignIn-iOS.git"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 8.0.0; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 8D00BB682D3B068100F6F6DD /* FacebookLogin */ = { - isa = XCSwiftPackageProductDependency; - package = 8D00BB672D3B067500F6F6DD /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */; - productName = FacebookLogin; - }; - 8D7951EA2D3B039D000FD694 /* FirebaseAuth */ = { - isa = XCSwiftPackageProductDependency; - package = 8D7951E62D3B034C000FD694 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = FirebaseAuth; - }; - 8D7951EE2D3B03BA000FD694 /* GoogleSignIn */ = { - isa = XCSwiftPackageProductDependency; - package = 8D7951E72D3B037B000FD694 /* XCRemoteSwiftPackageReference "GoogleSignIn-iOS" */; - productName = GoogleSignIn; - }; -/* End XCSwiftPackageProductDependency section */ }; rootObject = EAE4CBB924855E3A00245E92 /* Project object */; } diff --git a/authentication/AuthenticationExample.xcodeproj/xcshareddata/xcschemes/AuthenticationExample.xcscheme b/authentication/AuthenticationExample.xcodeproj/xcshareddata/xcschemes/AuthenticationExample.xcscheme index 85b30cbf4..139506a15 100644 --- a/authentication/AuthenticationExample.xcodeproj/xcshareddata/xcschemes/AuthenticationExample.xcscheme +++ b/authentication/AuthenticationExample.xcodeproj/xcshareddata/xcschemes/AuthenticationExample.xcscheme @@ -1,6 +1,6 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExample.xcodeproj/xcshareddata/xcschemes/AuthenticationExampleSwift.xcscheme b/authentication/LegacyAuthQuickstart/AuthenticationExample.xcodeproj/xcshareddata/xcschemes/AuthenticationExampleSwift.xcscheme new file mode 100644 index 000000000..b592ace31 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExample.xcodeproj/xcshareddata/xcschemes/AuthenticationExampleSwift.xcscheme @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExample/.clang-format b/authentication/LegacyAuthQuickstart/AuthenticationExample/.clang-format new file mode 100644 index 000000000..1f09ce0f2 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExample/.clang-format @@ -0,0 +1,4 @@ +BasedOnStyle: Google +ColumnLimit: 100 +BinPackParameters: false +AllowAllParametersOfDeclarationOnNextLine: true diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExample/AppDelegate.h b/authentication/LegacyAuthQuickstart/AuthenticationExample/AppDelegate.h new file mode 100644 index 000000000..00665f375 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExample/AppDelegate.h @@ -0,0 +1,27 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import UIKit; + +@import GoogleSignIn; + +// [START signin_delegate] +@interface AppDelegate : UIResponder +// [END signin_delegate] + +@property(nonatomic, strong) UIWindow *window; + +@end diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExample/AppDelegate.m b/authentication/LegacyAuthQuickstart/AuthenticationExample/AppDelegate.m new file mode 100644 index 000000000..599a79ed2 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExample/AppDelegate.m @@ -0,0 +1,97 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "AppDelegate.h" +#import "MainViewController.h" +#import "UIViewController+Alerts.h" +// [START auth_import] +@import FirebaseCore; +// [END auth_import] + +// [START google_import] +@import GoogleSignIn; +// [END google_import] +@import FBSDKCoreKit; + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // [START firebase_configure] + // Use Firebase library to configure APIs + [FIRApp configure]; + // [END firebase_configure] + + [[FBSDKApplicationDelegate sharedInstance] application:application + didFinishLaunchingWithOptions:launchOptions]; + return YES; +} + +// [START new_delegate] +- (BOOL)application:(nonnull UIApplication *)application + openURL:(nonnull NSURL *)url + options:(nonnull NSDictionary *)options { + // [END new_delegate] + return [self application:application + openURL:url + // [START new_options] + sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] + annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]; +} +// [END new_options] + +// [START old_delegate] +- (BOOL)application:(UIApplication *)application + openURL:(NSURL *)url + sourceApplication:(NSString *)sourceApplication + annotation:(id)annotation { + // [END old_delegate] + if ([self handlePasswordlessSignInWithLink:url]) { + return YES; + } + if ([[GIDSignIn sharedInstance] handleURL:url]) { + return YES; + } + return [[FBSDKApplicationDelegate sharedInstance] application:application + openURL:url + // [START old_options] + sourceApplication:sourceApplication + annotation:annotation]; +} +// [END old_options] + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 120000 +- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray> * _Nullable))restorationHandler { +#else +- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void(^)(NSArray * __nullable restorableObjects))restorationHandler { +#endif + return [self handlePasswordlessSignInWithLink:userActivity.webpageURL]; +} + +- (BOOL)handlePasswordlessSignInWithLink:(nonnull NSURL*)url { + NSString *link = url.absoluteString; + // [START is_signin_link] + if ([[FIRAuth auth] isSignInWithEmailLink:link]) { + // [END is_signin_link] + [NSUserDefaults.standardUserDefaults setObject:link forKey:@"Link"]; + [(UINavigationController*)_window.rootViewController popToRootViewControllerAnimated:NO]; + [_window.rootViewController.childViewControllers[0] performSegueWithIdentifier:@"passwordless" sender:nil]; + return YES; + } + return NO; +} + +@end diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExample/AuthenticationExample.entitlements b/authentication/LegacyAuthQuickstart/AuthenticationExample/AuthenticationExample.entitlements new file mode 100644 index 000000000..f2ab301e3 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExample/AuthenticationExample.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.developer.applesignin + + Default + + com.apple.developer.associated-domains + + applinks:sen9z.app.goo.gl + + + diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExample/Base.lproj/Main.storyboard b/authentication/LegacyAuthQuickstart/AuthenticationExample/Base.lproj/Main.storyboard new file mode 100644 index 000000000..df3954471 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExample/Base.lproj/Main.storyboard @@ -0,0 +1,588 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Please enter your custom token here, which is signed using the private key from a service account downloaded from the Google Developer Console + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExample/CustomTokenViewController.h b/authentication/LegacyAuthQuickstart/AuthenticationExample/CustomTokenViewController.h new file mode 100644 index 000000000..a787bbbae --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExample/CustomTokenViewController.h @@ -0,0 +1,20 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import UIKit; + +@interface CustomTokenViewController : UIViewController +@end \ No newline at end of file diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExample/CustomTokenViewController.m b/authentication/LegacyAuthQuickstart/AuthenticationExample/CustomTokenViewController.m new file mode 100644 index 000000000..268b75570 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExample/CustomTokenViewController.m @@ -0,0 +1,54 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "CustomTokenViewController.h" +#import "UIViewController+Alerts.h" + +// [START auth_view_import] +@import FirebaseAuth; +// [END auth_view_import] + +@interface CustomTokenViewController () +@property(weak, nonatomic) IBOutlet UITextView *tokenField; +@end +@implementation CustomTokenViewController + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + [self.view endEditing:YES]; +} + +- (IBAction)didTapCustomTokenLogin:(id)sender { + NSString *customToken = _tokenField.text; + [self showSpinner:^{ + // [START signinwithcustomtoken] + [[FIRAuth auth] signInWithCustomToken:customToken + completion:^(FIRAuthDataResult * _Nullable authResult, + NSError * _Nullable error) { + // [START_EXCLUDE] + [self hideSpinner:^{ + if (error) { + [self showMessagePrompt:error.localizedDescription]; + return; + } + [self.navigationController popViewControllerAnimated:YES]; + }]; + // [END_EXCLUDE] + }]; + // [END signinwithcustomtoken] + }]; +} + +@end diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExample/EmailViewController.h b/authentication/LegacyAuthQuickstart/AuthenticationExample/EmailViewController.h new file mode 100644 index 000000000..da4c22d4d --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExample/EmailViewController.h @@ -0,0 +1,21 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +@interface EmailViewController : UIViewController + +@end diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExample/EmailViewController.m b/authentication/LegacyAuthQuickstart/AuthenticationExample/EmailViewController.m new file mode 100644 index 000000000..4d7001441 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExample/EmailViewController.m @@ -0,0 +1,191 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "EmailViewController.h" +#import "UIViewController+Alerts.h" + +@import FirebaseAuth; + +@interface EmailViewController () +@property(weak, nonatomic) IBOutlet UITextField *emailField; +@property(weak, nonatomic) IBOutlet UITextField *passwordField; +@end + +@implementation EmailViewController + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + [self.view endEditing:YES]; +} + +- (IBAction)didTapEmailLogin:(id)sender { + [self showSpinner:^{ + // [START headless_email_auth] + [[FIRAuth auth] signInWithEmail:self->_emailField.text + password:self->_passwordField.text + completion:^(FIRAuthDataResult * _Nullable authResult, + NSError * _Nullable error) { + // [START_EXCLUDE] + [self hideSpinner:^{ + if (error && error.code == FIRAuthErrorCodeSecondFactorRequired) { + FIRMultiFactorResolver *resolver = error.userInfo[FIRAuthErrorUserInfoMultiFactorResolverKey]; + NSMutableString *displayNameString = [NSMutableString string]; + for (FIRMultiFactorInfo *tmpFactorInfo in resolver.hints) { + [displayNameString appendString:tmpFactorInfo.displayName]; + [displayNameString appendString:@" "]; + } + [self showTextInputPromptWithMessage:[NSString stringWithFormat:@"Select factor to sign in\n%@", displayNameString] + completionBlock:^(BOOL userPressedOK, NSString *_Nullable displayName) { + FIRPhoneMultiFactorInfo* selectedHint; + for (FIRMultiFactorInfo *tmpFactorInfo in resolver.hints) { + if ([displayName isEqualToString:tmpFactorInfo.displayName]) { + selectedHint = (FIRPhoneMultiFactorInfo *)tmpFactorInfo; + } + } + [FIRPhoneAuthProvider.provider + verifyPhoneNumberWithMultiFactorInfo:selectedHint + UIDelegate:nil + multiFactorSession:resolver.session + completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) { + if (error) { + NSLog(@"Multi factor start sign in failed. Error: %@", error.description); + } else { + [self showTextInputPromptWithMessage:[NSString stringWithFormat:@"Verification code for %@", selectedHint.displayName] + completionBlock:^(BOOL userPressedOK, NSString *_Nullable verificationCode) { + FIRPhoneAuthCredential *credential = + [[FIRPhoneAuthProvider provider] credentialWithVerificationID:verificationID + verificationCode:verificationCode]; + FIRMultiFactorAssertion *assertion = [FIRPhoneMultiFactorGenerator assertionWithCredential:credential]; + [resolver resolveSignInWithAssertion:assertion completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { + if (error) { + NSLog(@"Multi factor finanlize sign in failed. Error: %@", error.description); + } else { + [self.navigationController popViewControllerAnimated:YES]; + } + }]; + }]; + } + }]; + }]; + } else if (error) { + [self showMessagePrompt:error.localizedDescription]; + return; + } + [self.navigationController popViewControllerAnimated:YES]; + }]; + // [END_EXCLUDE] + }]; + // [END headless_email_auth] + }]; +} + +/** @fn requestPasswordReset + @brief Requests a "password reset" email be sent. + */ +- (IBAction)didRequestPasswordReset:(id)sender { + [self showTextInputPromptWithMessage:@"Email:" + completionBlock:^(BOOL userPressedOK, NSString *_Nullable userInput) { + if (!userPressedOK || !userInput.length) { + return; + } + + [self showSpinner:^{ + // [START password_reset] + [[FIRAuth auth] sendPasswordResetWithEmail:userInput completion:^(NSError *_Nullable error) { + // [START_EXCLUDE] + [self hideSpinner:^{ + if (error) { + [self showMessagePrompt:error.localizedDescription]; + return; + } + + [self showMessagePrompt:@"Sent"]; + }]; + // [END_EXCLUDE] + }]; + // [END password_reset] + }]; + }]; +} + +/** @fn getProvidersForEmail + @brief Prompts the user for an email address, calls @c FIRAuth.getProvidersForEmail:callback: + and displays the result. + */ +- (IBAction)didGetProvidersForEmail:(id)sender { + [self showTextInputPromptWithMessage:@"Email:" + completionBlock:^(BOOL userPressedOK, NSString *_Nullable userInput) { + if (!userPressedOK || !userInput.length) { + return; + } + + [self showSpinner:^{ + // [START get_methods] + [[FIRAuth auth] fetchSignInMethodsForEmail:userInput + completion:^(NSArray *_Nullable providers, + NSError *_Nullable error) { + // [START_EXCLUDE] + [self hideSpinner:^{ + if (error) { + [self showMessagePrompt:error.localizedDescription]; + return; + } + + [self showMessagePrompt:[providers componentsJoinedByString:@", "]]; + }]; + // [END_EXCLUDE] + }]; + // [END get_methods] + }]; + }]; +} + +- (IBAction)didCreateAccount:(id)sender { + [self showTextInputPromptWithMessage:@"Email:" + completionBlock:^(BOOL userPressedOK, NSString *_Nullable email) { + if (!userPressedOK || !email.length) { + return; + } + + [self showTextInputPromptWithMessage:@"Password:" + completionBlock:^(BOOL userPressedOK, NSString *_Nullable password) { + if (!userPressedOK || !password.length) { + return; + } + + [self showSpinner:^{ + // [START create_user] + [[FIRAuth auth] createUserWithEmail:email + password:password + completion:^(FIRAuthDataResult * _Nullable authResult, + NSError * _Nullable error) { + // [START_EXCLUDE] + [self hideSpinner:^{ + if (error) { + [self showMessagePrompt: error.localizedDescription]; + return; + } + NSLog(@"%@ created", authResult.user.email); + [self.navigationController popViewControllerAnimated:YES]; + }]; + // [END_EXCLUDE] + }]; + // [END create_user] + }]; + }]; + }]; +} + +@end diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExample/Info.plist b/authentication/LegacyAuthQuickstart/AuthenticationExample/Info.plist new file mode 100644 index 000000000..ac8f75903 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExample/Info.plist @@ -0,0 +1,107 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIcons + + CFBundleIcons~ipad + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + Client + CFBundleURLSchemes + + REVERSED_CLIENT_ID + + + + CFBundleVersion + 1 + FacebookAppID + Placeholder + FacebookDisplayName + Dev + LSApplicationQueriesSchemes + + fbapi + fbauth2 + + LSRequiresIPhoneOS + + NSAppTransportSecurity + + NSExceptionDomains + + akamaihd.net + + NSIncludesSubdomains + + NSThirdPartyExceptionRequiresForwardSecrecy + + + facebook.com + + NSIncludesSubdomains + + NSThirdPartyExceptionRequiresForwardSecrecy + + + fbcdn.net + + NSIncludesSubdomains + + NSThirdPartyExceptionRequiresForwardSecrecy + + + twimg.com + + NSIncludesSubdomains + + NSTemporaryExceptionAllowsInsecureHTTPLoads + + + + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExample/MainViewController.h b/authentication/LegacyAuthQuickstart/AuthenticationExample/MainViewController.h new file mode 100644 index 000000000..d9d82f4bf --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExample/MainViewController.h @@ -0,0 +1,26 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +@import GoogleSignIn; +@import FirebaseAuth; + +// [START signin_controller] +@interface MainViewController : UITableViewController +// [END signin_controller] +- (void)firebaseLoginWithCredential:(FIRAuthCredential *)credential; +@end diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExample/MainViewController.m b/authentication/LegacyAuthQuickstart/AuthenticationExample/MainViewController.m new file mode 100644 index 000000000..b3220651a --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExample/MainViewController.m @@ -0,0 +1,1197 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "MainViewController.h" +#import "UIViewController+Alerts.h" + +#import +#import + +@import AuthenticationServices; +@import FBSDKCoreKit; +@import FBSDKLoginKit; +@import FirebaseCore; +@import FirebaseAnalytics; + +static const int kSectionMultiFactor = 4; +static const int kSectionToken = 3; +static const int kSectionProviders = 2; +static const int kSectionUser = 1; +static const int kSectionSignIn = 0; + +typedef enum : NSUInteger { + AuthEmail, + AuthAnonymous, + AuthApple, + AuthFacebook, + AuthGoogle, + AuthTwitter, + AuthGitHub, + AuthCustom, + AuthPhone, + AuthPasswordless, + AuthGameCenter, + AuthMicrosoft, + AuthEmailMFA, +} AuthProvider; + +/*! @var kOKButtonText + @brief The text of the "OK" button for the Sign In result dialogs. + */ +static NSString *const kOKButtonText = @"OK"; + +/*! @var kTokenRefreshedAlertTitle + @brief The title of the "Token Refreshed" alert. + */ +static NSString *const kTokenRefreshedAlertTitle = @"Token"; + +/*! @var kTokenRefreshErrorAlertTitle + @brief The title of the "Token Refresh error" alert. + */ +static NSString *const kTokenRefreshErrorAlertTitle = @"Get Token Error"; + +/** @var kSetDisplayNameTitle + @brief The title of the "Set Display Name" error dialog. + */ +static NSString *const kSetDisplayNameTitle = @"Set Display Name"; + +/** @var kUnlinkTitle + @brief The text of the "Unlink from Provider" error Dialog. + */ +static NSString *const kUnlinkTitle = @"Unlink from Provider"; + +/** @var kChangeEmailText + @brief The title of the "Change Email" button. + */ +static NSString *const kChangeEmailText = @"Change Email"; + +/** @var kChangePasswordText + @brief The title of the "Change Password" button. + */ +static NSString *const kChangePasswordText = @"Change Password"; + +/** @var kUpdatePhoneNumberText + @brief The title of the "Update Phone Number" button. + */ +static NSString *const kUpdatePhoneNumberText = @"Update Phone Number"; + +static BOOL isMFAEnabled = NO; + +@interface MainViewController () +@property(strong, nonatomic) FIRAuthStateDidChangeListenerHandle handle; +@property(strong, nonatomic) FIROAuthProvider *microsoftProvider; +@property(strong, nonatomic) FIROAuthProvider *twitterProvider; +@property(strong, nonatomic) FIROAuthProvider *gitHubProvider; +@end + +@interface MainViewController (SignInWithApple) + +@property(nonatomic, readwrite, nullable) NSString *currentNonce; + +- (void)startSignInWithAppleFlow API_AVAILABLE(ios(13.0)); + +- (void)startSignInWithGoogleFlow; + +@end + +@implementation MainViewController { + NSString *_currentNonce; +} + +- (void)firebaseLoginWithCredential:(FIRAuthCredential *)credential { + [self showSpinner:^{ + if ([FIRAuth auth].currentUser) { + // [START link_credential] + [[FIRAuth auth].currentUser linkWithCredential:credential + completion:^(FIRAuthDataResult *result, NSError *_Nullable error) { + // [START_EXCLUDE] + [self hideSpinner:^{ + if (error) { + [self showMessagePrompt:error.localizedDescription]; + return; + } + [self.tableView reloadData]; + }]; + // [END_EXCLUDE] + }]; + // [END link_credential] + } else { + // [START signin_credential] + [[FIRAuth auth] signInWithCredential:credential + completion:^(FIRAuthDataResult * _Nullable authResult, + NSError * _Nullable error) { + // [START_EXCLUDE silent] + [self hideSpinner:^{ + // [END_EXCLUDE] + if (isMFAEnabled && error && error.code == FIRAuthErrorCodeSecondFactorRequired) { + FIRMultiFactorResolver *resolver = error.userInfo[FIRAuthErrorUserInfoMultiFactorResolverKey]; + NSMutableString *displayNameString = [NSMutableString string]; + for (FIRMultiFactorInfo *tmpFactorInfo in resolver.hints) { + [displayNameString appendString:tmpFactorInfo.displayName]; + [displayNameString appendString:@" "]; + } + [self showTextInputPromptWithMessage:[NSString stringWithFormat:@"Select factor to sign in\n%@", displayNameString] + completionBlock:^(BOOL userPressedOK, NSString *_Nullable displayName) { + FIRPhoneMultiFactorInfo* selectedHint; + for (FIRMultiFactorInfo *tmpFactorInfo in resolver.hints) { + if ([displayName isEqualToString:tmpFactorInfo.displayName]) { + selectedHint = (FIRPhoneMultiFactorInfo *)tmpFactorInfo; + } + } + [FIRPhoneAuthProvider.provider + verifyPhoneNumberWithMultiFactorInfo:selectedHint + UIDelegate:nil + multiFactorSession:resolver.session + completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) { + if (error) { + [self showMessagePrompt:error.localizedDescription]; + } else { + [self showTextInputPromptWithMessage:[NSString stringWithFormat:@"Verification code for %@", selectedHint.displayName] + completionBlock:^(BOOL userPressedOK, NSString *_Nullable verificationCode) { + FIRPhoneAuthCredential *credential = + [[FIRPhoneAuthProvider provider] credentialWithVerificationID:verificationID + verificationCode:verificationCode]; + FIRMultiFactorAssertion *assertion = [FIRPhoneMultiFactorGenerator assertionWithCredential:credential]; + [resolver resolveSignInWithAssertion:assertion completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { + if (error) { + [self showMessagePrompt:error.localizedDescription]; + } else { + NSLog(@"Multi factor finanlize sign in succeeded."); + } + }]; + }]; + } + }]; + }]; + } + else if (error) { + // [START_EXCLUDE] + [self showMessagePrompt:error.localizedDescription]; + // [END_EXCLUDE] + return; + } + // User successfully signed in. Get user data from the FIRUser object + if (authResult == nil) { return; } + FIRUser *user = authResult.user; + // [START_EXCLUDE] + }]; + // [END_EXCLUDE] + }]; + // [END signin_credential] + } + }]; +} + +- (void)showAuthPicker: (NSArray*) providers { + UIAlertController *picker = + [UIAlertController alertControllerWithTitle:@"Select Provider" + message:nil + preferredStyle:UIAlertControllerStyleAlert]; + + for (NSNumber *provider in providers) { + UIAlertAction *action; + switch (provider.unsignedIntegerValue) { + case AuthEmail: + { + action = [UIAlertAction actionWithTitle:@"Email" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * _Nonnull action) { + [self performSegueWithIdentifier:@"email" sender:nil]; + }]; + } + break; + case AuthEmailMFA: + { + action = [UIAlertAction actionWithTitle:@"Email with MFA" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * _Nonnull action) { + isMFAEnabled = YES; + [self performSegueWithIdentifier:@"email" sender:nil]; + }]; + } + break; + case AuthPasswordless: + { + action = [UIAlertAction actionWithTitle:@"Passwordless" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * _Nonnull action) { + [self performSegueWithIdentifier:@"passwordless" sender:nil]; + }]; + } + break; + case AuthCustom: + { + action = [UIAlertAction actionWithTitle:@"Custom" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * _Nonnull action) { + [self performSegueWithIdentifier:@"customToken" sender:nil]; + }]; + } + break; + case AuthApple: + { + if (@available(iOS 13, *)) { + action = [UIAlertAction actionWithTitle:@"Apple" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * _Nonnull action) { + [self startSignInWithAppleFlow]; + }]; + } else { + continue; + } + } + break; + case AuthTwitter: + { + action = [UIAlertAction actionWithTitle:@"Twitter" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * _Nonnull action) { + // [START firebase_auth_twitter] + [self.twitterProvider getCredentialWithUIDelegate:nil + completion:^(FIRAuthCredential *_Nullable credential, NSError *_Nullable error) { + [self showSpinner:^{ + if (error) { + [self hideSpinner:^{ + [self showMessagePrompt:error.localizedDescription]; + return; + }]; + } + if (credential) { + [[FIRAuth auth] signInWithCredential:credential + completion:^(FIRAuthDataResult *_Nullable authResult, + NSError *_Nullable error) { + [self hideSpinner:^{ + if (error) { + [self showMessagePrompt:error.localizedDescription]; + return; + } + }]; + }]; + } + }]; + }]; + // [END firebase_auth_twitter] + }]; + } + break; + case AuthGitHub: + { + action = [UIAlertAction actionWithTitle:@"GitHub" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * _Nonnull action) { + // [START firebase_auth_github] + [self.gitHubProvider getCredentialWithUIDelegate:nil + completion:^(FIRAuthCredential *_Nullable credential, NSError *_Nullable error) { + [self showSpinner:^{ + if (error) { + [self hideSpinner:^{ + [self showMessagePrompt:error.localizedDescription]; + return; + }]; + } + if (credential) { + [[FIRAuth auth] signInWithCredential:credential + completion:^(FIRAuthDataResult *_Nullable authResult, + NSError *_Nullable error) { + [self hideSpinner:^{ + if (error) { + [self showMessagePrompt:error.localizedDescription]; + return; + } + }]; + }]; + } + }]; + }]; + // [END firebase_auth_github] + }]; + } + break; + case AuthFacebook: { + action = [UIAlertAction actionWithTitle:@"Facebook" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * _Nonnull action) { + FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init]; + [loginManager logInWithPermissions:@[ @"public_profile", @"email" ] + fromViewController:self + handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { + if (error) { + [self showMessagePrompt:error.localizedDescription]; + } else if (result.isCancelled) { + NSLog(@"FBLogin cancelled"); + } else { + // [START headless_facebook_auth] + FIRAuthCredential *credential = [FIRFacebookAuthProvider + credentialWithAccessToken:[FBSDKAccessToken currentAccessToken].tokenString]; + // [END headless_facebook_auth] + [self firebaseLoginWithCredential:credential]; + } + }]; + }]; + } + break; + case AuthGoogle: { + action = [UIAlertAction actionWithTitle:@"Google" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * _Nonnull action) { + [self startSignInWithGoogleFlow]; + }]; + } + break; + case AuthPhone: { + action = [UIAlertAction actionWithTitle:@"Phone" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * _Nonnull action) { + [self showTextInputPromptWithMessage:@"Phone Number:" + completionBlock:^(BOOL userPressedOK, NSString *_Nullable userInput) { + if (!userPressedOK || !userInput.length) { + return; + } + + [self showSpinner:^{ + // [START phone_auth] + [[FIRPhoneAuthProvider provider] verifyPhoneNumber:userInput + UIDelegate:nil + completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) { + // [START_EXCLUDE silent] + [self hideSpinner:^{ + // [END_EXCLUDE] + if (error) { + [self showMessagePrompt:error.localizedDescription]; + return; + } + // Sign in using the verificationID and the code sent to the user + // [START_EXCLUDE] + [self showTextInputPromptWithMessage:@"Verification Code:" + completionBlock:^(BOOL userPressedOK, NSString *_Nullable userInput) { + if (!userPressedOK || !userInput.length) { + return; + } + + // [START get_phone_cred] + FIRAuthCredential *credential = [[FIRPhoneAuthProvider provider] + credentialWithVerificationID:verificationID + verificationCode:userInput]; + // [END get_phone_cred] + [self firebaseLoginWithCredential:credential]; + }]; + }]; + // [END_EXCLUDE] + }]; + // [END phone_auth] + }]; + }]; + }]; + } + break; + case AuthAnonymous: { + action = [UIAlertAction actionWithTitle:@"Anonymous" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * _Nonnull action) { + [self showSpinner:^{ + // [START firebase_auth_anonymous] + [[FIRAuth auth] signInAnonymouslyWithCompletion:^(FIRAuthDataResult * _Nullable authResult, + NSError * _Nullable error) { + // [START_EXCLUDE] + [self hideSpinner:^{ + if (error) { + [self showMessagePrompt:error.localizedDescription]; + return; + } + }]; + // [END_EXCLUDE] + }]; + // [END firebase_auth_anonymous] + }]; + }]; + } + break; + case AuthGameCenter: { + action = [UIAlertAction actionWithTitle:@"Game Center" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * _Nonnull action) { + // [START firebase_auth_gamecenter] + [FIRGameCenterAuthProvider + getCredentialWithCompletion:^(FIRAuthCredential * _Nullable credential, + NSError * _Nullable error) { + [self showSpinner:^{ + if (error) { + [self hideSpinner:^{ + [self showMessagePrompt:error.localizedDescription]; + return; + }]; + } + if (credential) { + [[FIRAuth auth] signInWithCredential:credential + completion:^(FIRAuthDataResult * _Nullable authResult, + NSError * _Nullable error) { + [self hideSpinner:^{ + if (error) { + [self showMessagePrompt:error.localizedDescription]; + return; + } + }]; + }]; + } + }]; + }]; + // [END firebase_auth_gamecenter] + }]; + }; + break; + case AuthMicrosoft: { + action = [UIAlertAction actionWithTitle:@"Microsoft" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * _Nonnull action) { + // [START firebase_auth_microsoft] + [self.microsoftProvider getCredentialWithUIDelegate:nil + completion:^(FIRAuthCredential *_Nullable credential, NSError *_Nullable error) { + [self showSpinner:^{ + if (error) { + [self hideSpinner:^{ + [self showMessagePrompt:error.localizedDescription]; + return; + }]; + } + if (credential) { + [[FIRAuth auth] signInWithCredential:credential + completion:^(FIRAuthDataResult *_Nullable authResult, + NSError *_Nullable error) { + [self hideSpinner:^{ + if (error) { + [self showMessagePrompt:error.localizedDescription]; + return; + } + }]; + }]; + } + }]; + }]; + // [END firebase_auth_microsoft] + }]; + } + break; + } + + [picker addAction:action]; + } + + + UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"Cancel" + style:UIAlertActionStyleCancel + handler:nil]; + [picker addAction:cancel]; + + [self presentViewController:picker animated:YES completion:nil]; +} + +- (IBAction)didTapSignIn:(id)sender { + [self showAuthPicker:@[@(AuthEmail), + @(AuthEmailMFA), + @(AuthAnonymous), + @(AuthApple), + @(AuthGoogle), + @(AuthFacebook), + @(AuthTwitter), + @(AuthGitHub), + @(AuthPhone), + @(AuthCustom), + @(AuthPasswordless), + @(AuthGameCenter), + @(AuthMicrosoft)]]; +} + +- (IBAction)didTapLink:(id)sender { + NSMutableArray *providers = [@[@(AuthGoogle), + @(AuthFacebook), + @(AuthTwitter), + @(AuthPhone)] mutableCopy]; + + // Remove any existing providers. Note that this is not a complete list of + // providers, so always check the documentation for a complete reference: + // https://firebase.google.com/docs/auth + for (id userInfo in [FIRAuth auth].currentUser.providerData) { + if ([userInfo.providerID isEqualToString:FIRFacebookAuthProviderID]) { + [providers removeObject:@(AuthFacebook)]; + } else if ([userInfo.providerID isEqualToString:FIRGoogleAuthProviderID]) { + [providers removeObject:@(AuthGoogle)]; + } else if ([userInfo.providerID isEqualToString:FIRTwitterAuthProviderID]) { + [providers removeObject:@(AuthTwitter)]; + } else if ([userInfo.providerID isEqualToString:FIRPhoneAuthProviderID]) { + [providers removeObject:@(AuthPhone)]; + } + } + [self showAuthPicker:providers]; +} + +- (IBAction)didTapSignOut:(id)sender { + // [START signout] + NSError *signOutError; + BOOL status = [[FIRAuth auth] signOut:&signOutError]; + if (!status) { + NSLog(@"Error signing out: %@", signOutError); + return; + } + // [END signout] +} + +- (void)authenticateGameCenterLocalPlayer { + __weak GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer]; + localPlayer.authenticateHandler = ^(UIViewController *gcAuthViewController, + NSError *error) { + if (gcAuthViewController != nil) { + // Pause any activities that require user interaction, then present the + // gcAuthViewController to the player. + [self presentViewController:gcAuthViewController animated:YES completion:nil]; + } else if (localPlayer.isAuthenticated) { + // Local player is logged in to Game Center. + } else { + // Error + if (error) { + [self showMessagePrompt:error.localizedDescription]; + return; + } + } + }; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + // [START auth_listener] + self.handle = [[FIRAuth auth] + addAuthStateDidChangeListener:^(FIRAuth *_Nonnull auth, FIRUser *_Nullable user) { + // [START_EXCLUDE] + [self setTitleDisplay:user]; + [self.tableView reloadData]; + // [END_EXCLUDE] + }]; + // [END auth_listener] + + self.microsoftProvider = [FIROAuthProvider providerWithProviderID:@"microsoft.com"]; + self.twitterProvider = [FIROAuthProvider providerWithProviderID:@"twitter.com"]; + self.gitHubProvider = [FIROAuthProvider providerWithProviderID:@"github.com"]; + + // Authenticate Game Center Local Player + // Uncomment to sign in with Game Center + // [self authenticateGameCenterLocalPlayer]; +} + +- (void)setTitleDisplay: (FIRUser *)user { + if (user.displayName) { + self.navigationItem.title = [NSString stringWithFormat:@"Welcome %@", user.displayName]; + } else { + self.navigationItem.title = @"Authentication Example"; + } +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + // [START remove_auth_listener] + [[FIRAuth auth] removeAuthStateDidChangeListener:_handle]; + // [END remove_auth_listener] +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + if (section == kSectionSignIn) { + return 1; + } else if (section == kSectionUser || section == kSectionToken || section == kSectionMultiFactor) { + if ([FIRAuth auth].currentUser) { + return 1; + } else { + return 0; + } + } else if (section == kSectionProviders) { + return [[FIRAuth auth].currentUser.providerData count]; + } + NSAssert(NO, @"Unexpected section"); + return 0; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView + cellForRowAtIndexPath:(NSIndexPath *)indexPath { + UITableViewCell *cell; + if (indexPath.section == kSectionSignIn) { + // [START current_user] + if ([FIRAuth auth].currentUser) { + // User is signed in. + // [START_EXCLUDE] + cell = [tableView dequeueReusableCellWithIdentifier:@"SignOut"]; + // [END_EXCLUDE] + } else { + // No user is signed in. + // [START_EXCLUDE] + cell = [tableView dequeueReusableCellWithIdentifier:@"SignIn"]; + // [END_EXCLUDE] + } + // [END current_user] + } else if (indexPath.section == kSectionUser) { + cell = [tableView dequeueReusableCellWithIdentifier:@"Profile"]; + // [START get_user_profile] + FIRUser *user = [FIRAuth auth].currentUser; + // [END get_user_profile] + // [START user_profile] + if (user) { + // The user's ID, unique to the Firebase project. + // Do NOT use this value to authenticate with your backend server, + // if you have one. Use getTokenWithCompletion:completion: instead. + NSString *email = user.email; + NSString *uid = user.uid; + NSMutableString *multiFactorString = [NSMutableString stringWithFormat:@"MultiFactor: "]; + for (FIRMultiFactorInfo *info in user.multiFactor.enrolledFactors) { + [multiFactorString appendString:info.displayName]; + [multiFactorString appendString:@" "]; + } + NSURL *photoURL = user.photoURL; + // [START_EXCLUDE] + UILabel *emailLabel = [(UILabel *)cell viewWithTag:1]; + UILabel *userIDLabel = [(UILabel *)cell viewWithTag:2]; + UIImageView *profileImageView = [(UIImageView *)cell viewWithTag:3]; + UILabel *multiFactorLabel = [(UILabel *)cell viewWithTag:4]; + emailLabel.text = email; + userIDLabel.text = uid; + multiFactorLabel.text = multiFactorString; + if (isMFAEnabled) { + multiFactorLabel.hidden = NO; + } else { + multiFactorLabel.hidden = YES; + } + + static NSURL *lastPhotoURL = nil; + lastPhotoURL = photoURL; // to prevent earlier image overwrites later one. + if (photoURL) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^() { + UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:photoURL]]; + dispatch_async(dispatch_get_main_queue(), ^() { + if (photoURL == lastPhotoURL) { + profileImageView.image = image; + } + }); + }); + } else { + profileImageView.image = [UIImage imageNamed:@"ic_account_circle"]; + } + // [END_EXCLUDE] + } + // [END user_profile] + } else if (indexPath.section == kSectionProviders) { + cell = [tableView dequeueReusableCellWithIdentifier:@"Provider"]; + // [START provider_data] + id userInfo = [FIRAuth auth].currentUser.providerData[indexPath.row]; + cell.textLabel.text = [userInfo providerID]; + // Provider-specific UID + cell.detailTextLabel.text = [userInfo uid]; + // [END provider_data] + } else if (indexPath.section == kSectionToken) { + cell = [tableView dequeueReusableCellWithIdentifier:@"Token"]; + UIButton *requestEmailButton = [(UIButton *)cell viewWithTag:4]; + requestEmailButton.enabled = [FIRAuth auth].currentUser.email ? YES : NO; + } else if (indexPath.section == kSectionMultiFactor) { + cell = [tableView dequeueReusableCellWithIdentifier:@"MultiFactor"]; + } else { + [NSException raise:NSInternalInconsistencyException format:@"Unexpected state"]; + } + return cell; +} + +- (NSString *)tableView:(UITableView *)tableView + titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath { + return @"Unlink"; +} + +- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView + editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { + if (indexPath.section == kSectionProviders) { + return UITableViewCellEditingStyleDelete; + } + return UITableViewCellEditingStyleNone; +} + +// Swipe to delete. +- (void)tableView:(UITableView *)tableView + commitEditingStyle:(UITableViewCellEditingStyle)editingStyle + forRowAtIndexPath:(NSIndexPath *)indexPath { + if (editingStyle == UITableViewCellEditingStyleDelete) { + NSString *providerID = [[FIRAuth auth].currentUser.providerData[indexPath.row] providerID]; + [self showSpinner:^{ + // [START unlink_provider] + [[FIRAuth auth].currentUser unlinkFromProvider:providerID + completion:^(FIRUser *_Nullable user, NSError *_Nullable error) { + // [START_EXCLUDE] + [self hideSpinner:^{ + if (error) { + [self showMessagePrompt:error.localizedDescription]; + return; + } + [self.tableView reloadData]; + }]; + // [END_EXCLUDE] + }]; + // [END unlink_provider] + }]; + } +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + if (indexPath.section == kSectionUser) { + return 200; + } + return 44; +} +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + if (isMFAEnabled) { + return 5; + } else { + return 4; + } +} + +- (IBAction)didMultiFactorEnroll:(id)sender { + FIRUser *user = FIRAuth.auth.currentUser; + if (!user) { + NSLog(@"Please sign in first."); + } else { + [self showTextInputPromptWithMessage:@"Phone Number" + completionBlock:^(BOOL userPressedOK, NSString *_Nullable phoneNumber) { + [user.multiFactor + getSessionWithCompletion:^(FIRMultiFactorSession *_Nullable session, NSError *_Nullable error) { + [FIRPhoneAuthProvider.provider verifyPhoneNumber:phoneNumber + UIDelegate:nil + multiFactorSession:session + completion:^(NSString * _Nullable verificationID, + NSError * _Nullable error) { + if (error) { + [self showMessagePrompt:error.localizedDescription]; + } else { + [self showTextInputPromptWithMessage:@"Verification code" + completionBlock:^(BOOL userPressedOK, + NSString *_Nullable verificationCode) { + FIRPhoneAuthCredential *credential = + [[FIRPhoneAuthProvider provider] credentialWithVerificationID:verificationID + verificationCode:verificationCode]; + FIRMultiFactorAssertion *assertion = + [FIRPhoneMultiFactorGenerator assertionWithCredential:credential]; + [self showTextInputPromptWithMessage:@"Display name" + completionBlock:^(BOOL userPressedOK, + NSString *_Nullable displayName) { + [user.multiFactor enrollWithAssertion:assertion + displayName:displayName + completion:^(NSError *_Nullable error) { + if (error) { + [self showMessagePrompt:error.localizedDescription]; + } else { + NSLog(@"Multi factor finanlize enroll succeeded."); + [self showTypicalUIForUserUpdateResultsWithTitle:@"Multi Factor" error:error]; + } + }]; + }]; + }]; + } + }]; + }]; + }]; + } +} + +- (IBAction)didMultiFactorUnenroll:(id)sender { + NSMutableString *displayNameString = [NSMutableString string]; + for (FIRMultiFactorInfo *tmpFactorInfo in FIRAuth.auth.currentUser.multiFactor.enrolledFactors) { + [displayNameString appendString:tmpFactorInfo.displayName]; + [displayNameString appendString:@" "]; + } + [self showTextInputPromptWithMessage:[NSString stringWithFormat:@"Multifactor Unenroll\n%@", displayNameString] + completionBlock:^(BOOL userPressedOK, NSString *_Nullable displayName) { + FIRMultiFactorInfo *factorInfo; + for (FIRMultiFactorInfo *tmpFactorInfo in FIRAuth.auth.currentUser.multiFactor.enrolledFactors) { + if ([displayName isEqualToString:tmpFactorInfo.displayName]) { + factorInfo = tmpFactorInfo; + } + } + [FIRAuth.auth.currentUser.multiFactor unenrollWithInfo:factorInfo + completion:^(NSError * _Nullable error) { + if (error) { + [self showMessagePrompt:error.localizedDescription]; + } else { + NSLog(@"Multi factor finanlize unenroll succeeded."); + [self showTypicalUIForUserUpdateResultsWithTitle:@"Multi Factor" error:error]; + } + }]; + }]; +} + +- (IBAction)didTokenRefresh:(id)sender { + FIRAuthTokenCallback action = ^(NSString *_Nullable token, NSError *_Nullable error) { + UIAlertAction *okAction = [UIAlertAction actionWithTitle:kOKButtonText + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action) { + NSLog(kOKButtonText); + }]; + if (error) { + UIAlertController *alertController = + [UIAlertController alertControllerWithTitle:kTokenRefreshErrorAlertTitle + message:error.localizedDescription + preferredStyle:UIAlertControllerStyleAlert]; + [alertController addAction:okAction]; + [self presentViewController:alertController animated:YES completion:nil]; + return; + } + + // Log token refresh event to Analytics. + [FIRAnalytics logEventWithName:@"tokenrefresh" parameters:nil]; + + UIAlertController *alertController = + [UIAlertController alertControllerWithTitle:kTokenRefreshedAlertTitle + message:token + preferredStyle:UIAlertControllerStyleAlert]; + [alertController addAction:okAction]; + [self presentViewController:alertController animated:YES completion:nil]; + }; + // [START token_refresh] + [[FIRAuth auth].currentUser getIDTokenForcingRefresh:YES completion:action]; + // [END token_refresh] +} + + +/** @fn setDisplayName + @brief Changes the display name of the current user. + */ +- (IBAction)didSetDisplayName:(id)sender { + [self showTextInputPromptWithMessage:@"Display Name:" + completionBlock:^(BOOL userPressedOK, NSString *_Nullable userInput) { + if (!userPressedOK || !userInput.length) { + return; + } + + [self showSpinner:^{ + // [START profile_change] + FIRUserProfileChangeRequest *changeRequest = [[FIRAuth auth].currentUser profileChangeRequest]; + changeRequest.displayName = userInput; + [changeRequest commitChangesWithCompletion:^(NSError *_Nullable error) { + // [START_EXCLUDE] + [self hideSpinner:^{ + [self showTypicalUIForUserUpdateResultsWithTitle:kSetDisplayNameTitle error:error]; + [self setTitleDisplay:[FIRAuth auth].currentUser]; + }]; + // [END_EXCLUDE] + }]; + // [END profile_change] + }]; + }]; +} + +/** @fn requestVerifyEmail + @brief Requests a "verify email" email be sent. + */ +- (IBAction)didRequestVerifyEmail:(id)sender { + [self showSpinner:^{ + // [START send_verification_email] + [[FIRAuth auth].currentUser sendEmailVerificationWithCompletion:^(NSError *_Nullable error) { + // [START_EXCLUDE] + [self hideSpinner:^{ + if (error) { + [self showMessagePrompt:error.localizedDescription]; + return; + } + + [self showMessagePrompt:@"Sent"]; + }]; + // [END_EXCLUDE] + }]; + // [END send_verification_email] + }]; +} + +/** @fn changeEmail + @brief Changes the email address of the current user. + */ +- (IBAction)didChangeEmail:(id)sender { + [self showTextInputPromptWithMessage:@"Email Address:" + completionBlock:^(BOOL userPressedOK, NSString *_Nullable userInput) { + if (!userPressedOK || !userInput.length) { + return; + } + + [self showSpinner:^{ + // [START change_email] + [[FIRAuth auth].currentUser updateEmail:userInput completion:^(NSError *_Nullable error) { + // [START_EXCLUDE] + [self hideSpinner:^{ + [self showTypicalUIForUserUpdateResultsWithTitle:kChangeEmailText error:error]; + }]; + // [END_EXCLUDE] + }]; + // [END change_email] + }]; + }]; +} + +/** @fn changePassword + @brief Changes the password of the current user. + */ +- (IBAction)didChangePassword:(id)sender { + [self showTextInputPromptWithMessage:@"New Password:" + completionBlock:^(BOOL userPressedOK, NSString *_Nullable userInput) { + if (!userPressedOK || !userInput.length) { + return; + } + + [self showSpinner:^{ + // [START change_password] + [[FIRAuth auth].currentUser updatePassword:userInput completion:^(NSError *_Nullable error) { + // [START_EXCLUDE] + [self hideSpinner:^{ + [self showTypicalUIForUserUpdateResultsWithTitle:kChangePasswordText error:error]; + }]; + // [END_EXCLUDE] + }]; + // [END change_password] + }]; + }]; +} + +/** @fn updatePhoneNumber + @brief Updates the phone number of the current user. + */ +- (IBAction)didUpdatePhoneNumber:(id)sender { + [self showTextInputPromptWithMessage:@"New Phone Number:" + completionBlock:^(BOOL userPressedOK, NSString *_Nullable userInput) { + if (!userPressedOK || !userInput.length) { + return; + } + + [self showSpinner:^{ + // [START update_phone] + [[FIRPhoneAuthProvider provider] verifyPhoneNumber:userInput + UIDelegate:nil + completion:^(NSString * _Nullable verificationID, + NSError * _Nullable error) { + // [START_EXCLUDE] + [self hideSpinner:^{ + if (error) { + [self showMessagePrompt:error.localizedDescription]; + return; + } + [self showTextInputPromptWithMessage:@"Verification Code:" + completionBlock:^(BOOL userPressedOK, NSString *_Nullable userInput) { + if (!userPressedOK || !userInput.length) { + return; + } + + [self showSpinner:^{ + // [END_EXCLUDE] + FIRPhoneAuthCredential *credential = [[FIRPhoneAuthProvider provider] + credentialWithVerificationID:verificationID + verificationCode:userInput]; + [[FIRAuth auth].currentUser updatePhoneNumberCredential:credential + completion:^(NSError * _Nullable error) { + // [END update_phone] + [self hideSpinner:^{ + [self showTypicalUIForUserUpdateResultsWithTitle:kUpdatePhoneNumberText + error:error]; + }]; + }]; + }]; + }]; + }]; + }]; + }]; + }]; +} + +/** @fn showTypicalUIForUserUpdateResultsWithTitle:error: + @brief Shows a @c UIAlertView if error is non-nil with the localized description of the error. + @param resultsTitle The title of the @c UIAlertView + @param error The error details to display if non-nil. + */ +- (void)showTypicalUIForUserUpdateResultsWithTitle:(NSString *)resultsTitle error:(NSError *)error { + if (error) { + NSString *message = [NSString stringWithFormat:@"%@ (%ld)\n%@", error.domain, (long)error.code, + error.localizedDescription]; + if ([UIAlertController class]) { + UIAlertAction *okAction = [UIAlertAction actionWithTitle:kOKButtonText + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action) { + NSLog(@"OK"); + }]; + + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:resultsTitle + message:message + preferredStyle:UIAlertControllerStyleAlert]; + [alertController addAction:okAction]; + [self presentViewController:alertController + animated:YES + completion:nil]; + } else { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:resultsTitle + message:message + delegate:nil + cancelButtonTitle:nil + otherButtonTitles:kOKButtonText, nil]; + [alert show]; + return; + } + } + [self.tableView reloadData]; +} + +@end + +#pragma mark - Sign in with Apple + +@implementation MainViewController (SignInWithApple) + +- (void)startSignInWithAppleFlow { + NSString *nonce = [self randomNonce:32]; + self.currentNonce = nonce; + ASAuthorizationAppleIDProvider *appleIDProvider = [[ASAuthorizationAppleIDProvider alloc] init]; + ASAuthorizationAppleIDRequest *request = [appleIDProvider createRequest]; + request.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail]; + request.nonce = [self stringBySha256HashingString:nonce]; + + ASAuthorizationController *authorizationController = + [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]]; + authorizationController.delegate = self; + authorizationController.presentationContextProvider = self; + [authorizationController performRequests]; +} + +// [START random_nonce] +// Adapted from https://auth0.com/docs/api-auth/tutorials/nonce#generate-a-cryptographically-random-nonce +- (NSString *)randomNonce:(NSInteger)length { + NSAssert(length > 0, @"Expected nonce to have positive length"); + NSString *characterSet = @"0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._"; + NSMutableString *result = [NSMutableString string]; + NSInteger remainingLength = length; + + while (remainingLength > 0) { + NSMutableArray *randoms = [NSMutableArray arrayWithCapacity:16]; + for (NSInteger i = 0; i < 16; i++) { + uint8_t random = 0; + int errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random); + NSAssert(errorCode == errSecSuccess, @"Unable to generate nonce: OSStatus %i", errorCode); + + [randoms addObject:@(random)]; + } + + for (NSNumber *random in randoms) { + if (remainingLength == 0) { + break; + } + + if (random.unsignedIntValue < characterSet.length) { + unichar character = [characterSet characterAtIndex:random.unsignedIntValue]; + [result appendFormat:@"%C", character]; + remainingLength--; + } + } + } + + return [result copy]; +} +// [END random_nonce] + +// [START sha_256] +- (NSString *)stringBySha256HashingString:(NSString *)input { + const char *string = [input UTF8String]; + unsigned char result[CC_SHA256_DIGEST_LENGTH]; + CC_SHA256(string, (CC_LONG)strlen(string), result); + + NSMutableString *hashed = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2]; + for (NSInteger i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) { + [hashed appendFormat:@"%02x", result[i]]; + } + return hashed; +} +// [END sha_256] + +- (void)authorizationController:(ASAuthorizationController *)controller + didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0)) { + if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) { + ASAuthorizationAppleIDCredential *appleIDCredential = authorization.credential; + NSString *rawNonce = self.currentNonce; + NSAssert(rawNonce != nil, @"Invalid state: A login callback was received, but no login request was sent."); + + if (appleIDCredential.identityToken == nil) { + NSLog(@"Unable to fetch identity token."); + return; + } + + NSString *idToken = [[NSString alloc] initWithData:appleIDCredential.identityToken + encoding:NSUTF8StringEncoding]; + if (idToken == nil) { + NSLog(@"Unable to serialize id token from data: %@", appleIDCredential.identityToken); + } + + // Initialize a Firebase credential. + FIROAuthCredential *credential = [FIROAuthProvider credentialWithProviderID:@"apple.com" + IDToken:idToken + rawNonce:rawNonce]; + + // Sign in with Firebase. + [self firebaseLoginWithCredential:credential]; + } +} + +- (void)authorizationController:(ASAuthorizationController *)controller + didCompleteWithError:(NSError *)error API_AVAILABLE(ios(13.0)) { + NSLog(@"Sign in with Apple errored: %@", error); +} + +- (ASPresentationAnchor)presentationAnchorForAuthorizationController:(ASAuthorizationController *)controller API_AVAILABLE(ios(13.0)) { + return self.view.window; +} + +- (void)setCurrentNonce:(NSString *)currentNonce { + _currentNonce = [currentNonce copy]; +} + +- (NSString *)currentNonce { + return [_currentNonce copy]; +} + +#pragma mark - Sign in with Google + +- (void)startSignInWithGoogleFlow { + // [START headless_google_auth] + GIDConfiguration *config = [[GIDConfiguration alloc] initWithClientID:[FIRApp defaultApp].options.clientID]; + [GIDSignIn.sharedInstance setConfiguration:config]; + + __weak __auto_type weakSelf = self; + [GIDSignIn.sharedInstance signInWithPresentingViewController:self + completion:^(GIDSignInResult * _Nullable result, NSError * _Nullable error) { + __auto_type strongSelf = weakSelf; + if (strongSelf == nil) { return; } + + if (error == nil) { + // [START google_credential] + FIRAuthCredential *credential = + [FIRGoogleAuthProvider credentialWithIDToken:result.user.idToken.tokenString + accessToken:result.user.accessToken.tokenString]; + // [END google_credential] + // [START_EXCLUDE] + [strongSelf firebaseLoginWithCredential:credential]; + // [END_EXCLUDE] + } else { + // [START_EXCLUDE] + [strongSelf showMessagePrompt:error.localizedDescription]; + // [END_EXCLUDE] + } + }]; + + // [END headless_google_auth] +} + +@end diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExample/PasswordlessViewController.h b/authentication/LegacyAuthQuickstart/AuthenticationExample/PasswordlessViewController.h new file mode 100644 index 000000000..8a42259a8 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExample/PasswordlessViewController.h @@ -0,0 +1,21 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import UIKit; + +@interface PasswordlessViewController : UIViewController +@end + diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExample/PasswordlessViewController.m b/authentication/LegacyAuthQuickstart/AuthenticationExample/PasswordlessViewController.m new file mode 100644 index 000000000..dbe167c69 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExample/PasswordlessViewController.m @@ -0,0 +1,102 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "PasswordlessViewController.h" +#import "UIViewController+Alerts.h" + +@import FirebaseAuth; + +@interface PasswordlessViewController () +@property (weak, nonatomic) IBOutlet UITextField *emailField; +@property (weak, nonatomic) IBOutlet UIButton *signInButton; +@property(strong, nonatomic) NSString *link; +@end + +@implementation PasswordlessViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + _emailField.text = [NSUserDefaults.standardUserDefaults valueForKey:@"Email"]; + self.link = [NSUserDefaults.standardUserDefaults valueForKey:@"Link"]; + if (_link) { + _signInButton.enabled = YES; + } +} + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + [self.view endEditing:YES]; +} + +- (IBAction)didTapSignInWithEmailLink:(id)sender { + NSString *email = _emailField.text; + NSString *link = _link; + [self showSpinner:^{ + // [START signin_emaillink] + [[FIRAuth auth] signInWithEmail:email + link:link + completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { + // [START_EXCLUDE] + [self hideSpinner:^{ + if (error) { + [self showMessagePrompt:error.localizedDescription]; + return; + } + [self.navigationController popViewControllerAnimated:YES]; + }]; + // [END_EXCLUDE] + }]; + // [END signin_emaillink] + }]; +} + +- (IBAction)didTapSendSignInLink:(id)sender { + NSString *email = _emailField.text; + [self showSpinner:^{ + // [START action_code_settings] + FIRActionCodeSettings *actionCodeSettings = [[FIRActionCodeSettings alloc] init]; + [actionCodeSettings setURL:[NSURL URLWithString:@"https://www.example.com"]]; + // The sign-in operation has to always be completed in the app. + actionCodeSettings.handleCodeInApp = YES; + [actionCodeSettings setIOSBundleID:[[NSBundle mainBundle] bundleIdentifier]]; + [actionCodeSettings setAndroidPackageName:@"com.example.android" + installIfNotAvailable:NO + minimumVersion:@"12"]; + // [END action_code_settings] + // [START send_signin_link] + [[FIRAuth auth] sendSignInLinkToEmail:email + actionCodeSettings:actionCodeSettings + completion:^(NSError *_Nullable error) { + // [START_EXCLUDE] + [self hideSpinner:^{ + // [END_EXCLUDE] + if (error) { + [self showMessagePrompt:error.localizedDescription]; + return; + } + // The link was successfully sent. Inform the user. + // Save the email locally so you don't need to ask the user for it again + // if they open the link on the same device. + [NSUserDefaults.standardUserDefaults setObject:email forKey:@"Email"]; + [self showMessagePrompt:@"Check your email for link"]; + // [START_EXCLUDE] + }]; + // [END_EXCLUDE] + }]; + // [END send_signin_link] + }]; +} + +@end diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExample/UIViewController+Alerts.h b/authentication/LegacyAuthQuickstart/AuthenticationExample/UIViewController+Alerts.h new file mode 100644 index 000000000..c610cddd4 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExample/UIViewController+Alerts.h @@ -0,0 +1,60 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/*! @typedef AlertPromptCompletionBlock + @brief The type of callback used to report text input prompt results. + */ +typedef void (^AlertPromptCompletionBlock)(BOOL userPressedOK, NSString *_Nullable userInput); + +/*! @class Alerts + @brief Wrapper for @c UIAlertController and @c UIAlertView for backwards compatability with + iOS 6+. + */ +@interface UIViewController (Alerts) + +/*! @fn showMessagePrompt: + @brief Displays an alert with an 'OK' button and a message. + @param message The message to display. + */ +- (void)showMessagePrompt:(NSString *)message; + +/*! @fn showTextInputPromptWithMessage:completionBlock: + @brief Shows a prompt with a text field and 'OK'/'Cancel' buttons. + @param message The message to display. + @param completion A block to call when the user taps 'OK' or 'Cancel'. + */ +- (void)showTextInputPromptWithMessage:(NSString *)message + completionBlock:(AlertPromptCompletionBlock)completion; + +/*! @fn showSpinner + @brief Shows the please wait spinner. + @param completion Called after the spinner has been shown. + */ +- (void)showSpinner:(nullable void (^)(void))completion; + +/*! @fn hideSpinner + @brief Hides the please wait spinner. + @param completion Called after the spinner has been hidden. + */ +- (void)hideSpinner:(nullable void (^)(void))completion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExample/UIViewController+Alerts.m b/authentication/LegacyAuthQuickstart/AuthenticationExample/UIViewController+Alerts.m new file mode 100644 index 000000000..c7e297f5f --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExample/UIViewController+Alerts.m @@ -0,0 +1,159 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "UIViewController+Alerts.h" + +#import + +/*! @var kPleaseWaitAssociatedObjectKey + @brief Key used to identify the "please wait" spinner associated object. + */ +static NSString *const kPleaseWaitAssociatedObjectKey = + @"_UIViewControllerAlertCategory_PleaseWaitScreenAssociatedObject"; + +/*! @var kOK + @brief Text for an 'OK' button. + */ +static NSString *const kOK = @"OK"; + +/*! @var kCancel + @brief Text for an 'Cancel' button. + */ +static NSString *const kCancel = @"Cancel"; + +/*! @class SimpleTextPromptDelegate + @brief A @c UIAlertViewDelegate which allows @c UIAlertView to be used with blocks more easily. + */ +@interface SimpleTextPromptDelegate : NSObject + +/*! @fn init + @brief Please use initWithCompletionHandler. + */ +- (nullable instancetype)init NS_UNAVAILABLE; + +/*! @fn initWithCompletionHandler: + @brief Designated initializer. + @param completionHandler The block to call when the alert view is dismissed. + */ +- (nullable instancetype)initWithCompletionHandler:(AlertPromptCompletionBlock)completionHandler + NS_DESIGNATED_INITIALIZER; + +@end + +@implementation UIViewController (Alerts) + +- (void)showMessagePrompt:(NSString *)message { + UIAlertController *alert = + [UIAlertController alertControllerWithTitle:nil + message:message + preferredStyle:UIAlertControllerStyleAlert]; + UIAlertAction *okAction = + [UIAlertAction actionWithTitle:kOK style:UIAlertActionStyleDefault handler:nil]; + [alert addAction:okAction]; + [self presentViewController:alert animated:YES completion:nil]; +} + +- (void)showTextInputPromptWithMessage:(NSString *)message + completionBlock:(AlertPromptCompletionBlock)completion { + UIAlertController *prompt = + [UIAlertController alertControllerWithTitle:nil + message:message + preferredStyle:UIAlertControllerStyleAlert]; + __weak UIAlertController *weakPrompt = prompt; + UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:kCancel + style:UIAlertActionStyleCancel + handler:^(UIAlertAction *_Nonnull action) { + completion(NO, nil); + }]; + UIAlertAction *okAction = + [UIAlertAction actionWithTitle:kOK + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *_Nonnull action) { + UIAlertController *strongPrompt = weakPrompt; + completion(YES, strongPrompt.textFields[0].text); + }]; + [prompt addTextFieldWithConfigurationHandler:nil]; + [prompt addAction:cancelAction]; + [prompt addAction:okAction]; + [self presentViewController:prompt animated:YES completion:nil]; +} + +- (void)showSpinner:(nullable void (^)(void))completion { + UIAlertController *pleaseWaitAlert = + objc_getAssociatedObject(self, (__bridge const void *)(kPleaseWaitAssociatedObjectKey)); + if (pleaseWaitAlert) { + if (completion) { + completion(); + } + return; + } + pleaseWaitAlert = [UIAlertController alertControllerWithTitle:nil + message:@"Please Wait...\n\n\n\n" + preferredStyle:UIAlertControllerStyleAlert]; + + UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] + initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; + spinner.color = [UIColor blackColor]; + spinner.center = CGPointMake(pleaseWaitAlert.view.bounds.size.width / 2, + pleaseWaitAlert.view.bounds.size.height / 2); + spinner.autoresizingMask = + UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin | + UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; + [spinner startAnimating]; + [pleaseWaitAlert.view addSubview:spinner]; + + objc_setAssociatedObject(self, (__bridge const void *)(kPleaseWaitAssociatedObjectKey), + pleaseWaitAlert, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + [self presentViewController:pleaseWaitAlert animated:YES completion:completion]; +} + +- (void)hideSpinner:(nullable void (^)(void))completion { + UIAlertController *pleaseWaitAlert = + objc_getAssociatedObject(self, (__bridge const void *)(kPleaseWaitAssociatedObjectKey)); + + [pleaseWaitAlert dismissViewControllerAnimated:YES completion:completion]; + + objc_setAssociatedObject(self, (__bridge const void *)(kPleaseWaitAssociatedObjectKey), nil, + OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +@end + +@implementation SimpleTextPromptDelegate { + AlertPromptCompletionBlock _completionHandler; + SimpleTextPromptDelegate *_retainedSelf; +} + +- (instancetype)initWithCompletionHandler:(AlertPromptCompletionBlock)completionHandler { + self = [super init]; + if (self) { + _completionHandler = completionHandler; + _retainedSelf = self; + } + return self; +} + +- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { + if (buttonIndex == alertView.firstOtherButtonIndex) { + _completionHandler(YES, [alertView textFieldAtIndex:0].text); + } else { + _completionHandler(NO, nil); + } + _completionHandler = nil; + _retainedSelf = nil; +} + +@end diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExample/main.m b/authentication/LegacyAuthQuickstart/AuthenticationExample/main.m new file mode 100644 index 000000000..d4878306b --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExample/main.m @@ -0,0 +1,24 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/AppDelegate.swift b/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/AppDelegate.swift new file mode 100644 index 000000000..ec762c4bf --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/AppDelegate.swift @@ -0,0 +1,104 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit + +// [START auth_import] +import FirebaseCore +// [END auth_import] + +// [START google_import] +import GoogleSignIn +// [END google_import] +import FBSDKCoreKit + +@UIApplicationMain +// [START signin_delegate] +class AppDelegate: UIResponder, UIApplicationDelegate { + // [END signin_delegate] + + var window: UIWindow? + + func application(_ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [ + UIApplication.LaunchOptionsKey: Any + ]?) -> Bool { + // [START firebase_configure] + // Use Firebase library to configure APIs + FirebaseApp.configure() + // [END firebase_configure] + + ApplicationDelegate.shared.application(application, + didFinishLaunchingWithOptions: launchOptions) + + return true + } + + // [START new_delegate] + @available(iOS 9.0, *) + func application(_ application: UIApplication, open url: URL, + options: [UIApplication.OpenURLOptionsKey: Any]) + -> Bool { + // [END new_delegate] + return self.application(application, + open: url, + // [START new_options] + sourceApplication: options[UIApplication.OpenURLOptionsKey + .sourceApplication] as? String, + annotation: [:]) + } + + // [END new_options] + + // [START old_delegate] + func application(_ application: UIApplication, open url: URL, sourceApplication: String?, + annotation: Any) -> Bool { + // [END old_delegate] + if handlePasswordlessSignIn(withURL: url) { + return true + } + if GIDSignIn.sharedInstance.handle(url) { + return true + } + return ApplicationDelegate.shared.application(application, + open: url, + // [START old_options] + sourceApplication: sourceApplication, + annotation: annotation) + } + + // [END old_options] + + func application(_ application: UIApplication, continue userActivity: NSUserActivity, + restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { + return userActivity.webpageURL.flatMap(handlePasswordlessSignIn)! + } + + func handlePasswordlessSignIn(withURL url: URL) -> Bool { + let link = url.absoluteString + // [START is_signin_link] + if Auth.auth().isSignIn(withEmailLink: link) { + // [END is_signin_link] + UserDefaults.standard.set(link, forKey: "Link") + (window?.rootViewController as? UINavigationController)? + .popToRootViewController(animated: false) + window?.rootViewController?.children[0] + .performSegue(withIdentifier: "passwordless", sender: nil) + return true + } + return false + } +} diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/AuthenticationExample.entitlements b/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/AuthenticationExample.entitlements new file mode 100644 index 000000000..a8aefa8f0 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/AuthenticationExample.entitlements @@ -0,0 +1,10 @@ + + + + + keychain-access-groups + + $(AppIdentifierPrefix)com.google.firebase.quickstart.AuthenticationExample + + + diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/CustomTokenViewController.swift b/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/CustomTokenViewController.swift new file mode 100644 index 000000000..fc7fccfc0 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/CustomTokenViewController.swift @@ -0,0 +1,49 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit + +// [START auth_view_import] +import FirebaseAuth +// [END auth_view_import] + +@objc(CustomTokenViewController) +class CustomTokenViewController: UIViewController { + @IBOutlet var tokenField: UITextView! + + override func touchesBegan(_ touches: Set, with event: UIEvent?) { + view.endEditing(true) + } + + @IBAction func didTapCustomTokenLogin(_ sender: AnyObject) { + let customToken = tokenField.text + showSpinner { + // [START signinwithcustomtoken] + Auth.auth().signIn(withCustomToken: customToken ?? "") { user, error in + // [START_EXCLUDE] + self.hideSpinner { + if let error = error { + self.showMessagePrompt(error.localizedDescription) + return + } + self.navigationController!.popViewController(animated: true) + } + // [END_EXCLUDE] + } + // [END signinwithcustomtoken] + } + } +} diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/EmailViewController.swift b/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/EmailViewController.swift new file mode 100644 index 000000000..bdb55d25d --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/EmailViewController.swift @@ -0,0 +1,190 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit + +import FirebaseAuth + +@objc(EmailViewController) +class EmailViewController: UIViewController { + @IBOutlet var emailField: UITextField! + @IBOutlet var passwordField: UITextField! + + override func touchesBegan(_ touches: Set, with event: UIEvent?) { + view.endEditing(true) + } + + @IBAction func didTapEmailLogin(_ sender: AnyObject) { + guard let email = emailField.text, let password = passwordField.text else { + showMessagePrompt("email/password can't be empty") + return + } + showSpinner { + // [START headless_email_auth] + Auth.auth().signIn(withEmail: email, password: password) { [weak self] authResult, error in + guard let strongSelf = self else { return } + // [START_EXCLUDE] + strongSelf.hideSpinner { + if let error = error { + let authError = error as NSError + if authError.code == AuthErrorCode.secondFactorRequired.rawValue { + // The user is a multi-factor user. Second factor challenge is required. + let resolver = authError + .userInfo[AuthErrorUserInfoMultiFactorResolverKey] as! MultiFactorResolver + var displayNameString = "" + for tmpFactorInfo in resolver.hints { + displayNameString += tmpFactorInfo.displayName ?? "" + displayNameString += " " + } + self!.showTextInputPrompt( + withMessage: "Select factor to sign in\n\(displayNameString)", + completionBlock: { userPressedOK, displayName in + var selectedHint: PhoneMultiFactorInfo? + for tmpFactorInfo in resolver.hints { + if displayName == tmpFactorInfo.displayName { + selectedHint = tmpFactorInfo as? PhoneMultiFactorInfo + } + } + PhoneAuthProvider.provider() + .verifyPhoneNumber(with: selectedHint!, uiDelegate: nil, + multiFactorSession: resolver + .session) { verificationID, error in + if error != nil { + print("Multi factor start sign in failed. Error: \(error.debugDescription)") + } else { + self!.showTextInputPrompt( + withMessage: "Verification code for \(selectedHint?.displayName ?? "")", + completionBlock: { userPressedOK, verificationCode in + let credential: PhoneAuthCredential? = PhoneAuthProvider.provider() + .credential(withVerificationID: verificationID!, + verificationCode: verificationCode!) + let assertion: MultiFactorAssertion? = PhoneMultiFactorGenerator + .assertion(with: credential!) + resolver.resolveSignIn(with: assertion!) { authResult, error in + if error != nil { + print( + "Multi factor finanlize sign in failed. Error: \(error.debugDescription)" + ) + } else { + strongSelf.navigationController?.popViewController(animated: true) + } + } + } + ) + } + } + } + ) + } else { + strongSelf.showMessagePrompt(error.localizedDescription) + return + } + } + strongSelf.navigationController?.popViewController(animated: true) + } + // [END_EXCLUDE] + } + // [END headless_email_auth] + } + } + + /** @fn requestPasswordReset + @brief Requests a "password reset" email be sent. + */ + @IBAction func didRequestPasswordReset(_ sender: AnyObject) { + showTextInputPrompt(withMessage: "Email:") { [weak self] userPressedOK, email in + guard let strongSelf = self, let email = email else { + return + } + strongSelf.showSpinner { + // [START password_reset] + Auth.auth().sendPasswordReset(withEmail: email) { error in + // [START_EXCLUDE] + strongSelf.hideSpinner { + if let error = error { + strongSelf.showMessagePrompt(error.localizedDescription) + return + } + strongSelf.showMessagePrompt("Sent") + } + // [END_EXCLUDE] + } + // [END password_reset] + } + } + } + + /** @fn getProvidersForEmail + @brief Prompts the user for an email address, calls @c FIRAuth.getProvidersForEmail:callback: + and displays the result. + */ + @IBAction func didGetProvidersForEmail(_ sender: AnyObject) { + showTextInputPrompt(withMessage: "Email:") { [weak self] userPressedOK, email in + guard let strongSelf = self else { return } + guard let email = email else { + strongSelf.showMessagePrompt("email can't be empty") + return + } + strongSelf.showSpinner { + // [START get_methods] + Auth.auth().fetchSignInMethods(forEmail: email) { methods, error in + // [START_EXCLUDE] + strongSelf.hideSpinner { + if let error = error { + strongSelf.showMessagePrompt(error.localizedDescription) + return + } + strongSelf.showMessagePrompt(methods!.joined(separator: ", ")) + } + // [END_EXCLUDE] + } + // [END get_methods] + } + } + } + + @IBAction func didCreateAccount(_ sender: AnyObject) { + showTextInputPrompt(withMessage: "Email:") { [weak self] userPressedOK, email in + guard let strongSelf = self else { return } + guard let email = email else { + strongSelf.showMessagePrompt("email can't be empty") + return + } + strongSelf.showTextInputPrompt(withMessage: "Password:") { userPressedOK, password in + guard let password = password else { + strongSelf.showMessagePrompt("password can't be empty") + return + } + strongSelf.showSpinner { + // [START create_user] + Auth.auth().createUser(withEmail: email, password: password) { authResult, error in + // [START_EXCLUDE] + strongSelf.hideSpinner { + guard let user = authResult?.user, error == nil else { + strongSelf.showMessagePrompt(error!.localizedDescription) + return + } + print("\(user.email!) created") + strongSelf.navigationController?.popViewController(animated: true) + } + // [END_EXCLUDE] + } + // [END create_user] + } + } + } + } +} diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/MainViewController.swift b/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/MainViewController.swift new file mode 100644 index 000000000..71ab339e6 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/MainViewController.swift @@ -0,0 +1,1121 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import AuthenticationServices +import CryptoKit +import GameKit +import UIKit + +import FirebaseCore +import Security + +// [START usermanagement_view_import] +import FirebaseAuth +// [END usermanagement_view_import] +import GoogleSignIn +import FBSDKCoreKit +import FBSDKLoginKit + +private var isMFAEnabled = false + +@objc(MainViewController) +// [START signin_controller] +class MainViewController: UITableViewController { + // [END signin_controller] + + let kSectionMultiFactor = 4 + let kSectionToken = 3 + let kSectionProviders = 2 + let kSectionUser = 1 + let kSectionSignIn = 0 + + enum AuthProvider { + case authEmail + case authEmailMFA + case authAnonymous + case authApple + case authFacebook + case authGoogle + case authTwitter + case authGitHub + case authPhone + case authCustom + case authPasswordless + case authGameCenter + case authMicrosoft + } + + /*! @var kOKButtonText + @brief The text of the "OK" button for the Sign In result dialogs. + */ + let kOKButtonText = "OK" + + /*! @var kTokenRefreshedAlertTitle + @brief The title of the "Token Refreshed" alert. + */ + let kTokenRefreshedAlertTitle = "Token" + + /*! @var kTokenRefreshErrorAlertTitle + @brief The title of the "Token Refresh error" alert. + */ + let kTokenRefreshErrorAlertTitle = "Get Token Error" + + /** @var kSetDisplayNameTitle + @brief The title of the "Set Display Name" error dialog. + */ + let kSetDisplayNameTitle = "Set Display Name" + + /** @var kUnlinkTitle + @brief The text of the "Unlink from Provider" error Dialog. + */ + let kUnlinkTitle = "Unlink from Provider" + + /** @var kChangeEmailText + @brief The title of the "Change Email" button. + */ + let kChangeEmailText = "Change Email" + + /** @var kChangePasswordText + @brief The title of the "Change Password" button. + */ + let kChangePasswordText = "Change Password" + + /** @var kUpdatePhoneNumberText + @brief The title of the "Update Phone Number" button. + */ + let kUpdatePhoneNumberText = "Update Phone Number" + + /** @var handle + @brief The handler for the auth state listener, to allow cancelling later. + */ + var handle: AuthStateDidChangeListenerHandle? + + /** @var microsoftProvider + @brief The OAuth provider instance for Microsoft. + */ + var microsoftProvider: OAuthProvider? + + /** @var twitterProvider + @brief The OAuth provider instance for Twitter. + */ + var twitterProvider: OAuthProvider? + + /** @var gitHubProvider + @brief The OAuth provider instance for GitHub. + */ + var gitHubProvider: OAuthProvider? + + func showAuthPicker(_ providers: [AuthProvider]) { + let picker = UIAlertController(title: "Select Provider", + message: nil, + preferredStyle: .alert) + for provider in providers { + var action: UIAlertAction + switch provider { + case .authEmail: + action = UIAlertAction(title: "Email", style: .default) { UIAlertAction in + self.performSegue(withIdentifier: "email", sender: nil) + } + case .authEmailMFA: + action = UIAlertAction(title: "Email with MFA", style: .default) { UIAlertAction in + isMFAEnabled = true + self.performSegue(withIdentifier: "email", sender: nil) + } + case .authPasswordless: + action = UIAlertAction(title: "Passwordless", style: .default) { UIAlertAction in + self.performSegue(withIdentifier: "passwordless", sender: nil) + } + case .authCustom: + action = UIAlertAction(title: "Custom", style: .default) { UIAlertAction in + self.performSegue(withIdentifier: "customToken", sender: nil) + } + case .authAnonymous: + action = UIAlertAction(title: "Anonymous", style: .default) { UIAlertAction in + self.showSpinner { + // [START firebase_auth_anonymous] + Auth.auth().signInAnonymously { authResult, error in + // [START_EXCLUDE] + self.hideSpinner { + if let error = error { + self.showMessagePrompt(error.localizedDescription) + return + } + } + // [END_EXCLUDE] + } + // [END firebase_auth_anonymous] + } + } + case .authApple: + if #available(iOS 13, *) { + action = UIAlertAction(title: "Apple", style: .default) { UIAlertAction in + self.startSignInWithAppleFlow() + } + } else { + continue + } + case .authFacebook: + action = UIAlertAction(title: "Facebook", style: .default) { UIAlertAction in + let loginManager = LoginManager() + loginManager.logIn(permissions: ["email"], from: self, handler: { result, error in + if let error = error { + self.showMessagePrompt(error.localizedDescription) + } else if result!.isCancelled { + print("FBLogin cancelled") + } else { + // [START headless_facebook_auth] + let credential = FacebookAuthProvider + .credential(withAccessToken: AccessToken.current!.tokenString) + // [END headless_facebook_auth] + self.firebaseLogin(credential) + } + }) + } + case .authGoogle: + action = UIAlertAction(title: "Google", style: .default) { UIAlertAction in + self.startSignInWithGoogleFlow() + } + case .authTwitter: + action = UIAlertAction(title: "Twitter", style: .default) { UIAlertAction in + // [START firebase_auth_twitter] + self.twitterProvider?.getCredentialWith(_: nil) { credential, error in + self.showSpinner { + if let error = error { + self.hideSpinner { + self.showMessagePrompt(error.localizedDescription) + return + } + } + if let credential = credential { + Auth.auth().signIn(with: credential) { result, error in + self.hideSpinner { + if let error = error { + self.showMessagePrompt(error.localizedDescription) + return + } + } + } + } + } + } + // [END firebase_auth_twitter] + } + case .authGitHub: + action = UIAlertAction(title: "GitHub", style: .default) { UIAlertAction in + // [START firebase_auth_github] + self.gitHubProvider?.getCredentialWith(_: nil) { credential, error in + self.showSpinner { + if let error = error { + self.hideSpinner { + self.showMessagePrompt(error.localizedDescription) + return + } + } + if let credential = credential { + Auth.auth().signIn(with: credential) { result, error in + self.hideSpinner { + if let error = error { + self.showMessagePrompt(error.localizedDescription) + return + } + } + } + } + } + } + // [END firebase_auth_github] + } + case .authPhone: + action = UIAlertAction(title: "Phone", style: .default) { UIAlertAction in + self.showTextInputPrompt(withMessage: "Phone Number:") { userPressedOK, userInput in + if let phoneNumber = userInput { + self.showSpinner { + // [START phone_auth] + PhoneAuthProvider.provider() + .verifyPhoneNumber(phoneNumber, uiDelegate: nil) { verificationID, error in + // [START_EXCLUDE silent] + self.hideSpinner { + // [END_EXCLUDE] + if let error = error { + self.showMessagePrompt(error.localizedDescription) + return + } + // Sign in using the verificationID and the code sent to the user + // [START_EXCLUDE] + guard let verificationID = verificationID else { return } + self + .showTextInputPrompt(withMessage: "Verification Code:") { userPressedOK, verificationCode in + if let verificationCode = verificationCode { + // [START get_phone_cred] + let credential = PhoneAuthProvider.provider().credential( + withVerificationID: verificationID, + verificationCode: verificationCode + ) + // [END get_phone_cred] + self.firebaseLogin(credential) + } else { + self.showMessagePrompt("verification code can't be empty") + } + } + } + // [END_EXCLUDE] + } + // [END phone_auth] + } + } else { + self.showMessagePrompt("phone number can't be empty") + } + } + } + case .authGameCenter: + action = UIAlertAction(title: "Game Center", style: .default) { UIAlertAction in + // [START firebase_auth_gamecenter] + GameCenterAuthProvider.getCredential { credential, error in + self.showSpinner { + if let error = error { + self.hideSpinner { + self.showMessagePrompt(error.localizedDescription) + return + } + } + if let credential = credential { + Auth.auth().signIn(with: credential) { result, error in + self.hideSpinner { + if let error = error { + self.showMessagePrompt(error.localizedDescription) + return + } + } + } + } + } + } + // [END firebase_auth_gamecenter] + } + case .authMicrosoft: + action = UIAlertAction(title: "Microsoft", style: .default) { UIAlertAction in + // [START firebase_auth_microsoft] + self.microsoftProvider?.getCredentialWith(_: nil) { credential, error in + self.showSpinner { + if let error = error { + self.hideSpinner { + self.showMessagePrompt(error.localizedDescription) + return + } + } + if let credential = credential { + Auth.auth().signIn(with: credential) { result, error in + self.hideSpinner { + if let error = error { + self.showMessagePrompt(error.localizedDescription) + return + } + } + } + } + } + } + // [END firebase_auth_microsoft] + } + } + picker.addAction(action) + } + + picker.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) + present(picker, animated: true, completion: nil) + } + + @IBAction func didTapSignIn(_ sender: AnyObject) { + showAuthPicker([ + AuthProvider.authEmail, + AuthProvider.authAnonymous, + AuthProvider.authApple, + AuthProvider.authGoogle, + AuthProvider.authFacebook, + AuthProvider.authTwitter, + AuthProvider.authGitHub, + AuthProvider.authPhone, + AuthProvider.authCustom, + AuthProvider.authPasswordless, + AuthProvider.authGameCenter, + AuthProvider.authMicrosoft, + ]) + } + + @IBAction func didTapLink(_ sender: AnyObject) { + var providers = Set([ + AuthProvider.authGoogle, + AuthProvider.authFacebook, + AuthProvider.authTwitter, + AuthProvider.authPhone, + ]) + // Remove any existing providers. Note that this is not a complete list of + // providers, so always check the documentation for a complete reference: + // https://firebase.google.com/docs/auth + let user = Auth.auth().currentUser + for info in (user?.providerData)! { + switch info.providerID { + case TwitterAuthProviderID: + providers.remove(AuthProvider.authTwitter) + case FacebookAuthProviderID: + providers.remove(AuthProvider.authFacebook) + case GoogleAuthProviderID: + providers.remove(AuthProvider.authGoogle) + case PhoneAuthProviderID: + providers.remove(AuthProvider.authPhone) + default: + break + } + } + showAuthPicker(Array(providers)) + } + + func setTitleDisplay(_ user: User?) { + if let name = user?.displayName { + navigationItem.title = "Welcome \(name)" + } else { + navigationItem.title = "Authentication Example" + } + } + + func firebaseLogin(_ credential: AuthCredential) { + showSpinner { + if let user = Auth.auth().currentUser { + // [START link_credential] + user.link(with: credential) { authResult, error in + // [START_EXCLUDE] + self.hideSpinner { + if let error = error { + self.showMessagePrompt(error.localizedDescription) + return + } + self.tableView.reloadData() + } + // [END_EXCLUDE] + } + // [END link_credential] + } else { + // [START signin_credential] + Auth.auth().signIn(with: credential) { authResult, error in + // [START_EXCLUDE silent] + self.hideSpinner { + // [END_EXCLUDE] + if let error = error { + let authError = error as NSError + if isMFAEnabled, authError.code == AuthErrorCode.secondFactorRequired.rawValue { + // The user is a multi-factor user. Second factor challenge is required. + let resolver = authError + .userInfo[AuthErrorUserInfoMultiFactorResolverKey] as! MultiFactorResolver + var displayNameString = "" + for tmpFactorInfo in resolver.hints { + displayNameString += tmpFactorInfo.displayName ?? "" + displayNameString += " " + } + self.showTextInputPrompt( + withMessage: "Select factor to sign in\n\(displayNameString)", + completionBlock: { userPressedOK, displayName in + var selectedHint: PhoneMultiFactorInfo? + for tmpFactorInfo in resolver.hints { + if displayName == tmpFactorInfo.displayName { + selectedHint = tmpFactorInfo as? PhoneMultiFactorInfo + } + } + PhoneAuthProvider.provider() + .verifyPhoneNumber(with: selectedHint!, uiDelegate: nil, + multiFactorSession: resolver + .session) { verificationID, error in + if error != nil { + print( + "Multi factor start sign in failed. Error: \(error.debugDescription)" + ) + } else { + self.showTextInputPrompt( + withMessage: "Verification code for \(selectedHint?.displayName ?? "")", + completionBlock: { userPressedOK, verificationCode in + let credential: PhoneAuthCredential? = PhoneAuthProvider.provider() + .credential(withVerificationID: verificationID!, + verificationCode: verificationCode!) + let assertion: MultiFactorAssertion? = PhoneMultiFactorGenerator + .assertion(with: credential!) + resolver.resolveSignIn(with: assertion!) { authResult, error in + if error != nil { + print( + "Multi factor finanlize sign in failed. Error: \(error.debugDescription)" + ) + } else { + self.navigationController?.popViewController(animated: true) + } + } + } + ) + } + } + } + ) + } else { + self.showMessagePrompt(error.localizedDescription) + return + } + // [START_EXCLUDE] + self.showMessagePrompt(error.localizedDescription) + // [END_EXCLUDE] + return + } + // User is signed in + // [START_EXCLUDE] + // Merge prevUser and currentUser accounts and data + // ... + // [END_EXCLUDE] + // [START_EXCLUDE silent] + } + // [END_EXCLUDE] + } + // [END signin_credential] + } + } + } + + @IBAction func didTapSignOut(_ sender: AnyObject) { + // [START signout] + let firebaseAuth = Auth.auth() + do { + try firebaseAuth.signOut() + } catch let signOutError as NSError { + print("Error signing out: %@", signOutError) + } + // [END signout] + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + // [START auth_listener] + handle = Auth.auth().addStateDidChangeListener { auth, user in + // [START_EXCLUDE] + self.setTitleDisplay(user) + self.tableView.reloadData() + // [END_EXCLUDE] + } + // [END auth_listener] + microsoftProvider = OAuthProvider(providerID: "microsoft.com") + twitterProvider = OAuthProvider(providerID: "twitter.com") + gitHubProvider = OAuthProvider(providerID: "github.com") + // Authenticate Game Center Local Player + // Uncomment to sign in with Game Center + // self.authenticateGameCenterLocalPlayer() + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + // [START remove_auth_listener] + Auth.auth().removeStateDidChangeListener(handle!) + // [END remove_auth_listener] + } + + func authenticateGameCenterLocalPlayer() { + let localPlayer = GKLocalPlayer.local + localPlayer.authenticateHandler = { gcAuthViewController, error in + if let gcAuthViewController = gcAuthViewController { + // Pause any activities that require user interaction, then present the + // gcAuthViewController to the player. + self.present(gcAuthViewController, animated: true, completion: nil) + } else if localPlayer.isAuthenticated { + // Local player is logged in to Game Center. + } else { + // Error + if let error = error { + self.showMessagePrompt(error.localizedDescription) + return + } + } + } + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + switch section { + case kSectionSignIn: + return 1 + case kSectionUser, kSectionToken, kSectionMultiFactor: + if Auth.auth().currentUser != nil { + return 1 + } else { + return 0 + } + case kSectionProviders: + if let user = Auth.auth().currentUser { + return user.providerData.count + } + return 0 + default: + return 0 + } + } + + override func tableView(_ tableView: UITableView, + cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell: UITableViewCell? + switch indexPath.section { + case kSectionSignIn: + // [START current_user] + if Auth.auth().currentUser != nil { + // User is signed in. + // [START_EXCLUDE] + cell = tableView.dequeueReusableCell(withIdentifier: "SignOut") + // [END_EXCLUDE] + } else { + // No user is signed in. + // [START_EXCLUDE] + cell = tableView.dequeueReusableCell(withIdentifier: "SignIn") + // [END_EXCLUDE] + } + // [END current_user] + case kSectionUser: + cell = tableView.dequeueReusableCell(withIdentifier: "Profile") + // [START get_user_profile] + let user = Auth.auth().currentUser + // [END get_user_profile] + // [START user_profile] + if let user = user { + // The user's ID, unique to the Firebase project. + // Do NOT use this value to authenticate with your backend server, + // if you have one. Use getTokenWithCompletion:completion: instead. + let uid = user.uid + let email = user.email + let photoURL = user.photoURL + var multiFactorString = "MultiFactor: " + for info in user.multiFactor.enrolledFactors { + multiFactorString += info.displayName ?? "[DispayName]" + multiFactorString += " " + } + // [START_EXCLUDE] + let emailLabel = cell?.viewWithTag(1) as? UILabel + let userIDLabel = cell?.viewWithTag(2) as? UILabel + let profileImageView = cell?.viewWithTag(3) as? UIImageView + let multiFactorLabel = cell?.viewWithTag(4) as? UILabel + emailLabel?.text = email + userIDLabel?.text = uid + multiFactorLabel?.text = multiFactorString + if isMFAEnabled { + multiFactorLabel?.isHidden = false + } else { + multiFactorLabel?.isHidden = true + } + + struct last { + static var photoURL: URL? = nil + } + last.photoURL = photoURL // to prevent earlier image overwrites later one. + if let photoURL = photoURL { + DispatchQueue.global(qos: .default).async { + let data = try? Data(contentsOf: photoURL) + if let data = data { + let image = UIImage(data: data) + DispatchQueue.main.async { + if photoURL == last.photoURL { + profileImageView?.image = image + } + } + } + } + } else { + profileImageView?.image = UIImage(named: "ic_account_circle") + } + // [END_EXCLUDE] + } + // [END user_profile] + case kSectionProviders: + cell = tableView.dequeueReusableCell(withIdentifier: "Provider") + // [START provider_data] + let userInfo = Auth.auth().currentUser?.providerData[indexPath.row] + cell?.textLabel?.text = userInfo?.providerID + // Provider-specific UID + cell?.detailTextLabel?.text = userInfo?.uid + // [END provider_data] + case kSectionToken: + cell = tableView.dequeueReusableCell(withIdentifier: "Token") + let requestEmailButton = cell?.viewWithTag(4) as? UIButton + requestEmailButton?.isEnabled = (Auth.auth().currentUser?.email != nil) ? true : false + case kSectionMultiFactor: + cell = tableView.dequeueReusableCell(withIdentifier: "MultiFactor") + + default: + fatalError("Unknown section in UITableView") + } + return cell! + } + + override func tableView(_ tableView: UITableView, + titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) + -> String? { + return "Unlink" + } + + override func tableView(_ tableView: UITableView, + editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell + .EditingStyle { + if indexPath.section == kSectionProviders { + return .delete + } + return .none + } + + // Swipe to delete + override func tableView(_ tableView: UITableView, + commit editingStyle: UITableViewCell.EditingStyle, + forRowAt indexPath: IndexPath) { + if editingStyle == .delete { + let providerID = Auth.auth().currentUser?.providerData[indexPath.row].providerID + showSpinner { + // [START unlink_provider] + Auth.auth().currentUser?.unlink(fromProvider: providerID!) { user, error in + // [START_EXCLUDE] + self.hideSpinner { + if let error = error { + self.showMessagePrompt(error.localizedDescription) + return + } + tableView.reloadData() + } + // [END_EXCLUDE] + } + // [END unlink_provider] + } + } + } + + override func tableView(_ tableView: UITableView, + heightForRowAt indexPath: IndexPath) -> CGFloat { + if indexPath.section == kSectionUser { + return 200 + } + return 44 + } + + override func numberOfSections(in tableView: UITableView) -> Int { + if isMFAEnabled { + return 5 + } else { + return 4 + } + } + + @IBAction func didMultiFactorEnroll(_ sender: Any) { + let user = Auth.auth().currentUser + if user == nil { + print("Please sign in first.") + } else { + showTextInputPrompt(withMessage: "Phone Number") { userPressedOK, phoneNumber in + user?.multiFactor.getSessionWithCompletion { session, error in + PhoneAuthProvider.provider().verifyPhoneNumber( + phoneNumber!, + uiDelegate: nil, + multiFactorSession: session, + completion: { verificationID, error in + if let error = error { + self.showMessagePrompt(error.localizedDescription) + } else { + self.showTextInputPrompt( + withMessage: "Verification code", + completionBlock: { userPressedOK, verificationCode in + let credential = PhoneAuthProvider.provider() + .credential(withVerificationID: verificationID!, + verificationCode: verificationCode!) + let assertion = PhoneMultiFactorGenerator.assertion(with: credential) + self.showTextInputPrompt( + withMessage: "Display name", + completionBlock: { userPressedOK, displayName in + user?.multiFactor.enroll( + with: assertion, + displayName: displayName, + completion: { error in + if let error = error { + self.showMessagePrompt(error.localizedDescription) + } else { + print("Multi factor finanlize enroll succeeded.") + self.showTypicalUIForUserUpdateResults( + withTitle: "Multi Factor", + error: error + ) + } + } + ) + } + ) + } + ) + } + } + ) + } + } + } + } + + @IBAction func didMultiFactorUnenroll(_ sender: Any) { + var displayNameString = "" + for tmpFactorInfo in Auth.auth().currentUser!.multiFactor.enrolledFactors { + displayNameString += tmpFactorInfo.displayName ?? " " + displayNameString += " " + } + showTextInputPrompt(withMessage: "Multifactor Unenroll \(displayNameString)") { userPressedOK, displayName in + var factorInfo: MultiFactorInfo? + for tmpFactorInfo: MultiFactorInfo in Auth.auth().currentUser!.multiFactor.enrolledFactors { + if displayName == tmpFactorInfo.displayName { + factorInfo = tmpFactorInfo + } + } + Auth.auth().currentUser?.multiFactor.unenroll(with: factorInfo!, completion: { error in + if let error = error { + self.showMessagePrompt(error.localizedDescription) + } else { + print("Multi factor finanlize unenroll succeeded.") + self.showTypicalUIForUserUpdateResults(withTitle: "Multi Factor", error: error) + } + }) + } + } + + @IBAction func didTokenRefresh(_ sender: AnyObject) { + let action: AuthTokenCallback = { token, error in + let okAction = UIAlertAction(title: self.kOKButtonText, style: .default) { + action in print(self.kOKButtonText) + } + if let error = error { + let alertController = UIAlertController(title: self.kTokenRefreshErrorAlertTitle, + message: error.localizedDescription, + preferredStyle: .alert) + alertController.addAction(okAction) + self.present(alertController, animated: true, completion: nil) + return + } + + // Log token refresh event to Scion. + Analytics.logEvent("tokenrefresh", parameters: nil) + + let alertController = UIAlertController(title: self.kTokenRefreshedAlertTitle, + message: token, preferredStyle: .alert) + alertController.addAction(okAction) + self.present(alertController, animated: true, completion: nil) + } + // [START token_refresh] + Auth.auth().currentUser?.getIDTokenForcingRefresh(true, completion: action) + // [END token_refresh] + } + + /** @fn setDisplayName + @brief Changes the display name of the current user. + */ + @IBAction func didSetDisplayName(_ sender: AnyObject) { + showTextInputPrompt(withMessage: "Display Name:") { userPressedOK, userInput in + if let displayName = userInput { + self.showSpinner { + // [START profile_change] + let changeRequest = Auth.auth().currentUser?.createProfileChangeRequest() + changeRequest?.displayName = displayName + changeRequest?.commitChanges { error in + // [START_EXCLUDE] + self.hideSpinner { + self.showTypicalUIForUserUpdateResults( + withTitle: self.kSetDisplayNameTitle, + error: error as NSError? + ) + self.setTitleDisplay(Auth.auth().currentUser) + } + // [END_EXCLUDE] + } + // [END profile_change] + } + } else { + self.showMessagePrompt("displayname can't be empty") + } + } + } + + /** @fn requestVerifyEmail + @brief Requests a "verify email" email be sent. + */ + @IBAction func didRequestVerifyEmail(_ sender: AnyObject) { + showSpinner { + // [START send_verification_email] + Auth.auth().currentUser?.sendEmailVerification { error in + // [START_EXCLUDE] + self.hideSpinner { + if let error = error { + self.showMessagePrompt(error.localizedDescription) + return + } + self.showMessagePrompt("Sent") + } + // [END_EXCLUDE] + } + // [END send_verification_email] + } + } + + /** @fn changeEmail + @brief Changes the email address of the current user. + */ + @IBAction func didChangeEmail(_ sender: AnyObject) { + showTextInputPrompt(withMessage: "Email Address:") { userPressedOK, userInput in + if let email = userInput { + self.showSpinner { + // [START change_email] + Auth.auth().currentUser?.updateEmail(to: email) { error in + // [START_EXCLUDE] + self.hideSpinner { + self.showTypicalUIForUserUpdateResults(withTitle: self.kChangeEmailText, error: error) + } + // [END_EXCLUDE] + } + // [END change_email] + } + } else { + self.showMessagePrompt("email can't be empty") + } + } + } + + /** @fn changePassword + @brief Changes the password of the current user. + */ + @IBAction func didChangePassword(_ sender: AnyObject) { + showTextInputPrompt(withMessage: "New Password:") { userPressedOK, userInput in + if let password = userInput { + self.showSpinner { + // [START change_password] + Auth.auth().currentUser?.updatePassword(to: password) { error in + // [START_EXCLUDE] + self.hideSpinner { + self.showTypicalUIForUserUpdateResults( + withTitle: self.kChangePasswordText, + error: error + ) + } + // [END_EXCLUDE] + } + // [END change_password] + } + } else { + self.showMessagePrompt("password can't be empty") + } + } + } + + /** @fn updatePhoneNumber + @brief Updates the phone number of the current user. + */ + @IBAction func didUpdatePhoneNumber(_ sender: AnyObject) { + showTextInputPrompt(withMessage: "New Phone Number:") { userPressedOK, userInput in + if let phoneNumber = userInput { + self.showSpinner { + // [START update_phone] + PhoneAuthProvider.provider() + .verifyPhoneNumber(phoneNumber, uiDelegate: nil) { verificationID, error in + // [START_EXCLUDE] + self.hideSpinner { + if let error = error { + self.showMessagePrompt(error.localizedDescription) + return + } + guard let verificationID = verificationID else { return } + self + .showTextInputPrompt(withMessage: "Verification Code:") { userPressedOK, userInput in + if let verificationCode = userInput { + self.showSpinner { + // [END_EXCLUDE] + let credential = PhoneAuthProvider.provider() + .credential(withVerificationID: verificationID, + verificationCode: verificationCode) + Auth.auth().currentUser?.updatePhoneNumber(credential) { error in + // [END update_phone] + self.hideSpinner { + self.showTypicalUIForUserUpdateResults( + withTitle: self.kUpdatePhoneNumberText, + error: error + ) + } + } + } + } else { + self.showMessagePrompt("verification code can't be empty") + } + } + } + } + } + } else { + self.showMessagePrompt("phone number can't be empty") + } + } + } + + // MARK: - Helpers + + /** @fn showTypicalUIForUserUpdateResultsWithTitle:error: + @brief Shows a @c UIAlertView if error is non-nil with the localized description of the error. + @param resultsTitle The title of the @c UIAlertView + @param error The error details to display if non-nil. + */ + func showTypicalUIForUserUpdateResults(withTitle resultsTitle: String, error: Error?) { + if let error = error { + let message = "\(error.localizedDescription)" + let okAction = UIAlertAction(title: kOKButtonText, style: .default) { + action in print(self.kOKButtonText) + } + let alertController = UIAlertController(title: resultsTitle, + message: message, preferredStyle: .alert) + alertController.addAction(okAction) + present(alertController, animated: true, completion: nil) + return + } + tableView.reloadData() + } + + // MARK: - Sign in with Google + + func startSignInWithGoogleFlow() { + // [START headless_google_auth] + guard let clientID = FirebaseApp.app()?.options.clientID else { return } + + // Create Google Sign In configuration object. + let config = GIDConfiguration(clientID: clientID) + + // Start the sign in flow! + GIDSignIn.sharedInstance.signIn(with: config, presenting: self) { [unowned self] user, error in + + if let error = error { + // [START_EXCLUDE] + self.showMessagePrompt(error.localizedDescription) + // [END_EXCLUDE] + return + } + + // [START google_credential] + guard + let authentication = user?.authentication, + let idToken = authentication.idToken + else { + return + } + + let credential = GoogleAuthProvider.credential(withIDToken: idToken, + accessToken: authentication.accessToken) + // [END google_credential] + + // [START_EXCLUDE] + self.firebaseLogin(credential) + // [END_EXCLUDE] + } + // [END headless_google_auth] + } + + // MARK: - Sign in with Apple + + // Unhashed nonce. + fileprivate var currentNonce: String? + + @available(iOS 13, *) + func startSignInWithAppleFlow() { + let nonce = randomNonceString() + currentNonce = nonce + let appleIDProvider = ASAuthorizationAppleIDProvider() + let request = appleIDProvider.createRequest() + request.requestedScopes = [.fullName, .email] + request.nonce = sha256(nonce) + + let authorizationController = ASAuthorizationController(authorizationRequests: [request]) + authorizationController.delegate = self + authorizationController.presentationContextProvider = self + authorizationController.performRequests() + } + + // [START random_nonce] + private func randomNonceString(length: Int = 32) -> String { + precondition(length > 0) + var randomBytes = [UInt8](repeating: 0, count: length) + let errorCode = SecRandomCopyBytes(kSecRandomDefault, randomBytes.count, &randomBytes) + if errorCode != errSecSuccess { + fatalError( + "Unable to generate nonce. SecRandomCopyBytes failed with OSStatus \(errorCode)" + ) + } + + let charset: [Character] = + Array("0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._") + + let nonce = randomBytes.map { byte in + // Pick a random character from the set, wrapping around if needed. + charset[Int(byte) % charset.count] + } + + return String(nonce) + } + + // [END random_nonce] + + // [START sha_256] + @available(iOS 13, *) + private func sha256(_ input: String) -> String { + let inputData = Data(input.utf8) + let hashedData = SHA256.hash(data: inputData) + let hashString = hashedData.compactMap { + String(format: "%02x", $0) + }.joined() + + return hashString + } + + // [END sha_256] +} + +@available(iOS 13.0, *) +extension MainViewController: ASAuthorizationControllerDelegate { + func authorizationController(controller: ASAuthorizationController, + didCompleteWithAuthorization authorization: ASAuthorization) { + if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential { + guard let nonce = currentNonce else { + fatalError("Invalid state: A login callback was received, but no login request was sent.") + } + + guard let appleIDToken = appleIDCredential.identityToken else { + print("Unable to fetch identity token") + return + } + guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else { + print("Unable to serialize token string from data: \(appleIDToken.debugDescription)") + return + } + // Initialize a Firebase credential. + let credential = OAuthProvider.credential(withProviderID: "apple.com", + idToken: idTokenString, + rawNonce: nonce) + // Sign in with Firebase. + firebaseLogin(credential) + } + } + + func authorizationController(controller: ASAuthorizationController, + didCompleteWithError error: Error) { + // Handle error. + print("Sign in with Apple errored: \(error)") + } +} + +@available(iOS 13.0, *) +extension MainViewController: ASAuthorizationControllerPresentationContextProviding { + func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor { + return view.window! + } +} diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/PasswordlessViewController.swift b/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/PasswordlessViewController.swift new file mode 100644 index 000000000..b20fa588e --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/PasswordlessViewController.swift @@ -0,0 +1,98 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import FirebaseAuth +import UIKit + +@objc(PasswordlessViewController) +class PasswordlessViewController: UIViewController { + @IBOutlet var emailField: UITextField! + @IBOutlet var signInButton: UIButton! + var link: String! + + override func viewDidLoad() { + super.viewDidLoad() + emailField.text = UserDefaults.standard.value(forKey: "Email") as? String + if let link = UserDefaults.standard.value(forKey: "Link") as? String { + self.link = link + signInButton.isEnabled = true + } + } + + override func touchesBegan(_ touches: Set, with event: UIEvent?) { + view.endEditing(true) + } + + @IBAction func didTapSignInWithEmailLink(_ sender: AnyObject) { + if let email = emailField.text { + showSpinner { + // [START signin_emaillink] + Auth.auth().signIn(withEmail: email, link: self.link) { user, error in + // [START_EXCLUDE] + self.hideSpinner { + if let error = error { + self.showMessagePrompt(error.localizedDescription) + return + } + self.navigationController!.popViewController(animated: true) + } + // [END_EXCLUDE] + } + // [END signin_emaillink] + } + } else { + showMessagePrompt("Email can't be empty") + } + } + + @IBAction func didTapSendSignInLink(_ sender: AnyObject) { + if let email = emailField.text { + showSpinner { + // [START action_code_settings] + let actionCodeSettings = ActionCodeSettings() + actionCodeSettings.url = URL(string: "https://www.example.com") + // The sign-in operation has to always be completed in the app. + actionCodeSettings.handleCodeInApp = true + actionCodeSettings.setIOSBundleID(Bundle.main.bundleIdentifier!) + actionCodeSettings.setAndroidPackageName("com.example.android", + installIfNotAvailable: false, minimumVersion: "12") + // [END action_code_settings] + // [START send_signin_link] + Auth.auth().sendSignInLink(toEmail: email, + actionCodeSettings: actionCodeSettings) { error in + // [START_EXCLUDE] + self.hideSpinner { + // [END_EXCLUDE] + if let error = error { + self.showMessagePrompt(error.localizedDescription) + return + } + // The link was successfully sent. Inform the user. + // Save the email locally so you don't need to ask the user for it again + // if they open the link on the same device. + UserDefaults.standard.set(email, forKey: "Email") + self.showMessagePrompt("Check your email for link") + // [START_EXCLUDE] + } + // [END_EXCLUDE] + } + // [END send_signin_link] + } + } else { + showMessagePrompt("Email can't be empty") + } + } +} diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/UIViewController.swift b/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/UIViewController.swift new file mode 100644 index 000000000..fff377868 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExampleSwift/UIViewController.swift @@ -0,0 +1,98 @@ +// +// Copyright (c) 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 UIKit + +private class SaveAlertHandle { + static var alertHandle: UIAlertController? + + class func set(_ handle: UIAlertController) { + alertHandle = handle + } + + class func clear() { + alertHandle = nil + } + + class func get() -> UIAlertController? { + return alertHandle + } +} + +extension UIViewController { + /*! @fn showMessagePrompt + @brief Displays an alert with an 'OK' button and a message. + @param message The message to display. + */ + func showMessagePrompt(_ message: String) { + let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert) + let okAction = UIAlertAction(title: "OK", style: .default, handler: nil) + alert.addAction(okAction) + present(alert, animated: false, completion: nil) + } + + /*! @fn showTextInputPromptWithMessage + @brief Shows a prompt with a text field and 'OK'/'Cancel' buttons. + @param message The message to display. + @param completion A block to call when the user taps 'OK' or 'Cancel'. + */ + func showTextInputPrompt(withMessage message: String, + completionBlock: @escaping ((Bool, String?) -> Void)) { + let prompt = UIAlertController(title: nil, message: message, preferredStyle: .alert) + let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { _ in + completionBlock(false, nil) + } + weak var weakPrompt = prompt + let okAction = UIAlertAction(title: "OK", style: .default) { _ in + guard let text = weakPrompt?.textFields?.first?.text else { return } + completionBlock(true, text) + } + prompt.addTextField(configurationHandler: nil) + prompt.addAction(cancelAction) + prompt.addAction(okAction) + present(prompt, animated: true, completion: nil) + } + + /*! @fn showSpinner + @brief Shows the please wait spinner. + @param completion Called after the spinner has been hidden. + */ + func showSpinner(_ completion: (() -> Void)?) { + let alertController = UIAlertController(title: nil, message: "Please Wait...\n\n\n\n", + preferredStyle: .alert) + SaveAlertHandle.set(alertController) + let spinner = UIActivityIndicatorView(style: .whiteLarge) + spinner.color = UIColor(ciColor: .black) + spinner.center = CGPoint(x: alertController.view.frame.midX, + y: alertController.view.frame.midY) + spinner.autoresizingMask = [.flexibleBottomMargin, .flexibleTopMargin, + .flexibleLeftMargin, .flexibleRightMargin] + spinner.startAnimating() + alertController.view.addSubview(spinner) + present(alertController, animated: true, completion: completion) + } + + /*! @fn hideSpinner + @brief Hides the please wait spinner. + @param completion Called after the spinner has been hidden. + */ + func hideSpinner(_ completion: (() -> Void)?) { + if let controller = SaveAlertHandle.get() { + SaveAlertHandle.clear() + controller.dismiss(animated: true, completion: completion) + } + } +} diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExampleSwiftUITests/AuthenticationExampleSwiftUITests.swift b/authentication/LegacyAuthQuickstart/AuthenticationExampleSwiftUITests/AuthenticationExampleSwiftUITests.swift new file mode 100644 index 000000000..040d4c31e --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExampleSwiftUITests/AuthenticationExampleSwiftUITests.swift @@ -0,0 +1,34 @@ +// +// AuthenticationExampleSwiftUITests.swift +// AuthenticationExampleSwiftUITests +// +// Created by Ibrahim Ulukaya on 2/12/18. +// Copyright © 2018 Google Inc. All rights reserved. +// + +import XCTest + +class AuthenticationExampleSwiftUITests: XCTestCase { + override func setUp() { + super.setUp() + + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. + XCUIApplication().launch() + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } +} diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExampleSwiftUITests/Info.plist b/authentication/LegacyAuthQuickstart/AuthenticationExampleSwiftUITests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExampleSwiftUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExampleTests/AuthenticationExampleTests.m b/authentication/LegacyAuthQuickstart/AuthenticationExampleTests/AuthenticationExampleTests.m new file mode 100644 index 000000000..fb1abd026 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExampleTests/AuthenticationExampleTests.m @@ -0,0 +1,47 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +@interface AuthenticationExampleTests : XCTestCase + +@end + +@implementation AuthenticationExampleTests + +- (void)setUp { + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. +} + +- (void)testPerformanceExample { + // This is an example of a performance test case. + [self measureBlock:^{ + // Put the code you want to measure the time of here. + }]; +} + +@end diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExampleUITests/AuthenticationExampleUITests.m b/authentication/LegacyAuthQuickstart/AuthenticationExampleUITests/AuthenticationExampleUITests.m new file mode 100644 index 000000000..8cf832395 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExampleUITests/AuthenticationExampleUITests.m @@ -0,0 +1,321 @@ +// +// Copyright (c) 2019 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import "FIREGHelper.h" +#import "FIREGSignInHelper.h" + +typedef BOOL (^SystemAlertHandler)(XCUIElement *); +static SystemAlertHandler const alertHandler = ^(XCUIElement *element) { + if (element.buttons[@"Continue"].exists) { + [element.buttons[@"Continue"] tap]; + } + + if (element.buttons[@"WLAN Only"].exists) { + [element.buttons[@"WLAN Only"] tap]; + } + return YES; +}; + +static NSString *const header = @"Authentication Example"; +static NSString *const signInButton = @"Sign In"; +static NSString *const createButton = @"Create"; +static NSString *const signOutButton = @"Sign Out"; +static NSString *const linkButton = @"Link"; +static NSString *const optionsHeader = @"Select Provider"; +static NSString *const emailPlaceholder = @"Email"; +static NSString *const passwordPlaceholder = @"Password"; +static NSString *const okButton = @"OK"; +static NSString *const backButton = @"Back"; +static NSString *const googleProvider = @"Google"; +static NSString *const tokenRefreshButton = @"Token Refresh"; +static NSString *const requestVerifyEmail = @"Request Verify Email"; +static NSString *const cancelButton = @"Cancel"; +static NSString *const errorMessage = + @"Wrong password. Try again or click Forgot password to reset it."; +static NSString *const alertMessage = @"The user canceled the sign-in flow."; + +// Test account credentials. +static NSString *const testEmail = @"test@test.com"; +static NSString *const testPassword = @"test12"; + +@interface AuthenticationExampleUITests : XCTestCase +@property NSArray *signInOptions; +@end + +@implementation AuthenticationExampleUITests { + XCUIApplication *_app; + id signInPermissionMonitor; +} + +- (void)setUp { + [super setUp]; + self.continueAfterFailure = NO; + _app = [[XCUIApplication alloc] init]; + signInPermissionMonitor = + [self addUIInterruptionMonitorWithDescription:@"Allow Google Sign-In" handler:alertHandler]; + _signInOptions = @[ @"Email", @"Anonymous", @"Google", @"Facebook" ]; + [_app launch]; + + if ([self signedIn]) { + [self signOut]; + } + FIRWaitForVisible(_app.buttons[signInButton]); +} + +- (void)tearDown { + [self removeUIInterruptionMonitor:signInPermissionMonitor]; + [super tearDown]; +} + +- (void)testAuth { + // Verify that Auth Example app launched successfully and its title is visible. + XCTAssertTrue(_app.navigationBars[header].exists); +} + +- (void)testAuthOptions { + [_app.buttons[signInButton] tap]; + FIRWaitForVisible(_app.alerts[optionsHeader]); + + // Make sure various authentication options are present. + for (NSString *option in _signInOptions) { + XCTAssertTrue(_app.buttons[option].exists); + } +} + +- (void)testAuthAnonymously { + // Verify that user is able to authenticate anonymously. + [self signInWith:@"Anonymous"]; + + FIRWaitForVisible(_app.buttons[signOutButton]); + XCTAssertTrue(_app.buttons[linkButton].exists); + [self signOut]; +} + +- (void)testAuthExistingAccount { + [self signInWith:@"Email"]; + FIRWaitForVisible(_app.buttons[createButton]); + + XCUIElement *inputText = [[_app textFields] elementBoundByIndex:0]; + FIRWaitForVisible(inputText); + [inputText tap]; + [inputText typeText:testEmail]; + + XCUIElement *password = [[_app secureTextFields] elementBoundByIndex:0]; + FIRWaitForVisible(password); + [password tap]; + [password typeText:testPassword]; + + [[_app buttons][signInButton] tap]; + FIRWaitForVisible(_app.buttons[signOutButton]); + XCTAssertTrue([self signedIn], @"User should be able to sign-in with existing credentials"); + [self signOut]; +} + +- (void)testAuthExistingAccountWrongPassword { + [self signInWith:@"Email"]; + FIRWaitForVisible(_app.buttons[createButton]); + + XCUIElement *inputText = [[_app textFields] elementBoundByIndex:0]; + FIRWaitForVisible(inputText); + [inputText tap]; + [inputText typeText:testEmail]; + + XCUIElement *password = [[_app secureTextFields] elementBoundByIndex:0]; + FIRWaitForVisible(password); + [password tap]; + [password typeText:@"wrong password"]; + + [[_app buttons][signInButton] tap]; + XCUIElement *error = + _app.alerts.staticTexts[@"The password is invalid or the user does not have a password."]; + FIRWaitForVisible(error); + XCTAssertTrue(error.exists); + + [self dismissAlertIfOpen]; + [self goBack]; + + XCTAssertFalse([self signedIn], @"User shouldn't be able to sign-in with wrong credentials"); +} + +- (void)testCreateAccountBadPassword { + [self signInWith:@"Email"]; + FIRWaitForVisible(_app.buttons[createButton]); + + // 5 characters is not long enough, user should see an error. + [self createLogin:testEmail withPassword:randomString(5)]; + + XCUIElement *error = _app.alerts.staticTexts[@"The password must be 6 characters long or more."]; + FIRWaitForVisible(error); + XCTAssertTrue(error.exists); + + [self dismissAlertIfOpen]; + [self goBack]; + XCTAssertFalse([self signedIn], @"User shouldn't be signed in with a weak password"); +} + +- (void)testCreateAlreadyExistingAccount { + [self signInWith:@"Email"]; + FIRWaitForVisible(_app.buttons[createButton]); + + // This account is already created. + [self createLogin:testEmail withPassword:testPassword]; + + XCUIElement *error = + _app.alerts.staticTexts[@"The email address is already in use by another account."]; + FIRWaitForVisible(error); + XCTAssertTrue(error.exists); + + [self dismissAlertIfOpen]; + [self goBack]; + XCTAssertFalse([self signedIn], @"User shouldn't be able to create an already existing account"); +} + +- (void)testCreateAccountCorrectPassword { + [self signInWith:@"Email"]; + FIRWaitForVisible(_app.buttons[createButton]); + + // These are valid credentials. + NSString *newEmail = [timestamp() stringByAppendingString:@"_test@test.com"]; + NSString *newPassword = randomString(10); + [self createLogin:newEmail withPassword:newPassword]; + + FIRWaitForVisible(_app.buttons[signOutButton]); + XCTAssertTrue([self signedIn], @"User should be signed in with newly created credentials"); + [self signOut]; +} + +// TODO(b/140411106): Fix the GoogleSignIn breakage. +- (void)FAILING_testGoogleSignInAndLinkAccount { + [self signInWith:@"Google"]; + + // User can be signed in right away, without following Google Sign-In flow. + if (![self signedIn]) { + doGoogleSignIn(_app, YES, YES); + // Wait till all alerts and spinners are gone. + FIRWaitForVisible(_app.buttons[signOutButton]); + } + // Make sure user is signed in. + XCTAssertTrue([self signedIn], @"User should be able to sign-in with existing credentials"); + + // Make sure all the required UI elements are present. + XCTAssertTrue(_app.buttons[tokenRefreshButton].exists); + XCTAssertTrue(_app.buttons[requestVerifyEmail].exists); + XCTAssertTrue(_app.buttons[linkButton].exists); + + // Sign out from this Google account. + [self signOut]; + XCTAssertFalse([self signedIn], @"User should be signed out"); + + // Sign in anonymously. + [self signInWith:@"Anonymous"]; + XCTAssertTrue([self signedIn], @"User should be able to sign-in anonymously"); + + // Try to link anonymous accout with exisiting Google account. + FIRWaitForVisible(_app.buttons[linkButton]); + [_app.buttons[linkButton] tap]; + FIRWaitForVisible(_app.buttons[@"Google"]); + [_app.buttons[@"Google"] tap]; + + XCUIElement *error = + _app.alerts + .staticTexts[@"This credential is already associated with a different user account."]; + FIRWaitForVisible(error); + XCTAssertTrue(error.exists); + + // Dismiss the alert. + [self dismissAlertIfOpen]; + + [self signOut]; +} + +// TODO(b/140411106): Fix the GoogleSignIn breakage. +- (void)FAILING_testGoogleSignInWrongPasswordAndCancelFlow { + [self signInWith:@"Google"]; + if (![self signedIn]) { + // Try to sign in with invalid credentials. + doGoogleSignIn(_app, NO, YES); + + XCUIElement *error = _app.staticTexts[errorMessage]; + XCTAssertTrue([error exists], @"Error message should be present."); + + // Close Safari ViewController. + [_app.buttons[cancelButton] tap]; + + // Make sure the correct alert message appears. + FIRWaitForVisible(_app.alerts.staticTexts[alertMessage]); + + // Dismiss the alert. + [self dismissAlertIfOpen]; + } +} + +#pragma mark - Helpers + +- (void)signInWith:(NSString *)provider { + FIRWaitForVisible(_app.buttons[signInButton]); + [_app.buttons[signInButton] tap]; + FIRWaitForVisible(_app.buttons[provider]); + [_app.buttons[provider] tap]; +} + +- (void)signOut { + FIRWaitForVisible(_app.buttons[signOutButton]); + [_app.buttons[signOutButton] tap]; + XCTAssertTrue(_app.buttons[signInButton].exists); +} + +- (BOOL)signedIn { + FIRWaitForVisible(_app.buttons[signOutButton]); + return _app.buttons[signOutButton].exists; +} + +// Navigate back using Navigation Controller (back button could different on different OS, +// so both options are checked). +- (void)goBack { + FIRWaitForVisible(_app.buttons[backButton]); + if (_app.buttons[backButton].exists) { + [_app.buttons[backButton] tap]; + } else { + [[_app.navigationBars.buttons firstMatch] tap]; + } +} + +// Dismiss alert by tapping "OK" button. +- (void)dismissAlertIfOpen { + XCUIElement *button = _app.buttons[okButton]; + FIRWaitForVisible(button); + if (button.exists) { + [button tap]; + } +} + +- (void)createLogin:(NSString *)login withPassword:(NSString *)password { + FIRWaitForVisible(_app.buttons[createButton]); + [_app.buttons[createButton] tap]; + + XCUIElement *inputText = [[[_app alerts] textFields] elementBoundByIndex:0]; + FIRWaitForVisible(inputText); + [inputText typeText:login]; + [[_app buttons][okButton] tap]; + + XCUIElement *passwordField = [[[_app alerts] textFields] elementBoundByIndex:0]; + FIRWaitForVisible(passwordField); + [passwordField typeText:password]; + [[_app buttons][okButton] tap]; +} + +@end diff --git a/authentication/LegacyAuthQuickstart/AuthenticationExampleUITests/Info.plist b/authentication/LegacyAuthQuickstart/AuthenticationExampleUITests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/AuthenticationExampleUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/authentication/LegacyAuthQuickstart/Podfile b/authentication/LegacyAuthQuickstart/Podfile new file mode 100644 index 000000000..e842b1c87 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/Podfile @@ -0,0 +1,21 @@ +# AuthenticationExample + +use_frameworks! +platform :ios, '15.0' +pod 'FirebaseAnalytics' +# [START auth_pod] +pod 'FirebaseAuth' +# [END auth_pod] + +# These are pods used for the auth providers. +pod 'FBSDKLoginKit' +# [START google_pod] +pod 'GoogleSignIn' +# [END google_pod] + +target 'AuthenticationExample' do +end +target 'AuthenticationExampleSwift' do +end +target 'AuthenticationExampleTests' do +end diff --git a/authentication/LegacyAuthQuickstart/Podfile.lock b/authentication/LegacyAuthQuickstart/Podfile.lock new file mode 100644 index 000000000..4a3fb2175 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/Podfile.lock @@ -0,0 +1,192 @@ +PODS: + - AppAuth (2.0.0): + - AppAuth/Core (= 2.0.0) + - AppAuth/ExternalUserAgent (= 2.0.0) + - AppAuth/Core (2.0.0) + - AppAuth/ExternalUserAgent (2.0.0): + - AppAuth/Core + - AppCheckCore (11.2.0): + - GoogleUtilities/Environment (~> 8.0) + - GoogleUtilities/UserDefaults (~> 8.0) + - PromisesObjC (~> 2.4) + - FBAEMKit (18.0.1): + - FBSDKCoreKit_Basics (= 18.0.1) + - FBSDKCoreKit (18.0.1): + - FBAEMKit (= 18.0.1) + - FBSDKCoreKit_Basics (= 18.0.1) + - FBSDKCoreKit_Basics (18.0.1) + - FBSDKLoginKit (18.0.1): + - FBSDKCoreKit (= 18.0.1) + - FirebaseAnalytics (12.6.0): + - FirebaseAnalytics/Default (= 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseAnalytics/Default (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleAppMeasurement/Default (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseAppCheckInterop (12.6.0) + - FirebaseAuth (12.6.0): + - FirebaseAppCheckInterop (~> 12.6.0) + - FirebaseAuthInterop (~> 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseCoreExtension (~> 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/Environment (~> 8.1) + - GTMSessionFetcher/Core (< 6.0, >= 3.4) + - RecaptchaInterop (~> 101.0) + - FirebaseAuthInterop (12.6.0) + - FirebaseCore (12.6.0): + - FirebaseCoreInternal (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreExtension (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseCoreInternal (12.6.0): + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseInstallations (12.6.0): + - FirebaseCore (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - PromisesObjC (~> 2.4) + - GoogleAdsOnDeviceConversion (3.2.0): + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Core (12.6.0): + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Default (12.6.0): + - GoogleAdsOnDeviceConversion (~> 3.2.0) + - GoogleAppMeasurement/Core (= 12.6.0) + - GoogleAppMeasurement/IdentitySupport (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/IdentitySupport (12.6.0): + - GoogleAppMeasurement/Core (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleSignIn (9.0.0): + - AppAuth (~> 2.0) + - AppCheckCore (~> 11.0) + - GTMAppAuth (~> 5.0) + - GTMSessionFetcher/Core (~> 3.3) + - GoogleUtilities/AppDelegateSwizzler (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Privacy + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - GoogleUtilities/MethodSwizzler (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/Network (8.1.0): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Privacy + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (8.1.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/Reachability (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/UserDefaults (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GTMAppAuth (5.0.0): + - AppAuth/Core (~> 2.0) + - GTMSessionFetcher/Core (< 4.0, >= 3.3) + - GTMSessionFetcher/Core (3.5.0) + - nanopb (3.30910.0): + - nanopb/decode (= 3.30910.0) + - nanopb/encode (= 3.30910.0) + - nanopb/decode (3.30910.0) + - nanopb/encode (3.30910.0) + - PromisesObjC (2.4.0) + - RecaptchaInterop (101.0.0) + +DEPENDENCIES: + - FBSDKLoginKit + - FirebaseAnalytics + - FirebaseAuth + - GoogleSignIn + +SPEC REPOS: + trunk: + - AppAuth + - AppCheckCore + - FBAEMKit + - FBSDKCoreKit + - FBSDKCoreKit_Basics + - FBSDKLoginKit + - FirebaseAnalytics + - FirebaseAppCheckInterop + - FirebaseAuth + - FirebaseAuthInterop + - FirebaseCore + - FirebaseCoreExtension + - FirebaseCoreInternal + - FirebaseInstallations + - GoogleAdsOnDeviceConversion + - GoogleAppMeasurement + - GoogleSignIn + - GoogleUtilities + - GTMAppAuth + - GTMSessionFetcher + - nanopb + - PromisesObjC + - RecaptchaInterop + +SPEC CHECKSUMS: + AppAuth: 1c1a8afa7e12f2ec3a294d9882dfa5ab7d3cb063 + AppCheckCore: cc8fd0a3a230ddd401f326489c99990b013f0c4f + FBAEMKit: b2ed182002dbcb65d5a60059c9693d322186cd00 + FBSDKCoreKit: 7f96852f2539bdb88ba8d47e5ab4ae70a6f8d691 + FBSDKCoreKit_Basics: 22d4c1a509ded4e45116f3bb167a14907550f62e + FBSDKLoginKit: f48c06446995cd209332831f692cea28b26e51da + FirebaseAnalytics: d0a97a0db6425e5a5d966340b87f92ca7b13a557 + FirebaseAppCheckInterop: e2178171b4145013c7c1a3cc464d1d446d3a1896 + FirebaseAuth: 613c463cb43545a7fd2cd99ade09b78ac472c544 + FirebaseAuthInterop: db06756ef028006d034b6004dc0c37c24f7828d4 + FirebaseCore: 0e38ad5d62d980a47a64b8e9301ffa311457be04 + FirebaseCoreExtension: 032fd6f8509e591fda8cb76f6651f20d926b121f + FirebaseCoreInternal: 69bf1306a05b8ac43004f6cc1f804bb7b05b229e + FirebaseInstallations: 631b38da2e11a83daa4bfb482f79d286a5dfa7ad + GoogleAdsOnDeviceConversion: d68c69dd9581a0f5da02617b6f377e5be483970f + GoogleAppMeasurement: 3bf40aff49a601af5da1c3345702fcb4991d35ee + GoogleSignIn: c7f09cfbc85a1abf69187be091997c317cc33b77 + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + GTMAppAuth: 217a876b249c3c585a54fd6f73e6b58c4f5c4238 + GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 + nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + RecaptchaInterop: 11e0b637842dfb48308d242afc3f448062325aba + +PODFILE CHECKSUM: 49d8a9dbfae5766ae10c73fa8acdf33de4335530 + +COCOAPODS: 1.16.2 diff --git a/authentication/LegacyAuthQuickstart/README.md b/authentication/LegacyAuthQuickstart/README.md new file mode 100644 index 000000000..a3c2a22c9 --- /dev/null +++ b/authentication/LegacyAuthQuickstart/README.md @@ -0,0 +1,130 @@ +Firebase Authentication Quickstart +============================= + +Introduction +------------ + +- [Read more about Firebase Authentication](https://firebase.google.com/docs/auth/) + +Getting Started +--------------- + +- [Add Firebase to your iOS Project](https://firebase.google.com/docs/ios/setup). + + +### Google Sign In Setup +- Go to the [Firebase Console](https://console.firebase.google.com) and navigate to your project: + - Select the **Auth** panel and then click the **Sign In Method** tab. + - Click **Google** and turn on the **Enable** switch, then click **Save**. +- In Xcode, [add a custom URL scheme for your reversed client ID](https://developers.google.com/identity/sign-in/ios/start-integrating). + - You can find this in the `GoogleService-Info.plist` +- Run the app on your device or simulator. + - Select **Sign In** and select Google to begin. + +### Sign in with Apple Setup +- Go to the [Firebase Console](https://console.firebase.google.com) and navigate to your project: + - Select the **Auth** panel and then click the **Sign In Method** tab. + - Click **Apple** and turn on the **Enable** switch, then click **Save**. +- Run the app on your device or simulator. + - Select **Sign In** and select Apple to begin. +- See the [Getting Started guide](https://firebase.google.com/docs/auth/ios/apple) for more details. + +### Microsoft Sign In Setup +- Go to the [Firebase Console](https://console.firebase.google.com) and navigate to your project: + - Select the **Auth** panel and then click the **Sign In Method** tab. + - Click **Microsoft** and turn on the **Enable** switch, then click **Save**. +- In Xcode, [add a custom URL scheme for your reversed client ID](https://developers.google.com/identity/sign-in/ios/start-integrating). + - You can find this in the `GoogleService-Info.plist` +- Run the app on your device or simulator. + - Select **Sign In** and select Microsoft to begin. + +### Facebook Login Setup +- Go to the [Facebook Developers Site](https://developers.facebook.com) and follow all + instructions to set up a new iOS app. When asked for a bundle ID, use + `com.google.firebase.quickstart.AuthenticationExample`. +- Go to the [Firebase Console](https://console.firebase.google.com) and navigate to your project: + - Select the **Auth** panel and then click the **Sign In Method** tab. + - Click **Facebook** and turn on the **Enable** switch, then click **Save**. + - Enter your Facebook **App Id** and **App Secret** and click **Save**. +- Open your regular `Info.plist` and replace the value of the `FacebookAppID` with the ID of the + Facebook app you just created, e.g 124567. Save that file. +- In the *Info* tab of your target settings add a *URL Type* with a *URL Scheme* of 'fb' + the ID + of your Facebook app, e.g. fb1234567. +- Run the app on your device or simulator. + - Select **Sign In** and select Facebook to begin. + +### Email/Password Setup +- Go to the [Firebase Console](https://console.firebase.google.com) and navigate to your project: + - Select the **Auth** panel and then click the **Sign In Method** tab. + - Click **Email/Password** and turn on the **Enable** switch, then click **Save**. +- Run the app on your device or simulator. + - Select **Sign In** and select Email to begin. + +### Multi Factor Authentication +**Note**: Multi Factor authentication only works for apps using [Google Cloud Identity Platform](https://cloud.google.com/identity-platform/docs/ios/mfa), +a paid service. If you are only using Firebase Authentication this sample will not work for you. + +- Run the app on your device + - Select **Email (with MFA)** from the main screen. + - Sign in (if necessary). + - Verify your email (if necessary). + - Hit **Enroll MFA** to begin enrolling an SMS second factor. + +### Twitter Login Setup +- [Register your app](https://apps.twitter.com) as a developer application on Twitter and get your + app's OAuth API key and API secret. +- Go to the [Firebase Console](https://console.firebase.google.com) and navigate to your project: + - Select the **Auth** panel and then click the **Sign In Method** tab. + - Click **Twitter** and turn on the **Enable** switch, then click **Save**. + - Enter your Twitter **API Key** and **App Secret** and click **Save**. + - Make sure your Firebase OAuth redirect URI (e.g. my-app-12345.firebaseapp.com/__/auth/handler) is set as your + Authorization callback URL in your app's settings page on your [Twitter app's config](https://apps.twitter.com). +- Run the app on your device or simulator. + - Select **Sign In** and select Twitter to begin. + +### Custom Authentication Setup +- In the [Firebase Console](https://console.firebase.google.com/), navigate to **Project settings**: + - Navigate to the **Service accounts** tab. + - Locate the section **All service account**, and click on the `X service accounts` link. This will take you to the Google Cloud Console. +- In the [Google Cloud Console](https://console.cloud.google.com): + - Make sure the right Firebase project is selected. + - From the left "hamburger" menu navigate to the **API Manager** tab. + - Click on the **Credentials** item in the left column. + - Click **New credentials** and select **Service account key**. Select **New service account**, + pick any name, and select **JSON** as the key type. Then click **Create**. + - You should now have a new JSON file for your service account in your Downloads directory. +- In the `quickstart-ios/authentication/LegacyAuthQuickstart/web` directory: + - Open the file `auth.html` in your computer's web browser. + - Click **Choose File** and upload the JSON file you just downloaded. + - Enter any User ID and click **Generate**. + - Copy the token link displayed. +- Run the app on the simulator. + - Select **Sign In** and select Custom to begin. + - Paste in the token you generated earlier. + - When you return to the main screen, you should see the User ID you entered when generating the + token. + +Support +------- + +- [Firebase Support](https://firebase.google.com/support/) + +License +------- + +Copyright 2016 Google, Inc. + +Licensed to the Apache Software Foundation (ASF) under one or more contributor +license agreements. See the NOTICE file distributed with this work for +additional information regarding copyright ownership. The ASF licenses this +file to you under the Apache License, Version 2.0 (the "License"); you may not +use this file except in compliance with the License. You may obtain a copy of +the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +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/authentication/web/auth.html b/authentication/LegacyAuthQuickstart/web/auth.html similarity index 100% rename from authentication/web/auth.html rename to authentication/LegacyAuthQuickstart/web/auth.html diff --git a/authentication/Podfile b/authentication/Podfile new file mode 100644 index 000000000..acef538d9 --- /dev/null +++ b/authentication/Podfile @@ -0,0 +1,28 @@ +# Uncomment the next line to define a global platform for your project +platform :ios, '15.0' + +target 'AuthenticationExample' do + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + + # Pods for AuthenticationExample + ## Firebase đŸ”¥ Pods + pod 'FirebaseAnalytics' + pod 'FirebaseAuth' + + ## Pod for Sign in with Google + pod 'GoogleSignIn' + + ## Pod for Sign in with Facebook + pod 'FBSDKLoginKit' + + target 'AuthenticationExampleTests' do + inherit! :search_paths + # Pods for testing + end + + target 'AuthenticationExampleUITests' do + # Pods for testing + end + +end diff --git a/authentication/Podfile.lock b/authentication/Podfile.lock new file mode 100644 index 000000000..d4df73c70 --- /dev/null +++ b/authentication/Podfile.lock @@ -0,0 +1,192 @@ +PODS: + - AppAuth (2.0.0): + - AppAuth/Core (= 2.0.0) + - AppAuth/ExternalUserAgent (= 2.0.0) + - AppAuth/Core (2.0.0) + - AppAuth/ExternalUserAgent (2.0.0): + - AppAuth/Core + - AppCheckCore (11.2.0): + - GoogleUtilities/Environment (~> 8.0) + - GoogleUtilities/UserDefaults (~> 8.0) + - PromisesObjC (~> 2.4) + - FBAEMKit (18.0.1): + - FBSDKCoreKit_Basics (= 18.0.1) + - FBSDKCoreKit (18.0.1): + - FBAEMKit (= 18.0.1) + - FBSDKCoreKit_Basics (= 18.0.1) + - FBSDKCoreKit_Basics (18.0.1) + - FBSDKLoginKit (18.0.1): + - FBSDKCoreKit (= 18.0.1) + - FirebaseAnalytics (12.6.0): + - FirebaseAnalytics/Default (= 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseAnalytics/Default (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleAppMeasurement/Default (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseAppCheckInterop (12.6.0) + - FirebaseAuth (12.6.0): + - FirebaseAppCheckInterop (~> 12.6.0) + - FirebaseAuthInterop (~> 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseCoreExtension (~> 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/Environment (~> 8.1) + - GTMSessionFetcher/Core (< 6.0, >= 3.4) + - RecaptchaInterop (~> 101.0) + - FirebaseAuthInterop (12.6.0) + - FirebaseCore (12.6.0): + - FirebaseCoreInternal (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreExtension (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseCoreInternal (12.6.0): + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseInstallations (12.6.0): + - FirebaseCore (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - PromisesObjC (~> 2.4) + - GoogleAdsOnDeviceConversion (3.2.0): + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Core (12.6.0): + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Default (12.6.0): + - GoogleAdsOnDeviceConversion (~> 3.2.0) + - GoogleAppMeasurement/Core (= 12.6.0) + - GoogleAppMeasurement/IdentitySupport (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/IdentitySupport (12.6.0): + - GoogleAppMeasurement/Core (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleSignIn (9.0.0): + - AppAuth (~> 2.0) + - AppCheckCore (~> 11.0) + - GTMAppAuth (~> 5.0) + - GTMSessionFetcher/Core (~> 3.3) + - GoogleUtilities/AppDelegateSwizzler (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Privacy + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - GoogleUtilities/MethodSwizzler (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/Network (8.1.0): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Privacy + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (8.1.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/Reachability (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/UserDefaults (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GTMAppAuth (5.0.0): + - AppAuth/Core (~> 2.0) + - GTMSessionFetcher/Core (< 4.0, >= 3.3) + - GTMSessionFetcher/Core (3.5.0) + - nanopb (3.30910.0): + - nanopb/decode (= 3.30910.0) + - nanopb/encode (= 3.30910.0) + - nanopb/decode (3.30910.0) + - nanopb/encode (3.30910.0) + - PromisesObjC (2.4.0) + - RecaptchaInterop (101.0.0) + +DEPENDENCIES: + - FBSDKLoginKit + - FirebaseAnalytics + - FirebaseAuth + - GoogleSignIn + +SPEC REPOS: + trunk: + - AppAuth + - AppCheckCore + - FBAEMKit + - FBSDKCoreKit + - FBSDKCoreKit_Basics + - FBSDKLoginKit + - FirebaseAnalytics + - FirebaseAppCheckInterop + - FirebaseAuth + - FirebaseAuthInterop + - FirebaseCore + - FirebaseCoreExtension + - FirebaseCoreInternal + - FirebaseInstallations + - GoogleAdsOnDeviceConversion + - GoogleAppMeasurement + - GoogleSignIn + - GoogleUtilities + - GTMAppAuth + - GTMSessionFetcher + - nanopb + - PromisesObjC + - RecaptchaInterop + +SPEC CHECKSUMS: + AppAuth: 1c1a8afa7e12f2ec3a294d9882dfa5ab7d3cb063 + AppCheckCore: cc8fd0a3a230ddd401f326489c99990b013f0c4f + FBAEMKit: b2ed182002dbcb65d5a60059c9693d322186cd00 + FBSDKCoreKit: 7f96852f2539bdb88ba8d47e5ab4ae70a6f8d691 + FBSDKCoreKit_Basics: 22d4c1a509ded4e45116f3bb167a14907550f62e + FBSDKLoginKit: f48c06446995cd209332831f692cea28b26e51da + FirebaseAnalytics: d0a97a0db6425e5a5d966340b87f92ca7b13a557 + FirebaseAppCheckInterop: e2178171b4145013c7c1a3cc464d1d446d3a1896 + FirebaseAuth: 613c463cb43545a7fd2cd99ade09b78ac472c544 + FirebaseAuthInterop: db06756ef028006d034b6004dc0c37c24f7828d4 + FirebaseCore: 0e38ad5d62d980a47a64b8e9301ffa311457be04 + FirebaseCoreExtension: 032fd6f8509e591fda8cb76f6651f20d926b121f + FirebaseCoreInternal: 69bf1306a05b8ac43004f6cc1f804bb7b05b229e + FirebaseInstallations: 631b38da2e11a83daa4bfb482f79d286a5dfa7ad + GoogleAdsOnDeviceConversion: d68c69dd9581a0f5da02617b6f377e5be483970f + GoogleAppMeasurement: 3bf40aff49a601af5da1c3345702fcb4991d35ee + GoogleSignIn: c7f09cfbc85a1abf69187be091997c317cc33b77 + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + GTMAppAuth: 217a876b249c3c585a54fd6f73e6b58c4f5c4238 + GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 + nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + RecaptchaInterop: 11e0b637842dfb48308d242afc3f448062325aba + +PODFILE CHECKSUM: e961b5862c2d62d7c01199e7e7e4a138bedd8395 + +COCOAPODS: 1.16.2 diff --git a/authentication/README.md b/authentication/README.md index 8da6949af..40a9df48e 100644 --- a/authentication/README.md +++ b/authentication/README.md @@ -5,6 +5,8 @@ This Firebase quickstart is written in Swift and aims to showcase how Firebase Auth can help manage user authentication. You can read more about Firebase Auth [here](https://firebase.google.com/docs/auth)! +To view the older Objective-C and Swift quickstarts, view the [`LegacyAuthQuickstart`](https://github.com/firebase/quickstart-ios/blob/main/authentication/LegacyAuthQuickstart) directory. + ## Getting Started Firebase Auth offers multiple ways to authenticate users. In this quickstart, we demonstrate how you can use Firebase Auth to authenticate users by providing implementations for the various authentication flows. Since each Firebase Auth flow is different, each may require a few extra steps to set everything up. Feel free to follow along and configure as many authentication flows as you would like to demo! @@ -296,7 +298,7 @@ If you wish to setup a custom auth system. The below steps can help in its confi - Click **New credentials** and select **Service account key**. Select **New service account**, pick any name, and select **JSON** as the key type. Then click **Create**. - You should now have a new JSON file for your service account in your Downloads directory. -- Open the file `web/auth.html` in your computer's web browser. The `auth.html` file can now be found in the current directory's `web` subdirectory. +- Open the file `web/auth.html` in your computer's web browser. The `auth.html` file can now be found in the current directory's `LegacyAuthQuickstart` subdirectory. - Click **Choose File** and upload the JSON file you just downloaded. - Enter any User ID and click **Generate**. - Copy the token link displayed. diff --git a/config/ConfigExample.xcodeproj/project.pbxproj b/config/ConfigExample.xcodeproj/project.pbxproj index 17ada2e54..19a7b5a06 100644 --- a/config/ConfigExample.xcodeproj/project.pbxproj +++ b/config/ConfigExample.xcodeproj/project.pbxproj @@ -3,14 +3,13 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 50; objects = { /* Begin PBXBuildFile section */ 16F8E38C3F42EB1FE8184C90 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 45ED9095BE4BD5109A65B35F /* GoogleService-Info.plist */; }; 3623B61971137623FD028C44 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 45ED9095BE4BD5109A65B35F /* GoogleService-Info.plist */; }; 72904828160EC19516620EF7 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 45ED9095BE4BD5109A65B35F /* GoogleService-Info.plist */; }; - 8D00BB6D2D3B07A500F6F6DD /* FirebaseRemoteConfig in Frameworks */ = {isa = PBXBuildFile; productRef = 8D00BB6C2D3B07A500F6F6DD /* FirebaseRemoteConfig */; }; EA062D6024A13966006714D3 /* RemoteConfigView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA062D5F24A13966006714D3 /* RemoteConfigView.swift */; }; EA20B48A2497CC9D00B5E581 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA20B4892497CC9D00B5E581 /* AppDelegate.swift */; }; EA20B48C2497CC9D00B5E581 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA20B48B2497CC9D00B5E581 /* SceneDelegate.swift */; }; @@ -70,7 +69,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8D00BB6D2D3B07A500F6F6DD /* FirebaseRemoteConfig in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -91,13 +89,6 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 8D00BB6B2D3B07A500F6F6DD /* Frameworks */ = { - isa = PBXGroup; - children = ( - ); - name = Frameworks; - sourceTree = ""; - }; EA062D5E24A135EC006714D3 /* JSON Recipes */ = { isa = PBXGroup; children = ( @@ -116,7 +107,6 @@ EA20B4AA2497CC9F00B5E581 /* ConfigExampleUITests */, EA20B4872497CC9D00B5E581 /* Products */, 45ED9095BE4BD5109A65B35F /* GoogleService-Info.plist */, - 8D00BB6B2D3B07A500F6F6DD /* Frameworks */, ); sourceTree = ""; }; @@ -253,9 +243,6 @@ Base, ); mainGroup = EA20B47D2497CC9D00B5E581; - packageReferences = ( - 8D00BB6A2D3B079000F6F6DD /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, - ); productRefGroup = EA20B4872497CC9D00B5E581 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -647,25 +634,6 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ - -/* Begin XCRemoteSwiftPackageReference section */ - 8D00BB6A2D3B079000F6F6DD /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/firebase/firebase-ios-sdk"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 11.7.0; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 8D00BB6C2D3B07A500F6F6DD /* FirebaseRemoteConfig */ = { - isa = XCSwiftPackageProductDependency; - package = 8D00BB6A2D3B079000F6F6DD /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = FirebaseRemoteConfig; - }; -/* End XCSwiftPackageProductDependency section */ }; rootObject = EA20B47E2497CC9D00B5E581 /* Project object */; } diff --git a/config/LegacyConfigQuickstart/ConfigExample.xcodeproj/project.pbxproj b/config/LegacyConfigQuickstart/ConfigExample.xcodeproj/project.pbxproj new file mode 100644 index 000000000..4c866e24a --- /dev/null +++ b/config/LegacyConfigQuickstart/ConfigExample.xcodeproj/project.pbxproj @@ -0,0 +1,875 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 107347112031593F004A66D1 /* ConfigExampleSwiftUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 107347102031593F004A66D1 /* ConfigExampleSwiftUITests.swift */; }; + 1073481B20333B45004A66D1 /* ConfigExampleUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1073481A20333B45004A66D1 /* ConfigExampleUITests.m */; }; + 32C355031CBC57CF009B576C /* RemoteConfigDefaults.plist in Resources */ = {isa = PBXBuildFile; fileRef = 32C355021CBC57CF009B576C /* RemoteConfigDefaults.plist */; }; + 32C355041CBC57CF009B576C /* RemoteConfigDefaults.plist in Resources */ = {isa = PBXBuildFile; fileRef = 32C355021CBC57CF009B576C /* RemoteConfigDefaults.plist */; }; + 44DBF868EE4B59A3A3A01384 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 3F1BE71E3A0003CC3082E839 /* GoogleService-Info.plist */; }; + 5091BAB3FED376BC2777F05C /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 3F1BE71E3A0003CC3082E839 /* GoogleService-Info.plist */; }; + 5F5A53521ADE670C00F81DF0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53511ADE670C00F81DF0 /* main.m */; }; + 5F5A53551ADE670C00F81DF0 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */; }; + 5F5A53581ADE670C00F81DF0 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53571ADE670C00F81DF0 /* ViewController.m */; }; + 5F5A535B1ADE670C00F81DF0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5F5A53591ADE670C00F81DF0 /* Main.storyboard */; }; + 5F5A537E1ADE67D500F81DF0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */; }; + 5F5A53801ADE67D500F81DF0 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A537F1ADE67D500F81DF0 /* ViewController.swift */; }; + 5F5A539C1ADE69AA00F81DF0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5F5A53591ADE670C00F81DF0 /* Main.storyboard */; }; + 5F99610A1AE0CF4F0034F503 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961061AE0CF4F0034F503 /* Images.xcassets */; }; + 5F99610B1AE0CF4F0034F503 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961061AE0CF4F0034F503 /* Images.xcassets */; }; + 5F99610C1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */; }; + 5F99610D1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */; }; + 5FDE055D1B0DAA090037B82F /* AppTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FDE055C1B0DAA090037B82F /* AppTests.m */; }; + BA16017E3251E0846083D3B7 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 3F1BE71E3A0003CC3082E839 /* GoogleService-Info.plist */; }; + BABE2147292F87FCA7DCA396 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 3F1BE71E3A0003CC3082E839 /* GoogleService-Info.plist */; }; + C5B8A32837551063A185BE1A /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 3F1BE71E3A0003CC3082E839 /* GoogleService-Info.plist */; }; + DEC82E3B23AAEA35000EA7B1 /* FIREGSignInHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = DEC82E3423AAEA0F000EA7B1 /* FIREGSignInHelper.m */; }; + DEC82E3C23AAEA3E000EA7B1 /* FIREGHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = DEC82E3523AAEA0F000EA7B1 /* FIREGHelper.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 107347132031593F004A66D1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5F5A53781ADE67D500F81DF0; + remoteInfo = ConfigExampleSwift; + }; + 1073481D20333B45004A66D1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5F5A534B1ADE670C00F81DF0; + remoteInfo = ConfigExample; + }; + 5FDE055E1B0DAA090037B82F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5F5A534B1ADE670C00F81DF0; + remoteInfo = Config; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 1073470E2031593F004A66D1 /* ConfigExampleSwiftUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ConfigExampleSwiftUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 107347102031593F004A66D1 /* ConfigExampleSwiftUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigExampleSwiftUITests.swift; sourceTree = ""; }; + 107347122031593F004A66D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1073481820333B45004A66D1 /* ConfigExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ConfigExampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 1073481A20333B45004A66D1 /* ConfigExampleUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ConfigExampleUITests.m; sourceTree = ""; }; + 1073481C20333B45004A66D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 32C355021CBC57CF009B576C /* RemoteConfigDefaults.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = RemoteConfigDefaults.plist; sourceTree = ""; }; + 3F1BE71E3A0003CC3082E839 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "../GoogleService-Info.plist"; sourceTree = ""; }; + 5F5A534C1ADE670C00F81DF0 /* ConfigExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ConfigExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5F5A53501ADE670C00F81DF0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5F5A53511ADE670C00F81DF0 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 5F5A53531ADE670C00F81DF0 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 5F5A53561ADE670C00F81DF0 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + 5F5A53571ADE670C00F81DF0 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 5F5A535A1ADE670C00F81DF0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 5F5A53791ADE67D500F81DF0 /* ConfigExampleSwift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ConfigExampleSwift.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 5F5A537F1ADE67D500F81DF0 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 5F9961061AE0CF4F0034F503 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LaunchScreen.xib; sourceTree = ""; }; + 5FDE05581B0DAA090037B82F /* ConfigExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ConfigExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5FDE055C1B0DAA090037B82F /* AppTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppTests.m; sourceTree = ""; }; + DEC82E3323AAEA0F000EA7B1 /* FIREGHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIREGHelper.h; sourceTree = ""; }; + DEC82E3423AAEA0F000EA7B1 /* FIREGSignInHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIREGSignInHelper.m; sourceTree = ""; }; + DEC82E3523AAEA0F000EA7B1 /* FIREGHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIREGHelper.m; sourceTree = ""; }; + DEC82E3623AAEA0F000EA7B1 /* FIREGSignInHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIREGSignInHelper.h; sourceTree = ""; }; + DED65CF723E9DE6400461312 /* FIREGSignInInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FIREGSignInInfo.h; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1073470B2031593F004A66D1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1073481520333B45004A66D1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53491ADE670C00F81DF0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53761ADE67D500F81DF0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FDE05551B0DAA090037B82F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1073470F2031593F004A66D1 /* ConfigExampleSwiftUITests */ = { + isa = PBXGroup; + children = ( + 107347102031593F004A66D1 /* ConfigExampleSwiftUITests.swift */, + 107347122031593F004A66D1 /* Info.plist */, + ); + path = ConfigExampleSwiftUITests; + sourceTree = ""; + }; + 1073481920333B45004A66D1 /* ConfigExampleUITests */ = { + isa = PBXGroup; + children = ( + 1073481A20333B45004A66D1 /* ConfigExampleUITests.m */, + 1073481C20333B45004A66D1 /* Info.plist */, + ); + path = ConfigExampleUITests; + sourceTree = ""; + }; + 5F5A53431ADE670C00F81DF0 = { + isa = PBXGroup; + children = ( + 5F5A534E1ADE670C00F81DF0 /* ConfigExample */, + 5F5A537A1ADE67D500F81DF0 /* ConfigExampleSwift */, + 5FDE05591B0DAA090037B82F /* ConfigExamleTests */, + 1073470F2031593F004A66D1 /* ConfigExampleSwiftUITests */, + 1073481920333B45004A66D1 /* ConfigExampleUITests */, + DEC82E3223AAEA0F000EA7B1 /* TestUtils */, + 5F5A534D1ADE670C00F81DF0 /* Products */, + 5F9961041AE0CF4F0034F503 /* Shared */, + 3F1BE71E3A0003CC3082E839 /* GoogleService-Info.plist */, + ); + sourceTree = ""; + wrapsLines = 0; + }; + 5F5A534D1ADE670C00F81DF0 /* Products */ = { + isa = PBXGroup; + children = ( + 5F5A534C1ADE670C00F81DF0 /* ConfigExample.app */, + 5F5A53791ADE67D500F81DF0 /* ConfigExampleSwift.app */, + 5FDE05581B0DAA090037B82F /* ConfigExampleTests.xctest */, + 1073470E2031593F004A66D1 /* ConfigExampleSwiftUITests.xctest */, + 1073481820333B45004A66D1 /* ConfigExampleUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 5F5A534E1ADE670C00F81DF0 /* ConfigExample */ = { + isa = PBXGroup; + children = ( + 5F5A53531ADE670C00F81DF0 /* AppDelegate.h */, + 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */, + 5F5A53561ADE670C00F81DF0 /* ViewController.h */, + 5F5A53571ADE670C00F81DF0 /* ViewController.m */, + 5F5A534F1ADE670C00F81DF0 /* Supporting Files */, + ); + path = ConfigExample; + sourceTree = ""; + }; + 5F5A534F1ADE670C00F81DF0 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 5F5A53591ADE670C00F81DF0 /* Main.storyboard */, + 5F5A53501ADE670C00F81DF0 /* Info.plist */, + 5F5A53511ADE670C00F81DF0 /* main.m */, + 32C355021CBC57CF009B576C /* RemoteConfigDefaults.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 5F5A537A1ADE67D500F81DF0 /* ConfigExampleSwift */ = { + isa = PBXGroup; + children = ( + 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */, + 5F5A537F1ADE67D500F81DF0 /* ViewController.swift */, + ); + path = ConfigExampleSwift; + sourceTree = ""; + }; + 5F9961041AE0CF4F0034F503 /* Shared */ = { + isa = PBXGroup; + children = ( + 5F9961061AE0CF4F0034F503 /* Images.xcassets */, + 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */, + ); + name = Shared; + path = ../../shared; + sourceTree = ""; + }; + 5FDE05591B0DAA090037B82F /* ConfigExamleTests */ = { + isa = PBXGroup; + children = ( + 5FDE055C1B0DAA090037B82F /* AppTests.m */, + ); + name = ConfigExamleTests; + path = ConfigExampleTests; + sourceTree = ""; + }; + DEC82E3223AAEA0F000EA7B1 /* TestUtils */ = { + isa = PBXGroup; + children = ( + DEC82E3323AAEA0F000EA7B1 /* FIREGHelper.h */, + DEC82E3423AAEA0F000EA7B1 /* FIREGSignInHelper.m */, + DEC82E3523AAEA0F000EA7B1 /* FIREGHelper.m */, + DEC82E3623AAEA0F000EA7B1 /* FIREGSignInHelper.h */, + DED65CF723E9DE6400461312 /* FIREGSignInInfo.h */, + ); + name = TestUtils; + path = ../TestUtils; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1073470D2031593F004A66D1 /* ConfigExampleSwiftUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 107347152031593F004A66D1 /* Build configuration list for PBXNativeTarget "ConfigExampleSwiftUITests" */; + buildPhases = ( + 1073470A2031593F004A66D1 /* Sources */, + 1073470B2031593F004A66D1 /* Frameworks */, + 1073470C2031593F004A66D1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 107347142031593F004A66D1 /* PBXTargetDependency */, + ); + name = ConfigExampleSwiftUITests; + productName = ConfigExampleSwiftUITests; + productReference = 1073470E2031593F004A66D1 /* ConfigExampleSwiftUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + 1073481720333B45004A66D1 /* ConfigExampleUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1073481F20333B45004A66D1 /* Build configuration list for PBXNativeTarget "ConfigExampleUITests" */; + buildPhases = ( + 1073481420333B45004A66D1 /* Sources */, + 1073481520333B45004A66D1 /* Frameworks */, + 1073481620333B45004A66D1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 1073481E20333B45004A66D1 /* PBXTargetDependency */, + ); + name = ConfigExampleUITests; + productName = ConfigExampleUITests; + productReference = 1073481820333B45004A66D1 /* ConfigExampleUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + 5F5A534B1ADE670C00F81DF0 /* ConfigExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5F5A536F1ADE670C00F81DF0 /* Build configuration list for PBXNativeTarget "ConfigExample" */; + buildPhases = ( + 5F5A53481ADE670C00F81DF0 /* Sources */, + 5F5A53491ADE670C00F81DF0 /* Frameworks */, + 5F5A534A1ADE670C00F81DF0 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ConfigExample; + productName = Config; + productReference = 5F5A534C1ADE670C00F81DF0 /* ConfigExample.app */; + productType = "com.apple.product-type.application"; + }; + 5F5A53781ADE67D500F81DF0 /* ConfigExampleSwift */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5F5A53991ADE67D500F81DF0 /* Build configuration list for PBXNativeTarget "ConfigExampleSwift" */; + buildPhases = ( + 5F5A53751ADE67D500F81DF0 /* Sources */, + 5F5A53761ADE67D500F81DF0 /* Frameworks */, + 5F5A53771ADE67D500F81DF0 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ConfigExampleSwift; + productName = ConfigSwift; + productReference = 5F5A53791ADE67D500F81DF0 /* ConfigExampleSwift.app */; + productType = "com.apple.product-type.application"; + }; + 5FDE05571B0DAA090037B82F /* ConfigExampleTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5FDE05621B0DAA090037B82F /* Build configuration list for PBXNativeTarget "ConfigExampleTests" */; + buildPhases = ( + 5FDE05541B0DAA090037B82F /* Sources */, + 5FDE05551B0DAA090037B82F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 5FDE055F1B0DAA090037B82F /* PBXTargetDependency */, + ); + name = ConfigExampleTests; + productName = ConfigTests; + productReference = 5FDE05581B0DAA090037B82F /* ConfigExampleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5F5A53441ADE670C00F81DF0 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = "Google Inc."; + TargetAttributes = { + 1073470D2031593F004A66D1 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1110; + ProvisioningStyle = Automatic; + TestTargetID = 5F5A53781ADE67D500F81DF0; + }; + 1073481720333B45004A66D1 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Automatic; + TestTargetID = 5F5A534B1ADE670C00F81DF0; + }; + 5F5A534B1ADE670C00F81DF0 = { + CreatedOnToolsVersion = 6.3; + ProvisioningStyle = Automatic; + }; + 5F5A53781ADE67D500F81DF0 = { + CreatedOnToolsVersion = 6.3; + LastSwiftMigration = 1110; + }; + 5FDE05571B0DAA090037B82F = { + CreatedOnToolsVersion = 6.3.2; + TestTargetID = 5F5A534B1ADE670C00F81DF0; + }; + }; + }; + buildConfigurationList = 5F5A53471ADE670C00F81DF0 /* Build configuration list for PBXProject "ConfigExample" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 5F5A53431ADE670C00F81DF0; + productRefGroup = 5F5A534D1ADE670C00F81DF0 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5F5A534B1ADE670C00F81DF0 /* ConfigExample */, + 5F5A53781ADE67D500F81DF0 /* ConfigExampleSwift */, + 5FDE05571B0DAA090037B82F /* ConfigExampleTests */, + 1073470D2031593F004A66D1 /* ConfigExampleSwiftUITests */, + 1073481720333B45004A66D1 /* ConfigExampleUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1073470C2031593F004A66D1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1073481620333B45004A66D1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A534A1ADE670C00F81DF0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 32C355031CBC57CF009B576C /* RemoteConfigDefaults.plist in Resources */, + 5F99610C1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */, + 5F99610A1AE0CF4F0034F503 /* Images.xcassets in Resources */, + 5F5A535B1ADE670C00F81DF0 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53771ADE67D500F81DF0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 32C355041CBC57CF009B576C /* RemoteConfigDefaults.plist in Resources */, + 5F99610D1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */, + 5F5A539C1ADE69AA00F81DF0 /* Main.storyboard in Resources */, + 5F99610B1AE0CF4F0034F503 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1073470A2031593F004A66D1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 107347112031593F004A66D1 /* ConfigExampleSwiftUITests.swift in Sources */, + BABE2147292F87FCA7DCA396 /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1073481420333B45004A66D1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1073481B20333B45004A66D1 /* ConfigExampleUITests.m in Sources */, + DEC82E3B23AAEA35000EA7B1 /* FIREGSignInHelper.m in Sources */, + DEC82E3C23AAEA3E000EA7B1 /* FIREGHelper.m in Sources */, + BA16017E3251E0846083D3B7 /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53481ADE670C00F81DF0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F5A53581ADE670C00F81DF0 /* ViewController.m in Sources */, + 5F5A53551ADE670C00F81DF0 /* AppDelegate.m in Sources */, + 5F5A53521ADE670C00F81DF0 /* main.m in Sources */, + 5091BAB3FED376BC2777F05C /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53751ADE67D500F81DF0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F5A53801ADE67D500F81DF0 /* ViewController.swift in Sources */, + 5F5A537E1ADE67D500F81DF0 /* AppDelegate.swift in Sources */, + 44DBF868EE4B59A3A3A01384 /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FDE05541B0DAA090037B82F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5FDE055D1B0DAA090037B82F /* AppTests.m in Sources */, + C5B8A32837551063A185BE1A /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 107347142031593F004A66D1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5F5A53781ADE67D500F81DF0 /* ConfigExampleSwift */; + targetProxy = 107347132031593F004A66D1 /* PBXContainerItemProxy */; + }; + 1073481E20333B45004A66D1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5F5A534B1ADE670C00F81DF0 /* ConfigExample */; + targetProxy = 1073481D20333B45004A66D1 /* PBXContainerItemProxy */; + }; + 5FDE055F1B0DAA090037B82F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5F5A534B1ADE670C00F81DF0 /* ConfigExample */; + targetProxy = 5FDE055E1B0DAA090037B82F /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 5F5A53591ADE670C00F81DF0 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5F5A535A1ADE670C00F81DF0 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 107347162031593F004A66D1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = ConfigExampleSwiftUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.ConfigExampleSwiftUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = ConfigExampleSwift; + }; + name = Debug; + }; + 107347172031593F004A66D1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = ConfigExampleSwiftUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.ConfigExampleSwiftUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = ConfigExampleSwift; + }; + name = Release; + }; + 1073482020333B45004A66D1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = ConfigExampleUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.ConfigExampleUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = ConfigExample; + }; + name = Debug; + }; + 1073482120333B45004A66D1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = ConfigExampleUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.ConfigExampleUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = ConfigExample; + }; + name = Release; + }; + 5F5A536D1ADE670C00F81DF0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + ENABLE_BITCODE = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5F5A536E1ADE670C00F81DF0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + ENABLE_BITCODE = NO; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5F5A53701ADE670C00F81DF0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = "$(SRCROOT)/ConfigExample/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.ConfigExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 5F5A53711ADE670C00F81DF0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = "$(SRCROOT)/ConfigExample/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.ConfigExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 5F5A53951ADE67D500F81DF0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "$(SRCROOT)/ConfigExample/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.ConfigExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 5F5A53961ADE67D500F81DF0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "$(SRCROOT)/ConfigExample/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.ConfigExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 5FDE05601B0DAA090037B82F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + Config, + ); + INFOPLIST_FILE = ConfigExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ConfigExample.app/ConfigExample"; + }; + name = Debug; + }; + 5FDE05611B0DAA090037B82F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + Config, + ); + INFOPLIST_FILE = ConfigExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ConfigExample.app/ConfigExample"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 107347152031593F004A66D1 /* Build configuration list for PBXNativeTarget "ConfigExampleSwiftUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 107347162031593F004A66D1 /* Debug */, + 107347172031593F004A66D1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1073481F20333B45004A66D1 /* Build configuration list for PBXNativeTarget "ConfigExampleUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1073482020333B45004A66D1 /* Debug */, + 1073482120333B45004A66D1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5F5A53471ADE670C00F81DF0 /* Build configuration list for PBXProject "ConfigExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5F5A536D1ADE670C00F81DF0 /* Debug */, + 5F5A536E1ADE670C00F81DF0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5F5A536F1ADE670C00F81DF0 /* Build configuration list for PBXNativeTarget "ConfigExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5F5A53701ADE670C00F81DF0 /* Debug */, + 5F5A53711ADE670C00F81DF0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5F5A53991ADE67D500F81DF0 /* Build configuration list for PBXNativeTarget "ConfigExampleSwift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5F5A53951ADE67D500F81DF0 /* Debug */, + 5F5A53961ADE67D500F81DF0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5FDE05621B0DAA090037B82F /* Build configuration list for PBXNativeTarget "ConfigExampleTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5FDE05601B0DAA090037B82F /* Debug */, + 5FDE05611B0DAA090037B82F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5F5A53441ADE670C00F81DF0 /* Project object */; +} diff --git a/config/LegacyConfigQuickstart/ConfigExample.xcodeproj/xcshareddata/xcschemes/ConfigExample.xcscheme b/config/LegacyConfigQuickstart/ConfigExample.xcodeproj/xcshareddata/xcschemes/ConfigExample.xcscheme new file mode 100644 index 000000000..3776b32c0 --- /dev/null +++ b/config/LegacyConfigQuickstart/ConfigExample.xcodeproj/xcshareddata/xcschemes/ConfigExample.xcscheme @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/LegacyConfigQuickstart/ConfigExample.xcodeproj/xcshareddata/xcschemes/ConfigExampleSwift.xcscheme b/config/LegacyConfigQuickstart/ConfigExample.xcodeproj/xcshareddata/xcschemes/ConfigExampleSwift.xcscheme new file mode 100644 index 000000000..ea65442d0 --- /dev/null +++ b/config/LegacyConfigQuickstart/ConfigExample.xcodeproj/xcshareddata/xcschemes/ConfigExampleSwift.xcscheme @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/LegacyConfigQuickstart/ConfigExample/.clang-format b/config/LegacyConfigQuickstart/ConfigExample/.clang-format new file mode 100644 index 000000000..1f09ce0f2 --- /dev/null +++ b/config/LegacyConfigQuickstart/ConfigExample/.clang-format @@ -0,0 +1,4 @@ +BasedOnStyle: Google +ColumnLimit: 100 +BinPackParameters: false +AllowAllParametersOfDeclarationOnNextLine: true diff --git a/config/LegacyConfigQuickstart/ConfigExample/AppDelegate.h b/config/LegacyConfigQuickstart/ConfigExample/AppDelegate.h new file mode 100644 index 000000000..66dc0c1c6 --- /dev/null +++ b/config/LegacyConfigQuickstart/ConfigExample/AppDelegate.h @@ -0,0 +1,23 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import UIKit; + +@interface AppDelegate : UIResponder + +@property(nonatomic, strong) UIWindow *window; + +@end diff --git a/config/LegacyConfigQuickstart/ConfigExample/AppDelegate.m b/config/LegacyConfigQuickstart/ConfigExample/AppDelegate.m new file mode 100644 index 000000000..c825f95a0 --- /dev/null +++ b/config/LegacyConfigQuickstart/ConfigExample/AppDelegate.m @@ -0,0 +1,30 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "AppDelegate.h" +@import FirebaseCore; + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // [START configure_firebase] + [FIRApp configure]; + // [END configure_firebase] + return YES; +} + +@end diff --git a/config/LegacyConfigQuickstart/ConfigExample/Base.lproj/Main.storyboard b/config/LegacyConfigQuickstart/ConfigExample/Base.lproj/Main.storyboard new file mode 100644 index 000000000..422802646 --- /dev/null +++ b/config/LegacyConfigQuickstart/ConfigExample/Base.lproj/Main.storyboard @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/LegacyConfigQuickstart/ConfigExample/Info.plist b/config/LegacyConfigQuickstart/ConfigExample/Info.plist new file mode 100644 index 000000000..35e706904 --- /dev/null +++ b/config/LegacyConfigQuickstart/ConfigExample/Info.plist @@ -0,0 +1,51 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIcons + + CFBundleIcons~ipad + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + Main + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/config/LegacyConfigQuickstart/ConfigExample/RemoteConfigDefaults.plist b/config/LegacyConfigQuickstart/ConfigExample/RemoteConfigDefaults.plist new file mode 100644 index 000000000..dd1561393 --- /dev/null +++ b/config/LegacyConfigQuickstart/ConfigExample/RemoteConfigDefaults.plist @@ -0,0 +1,12 @@ + + + + + loading_phrase + Fetching config... + welcome_message_caps + + welcome_message + Welcome to my awesome app! + + diff --git a/config/LegacyConfigQuickstart/ConfigExample/ViewController.h b/config/LegacyConfigQuickstart/ConfigExample/ViewController.h new file mode 100644 index 000000000..5f0f60a93 --- /dev/null +++ b/config/LegacyConfigQuickstart/ConfigExample/ViewController.h @@ -0,0 +1,24 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import UIKit; +@import FirebaseRemoteConfig; + +@interface ViewController : UIViewController +@property (weak, nonatomic) IBOutlet UILabel *welcomeLabel; +@property (weak, nonatomic) IBOutlet UIButton *fetchButton; +@property (nonatomic, strong) FIRRemoteConfig *remoteConfig; +@end diff --git a/config/LegacyConfigQuickstart/ConfigExample/ViewController.m b/config/LegacyConfigQuickstart/ConfigExample/ViewController.m new file mode 100644 index 000000000..75e84bfa2 --- /dev/null +++ b/config/LegacyConfigQuickstart/ConfigExample/ViewController.m @@ -0,0 +1,113 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "ViewController.h" +@import FirebaseRemoteConfig; + +@implementation ViewController + +NSString *const kWelcomeMessageConfigKey = @"welcome_message"; +NSString *const kWelcomeMessageCapsConfigKey = @"welcome_message_caps"; +NSString *const kLoadingPhraseConfigKey = @"loading_phrase"; + +- (void)viewDidLoad { + [super viewDidLoad]; + // [START get_remote_config_instance] + self.remoteConfig = [FIRRemoteConfig remoteConfig]; + // [END get_remote_config_instance] + + // Create a Remote Config Setting to enable developer mode, which you can use to increase + // the number of fetches available per hour during development. See Best Practices in the + // README for more information. + // [START enable_dev_mode] + FIRRemoteConfigSettings *remoteConfigSettings = [[FIRRemoteConfigSettings alloc] init]; + remoteConfigSettings.minimumFetchInterval = 0; + self.remoteConfig.configSettings = remoteConfigSettings; + // [END enable_dev_mode] + + // Set default Remote Config parameter values. An app uses the in-app default values until you + // update any values that you want to change in the Firebase console. See Best Practices in the + // README for more information. + // [START set_default_values] + [self.remoteConfig setDefaultsFromPlistFileName:@"RemoteConfigDefaults"]; + // [END set_default_values] + + // [START add_config_update_listener] + __weak __typeof__(self) weakSelf = self; + [self.remoteConfig addOnConfigUpdateListener:^(FIRRemoteConfigUpdate * _Nonnull configUpdate, NSError * _Nullable error) { + if (error != nil) { + NSLog(@"Error listening for config updates %@", error.localizedDescription); + } else { + NSLog(@"Updated keys: %@", configUpdate.updatedKeys); + __typeof__(self) strongSelf = weakSelf; + [strongSelf.remoteConfig activateWithCompletion:^(BOOL changed, NSError * _Nullable error) { + if (error != nil) { + NSLog(@"Activate error %@", error.localizedDescription); + } + + dispatch_async(dispatch_get_main_queue(), ^{ + [strongSelf displayWelcome]; + }); + }]; + } + }]; + // [END add_config_update_listener] + + [self fetchConfig]; + [super viewDidLoad]; +} + +- (void)fetchConfig { + self.welcomeLabel.text = self.remoteConfig[kLoadingPhraseConfigKey].stringValue; + + // [START fetch_config_with_callback] + [self.remoteConfig fetchWithCompletionHandler:^(FIRRemoteConfigFetchStatus status, NSError *error) { + if (status == FIRRemoteConfigFetchStatusSuccess) { + NSLog(@"Config fetched!"); + [self.remoteConfig activateWithCompletion:^(BOOL changed, NSError * _Nullable error) { + if (error != nil) { + NSLog(@"Activate error: %@", error.localizedDescription); + } else { + dispatch_async(dispatch_get_main_queue(), ^{ + [self displayWelcome]; + }); + } + }]; + } else { + NSLog(@"Config not fetched"); + NSLog(@"Error %@", error.localizedDescription); + } + }]; + // [END fetch_config_with_callback] +} + +// Display welcome message in all caps if welcome_message_caps is set to true. Otherwise +// display welcome message as fetched from welcome_message. +- (void)displayWelcome { + // [START get_config_value] + NSString *welcomeMessage = self.remoteConfig[kWelcomeMessageConfigKey].stringValue; + // [END get_config_value] + if (self.remoteConfig[kWelcomeMessageCapsConfigKey].boolValue) { + welcomeMessage = [welcomeMessage uppercaseString]; + } + self.welcomeLabel.text = welcomeMessage; +} + +- (IBAction)handleFetchTouch:(id)sender { + [self fetchConfig]; +} + +@end diff --git a/config/LegacyConfigQuickstart/ConfigExample/main.m b/config/LegacyConfigQuickstart/ConfigExample/main.m new file mode 100644 index 000000000..bc10c3ac6 --- /dev/null +++ b/config/LegacyConfigQuickstart/ConfigExample/main.m @@ -0,0 +1,24 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/config/LegacyConfigQuickstart/ConfigExampleSwift/AppDelegate.swift b/config/LegacyConfigQuickstart/ConfigExampleSwift/AppDelegate.swift new file mode 100644 index 000000000..ec466c6fa --- /dev/null +++ b/config/LegacyConfigQuickstart/ConfigExampleSwift/AppDelegate.swift @@ -0,0 +1,32 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit +import FirebaseCore + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? + + func application(_ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication + .LaunchOptionsKey: Any]?) -> Bool { + // [START configure_firebase] + FirebaseApp.configure() + // [END configure_firebase] + return true + } +} diff --git a/config/LegacyConfigQuickstart/ConfigExampleSwift/ViewController.swift b/config/LegacyConfigQuickstart/ConfigExampleSwift/ViewController.swift new file mode 100644 index 000000000..94fe190ec --- /dev/null +++ b/config/LegacyConfigQuickstart/ConfigExampleSwift/ViewController.swift @@ -0,0 +1,91 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit +import FirebaseRemoteConfig + +@objc(ViewController) +class ViewController: UIViewController { + let welcomeMessageConfigKey = "welcome_message" + let welcomeMessageCapsConfigKey = "welcome_message_caps" + let loadingPhraseConfigKey = "loading_phrase" + + var remoteConfig: RemoteConfig! + @IBOutlet var welcomeLabel: UILabel! + @IBOutlet var fetchButton: UIButton! + + override func viewDidLoad() { + super.viewDidLoad() + // [START get_remote_config_instance] + remoteConfig = RemoteConfig.remoteConfig() + // [END get_remote_config_instance] + + // Create a Remote Config Setting to enable developer mode, which you can use to increase + // the number of fetches available per hour during development. See Best Practices in the + // README for more information. + // [START enable_dev_mode] + let settings = RemoteConfigSettings() + settings.minimumFetchInterval = 0 + remoteConfig.configSettings = settings + // [END enable_dev_mode] + + // Set default Remote Config parameter values. An app uses the in-app default values, and + // when you need to adjust those defaults, you set an updated value for only the values you + // want to change in the Firebase console. See Best Practices in the README for more + // information. + // [START set_default_values] + remoteConfig.setDefaults(fromPlist: "RemoteConfigDefaults") + // [END set_default_values] + + fetchConfig() + } + + func fetchConfig() { + welcomeLabel.text = remoteConfig[loadingPhraseConfigKey].stringValue + + // [START fetch_config_with_callback] + remoteConfig.fetch { (status, error) -> Void in + if status == .success { + print("Config fetched!") + self.remoteConfig.activate { changed, error in + // ... + } + } else { + print("Config not fetched") + print("Error: \(error?.localizedDescription ?? "No error available.")") + } + self.displayWelcome() + } + // [END fetch_config_with_callback] + } + + func displayWelcome() { + // [START get_config_value] + var welcomeMessage = remoteConfig[welcomeMessageConfigKey].stringValue + // [END get_config_value] + + if remoteConfig[welcomeMessageCapsConfigKey].boolValue { + welcomeMessage = welcomeMessage?.uppercased() + } + welcomeLabel.text = welcomeMessage + } + + // Display welcome message in all caps if welcome_message_caps is set to true. Otherwise + // display welcome message as fetched from welcome_message. + @IBAction func handleFetchTouch(_ sender: AnyObject) { + fetchConfig() + } +} diff --git a/performance/PerformanceExampleUITests/PerformanceExampleUITests.swift b/config/LegacyConfigQuickstart/ConfigExampleSwiftUITests/ConfigExampleSwiftUITests.swift similarity index 97% rename from performance/PerformanceExampleUITests/PerformanceExampleUITests.swift rename to config/LegacyConfigQuickstart/ConfigExampleSwiftUITests/ConfigExampleSwiftUITests.swift index c78f2b169..9a4e6d93b 100644 --- a/performance/PerformanceExampleUITests/PerformanceExampleUITests.swift +++ b/config/LegacyConfigQuickstart/ConfigExampleSwiftUITests/ConfigExampleSwiftUITests.swift @@ -16,7 +16,7 @@ import XCTest -class PerformanceExampleUITests: XCTestCase { +class ConfigExampleSwiftUITests: XCTestCase { override func setUp() { super.setUp() diff --git a/config/LegacyConfigQuickstart/ConfigExampleSwiftUITests/Info.plist b/config/LegacyConfigQuickstart/ConfigExampleSwiftUITests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/config/LegacyConfigQuickstart/ConfigExampleSwiftUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/config/LegacyConfigQuickstart/ConfigExampleTests/AppTests.m b/config/LegacyConfigQuickstart/ConfigExampleTests/AppTests.m new file mode 100644 index 000000000..e60dafc80 --- /dev/null +++ b/config/LegacyConfigQuickstart/ConfigExampleTests/AppTests.m @@ -0,0 +1,40 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +#import +#import + +@interface AppTests : XCTestCase +@end + +@implementation AppTests + +- (void)setUp { + [super setUp]; + if ([FIRApp defaultApp] == nil) { + [FIRApp configure]; + } +} + +- (void)testRemoteConfig { + FIRRemoteConfig *remoteConfig = [FIRRemoteConfig remoteConfig]; + XCTAssert([remoteConfig isKindOfClass:[FIRRemoteConfig class]]); +} + +@end diff --git a/config/LegacyConfigQuickstart/ConfigExampleUITests/ConfigExampleUITests.m b/config/LegacyConfigQuickstart/ConfigExampleUITests/ConfigExampleUITests.m new file mode 100644 index 000000000..fd3ce2a20 --- /dev/null +++ b/config/LegacyConfigQuickstart/ConfigExampleUITests/ConfigExampleUITests.m @@ -0,0 +1,46 @@ +// +// Copyright (c) 2019 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import "FIREGHelper.h" + +@interface ConfigUITest : XCTestCase +@end + +@implementation ConfigUITest { + XCUIApplication *_app; +} + +- (void)setUp { + [super setUp]; + _app = [[XCUIApplication alloc] init]; + [_app launch]; +} + +- (void)testRemoteConfig { + // Verify that Remote Config Example app is launched successfully and its title is visible. + XCTAssertTrue([_app navigationBars][@"Remote Config Example"].exists); + + // Tap on 'Fetch Remote Config' button. + [_app.buttons[@"Fetch Remote Config"] tap]; + + // Verify that the Remote Config value is visible. + XCUIElement* config = [_app staticTexts][@"WELCOME TO MY AWESOME APP!"]; + FIRWaitForVisibleWithTimeout(config, 20); + XCTAssertTrue(config.exists); +} + +@end diff --git a/config/LegacyConfigQuickstart/ConfigExampleUITests/Info.plist b/config/LegacyConfigQuickstart/ConfigExampleUITests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/config/LegacyConfigQuickstart/ConfigExampleUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/config/LegacyConfigQuickstart/Podfile b/config/LegacyConfigQuickstart/Podfile new file mode 100644 index 000000000..0b1eee652 --- /dev/null +++ b/config/LegacyConfigQuickstart/Podfile @@ -0,0 +1,12 @@ +# ConfigExample +use_frameworks! +platform :ios, '15.0' + +pod 'FirebaseRemoteConfig' + +target 'ConfigExample' do +end +target 'ConfigExampleSwift' do +end +target 'ConfigExampleTests' do +end diff --git a/config/LegacyConfigQuickstart/Podfile.lock b/config/LegacyConfigQuickstart/Podfile.lock new file mode 100644 index 000000000..fa4641bc1 --- /dev/null +++ b/config/LegacyConfigQuickstart/Podfile.lock @@ -0,0 +1,66 @@ +PODS: + - FirebaseABTesting (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseCore (12.6.0): + - FirebaseCoreInternal (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreInternal (12.6.0): + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseInstallations (12.6.0): + - FirebaseCore (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - PromisesObjC (~> 2.4) + - FirebaseRemoteConfig (12.6.0): + - FirebaseABTesting (~> 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - FirebaseRemoteConfigInterop (~> 12.6.0) + - FirebaseSharedSwift (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseRemoteConfigInterop (12.6.0) + - FirebaseSharedSwift (12.6.0) + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - "GoogleUtilities/NSData+zlib (8.1.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/UserDefaults (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - PromisesObjC (2.4.0) + +DEPENDENCIES: + - FirebaseRemoteConfig + +SPEC REPOS: + trunk: + - FirebaseABTesting + - FirebaseCore + - FirebaseCoreInternal + - FirebaseInstallations + - FirebaseRemoteConfig + - FirebaseRemoteConfigInterop + - FirebaseSharedSwift + - GoogleUtilities + - PromisesObjC + +SPEC CHECKSUMS: + FirebaseABTesting: 119f0a2b2e68b1ae05d248c5adb2455f148f20c1 + FirebaseCore: 0e38ad5d62d980a47a64b8e9301ffa311457be04 + FirebaseCoreInternal: 69bf1306a05b8ac43004f6cc1f804bb7b05b229e + FirebaseInstallations: 631b38da2e11a83daa4bfb482f79d286a5dfa7ad + FirebaseRemoteConfig: c5dfe22828a7ae7673d16224ea92743687e993df + FirebaseRemoteConfigInterop: 3443b8cb8fffd76bb3e03b2a84bfd3db952fcda4 + FirebaseSharedSwift: 79f27fff0addd15c3de19b87fba426f3cc2c964f + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + +PODFILE CHECKSUM: 71083e79bdc3ce5e9a6678499506ae36d0b7449a + +COCOAPODS: 1.16.2 diff --git a/config/LegacyConfigQuickstart/README.md b/config/LegacyConfigQuickstart/README.md new file mode 100644 index 000000000..174ee2f82 --- /dev/null +++ b/config/LegacyConfigQuickstart/README.md @@ -0,0 +1,102 @@ +Firebase Remote Config Quickstart +============================= + +The Firebase Remote Config iOS quickstart app demonstrates using Remote +Config to define user-facing text in an iOS app. + +Introduction +------------ + +This is a simple example of using Remote Config to override in-app default +values by defining service-side parameter values in the Firebase console. This +example demonstrates a small subset of the capabilities of Firebase Remote +Config. To learn more about how you can use Firebase Remote Config in your app, +see +[Firebase Remote Config Introduction](https://firebase.google.com/docs/remote-config/). + +Getting started +--------------- + +1. [Add Firebase to your iOS Project](https://firebase.google.com/docs/ios/setup). +2. [Create a Remote Config project for the quickstart sample](https://firebase.google.com/docs/remote-config/ios#create_a_product_name_project_for_the_quickstart_sample), + defining the parameter values and parameter keys used by the sample. +3. Run the sample on an iOS device or emulator. +4. Change one or more parameter values in the Firebase Console (the value of + `welcome_message`, `welcome_message_caps`, or both). +5. Tap **Fetch Remote Config** in the app to fetch new parameter values and see + the resulting change in the app. + +Best practices +-------------- +This section provides some additional information about how the quickstart +example sets in-app default parameter values and fetches values from the Remote +Config service. + +### In-app default parameter values ### + +In-app default values are set using a plist file with the +`setDefaultsFromPlistFileName` method in this example, but you can also set +in-app default values inline using the other `setDefaults` methods of the +[`FIRRemoteConfig` class](https://firebase.google.com/docs/reference/ios/firebaseremoteconfig/api/reference/Classes/FIRRemoteConfig). + +Then, you can override only those values that you need to change from the +Firebase console. This lets you use Remote Config for any default value that you +might want to override in the future, without the need to set all of those +values in the Firebase console. + +### Fetch values from the Remote Config service ### + +When an app calls `fetchWithExpirationDuration:completionHandler`, updated +parameter values are fetched from the Remote Config service if either + +* the last successful fetch occurred more than 12 hours ago, or +* a value less than 43200 (the number of seconds in 12 hours) is specified for + `TimeInterval`. + +Otherwise, cached parameter values are used. + +Fetched values are cached locally, but not immediately activated. To activate +fetched values so that they take effect, call the `activateFetched` method. In +the quickstart sample app, you call this method from the UI by tapping +**Fetch Remote Config**. + +You can also create a Remote Config Setting to enable developer mode, but you +must remove this setting before distributing your app. Fetching Remote Config +data from the service is normally limited to a few requests per hour. By +enabling developer mode, you can make many more requests per hour, so you can +test your app with different Remote Config parameter values during development. + +- To learn more about fetching data from Remote Config, see the Remote Config + Frequently Asked Question (FAQ) on + [fetching and activating parameter values](https://firebase.google.com/support/faq#remote-config-values). +- To learn about parameters and conditions that you can use to change the + behavior and appearance of your app for segments of your userbase, see + [Remote Config Parameters and Conditions](https://firebase.google.com/docs/remote-config/parameters). +- To learn more about the Remote Config API, see + [Remote Config API Overview](https://firebase.google.com/docs/remote-config/api-overview). + +Support +------- + +- [Stack Overflow](https://stackoverflow.com/questions/tagged/firebase-remote-config) +- [Firebase Support](https://firebase.google.com/support/) + +License +------- + +Copyright 2015 Google, Inc. + +Licensed to the Apache Software Foundation (ASF) under one or more contributor +license agreements. See the NOTICE file distributed with this work for +additional information regarding copyright ownership. The ASF licenses this +file to you under the Apache License, Version 2.0 (the "License"); you may not +use this file except in compliance with the License. You may obtain a copy of +the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +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/config/Podfile b/config/Podfile new file mode 100644 index 000000000..3ace2a286 --- /dev/null +++ b/config/Podfile @@ -0,0 +1,20 @@ +# Uncomment the next line to define a global platform for your project +platform :ios, '15.0' + +target 'ConfigExample' do + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + + # Pods for ConfigExample + pod 'FirebaseRemoteConfig' + + target 'ConfigExampleTests' do + inherit! :search_paths + # Pods for testing + end + + target 'ConfigExampleUITests' do + # Pods for testing + end + +end diff --git a/config/Podfile.lock b/config/Podfile.lock new file mode 100644 index 000000000..0d5121962 --- /dev/null +++ b/config/Podfile.lock @@ -0,0 +1,66 @@ +PODS: + - FirebaseABTesting (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseCore (12.6.0): + - FirebaseCoreInternal (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreInternal (12.6.0): + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseInstallations (12.6.0): + - FirebaseCore (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - PromisesObjC (~> 2.4) + - FirebaseRemoteConfig (12.6.0): + - FirebaseABTesting (~> 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - FirebaseRemoteConfigInterop (~> 12.6.0) + - FirebaseSharedSwift (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseRemoteConfigInterop (12.6.0) + - FirebaseSharedSwift (12.6.0) + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - "GoogleUtilities/NSData+zlib (8.1.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/UserDefaults (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - PromisesObjC (2.4.0) + +DEPENDENCIES: + - FirebaseRemoteConfig + +SPEC REPOS: + trunk: + - FirebaseABTesting + - FirebaseCore + - FirebaseCoreInternal + - FirebaseInstallations + - FirebaseRemoteConfig + - FirebaseRemoteConfigInterop + - FirebaseSharedSwift + - GoogleUtilities + - PromisesObjC + +SPEC CHECKSUMS: + FirebaseABTesting: 119f0a2b2e68b1ae05d248c5adb2455f148f20c1 + FirebaseCore: 0e38ad5d62d980a47a64b8e9301ffa311457be04 + FirebaseCoreInternal: 69bf1306a05b8ac43004f6cc1f804bb7b05b229e + FirebaseInstallations: 631b38da2e11a83daa4bfb482f79d286a5dfa7ad + FirebaseRemoteConfig: c5dfe22828a7ae7673d16224ea92743687e993df + FirebaseRemoteConfigInterop: 3443b8cb8fffd76bb3e03b2a84bfd3db952fcda4 + FirebaseSharedSwift: 79f27fff0addd15c3de19b87fba426f3cc2c964f + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + +PODFILE CHECKSUM: 238baa1704ab985c7b31681149ca9a2bcc8636c1 + +COCOAPODS: 1.16.2 diff --git a/crashlytics/CrashlyticsExample.xcodeproj/project.pbxproj b/crashlytics/CrashlyticsExample.xcodeproj/project.pbxproj index c0276a557..adb6d943d 100644 --- a/crashlytics/CrashlyticsExample.xcodeproj/project.pbxproj +++ b/crashlytics/CrashlyticsExample.xcodeproj/project.pbxproj @@ -7,12 +7,11 @@ objects = { /* Begin PBXBuildFile section */ - 8D00BB712D3B0ADE00F6F6DD /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = 8D00BB702D3B0ADE00F6F6DD /* FirebaseCrashlytics */; }; - 8D00BB732D3B0AED00F6F6DD /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = 8D00BB722D3B0AED00F6F6DD /* FirebaseCrashlytics */; }; - 8D00BB752D3B0AF400F6F6DD /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = 8D00BB742D3B0AF400F6F6DD /* FirebaseCrashlytics */; }; - 8D00BB772D3B0AFF00F6F6DD /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = 8D00BB762D3B0AFF00F6F6DD /* FirebaseCrashlytics */; }; - 8D96F5EE2685442C00F1A2B7 /* ReachabilityHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C723B78C26853A1700AD34CD /* ReachabilityHelper.swift */; }; + 8D96F5DE2685440700F1A2B7 /* Reachability in Frameworks */ = {isa = PBXBuildFile; productRef = 8D96F5DD2685440700F1A2B7 /* Reachability */; }; + 8D96F5E62685442800F1A2B7 /* ReachabililtyHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C723B78C26853A1700AD34CD /* ReachabililtyHelper.swift */; }; + 8D96F5EE2685442C00F1A2B7 /* ReachabililtyHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C723B78C26853A1700AD34CD /* ReachabililtyHelper.swift */; }; C726B81C26D84D51000991C1 /* UITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C726B81B26D84D51000991C1 /* UITests.swift */; }; + C732A29826846B6D00AA7DEF /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = C732A29726846B6D00AA7DEF /* FirebaseCrashlytics */; }; C73C89A926845908003E5C2C /* CrashlyticsSwiftUIExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C73C899726845907003E5C2C /* CrashlyticsSwiftUIExampleApp.swift */; }; C73C89AA26845908003E5C2C /* CrashlyticsSwiftUIExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C73C899726845907003E5C2C /* CrashlyticsSwiftUIExampleApp.swift */; }; C73C89AB26845908003E5C2C /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C73C899826845907003E5C2C /* ContentView.swift */; }; @@ -20,20 +19,25 @@ C73C89AD26845908003E5C2C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C73C899926845908003E5C2C /* Assets.xcassets */; }; C73C89AE26845908003E5C2C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C73C899926845908003E5C2C /* Assets.xcassets */; }; C74593FE26BDDD6100153AE3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C74593FD26BDDD6100153AE3 /* Assets.xcassets */; }; - C745940526BDDD6200153AE3 /* CrashlyticsExample_(watchOS)_Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = C745940426BDDD6200153AE3 /* CrashlyticsExample_(watchOS)_Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + C745940526BDDD6200153AE3 /* CrashlyticsSwiftUIExample_(watchOS)_Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = C745940426BDDD6200153AE3 /* CrashlyticsSwiftUIExample_(watchOS)_Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; C745940E26BDDD6200153AE3 /* NotificationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C745940D26BDDD6200153AE3 /* NotificationController.swift */; }; C745941026BDDD6200153AE3 /* NotificationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C745940F26BDDD6200153AE3 /* NotificationView.swift */; }; C745941226BDDD6200153AE3 /* ComplicationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C745941126BDDD6200153AE3 /* ComplicationController.swift */; }; C745941426BDDD6300153AE3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C745941326BDDD6300153AE3 /* Assets.xcassets */; }; C745941726BDDD6300153AE3 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C745941626BDDD6300153AE3 /* Preview Assets.xcassets */; }; - C745941C26BDDD6300153AE3 /* CrashlyticsExample_(watchOS).app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = C74593FB26BDDD5F00153AE3 /* CrashlyticsExample_(watchOS).app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + C745941C26BDDD6300153AE3 /* CrashlyticsSwiftUIExample_(watchOS).app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = C74593FB26BDDD5F00153AE3 /* CrashlyticsSwiftUIExample_(watchOS).app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + C745942626BDDDA500153AE3 /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = C745942526BDDDA500153AE3 /* FirebaseCrashlytics */; }; C745942726BDDDEF00153AE3 /* CrashlyticsSwiftUIExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C73C899726845907003E5C2C /* CrashlyticsSwiftUIExampleApp.swift */; }; C745942826BDDDF500153AE3 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C73C899826845907003E5C2C /* ContentView.swift */; }; C74C554726B377F20043B835 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C74C554626B377F20043B835 /* Assets.xcassets */; }; C74C554A26B377F20043B835 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C74C554926B377F20043B835 /* Preview Assets.xcassets */; }; + C77AC00326BB151000BDE919 /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = C77AC00226BB151000BDE919 /* FirebaseCrashlytics */; }; + C77AC00526BB151000BDE919 /* Reachability in Frameworks */ = {isa = PBXBuildFile; productRef = C77AC00426BB151000BDE919 /* Reachability */; }; C77AC00626BB16C200BDE919 /* CrashlyticsSwiftUIExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C73C899726845907003E5C2C /* CrashlyticsSwiftUIExampleApp.swift */; }; - C77AC00726BB16C500BDE919 /* ReachabilityHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C723B78C26853A1700AD34CD /* ReachabilityHelper.swift */; }; + C77AC00726BB16C500BDE919 /* ReachabililtyHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C723B78C26853A1700AD34CD /* ReachabililtyHelper.swift */; }; C77AC00826BB16CA00BDE919 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C73C899826845907003E5C2C /* ContentView.swift */; }; + C77AC00A26BB16E300BDE919 /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = C77AC00926BB16E300BDE919 /* FirebaseCrashlytics */; }; + C77AC00C26BB16E300BDE919 /* Reachability in Frameworks */ = {isa = PBXBuildFile; productRef = C77AC00B26BB16E300BDE919 /* Reachability */; }; C79FD3BA26C728D800FE0261 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = C79FD3B926C728D800FE0261 /* GoogleService-Info.plist */; }; C79FD3BB26C728D800FE0261 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = C79FD3B926C728D800FE0261 /* GoogleService-Info.plist */; }; C79FD3BC26C728D800FE0261 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = C79FD3B926C728D800FE0261 /* GoogleService-Info.plist */; }; @@ -42,8 +46,6 @@ C7E7BA8626DDF54400EC8D24 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = C79FD3B226C6E75000FE0261 /* GoogleService-Info.plist */; }; C7F8A32126D95D0000F5D9FE /* UITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C726B81B26D84D51000991C1 /* UITests.swift */; }; C7F8A33F26D95DBF00F5D9FE /* UITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C726B81B26D84D51000991C1 /* UITests.swift */; }; - EAC899832E9FDEE5004DA35E /* ReachabilityHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C723B78C26853A1700AD34CD /* ReachabilityHelper.swift */; }; - EAC899842E9FDEFF004DA35E /* ReachabilityHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C723B78C26853A1700AD34CD /* ReachabilityHelper.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -52,7 +54,7 @@ containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; proxyType = 1; remoteGlobalIDString = C73C899D26845908003E5C2C; - remoteInfo = "CrashlyticsExample"; + remoteInfo = "CrashlyticsSwiftUIExample (iOS)"; }; C745940626BDDD6200153AE3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -98,7 +100,7 @@ dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; dstSubfolderSpec = 16; files = ( - C745941C26BDDD6300153AE3 /* CrashlyticsExample_(watchOS).app in Embed Watch Content */, + C745941C26BDDD6300153AE3 /* CrashlyticsSwiftUIExample_(watchOS).app in Embed Watch Content */, ); name = "Embed Watch Content"; runOnlyForDeploymentPostprocessing = 0; @@ -109,7 +111,7 @@ dstPath = ""; dstSubfolderSpec = 13; files = ( - C745940526BDDD6200153AE3 /* CrashlyticsExample_(watchOS)_Extension.appex in Embed App Extensions */, + C745940526BDDD6200153AE3 /* CrashlyticsSwiftUIExample_(watchOS)_Extension.appex in Embed App Extensions */, ); name = "Embed App Extensions"; runOnlyForDeploymentPostprocessing = 0; @@ -117,7 +119,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - C723B78C26853A1700AD34CD /* ReachabilityHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReachabilityHelper.swift; sourceTree = ""; }; + C723B78C26853A1700AD34CD /* ReachabililtyHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReachabililtyHelper.swift; sourceTree = ""; }; C726B81926D84D51000991C1 /* UITests_iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UITests_iOS.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; C726B81B26D84D51000991C1 /* UITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITests.swift; sourceTree = ""; }; C73C899726845907003E5C2C /* CrashlyticsSwiftUIExampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashlyticsSwiftUIExampleApp.swift; sourceTree = ""; }; @@ -128,10 +130,10 @@ C73C89A526845908003E5C2C /* CrashlyticsSwiftUIExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CrashlyticsSwiftUIExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; C73C89A726845908003E5C2C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; C73C89A826845908003E5C2C /* macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = macOS.entitlements; sourceTree = ""; }; - C74593FB26BDDD5F00153AE3 /* CrashlyticsExample_(watchOS).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "CrashlyticsExample_(watchOS).app"; sourceTree = BUILT_PRODUCTS_DIR; }; + C74593FB26BDDD5F00153AE3 /* CrashlyticsSwiftUIExample_(watchOS).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "CrashlyticsSwiftUIExample_(watchOS).app"; sourceTree = BUILT_PRODUCTS_DIR; }; C74593FD26BDDD6100153AE3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; C74593FF26BDDD6100153AE3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - C745940426BDDD6200153AE3 /* CrashlyticsExample_(watchOS)_Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "CrashlyticsExample_(watchOS)_Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; + C745940426BDDD6200153AE3 /* CrashlyticsSwiftUIExample_(watchOS)_Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "CrashlyticsSwiftUIExample_(watchOS)_Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; C745940D26BDDD6200153AE3 /* NotificationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationController.swift; sourceTree = ""; }; C745940F26BDDD6200153AE3 /* NotificationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationView.swift; sourceTree = ""; }; C745941126BDDD6200153AE3 /* ComplicationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComplicationController.swift; sourceTree = ""; }; @@ -139,7 +141,7 @@ C745941626BDDD6300153AE3 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; C745941826BDDD6300153AE3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; C745941926BDDD6300153AE3 /* PushNotificationPayload.apns */ = {isa = PBXFileReference; lastKnownFileType = text; path = PushNotificationPayload.apns; sourceTree = ""; }; - C74C554026B377EF0043B835 /* CrashlyticsExample (tvOS).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "CrashlyticsExample (tvOS).app"; sourceTree = BUILT_PRODUCTS_DIR; }; + C74C554026B377EF0043B835 /* CrashlyticsSwiftUIExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CrashlyticsSwiftUIExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; C74C554626B377F20043B835 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; C74C554926B377F20043B835 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; C74C554B26B377F20043B835 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -163,7 +165,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8D00BB772D3B0AFF00F6F6DD /* FirebaseCrashlytics in Frameworks */, + C732A29826846B6D00AA7DEF /* FirebaseCrashlytics in Frameworks */, + 8D96F5DE2685440700F1A2B7 /* Reachability in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -171,7 +174,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8D00BB752D3B0AF400F6F6DD /* FirebaseCrashlytics in Frameworks */, + C77AC00326BB151000BDE919 /* FirebaseCrashlytics in Frameworks */, + C77AC00526BB151000BDE919 /* Reachability in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -179,7 +183,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8D00BB712D3B0ADE00F6F6DD /* FirebaseCrashlytics in Frameworks */, + C745942626BDDDA500153AE3 /* FirebaseCrashlytics in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -187,7 +191,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8D00BB732D3B0AED00F6F6DD /* FirebaseCrashlytics in Frameworks */, + C77AC00A26BB16E300BDE919 /* FirebaseCrashlytics in Frameworks */, + C77AC00C26BB16E300BDE919 /* Reachability in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -226,7 +231,6 @@ C74C554126B377EF0043B835 /* CrashlyticsSwiftUIExample */, C74593FC26BDDD5F00153AE3 /* CrashlyticsSwiftUIExample_(watchOS) */, C745940826BDDD6200153AE3 /* CrashlyticsSwiftUIExample_(watchOS)_Extension */, - 8D00BB6F2D3B0ADE00F6F6DD /* Frameworks */, 5F5A534D1ADE670C00F81DF0 /* Products */, ); sourceTree = ""; @@ -237,9 +241,9 @@ children = ( C73C899E26845908003E5C2C /* CrashlyticsSwiftUIExample.app */, C73C89A526845908003E5C2C /* CrashlyticsSwiftUIExample.app */, - C74C554026B377EF0043B835 /* CrashlyticsExample (tvOS).app */, - C74593FB26BDDD5F00153AE3 /* CrashlyticsExample_(watchOS).app */, - C745940426BDDD6200153AE3 /* CrashlyticsExample_(watchOS)_Extension.appex */, + C74C554026B377EF0043B835 /* CrashlyticsSwiftUIExample.app */, + C74593FB26BDDD5F00153AE3 /* CrashlyticsSwiftUIExample_(watchOS).app */, + C745940426BDDD6200153AE3 /* CrashlyticsSwiftUIExample_(watchOS)_Extension.appex */, C726B81926D84D51000991C1 /* UITests_iOS.xctest */, C7F8A31726D95CF700F5D9FE /* UITests_macOS.xctest */, C7F8A33526D95D3600F5D9FE /* UITests_tvOS.xctest */, @@ -248,18 +252,11 @@ name = Products; sourceTree = ""; }; - 8D00BB6F2D3B0ADE00F6F6DD /* Frameworks */ = { - isa = PBXGroup; - children = ( - ); - name = Frameworks; - sourceTree = ""; - }; C73C899626845907003E5C2C /* Shared */ = { isa = PBXGroup; children = ( C73C899726845907003E5C2C /* CrashlyticsSwiftUIExampleApp.swift */, - C723B78C26853A1700AD34CD /* ReachabilityHelper.swift */, + C723B78C26853A1700AD34CD /* ReachabililtyHelper.swift */, C73C899826845907003E5C2C /* ContentView.swift */, C726B81B26D84D51000991C1 /* UITests.swift */, C73C899926845908003E5C2C /* Assets.xcassets */, @@ -355,9 +352,9 @@ productReference = C726B81926D84D51000991C1 /* UITests_iOS.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; - C73C899D26845908003E5C2C /* CrashlyticsExample */ = { + C73C899D26845908003E5C2C /* CrashlyticsSwiftUIExample (iOS) */ = { isa = PBXNativeTarget; - buildConfigurationList = C73C89B326845908003E5C2C /* Build configuration list for PBXNativeTarget "CrashlyticsExample" */; + buildConfigurationList = C73C89B326845908003E5C2C /* Build configuration list for PBXNativeTarget "CrashlyticsSwiftUIExample (iOS)" */; buildPhases = ( C73C899A26845908003E5C2C /* Sources */, C73C899B26845908003E5C2C /* Frameworks */, @@ -370,17 +367,18 @@ dependencies = ( C745941B26BDDD6300153AE3 /* PBXTargetDependency */, ); - name = CrashlyticsExample; + name = "CrashlyticsSwiftUIExample (iOS)"; packageProductDependencies = ( - 8D00BB762D3B0AFF00F6F6DD /* FirebaseCrashlytics */, + C732A29726846B6D00AA7DEF /* FirebaseCrashlytics */, + 8D96F5DD2685440700F1A2B7 /* Reachability */, ); - productName = "CrashlyticsExample"; + productName = "CrashlyticsSwiftUIExample (iOS)"; productReference = C73C899E26845908003E5C2C /* CrashlyticsSwiftUIExample.app */; productType = "com.apple.product-type.application"; }; - C73C89A426845908003E5C2C /* CrashlyticsExample (macOS) */ = { + C73C89A426845908003E5C2C /* CrashlyticsSwiftUIExample (macOS) */ = { isa = PBXNativeTarget; - buildConfigurationList = C73C89B426845908003E5C2C /* Build configuration list for PBXNativeTarget "CrashlyticsExample (macOS)" */; + buildConfigurationList = C73C89B426845908003E5C2C /* Build configuration list for PBXNativeTarget "CrashlyticsSwiftUIExample (macOS)" */; buildPhases = ( C73C89A126845908003E5C2C /* Sources */, C73C89A226845908003E5C2C /* Frameworks */, @@ -390,17 +388,18 @@ ); dependencies = ( ); - name = "CrashlyticsExample (macOS)"; + name = "CrashlyticsSwiftUIExample (macOS)"; packageProductDependencies = ( - 8D00BB742D3B0AF400F6F6DD /* FirebaseCrashlytics */, + C77AC00226BB151000BDE919 /* FirebaseCrashlytics */, + C77AC00426BB151000BDE919 /* Reachability */, ); productName = "CrashlyticsSwiftUIExample (macOS)"; productReference = C73C89A526845908003E5C2C /* CrashlyticsSwiftUIExample.app */; productType = "com.apple.product-type.application"; }; - C74593FA26BDDD5F00153AE3 /* CrashlyticsExample_(watchOS) */ = { + C74593FA26BDDD5F00153AE3 /* CrashlyticsSwiftUIExample_(watchOS) */ = { isa = PBXNativeTarget; - buildConfigurationList = C745942426BDDD6300153AE3 /* Build configuration list for PBXNativeTarget "CrashlyticsExample_(watchOS)" */; + buildConfigurationList = C745942426BDDD6300153AE3 /* Build configuration list for PBXNativeTarget "CrashlyticsSwiftUIExample_(watchOS)" */; buildPhases = ( C74593F926BDDD5F00153AE3 /* Resources */, C745942026BDDD6300153AE3 /* Embed App Extensions */, @@ -410,14 +409,14 @@ dependencies = ( C745940726BDDD6200153AE3 /* PBXTargetDependency */, ); - name = "CrashlyticsExample_(watchOS)"; + name = "CrashlyticsSwiftUIExample_(watchOS)"; productName = "CrashlyticsSwiftUIExample (watchOS)"; - productReference = C74593FB26BDDD5F00153AE3 /* CrashlyticsExample_(watchOS).app */; + productReference = C74593FB26BDDD5F00153AE3 /* CrashlyticsSwiftUIExample_(watchOS).app */; productType = "com.apple.product-type.application.watchapp2"; }; - C745940326BDDD6200153AE3 /* CrashlyticsExample_(watchOS)_Extension */ = { + C745940326BDDD6200153AE3 /* CrashlyticsSwiftUIExample_(watchOS)_Extension */ = { isa = PBXNativeTarget; - buildConfigurationList = C745942326BDDD6300153AE3 /* Build configuration list for PBXNativeTarget "CrashlyticsExample_(watchOS)_Extension" */; + buildConfigurationList = C745942326BDDD6300153AE3 /* Build configuration list for PBXNativeTarget "CrashlyticsSwiftUIExample_(watchOS)_Extension" */; buildPhases = ( C745940026BDDD6200153AE3 /* Sources */, C745940126BDDD6200153AE3 /* Frameworks */, @@ -427,17 +426,17 @@ ); dependencies = ( ); - name = "CrashlyticsExample_(watchOS)_Extension"; + name = "CrashlyticsSwiftUIExample_(watchOS)_Extension"; packageProductDependencies = ( - 8D00BB702D3B0ADE00F6F6DD /* FirebaseCrashlytics */, + C745942526BDDDA500153AE3 /* FirebaseCrashlytics */, ); productName = "CrashlyticsSwiftUIExample (watchOS) Extension"; - productReference = C745940426BDDD6200153AE3 /* CrashlyticsExample_(watchOS)_Extension.appex */; + productReference = C745940426BDDD6200153AE3 /* CrashlyticsSwiftUIExample_(watchOS)_Extension.appex */; productType = "com.apple.product-type.watchkit2-extension"; }; - C74C553F26B377EF0043B835 /* CrashlyticsExample (tvOS) */ = { + C74C553F26B377EF0043B835 /* CrashlyticsSwiftUIExample */ = { isa = PBXNativeTarget; - buildConfigurationList = C74C554C26B377F20043B835 /* Build configuration list for PBXNativeTarget "CrashlyticsExample (tvOS)" */; + buildConfigurationList = C74C554C26B377F20043B835 /* Build configuration list for PBXNativeTarget "CrashlyticsSwiftUIExample" */; buildPhases = ( C74C553C26B377EF0043B835 /* Sources */, C74C553D26B377EF0043B835 /* Frameworks */, @@ -447,12 +446,13 @@ ); dependencies = ( ); - name = "CrashlyticsExample (tvOS)"; + name = CrashlyticsSwiftUIExample; packageProductDependencies = ( - 8D00BB722D3B0AED00F6F6DD /* FirebaseCrashlytics */, + C77AC00926BB16E300BDE919 /* FirebaseCrashlytics */, + C77AC00B26BB16E300BDE919 /* Reachability */, ); productName = CrashlyticsSwiftUIExample; - productReference = C74C554026B377EF0043B835 /* CrashlyticsExample (tvOS).app */; + productReference = C74C554026B377EF0043B835 /* CrashlyticsSwiftUIExample.app */; productType = "com.apple.product-type.application"; }; C7E7BA7626DDF34C00EC8D24 /* UITests_watchOS */ = { @@ -566,17 +566,18 @@ ); mainGroup = 5F5A53431ADE670C00F81DF0; packageReferences = ( - 8D00BB6E2D3B0ACF00F6F6DD /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, + C732A28E2684656200AA7DEF /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, + 8D96F5DC2685440700F1A2B7 /* XCRemoteSwiftPackageReference "Reachability.swift" */, ); productRefGroup = 5F5A534D1ADE670C00F81DF0 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - C73C899D26845908003E5C2C /* CrashlyticsExample */, - C73C89A426845908003E5C2C /* CrashlyticsExample (macOS) */, - C74C553F26B377EF0043B835 /* CrashlyticsExample (tvOS) */, - C74593FA26BDDD5F00153AE3 /* CrashlyticsExample_(watchOS) */, - C745940326BDDD6200153AE3 /* CrashlyticsExample_(watchOS)_Extension */, + C73C899D26845908003E5C2C /* CrashlyticsSwiftUIExample (iOS) */, + C73C89A426845908003E5C2C /* CrashlyticsSwiftUIExample (macOS) */, + C74C553F26B377EF0043B835 /* CrashlyticsSwiftUIExample */, + C74593FA26BDDD5F00153AE3 /* CrashlyticsSwiftUIExample_(watchOS) */, + C745940326BDDD6200153AE3 /* CrashlyticsSwiftUIExample_(watchOS)_Extension */, C726B81826D84D51000991C1 /* UITests_iOS */, C7F8A31626D95CF700F5D9FE /* UITests_macOS */, C7F8A33426D95D3600F5D9FE /* UITests_tvOS */, @@ -699,8 +700,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 8D96F5E62685442800F1A2B7 /* ReachabililtyHelper.swift in Sources */, C73C89AB26845908003E5C2C /* ContentView.swift in Sources */, - EAC899842E9FDEFF004DA35E /* ReachabilityHelper.swift in Sources */, C73C89A926845908003E5C2C /* CrashlyticsSwiftUIExampleApp.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -709,7 +710,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 8D96F5EE2685442C00F1A2B7 /* ReachabilityHelper.swift in Sources */, + 8D96F5EE2685442C00F1A2B7 /* ReachabililtyHelper.swift in Sources */, C73C89AC26845908003E5C2C /* ContentView.swift in Sources */, C73C89AA26845908003E5C2C /* CrashlyticsSwiftUIExampleApp.swift in Sources */, ); @@ -723,7 +724,6 @@ C745942826BDDDF500153AE3 /* ContentView.swift in Sources */, C745941226BDDD6200153AE3 /* ComplicationController.swift in Sources */, C745942726BDDDEF00153AE3 /* CrashlyticsSwiftUIExampleApp.swift in Sources */, - EAC899832E9FDEE5004DA35E /* ReachabilityHelper.swift in Sources */, C745941026BDDD6200153AE3 /* NotificationView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -733,7 +733,7 @@ buildActionMask = 2147483647; files = ( C77AC00626BB16C200BDE919 /* CrashlyticsSwiftUIExampleApp.swift in Sources */, - C77AC00726BB16C500BDE919 /* ReachabilityHelper.swift in Sources */, + C77AC00726BB16C500BDE919 /* ReachabililtyHelper.swift in Sources */, C77AC00826BB16CA00BDE919 /* ContentView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -767,32 +767,32 @@ /* Begin PBXTargetDependency section */ C726B81F26D84D51000991C1 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = C73C899D26845908003E5C2C /* CrashlyticsExample */; + target = C73C899D26845908003E5C2C /* CrashlyticsSwiftUIExample (iOS) */; targetProxy = C726B81E26D84D51000991C1 /* PBXContainerItemProxy */; }; C745940726BDDD6200153AE3 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = C745940326BDDD6200153AE3 /* CrashlyticsExample_(watchOS)_Extension */; + target = C745940326BDDD6200153AE3 /* CrashlyticsSwiftUIExample_(watchOS)_Extension */; targetProxy = C745940626BDDD6200153AE3 /* PBXContainerItemProxy */; }; C745941B26BDDD6300153AE3 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = C74593FA26BDDD5F00153AE3 /* CrashlyticsExample_(watchOS) */; + target = C74593FA26BDDD5F00153AE3 /* CrashlyticsSwiftUIExample_(watchOS) */; targetProxy = C745941A26BDDD6300153AE3 /* PBXContainerItemProxy */; }; C7E7BA7E26DDF34C00EC8D24 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = C74593FA26BDDD5F00153AE3 /* CrashlyticsExample_(watchOS) */; + target = C74593FA26BDDD5F00153AE3 /* CrashlyticsSwiftUIExample_(watchOS) */; targetProxy = C7E7BA7D26DDF34C00EC8D24 /* PBXContainerItemProxy */; }; C7F8A31D26D95CF700F5D9FE /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = C73C89A426845908003E5C2C /* CrashlyticsExample (macOS) */; + target = C73C89A426845908003E5C2C /* CrashlyticsSwiftUIExample (macOS) */; targetProxy = C7F8A31C26D95CF700F5D9FE /* PBXContainerItemProxy */; }; C7F8A33B26D95D3600F5D9FE /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = C74C553F26B377EF0043B835 /* CrashlyticsExample (tvOS) */; + target = C74C553F26B377EF0043B835 /* CrashlyticsSwiftUIExample */; targetProxy = C7F8A33A26D95D3600F5D9FE /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -933,7 +933,7 @@ SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = "CrashlyticsExample"; + TEST_TARGET_NAME = "CrashlyticsSwiftUIExample (iOS)"; }; name = Debug; }; @@ -963,7 +963,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = "CrashlyticsExample"; + TEST_TARGET_NAME = "CrashlyticsSwiftUIExample (iOS)"; }; name = Release; }; @@ -1356,7 +1356,7 @@ SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 4; - TEST_TARGET_NAME = "CrashlyticsExample (watchOS)"; + TEST_TARGET_NAME = "CrashlyticsSwiftUIExample_(watchOS)"; WATCHOS_DEPLOYMENT_TARGET = 7.4; }; name = Debug; @@ -1391,7 +1391,7 @@ SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 4; - TEST_TARGET_NAME = "CrashlyticsExample (watchOS)"; + TEST_TARGET_NAME = "CrashlyticsSwiftUIExample_(watchOS)"; WATCHOS_DEPLOYMENT_TARGET = 7.4; }; name = Release; @@ -1425,7 +1425,7 @@ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; - TEST_TARGET_NAME = "CrashlyticsExample (macOS)"; + TEST_TARGET_NAME = "CrashlyticsSwiftUIExample (macOS)"; }; name = Debug; }; @@ -1456,7 +1456,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; SWIFT_VERSION = 5.0; - TEST_TARGET_NAME = "CrashlyticsExample (macOS)"; + TEST_TARGET_NAME = "CrashlyticsSwiftUIExample (macOS)"; }; name = Release; }; @@ -1488,7 +1488,7 @@ SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 3; - TEST_TARGET_NAME = "CrashlyticsExample (tvOS)"; + TEST_TARGET_NAME = CrashlyticsSwiftUIExample; TVOS_DEPLOYMENT_TARGET = 15.0; }; name = Debug; @@ -1519,7 +1519,7 @@ SDKROOT = appletvos; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 3; - TEST_TARGET_NAME = "CrashlyticsExample (tvOS)"; + TEST_TARGET_NAME = CrashlyticsSwiftUIExample; TVOS_DEPLOYMENT_TARGET = 15.0; }; name = Release; @@ -1545,7 +1545,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - C73C89B326845908003E5C2C /* Build configuration list for PBXNativeTarget "CrashlyticsExample" */ = { + C73C89B326845908003E5C2C /* Build configuration list for PBXNativeTarget "CrashlyticsSwiftUIExample (iOS)" */ = { isa = XCConfigurationList; buildConfigurations = ( C73C89AF26845908003E5C2C /* Debug */, @@ -1554,7 +1554,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - C73C89B426845908003E5C2C /* Build configuration list for PBXNativeTarget "CrashlyticsExample (macOS)" */ = { + C73C89B426845908003E5C2C /* Build configuration list for PBXNativeTarget "CrashlyticsSwiftUIExample (macOS)" */ = { isa = XCConfigurationList; buildConfigurations = ( C73C89B126845908003E5C2C /* Debug */, @@ -1563,7 +1563,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - C745942326BDDD6300153AE3 /* Build configuration list for PBXNativeTarget "CrashlyticsExample_(watchOS)_Extension" */ = { + C745942326BDDD6300153AE3 /* Build configuration list for PBXNativeTarget "CrashlyticsSwiftUIExample_(watchOS)_Extension" */ = { isa = XCConfigurationList; buildConfigurations = ( C745942126BDDD6300153AE3 /* Debug */, @@ -1572,7 +1572,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - C745942426BDDD6300153AE3 /* Build configuration list for PBXNativeTarget "CrashlyticsExample_(watchOS)" */ = { + C745942426BDDD6300153AE3 /* Build configuration list for PBXNativeTarget "CrashlyticsSwiftUIExample_(watchOS)" */ = { isa = XCConfigurationList; buildConfigurations = ( C745941E26BDDD6300153AE3 /* Debug */, @@ -1581,7 +1581,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - C74C554C26B377F20043B835 /* Build configuration list for PBXNativeTarget "CrashlyticsExample (tvOS)" */ = { + C74C554C26B377F20043B835 /* Build configuration list for PBXNativeTarget "CrashlyticsSwiftUIExample" */ = { isa = XCConfigurationList; buildConfigurations = ( C74C554D26B377F20043B835 /* Debug */, @@ -1620,37 +1620,60 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ - 8D00BB6E2D3B0ACF00F6F6DD /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { + 8D96F5DC2685440700F1A2B7 /* XCRemoteSwiftPackageReference "Reachability.swift" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/ashleymills/Reachability.swift.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 5.1.0; + }; + }; + C732A28E2684656200AA7DEF /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/firebase/firebase-ios-sdk"; + repositoryURL = "https://github.com/firebase/firebase-ios-sdk.git"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 11.7.0; + minimumVersion = 10.0.0; }; }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ - 8D00BB702D3B0ADE00F6F6DD /* FirebaseCrashlytics */ = { + 8D96F5DD2685440700F1A2B7 /* Reachability */ = { + isa = XCSwiftPackageProductDependency; + package = 8D96F5DC2685440700F1A2B7 /* XCRemoteSwiftPackageReference "Reachability.swift" */; + productName = Reachability; + }; + C732A29726846B6D00AA7DEF /* FirebaseCrashlytics */ = { isa = XCSwiftPackageProductDependency; - package = 8D00BB6E2D3B0ACF00F6F6DD /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + package = C732A28E2684656200AA7DEF /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; productName = FirebaseCrashlytics; }; - 8D00BB722D3B0AED00F6F6DD /* FirebaseCrashlytics */ = { + C745942526BDDDA500153AE3 /* FirebaseCrashlytics */ = { isa = XCSwiftPackageProductDependency; - package = 8D00BB6E2D3B0ACF00F6F6DD /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + package = C732A28E2684656200AA7DEF /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; productName = FirebaseCrashlytics; }; - 8D00BB742D3B0AF400F6F6DD /* FirebaseCrashlytics */ = { + C77AC00226BB151000BDE919 /* FirebaseCrashlytics */ = { isa = XCSwiftPackageProductDependency; - package = 8D00BB6E2D3B0ACF00F6F6DD /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + package = C732A28E2684656200AA7DEF /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; productName = FirebaseCrashlytics; }; - 8D00BB762D3B0AFF00F6F6DD /* FirebaseCrashlytics */ = { + C77AC00426BB151000BDE919 /* Reachability */ = { isa = XCSwiftPackageProductDependency; - package = 8D00BB6E2D3B0ACF00F6F6DD /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + package = 8D96F5DC2685440700F1A2B7 /* XCRemoteSwiftPackageReference "Reachability.swift" */; + productName = Reachability; + }; + C77AC00926BB16E300BDE919 /* FirebaseCrashlytics */ = { + isa = XCSwiftPackageProductDependency; + package = C732A28E2684656200AA7DEF /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; productName = FirebaseCrashlytics; }; + C77AC00B26BB16E300BDE919 /* Reachability */ = { + isa = XCSwiftPackageProductDependency; + package = 8D96F5DC2685440700F1A2B7 /* XCRemoteSwiftPackageReference "Reachability.swift" */; + productName = Reachability; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 5F5A53441ADE670C00F81DF0 /* Project object */; diff --git a/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample.xcscheme b/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (iOS).xcscheme similarity index 94% rename from crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample.xcscheme rename to crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (iOS).xcscheme index c762bff26..a78d5aefc 100644 --- a/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample.xcscheme +++ b/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (iOS).xcscheme @@ -16,7 +16,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "C73C899D26845908003E5C2C" BuildableName = "CrashlyticsSwiftUIExample.app" - BlueprintName = "CrashlyticsExample" + BlueprintName = "CrashlyticsSwiftUIExample (iOS)" ReferencedContainer = "container:CrashlyticsExample.xcodeproj"> @@ -61,7 +61,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "C73C899D26845908003E5C2C" BuildableName = "CrashlyticsSwiftUIExample.app" - BlueprintName = "CrashlyticsExample" + BlueprintName = "CrashlyticsSwiftUIExample (iOS)" ReferencedContainer = "container:CrashlyticsExample.xcodeproj"> @@ -78,7 +78,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "C73C899D26845908003E5C2C" BuildableName = "CrashlyticsSwiftUIExample.app" - BlueprintName = "CrashlyticsExample" + BlueprintName = "CrashlyticsSwiftUIExample (iOS)" ReferencedContainer = "container:CrashlyticsExample.xcodeproj"> diff --git a/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (macOS).xcscheme b/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (macOS).xcscheme index b559c57fe..4668351e6 100644 --- a/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (macOS).xcscheme +++ b/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (macOS).xcscheme @@ -16,7 +16,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "C73C89A426845908003E5C2C" BuildableName = "CrashlyticsSwiftUIExample.app" - BlueprintName = "CrashlyticsExample (macOS)" + BlueprintName = "CrashlyticsSwiftUIExample (macOS)" ReferencedContainer = "container:CrashlyticsExample.xcodeproj"> @@ -61,7 +61,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "C73C89A426845908003E5C2C" BuildableName = "CrashlyticsSwiftUIExample.app" - BlueprintName = "CrashlyticsExample (macOS)" + BlueprintName = "CrashlyticsSwiftUIExample (macOS)" ReferencedContainer = "container:CrashlyticsExample.xcodeproj"> @@ -78,7 +78,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "C73C89A426845908003E5C2C" BuildableName = "CrashlyticsSwiftUIExample.app" - BlueprintName = "CrashlyticsExample (macOS)" + BlueprintName = "CrashlyticsSwiftUIExample (macOS)" ReferencedContainer = "container:CrashlyticsExample.xcodeproj"> diff --git a/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (tvOS).xcscheme b/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (tvOS).xcscheme index bc9cb943a..92e826249 100644 --- a/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (tvOS).xcscheme +++ b/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (tvOS).xcscheme @@ -15,8 +15,8 @@ @@ -60,8 +60,8 @@ @@ -77,8 +77,8 @@ diff --git a/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (watchOS) (Complication).xcscheme b/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (watchOS) (Complication).xcscheme index 47a905517..5460d7d05 100644 --- a/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (watchOS) (Complication).xcscheme +++ b/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (watchOS) (Complication).xcscheme @@ -15,8 +15,8 @@ @@ -30,7 +30,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "C73C899D26845908003E5C2C" BuildableName = "CrashlyticsSwiftUIExample.app" - BlueprintName = "CrashlyticsExample" + BlueprintName = "CrashlyticsSwiftUIExample (iOS)" ReferencedContainer = "container:CrashlyticsExample.xcodeproj"> @@ -65,16 +65,18 @@ debugServiceExtension = "internal" allowLocationSimulation = "YES" launchAutomaticallySubstyle = "32"> - + - + - + - + + + + + diff --git a/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (watchOS) (Notification).xcscheme b/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (watchOS) (Notification).xcscheme index 968474a9d..8135cd872 100644 --- a/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (watchOS) (Notification).xcscheme +++ b/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (watchOS) (Notification).xcscheme @@ -15,8 +15,8 @@ @@ -30,7 +30,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "C73C899D26845908003E5C2C" BuildableName = "CrashlyticsSwiftUIExample.app" - BlueprintName = "CrashlyticsExample" + BlueprintName = "CrashlyticsSwiftUIExample (iOS)" ReferencedContainer = "container:CrashlyticsExample.xcodeproj"> @@ -66,16 +66,18 @@ allowLocationSimulation = "YES" launchAutomaticallySubstyle = "8" notificationPayloadFile = "CrashlyticsSwiftUIExample_(watchOS)_Extension/PushNotificationPayload.apns"> - + - + - + - + + + + + diff --git a/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (watchOS).xcscheme b/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (watchOS).xcscheme index a177a25be..71f3d8bed 100644 --- a/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (watchOS).xcscheme +++ b/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample (watchOS).xcscheme @@ -15,8 +15,8 @@ @@ -30,7 +30,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "C73C899D26845908003E5C2C" BuildableName = "CrashlyticsSwiftUIExample.app" - BlueprintName = "CrashlyticsExample" + BlueprintName = "CrashlyticsSwiftUIExample (iOS)" ReferencedContainer = "container:CrashlyticsExample.xcodeproj"> @@ -76,16 +76,18 @@ debugServiceExtension = "internal" allowLocationSimulation = "YES" notificationPayloadFile = "CrashlyticsSwiftUIExample_(watchOS)_Extension/PushNotificationPayload.apns"> - + - + - + - + + + + + diff --git a/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/UITests_iOS.xcscheme b/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/UITests_iOS.xcscheme deleted file mode 100644 index a6e1384ae..000000000 --- a/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/UITests_iOS.xcscheme +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/UITests_macOS.xcscheme b/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/UITests_macOS.xcscheme deleted file mode 100644 index f8ac28362..000000000 --- a/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/UITests_macOS.xcscheme +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/UITests_tvOS.xcscheme b/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/UITests_tvOS.xcscheme deleted file mode 100644 index 0ec483ee4..000000000 --- a/crashlytics/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/UITests_tvOS.xcscheme +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample.xcodeproj/project.pbxproj b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample.xcodeproj/project.pbxproj new file mode 100644 index 000000000..d8e38e95f --- /dev/null +++ b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample.xcodeproj/project.pbxproj @@ -0,0 +1,954 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 52; + objects = { + +/* Begin PBXBuildFile section */ + 0DDAE1A41098B006303515E2 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = A635694C8BE79DC67214731F /* GoogleService-Info.plist */; }; + 1073472D20315969004A66D1 /* CrashReportingExampleSwiftUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1073472C20315969004A66D1 /* CrashReportingExampleSwiftUITests.swift */; }; + 1073482920333B71004A66D1 /* CrashReportingExampleUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1073482820333B71004A66D1 /* CrashReportingExampleUITests.m */; }; + 5F5A53521ADE670C00F81DF0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53511ADE670C00F81DF0 /* main.m */; }; + 5F5A53551ADE670C00F81DF0 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */; }; + 5F5A53581ADE670C00F81DF0 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53571ADE670C00F81DF0 /* ViewController.m */; }; + 5F5A535B1ADE670C00F81DF0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5F5A53591ADE670C00F81DF0 /* Main.storyboard */; }; + 5F5A537E1ADE67D500F81DF0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */; }; + 5F5A53801ADE67D500F81DF0 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A537F1ADE67D500F81DF0 /* ViewController.swift */; }; + 5F5A539C1ADE69AA00F81DF0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5F5A53591ADE670C00F81DF0 /* Main.storyboard */; }; + 5FDE055D1B0DAA090037B82F /* AppTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FDE055C1B0DAA090037B82F /* AppTests.m */; }; + 7FD4CBFA51EAB8A25764BF8B /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = A635694C8BE79DC67214731F /* GoogleService-Info.plist */; }; + 85F2A78F84665B33B5E340A6 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = A635694C8BE79DC67214731F /* GoogleService-Info.plist */; }; + 8D07E3D5268BF7210002C432 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8D07E3D3268BF7210002C432 /* Images.xcassets */; }; + 8D07E3D6268BF7210002C432 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8D07E3D4268BF7210002C432 /* LaunchScreen.xib */; }; + 8D07E3D7268BF7250002C432 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8D07E3D3268BF7210002C432 /* Images.xcassets */; }; + 8D07E3D8268BF7280002C432 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8D07E3D4268BF7210002C432 /* LaunchScreen.xib */; }; + A65DFC68874CB909A594C72A /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = A635694C8BE79DC67214731F /* GoogleService-Info.plist */; }; + FAC4F6426F15EB440B635B88 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = A635694C8BE79DC67214731F /* GoogleService-Info.plist */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 1073472F20315969004A66D1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5F5A53781ADE67D500F81DF0; + remoteInfo = CrashReportingExampleSwift; + }; + 1073482B20333B71004A66D1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5F5A534B1ADE670C00F81DF0; + remoteInfo = CrashReportingExample; + }; + 5FDE055E1B0DAA090037B82F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5F5A534B1ADE670C00F81DF0; + remoteInfo = CrashReporter; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 1073472A20315969004A66D1 /* CrashlyticsExampleSwiftUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CrashlyticsExampleSwiftUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 1073472C20315969004A66D1 /* CrashReportingExampleSwiftUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReportingExampleSwiftUITests.swift; sourceTree = ""; }; + 1073472E20315969004A66D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1073482620333B71004A66D1 /* CrashlyticsExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CrashlyticsExampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 1073482820333B71004A66D1 /* CrashReportingExampleUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CrashReportingExampleUITests.m; sourceTree = ""; }; + 1073482A20333B71004A66D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5F5A534C1ADE670C00F81DF0 /* CrashlyticsExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CrashlyticsExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5F5A53501ADE670C00F81DF0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5F5A53511ADE670C00F81DF0 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 5F5A53531ADE670C00F81DF0 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 5F5A53561ADE670C00F81DF0 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + 5F5A53571ADE670C00F81DF0 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 5F5A535A1ADE670C00F81DF0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 5F5A53791ADE67D500F81DF0 /* CrashlyticsExampleSwift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CrashlyticsExampleSwift.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 5F5A537F1ADE67D500F81DF0 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 5FDE05581B0DAA090037B82F /* CrashlyticsExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CrashlyticsExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5FDE055C1B0DAA090037B82F /* AppTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppTests.m; sourceTree = ""; }; + 8D07E3D3268BF7210002C432 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ../../shared/Images.xcassets; sourceTree = ""; }; + 8D07E3D4268BF7210002C432 /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = LaunchScreen.xib; path = ../../shared/LaunchScreen.xib; sourceTree = ""; }; + A635694C8BE79DC67214731F /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "../GoogleService-Info.plist"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1073472720315969004A66D1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1073482320333B71004A66D1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53491ADE670C00F81DF0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53761ADE67D500F81DF0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FDE05551B0DAA090037B82F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1073472B20315969004A66D1 /* CrashlyticsExampleSwiftUITests */ = { + isa = PBXGroup; + children = ( + 1073472C20315969004A66D1 /* CrashReportingExampleSwiftUITests.swift */, + 1073472E20315969004A66D1 /* Info.plist */, + ); + path = CrashlyticsExampleSwiftUITests; + sourceTree = ""; + }; + 1073482720333B71004A66D1 /* CrashlyticsExampleUITests */ = { + isa = PBXGroup; + children = ( + 1073482820333B71004A66D1 /* CrashReportingExampleUITests.m */, + 1073482A20333B71004A66D1 /* Info.plist */, + ); + path = CrashlyticsExampleUITests; + sourceTree = ""; + }; + 5F5A53431ADE670C00F81DF0 = { + isa = PBXGroup; + children = ( + 5F5A534E1ADE670C00F81DF0 /* CrashlyticsExample */, + 5F5A537A1ADE67D500F81DF0 /* CrashlyticsExampleSwift */, + 5FDE05591B0DAA090037B82F /* CrashlyticsExampleTests */, + 1073472B20315969004A66D1 /* CrashlyticsExampleSwiftUITests */, + 1073482720333B71004A66D1 /* CrashlyticsExampleUITests */, + 5F5A534D1ADE670C00F81DF0 /* Products */, + 5F9961041AE0CF4F0034F503 /* Shared */, + 71EF67FCA020EBD17372A579 /* Pods */, + A635694C8BE79DC67214731F /* GoogleService-Info.plist */, + ); + sourceTree = ""; + wrapsLines = 0; + }; + 5F5A534D1ADE670C00F81DF0 /* Products */ = { + isa = PBXGroup; + children = ( + 5F5A534C1ADE670C00F81DF0 /* CrashlyticsExample.app */, + 5F5A53791ADE67D500F81DF0 /* CrashlyticsExampleSwift.app */, + 5FDE05581B0DAA090037B82F /* CrashlyticsExampleTests.xctest */, + 1073472A20315969004A66D1 /* CrashlyticsExampleSwiftUITests.xctest */, + 1073482620333B71004A66D1 /* CrashlyticsExampleUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 5F5A534E1ADE670C00F81DF0 /* CrashlyticsExample */ = { + isa = PBXGroup; + children = ( + 5F5A53531ADE670C00F81DF0 /* AppDelegate.h */, + 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */, + 5F5A53561ADE670C00F81DF0 /* ViewController.h */, + 5F5A53571ADE670C00F81DF0 /* ViewController.m */, + 5F5A534F1ADE670C00F81DF0 /* Supporting Files */, + ); + path = CrashlyticsExample; + sourceTree = ""; + }; + 5F5A534F1ADE670C00F81DF0 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 5F5A53591ADE670C00F81DF0 /* Main.storyboard */, + 5F5A53501ADE670C00F81DF0 /* Info.plist */, + 5F5A53511ADE670C00F81DF0 /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 5F5A537A1ADE67D500F81DF0 /* CrashlyticsExampleSwift */ = { + isa = PBXGroup; + children = ( + 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */, + 5F5A537F1ADE67D500F81DF0 /* ViewController.swift */, + ); + path = CrashlyticsExampleSwift; + sourceTree = ""; + }; + 5F9961041AE0CF4F0034F503 /* Shared */ = { + isa = PBXGroup; + children = ( + 8D07E3D3268BF7210002C432 /* Images.xcassets */, + 8D07E3D4268BF7210002C432 /* LaunchScreen.xib */, + ); + name = Shared; + path = ../shared; + sourceTree = ""; + }; + 5FDE05591B0DAA090037B82F /* CrashlyticsExampleTests */ = { + isa = PBXGroup; + children = ( + 5FDE055C1B0DAA090037B82F /* AppTests.m */, + ); + path = CrashlyticsExampleTests; + sourceTree = ""; + }; + 71EF67FCA020EBD17372A579 /* Pods */ = { + isa = PBXGroup; + children = ( + ); + path = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1073472920315969004A66D1 /* CrashlyticsExampleSwiftUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1073473120315969004A66D1 /* Build configuration list for PBXNativeTarget "CrashlyticsExampleSwiftUITests" */; + buildPhases = ( + 1073472620315969004A66D1 /* Sources */, + 1073472720315969004A66D1 /* Frameworks */, + 1073472820315969004A66D1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 1073473020315969004A66D1 /* PBXTargetDependency */, + ); + name = CrashlyticsExampleSwiftUITests; + productName = CrashReportingExampleSwiftUITests; + productReference = 1073472A20315969004A66D1 /* CrashlyticsExampleSwiftUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + 1073482520333B71004A66D1 /* CrashlyticsExampleUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1073482D20333B71004A66D1 /* Build configuration list for PBXNativeTarget "CrashlyticsExampleUITests" */; + buildPhases = ( + 1073482220333B71004A66D1 /* Sources */, + 1073482320333B71004A66D1 /* Frameworks */, + 1073482420333B71004A66D1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 1073482C20333B71004A66D1 /* PBXTargetDependency */, + ); + name = CrashlyticsExampleUITests; + productName = CrashReportingExampleUITests; + productReference = 1073482620333B71004A66D1 /* CrashlyticsExampleUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + 5F5A534B1ADE670C00F81DF0 /* CrashlyticsExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5F5A536F1ADE670C00F81DF0 /* Build configuration list for PBXNativeTarget "CrashlyticsExample" */; + buildPhases = ( + 5F5A53481ADE670C00F81DF0 /* Sources */, + 5F5A53491ADE670C00F81DF0 /* Frameworks */, + 5F5A534A1ADE670C00F81DF0 /* Resources */, + 10E114DA20E3DDE20013E4A4 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CrashlyticsExample; + productName = CrashReporter; + productReference = 5F5A534C1ADE670C00F81DF0 /* CrashlyticsExample.app */; + productType = "com.apple.product-type.application"; + }; + 5F5A53781ADE67D500F81DF0 /* CrashlyticsExampleSwift */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5F5A53991ADE67D500F81DF0 /* Build configuration list for PBXNativeTarget "CrashlyticsExampleSwift" */; + buildPhases = ( + 5F5A53751ADE67D500F81DF0 /* Sources */, + 5F5A53761ADE67D500F81DF0 /* Frameworks */, + 5F5A53771ADE67D500F81DF0 /* Resources */, + 10E114DB20E3DDF00013E4A4 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CrashlyticsExampleSwift; + productName = CrashReporterSwift; + productReference = 5F5A53791ADE67D500F81DF0 /* CrashlyticsExampleSwift.app */; + productType = "com.apple.product-type.application"; + }; + 5FDE05571B0DAA090037B82F /* CrashlyticsExampleTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5FDE05621B0DAA090037B82F /* Build configuration list for PBXNativeTarget "CrashlyticsExampleTests" */; + buildPhases = ( + 5FDE05541B0DAA090037B82F /* Sources */, + 5FDE05551B0DAA090037B82F /* Frameworks */, + 5FDE05561B0DAA090037B82F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5FDE055F1B0DAA090037B82F /* PBXTargetDependency */, + ); + name = CrashlyticsExampleTests; + productName = CrashReporterTests; + productReference = 5FDE05581B0DAA090037B82F /* CrashlyticsExampleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5F5A53441ADE670C00F81DF0 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1250; + LastUpgradeCheck = 1110; + ORGANIZATIONNAME = "Google Inc."; + TargetAttributes = { + 1073472920315969004A66D1 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1110; + ProvisioningStyle = Automatic; + TestTargetID = 5F5A53781ADE67D500F81DF0; + }; + 1073482520333B71004A66D1 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Automatic; + TestTargetID = 5F5A534B1ADE670C00F81DF0; + }; + 5F5A534B1ADE670C00F81DF0 = { + CreatedOnToolsVersion = 6.3; + LastSwiftMigration = 0800; + ProvisioningStyle = Automatic; + }; + 5F5A53781ADE67D500F81DF0 = { + CreatedOnToolsVersion = 6.3; + LastSwiftMigration = 1110; + ProvisioningStyle = Automatic; + }; + 5FDE05571B0DAA090037B82F = { + CreatedOnToolsVersion = 6.3.2; + LastSwiftMigration = 0800; + ProvisioningStyle = Automatic; + TestTargetID = 5F5A534B1ADE670C00F81DF0; + }; + }; + }; + buildConfigurationList = 5F5A53471ADE670C00F81DF0 /* Build configuration list for PBXProject "CrashlyticsExample" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + English, + en, + Base, + ); + mainGroup = 5F5A53431ADE670C00F81DF0; + productRefGroup = 5F5A534D1ADE670C00F81DF0 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5F5A534B1ADE670C00F81DF0 /* CrashlyticsExample */, + 5F5A53781ADE67D500F81DF0 /* CrashlyticsExampleSwift */, + 5FDE05571B0DAA090037B82F /* CrashlyticsExampleTests */, + 1073472920315969004A66D1 /* CrashlyticsExampleSwiftUITests */, + 1073482520333B71004A66D1 /* CrashlyticsExampleUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1073472820315969004A66D1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1073482420333B71004A66D1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A534A1ADE670C00F81DF0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F5A535B1ADE670C00F81DF0 /* Main.storyboard in Resources */, + 8D07E3D6268BF7210002C432 /* LaunchScreen.xib in Resources */, + 8D07E3D5268BF7210002C432 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53771ADE67D500F81DF0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F5A539C1ADE69AA00F81DF0 /* Main.storyboard in Resources */, + 8D07E3D8268BF7280002C432 /* LaunchScreen.xib in Resources */, + 8D07E3D7268BF7250002C432 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FDE05561B0DAA090037B82F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 10E114DA20E3DDE20013E4A4 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\n# If installed via CocoaPods, then the \"run\" script will exist there\nif test -f \"${PODS_ROOT}/FirebaseCrashlytics/run\"; then\n \"${PODS_ROOT}/FirebaseCrashlytics/run\"\n\n# If just the contents of the \"FirebaseCrashlytics\" folder from the\n# zip download was dragged into the Xcode project, check the project root\nelif test -f \"${PROJECT_DIR}/run\"; then\n \"${PROJECT_DIR}/run\"\n \n# If the whole \"FirebaseCrashlytics\" folder was dragged in from the\n# zip download, check for it in the root of the project \nelif test -f \"${PROJECT_DIR}/FirebaseCrashlytics/run\"; then\n \"${PROJECT_DIR}/FirebaseCrashlytics/run\"\n \n# If we can't find the run script, fail the build so that we\n# know to fix the issue\nelse\n echo 'error: Could not find path to Crashlytics \"run\" script. Please ensure you have included the Crashlytics \"run\" script in the Xcode project directory, or update the path to the script in the Xcode project \"Build Phases\" > \"Run Script\"'\n exit 1\nfi\n"; + }; + 10E114DB20E3DDF00013E4A4 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\n# If installed via CocoaPods, then the \"run\" script will exist there\nif test -f \"${PODS_ROOT}/FirebaseCrashlytics/run\"; then\n \"${PODS_ROOT}/FirebaseCrashlytics/run\"\n\n# If just the contents of the \"FirebaseCrashlytics\" folder from the\n# zip download was dragged into the Xcode project, check the project root\nelif test -f \"${PROJECT_DIR}/run\"; then\n \"${PROJECT_DIR}/run\"\n \n# If the whole \"FirebaseCrashlytics\" folder was dragged in from the\n# zip download, check for it in the root of the project \nelif test -f \"${PROJECT_DIR}/FirebaseCrashlytics/run\"; then\n \"${PROJECT_DIR}/FirebaseCrashlytics/run\"\n \n# If we can't find the run script, fail the build so that we\n# know to fix the issue\nelse\n echo 'error: Could not find path to Crashlytics \"run\" script. Please ensure you have included the Crashlytics \"run\" script in the Xcode project directory, or update the path to the script in the Xcode project \"Build Phases\" > \"Run Script\"'\n exit 1\nfi\n"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1073472620315969004A66D1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1073472D20315969004A66D1 /* CrashReportingExampleSwiftUITests.swift in Sources */, + FAC4F6426F15EB440B635B88 /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1073482220333B71004A66D1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1073482920333B71004A66D1 /* CrashReportingExampleUITests.m in Sources */, + 85F2A78F84665B33B5E340A6 /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53481ADE670C00F81DF0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F5A53581ADE670C00F81DF0 /* ViewController.m in Sources */, + 5F5A53551ADE670C00F81DF0 /* AppDelegate.m in Sources */, + 5F5A53521ADE670C00F81DF0 /* main.m in Sources */, + A65DFC68874CB909A594C72A /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53751ADE67D500F81DF0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F5A53801ADE67D500F81DF0 /* ViewController.swift in Sources */, + 5F5A537E1ADE67D500F81DF0 /* AppDelegate.swift in Sources */, + 0DDAE1A41098B006303515E2 /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FDE05541B0DAA090037B82F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5FDE055D1B0DAA090037B82F /* AppTests.m in Sources */, + 7FD4CBFA51EAB8A25764BF8B /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 1073473020315969004A66D1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5F5A53781ADE67D500F81DF0 /* CrashlyticsExampleSwift */; + targetProxy = 1073472F20315969004A66D1 /* PBXContainerItemProxy */; + }; + 1073482C20333B71004A66D1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5F5A534B1ADE670C00F81DF0 /* CrashlyticsExample */; + targetProxy = 1073482B20333B71004A66D1 /* PBXContainerItemProxy */; + }; + 5FDE055F1B0DAA090037B82F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5F5A534B1ADE670C00F81DF0 /* CrashlyticsExample */; + targetProxy = 5FDE055E1B0DAA090037B82F /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 5F5A53591ADE670C00F81DF0 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5F5A535A1ADE670C00F81DF0 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1073473220315969004A66D1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = CrashlyticsExampleSwiftUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.CrashReportingExampleSwiftUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = CrashlyticsExampleSwift; + }; + name = Debug; + }; + 1073473320315969004A66D1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = CrashlyticsExampleSwiftUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.CrashReportingExampleSwiftUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = CrashlyticsExampleSwift; + }; + name = Release; + }; + 1073482E20333B71004A66D1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = CrashlyticsExampleUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.CrashReportingExampleUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = CrashlyticsExample; + }; + name = Debug; + }; + 1073482F20333B71004A66D1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = CrashlyticsExampleUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.CrashReportingExampleUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = CrashlyticsExample; + }; + name = Release; + }; + 5F5A536D1ADE670C00F81DF0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + ENABLE_BITCODE = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5F5A536E1ADE670C00F81DF0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + ENABLE_BITCODE = NO; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5F5A53701ADE670C00F81DF0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = "$(SRCROOT)/CrashlyticsExample/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.CrashReportingExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; + }; + name = Debug; + }; + 5F5A53711ADE670C00F81DF0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = "$(SRCROOT)/CrashlyticsExample/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.CrashReportingExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; + }; + name = Release; + }; + 5F5A53951ADE67D500F81DF0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "$(SRCROOT)/CrashlyticsExample/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.CrashReportingExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 5F5A53961ADE67D500F81DF0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "$(SRCROOT)/CrashlyticsExample/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.CrashReportingExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 5FDE05601B0DAA090037B82F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + CrashReporter, + ); + INFOPLIST_FILE = CrashlyticsExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CrashlyticsExample.app/CrashlyticsExample"; + }; + name = Debug; + }; + 5FDE05611B0DAA090037B82F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + CrashReporter, + ); + INFOPLIST_FILE = CrashlyticsExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CrashlyticsExample.app/CrashlyticsExample"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1073473120315969004A66D1 /* Build configuration list for PBXNativeTarget "CrashlyticsExampleSwiftUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1073473220315969004A66D1 /* Debug */, + 1073473320315969004A66D1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1073482D20333B71004A66D1 /* Build configuration list for PBXNativeTarget "CrashlyticsExampleUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1073482E20333B71004A66D1 /* Debug */, + 1073482F20333B71004A66D1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5F5A53471ADE670C00F81DF0 /* Build configuration list for PBXProject "CrashlyticsExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5F5A536D1ADE670C00F81DF0 /* Debug */, + 5F5A536E1ADE670C00F81DF0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5F5A536F1ADE670C00F81DF0 /* Build configuration list for PBXNativeTarget "CrashlyticsExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5F5A53701ADE670C00F81DF0 /* Debug */, + 5F5A53711ADE670C00F81DF0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5F5A53991ADE67D500F81DF0 /* Build configuration list for PBXNativeTarget "CrashlyticsExampleSwift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5F5A53951ADE67D500F81DF0 /* Debug */, + 5F5A53961ADE67D500F81DF0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5FDE05621B0DAA090037B82F /* Build configuration list for PBXNativeTarget "CrashlyticsExampleTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5FDE05601B0DAA090037B82F /* Debug */, + 5FDE05611B0DAA090037B82F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5F5A53441ADE670C00F81DF0 /* Project object */; +} diff --git a/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample.xcscheme b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample.xcscheme new file mode 100644 index 000000000..372fc9be5 --- /dev/null +++ b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExample.xcscheme @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/performance/PerformanceExample.xcodeproj/xcshareddata/xcschemes/PerformanceExample.xcscheme b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExampleSwift.xcscheme similarity index 65% rename from performance/PerformanceExample.xcodeproj/xcshareddata/xcschemes/PerformanceExample.xcscheme rename to crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExampleSwift.xcscheme index 1d3e807b7..2820fa348 100644 --- a/performance/PerformanceExample.xcodeproj/xcshareddata/xcschemes/PerformanceExample.xcscheme +++ b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample.xcodeproj/xcshareddata/xcschemes/CrashlyticsExampleSwift.xcscheme @@ -1,11 +1,10 @@ + LastUpgradeVersion = "1110" + version = "1.3"> + buildImplicitDependencies = "YES"> + BuildableName = "CrashlyticsExampleSwift.app" + BlueprintName = "CrashlyticsExampleSwift" + ReferencedContainer = "container:CrashlyticsExample.xcodeproj"> @@ -27,17 +26,25 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES" - shouldAutocreateTestPlan = "YES"> + shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + BlueprintIdentifier = "1073472920315969004A66D1" + BuildableName = "CrashlyticsExampleSwiftUITests.xctest" + BlueprintName = "CrashlyticsExampleSwiftUITests" + ReferencedContainer = "container:CrashlyticsExample.xcodeproj"> @@ -57,9 +64,9 @@ + BuildableName = "CrashlyticsExampleSwift.app" + BlueprintName = "CrashlyticsExampleSwift" + ReferencedContainer = "container:CrashlyticsExample.xcodeproj"> @@ -74,9 +81,9 @@ + BuildableName = "CrashlyticsExampleSwift.app" + BlueprintName = "CrashlyticsExampleSwift" + ReferencedContainer = "container:CrashlyticsExample.xcodeproj"> diff --git a/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/.clang-format b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/.clang-format new file mode 100644 index 000000000..1f09ce0f2 --- /dev/null +++ b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/.clang-format @@ -0,0 +1,4 @@ +BasedOnStyle: Google +ColumnLimit: 100 +BinPackParameters: false +AllowAllParametersOfDeclarationOnNextLine: true diff --git a/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/AppDelegate.h b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/AppDelegate.h new file mode 100644 index 000000000..f284483f9 --- /dev/null +++ b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/AppDelegate.h @@ -0,0 +1,23 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import UIKit; + +@interface AppDelegate : UIResponder + +@property(nonatomic, strong) UIWindow *window; + +@end diff --git a/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/AppDelegate.m b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/AppDelegate.m new file mode 100644 index 000000000..14c6d2892 --- /dev/null +++ b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/AppDelegate.m @@ -0,0 +1,31 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "AppDelegate.h" + +@import FirebaseCore; + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + + // Initialize Firebase service. + [FIRApp configure]; + return YES; +} + +@end diff --git a/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/Base.lproj/Main.storyboard b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/Base.lproj/Main.storyboard new file mode 100644 index 000000000..6741c96d6 --- /dev/null +++ b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/Base.lproj/Main.storyboard @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/Info.plist b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/Info.plist new file mode 100644 index 000000000..30d7c4861 --- /dev/null +++ b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/Info.plist @@ -0,0 +1,51 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIcons + + CFBundleIcons~ipad + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/ViewController.h b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/ViewController.h new file mode 100644 index 000000000..6f7955919 --- /dev/null +++ b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/ViewController.h @@ -0,0 +1,20 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import UIKit; + +@interface ViewController : UIViewController +@end diff --git a/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/ViewController.m b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/ViewController.m new file mode 100644 index 000000000..8ce0a2bbd --- /dev/null +++ b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/ViewController.m @@ -0,0 +1,57 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "ViewController.h" +@import FirebaseCrashlytics; + +@implementation ViewController + + +- (void)viewDidLoad { + [super viewDidLoad]; + + // Log that the view did load, CLSNSLog is used here so the log message will be + // shown in the console output. If CLSLog is used the message is not shown in + // the console output. + [[FIRCrashlytics crashlytics] log:@"View loaded"]; + + [[FIRCrashlytics crashlytics] setCustomValue:@3 forKey:@"current_level"]; + [[FIRCrashlytics crashlytics] setCustomValue:@"logged_in" forKey:@"last_UI_action"]; + [[FIRCrashlytics crashlytics] setUserID:@"123456789"]; + + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"The request failed.", nil), + NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"The response returned a 404.", nil), + NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(@"Does this page exist?", nil), + @"ProductID": @"123456", + @"UserID": @"Jane Smith" + }; + NSError *error = [NSError errorWithDomain:NSURLErrorDomain + code:-1001 + userInfo:userInfo]; + [[FIRCrashlytics crashlytics] recordError:error]; +} + +- (IBAction)initiateCrash:(id)sender { + // [START log_and_crash] + [[FIRCrashlytics crashlytics] log:@"Cause Crash button clicked"]; + // crash + int *x = NULL; + *x = 10; + // [END log_and_crash] +} + +@end diff --git a/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/main.m b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/main.m new file mode 100644 index 000000000..d4878306b --- /dev/null +++ b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExample/main.m @@ -0,0 +1,24 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleSwift/AppDelegate.swift b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleSwift/AppDelegate.swift new file mode 100644 index 000000000..e94de8f73 --- /dev/null +++ b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleSwift/AppDelegate.swift @@ -0,0 +1,31 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit +import FirebaseCore + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? + + func application(_ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication + .LaunchOptionsKey: Any]?) -> Bool { + // Initialize Firebase service. + FirebaseApp.configure() + return true + } +} diff --git a/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleSwift/ViewController.swift b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleSwift/ViewController.swift new file mode 100644 index 000000000..95d5c28d8 --- /dev/null +++ b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleSwift/ViewController.swift @@ -0,0 +1,116 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit +import FirebaseCrashlytics +import Reachability + +@objc(ViewController) +class ViewController: UIViewController { + lazy var crashlytics = Crashlytics.crashlytics() + + override func viewDidLoad() { + super.viewDidLoad() + + // Log that the view did load, CLSNSLogv is used here so the log message will be + // shown in the console output. If CLSLogv is used the message is not shown in + // the console output. + Crashlytics.crashlytics().log("View loaded") + + Crashlytics.crashlytics().setCustomValue(42, forKey: "MeaningOfLife") + Crashlytics.crashlytics().setCustomValue("Test value", forKey: "last_UI_action") + + let customKeysObject = [ + "locale": getLocale(), + "network_connection": getNetworkStatus(), + ] as [String: Any] + Crashlytics.crashlytics().setCustomKeysAndValues(customKeysObject) + + updateAndTrackNetworkStatus() + + Crashlytics.crashlytics().setUserID("123456789") + + let userInfo = [ + NSLocalizedDescriptionKey: NSLocalizedString("The request failed.", comment: ""), + NSLocalizedFailureReasonErrorKey: NSLocalizedString( + "The response returned a 404.", + comment: "" + ), + NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString( + "Does this page exist?", + comment: "" + ), + "ProductID": "123456", + "UserID": "Jane Smith", + ] + let error = NSError(domain: NSURLErrorDomain, code: -1001, userInfo: userInfo) + Crashlytics.crashlytics().record(error: error) + } + + @IBAction func initiateCrash(_ sender: AnyObject) { + // [START log_and_crash_swift] + Crashlytics.crashlytics().log("Cause Crash button clicked") + fatalError() + // [END log_and_crash_swift] + } + + /** + * Retrieve the locale information for the app. + */ + func getLocale() -> String { + return Locale.preferredLanguages[0] + } + + /** + * Retrieve the network status for the app. + */ + func getNetworkStatus() -> String { + guard let reachability = try? Reachability() else { + return "unknown" + } + switch reachability.connection { + case .wifi: + return "wifi" + case .cellular: + return "cellular" + case .unavailable: + return "unavailable" + case .none: + // Duplicate of unavailable. + return "unavailable" + } + } + + /** + * Add a hook to update network status going forward. + */ + func updateAndTrackNetworkStatus() { + NotificationCenter.default.addObserver(self, + selector: #selector(reachabilityChanged(note:)), + name: .reachabilityChanged, + object: nil) + do { + let reachability = try Reachability() + try reachability.startNotifier() + } catch { + print("Could not start reachability notifier: \(error)") + } + } + + @objc func reachabilityChanged(note: Notification) { + Crashlytics.crashlytics().setCustomValue(getNetworkStatus(), forKey: "network_connection") + } +} diff --git a/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleSwiftUITests/CrashReportingExampleSwiftUITests.swift b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleSwiftUITests/CrashReportingExampleSwiftUITests.swift new file mode 100644 index 000000000..4ebc5f8b5 --- /dev/null +++ b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleSwiftUITests/CrashReportingExampleSwiftUITests.swift @@ -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 XCTest + +class CrashReportingExampleSwiftUITests: XCTestCase { + override func setUp() { + super.setUp() + XCUIApplication().launch() + } + + func testVerifyAppLaunched() { + XCTAssertTrue(XCUIApplication().navigationBars["Crashlytics Example"].exists, + "Crashlytics is missing from the navigation bar") + XCTAssertTrue(XCUIApplication().buttons["Cause Crash"].exists, + "Cause Crash button is missing") + } +} diff --git a/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleSwiftUITests/Info.plist b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleSwiftUITests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleSwiftUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleTests/AppTests.m b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleTests/AppTests.m new file mode 100644 index 000000000..e5f892a30 --- /dev/null +++ b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleTests/AppTests.m @@ -0,0 +1,40 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +@interface AppTests : XCTestCase +@end + +@implementation AppTests + +- (void)setUp { + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample { + // This is an example of a functional test case. + XCTAssert(YES, @"Pass"); +} + +@end diff --git a/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleUITests/CrashReportingExampleUITests.m b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleUITests/CrashReportingExampleUITests.m new file mode 100644 index 000000000..4e4193307 --- /dev/null +++ b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleUITests/CrashReportingExampleUITests.m @@ -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 + +@interface CrashReportingExampleUITests : XCTestCase + +@end + +@implementation CrashReportingExampleUITests { + XCUIApplication *_app; +} + +- (void)setUp { + [super setUp]; + _app = [[XCUIApplication alloc] init]; + [_app launch]; +} + +- (void)testVerifyAppLaunched { + // Verify that Crashlytics app launched successfully and its title is visible. + XCTAssertTrue([_app navigationBars][@"Crashlytics Example"].exists); +} + +@end diff --git a/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleUITests/Info.plist b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleUITests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/crashlytics/LegacyCrashlyticsQuickstart/CrashlyticsExampleUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/crashlytics/LegacyCrashlyticsQuickstart/Podfile b/crashlytics/LegacyCrashlyticsQuickstart/Podfile new file mode 100644 index 000000000..3abd8288b --- /dev/null +++ b/crashlytics/LegacyCrashlyticsQuickstart/Podfile @@ -0,0 +1,13 @@ +# CrashlyticsExample +use_frameworks! +platform :ios, '15.0' + +target 'CrashlyticsExample' do + pod 'FirebaseCrashlytics' + pod 'ReachabilitySwift' +end + +target 'CrashlyticsExampleSwift' do + pod 'FirebaseCrashlytics' + pod 'ReachabilitySwift' +end diff --git a/crashlytics/LegacyCrashlyticsQuickstart/Podfile.lock b/crashlytics/LegacyCrashlyticsQuickstart/Podfile.lock new file mode 100644 index 000000000..82d22e9e9 --- /dev/null +++ b/crashlytics/LegacyCrashlyticsQuickstart/Podfile.lock @@ -0,0 +1,95 @@ +PODS: + - FirebaseCore (12.6.0): + - FirebaseCoreInternal (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreExtension (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseCoreInternal (12.6.0): + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseCrashlytics (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - FirebaseRemoteConfigInterop (~> 12.6.0) + - FirebaseSessions (~> 12.6.0) + - GoogleDataTransport (~> 10.1) + - GoogleUtilities/Environment (~> 8.1) + - nanopb (~> 3.30910.0) + - PromisesObjC (~> 2.4) + - FirebaseInstallations (12.6.0): + - FirebaseCore (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - PromisesObjC (~> 2.4) + - FirebaseRemoteConfigInterop (12.6.0) + - FirebaseSessions (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseCoreExtension (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleDataTransport (~> 10.1) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - nanopb (~> 3.30910.0) + - PromisesSwift (~> 2.1) + - GoogleDataTransport (10.1.0): + - nanopb (~> 3.30910.0) + - PromisesObjC (~> 2.4) + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - "GoogleUtilities/NSData+zlib (8.1.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/UserDefaults (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - nanopb (3.30910.0): + - nanopb/decode (= 3.30910.0) + - nanopb/encode (= 3.30910.0) + - nanopb/decode (3.30910.0) + - nanopb/encode (3.30910.0) + - PromisesObjC (2.4.0) + - PromisesSwift (2.4.0): + - PromisesObjC (= 2.4.0) + - ReachabilitySwift (5.2.4) + +DEPENDENCIES: + - FirebaseCrashlytics + - ReachabilitySwift + +SPEC REPOS: + trunk: + - FirebaseCore + - FirebaseCoreExtension + - FirebaseCoreInternal + - FirebaseCrashlytics + - FirebaseInstallations + - FirebaseRemoteConfigInterop + - FirebaseSessions + - GoogleDataTransport + - GoogleUtilities + - nanopb + - PromisesObjC + - PromisesSwift + - ReachabilitySwift + +SPEC CHECKSUMS: + FirebaseCore: 0e38ad5d62d980a47a64b8e9301ffa311457be04 + FirebaseCoreExtension: 032fd6f8509e591fda8cb76f6651f20d926b121f + FirebaseCoreInternal: 69bf1306a05b8ac43004f6cc1f804bb7b05b229e + FirebaseCrashlytics: 3d6248c50726ee7832aef0e53cb84c9e64d9fa7e + FirebaseInstallations: 631b38da2e11a83daa4bfb482f79d286a5dfa7ad + FirebaseRemoteConfigInterop: 3443b8cb8fffd76bb3e03b2a84bfd3db952fcda4 + FirebaseSessions: 2e8f808347e665dff3e5843f275715f07045297d + GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851 + ReachabilitySwift: 32793e867593cfc1177f5d16491e3a197d2fccda + +PODFILE CHECKSUM: dac9610386043d3b4b02c811f970d8a76a5b86b0 + +COCOAPODS: 1.16.2 diff --git a/crashlytics/OUTLINE.md b/crashlytics/OUTLINE.md index ec9406100..e489c5c87 100644 --- a/crashlytics/OUTLINE.md +++ b/crashlytics/OUTLINE.md @@ -22,14 +22,16 @@ operating system, time of crash), the crash report contains custom keys and logs network status) which can help developers to debug the crash as well as illustrate how to add custom data to their own crashes. -### Network Status +### Reachability There are many reasons behind a crash, and developers are challenged to understand the root cause behind the crash in order to apply the proper fix. Thus, receiving different types of information -from the crash can help developers to understand the crash. Network status gives information about a +from the crash can help developers to understand the crash. Reachability gives information about a device’s network configuration settings. -This quickstart uses Apple's [Network](https://developer.apple.com/documentation/network) -framework to monitor the network state of a device. Specifically, it uses `NWPathMonitor` to get -network status changes. +[Reachability.swift](https://github.com/ashleymills/Reachability.swift) uses the [System +Configuration](https://developer.apple.com/documentation/systemconfiguration) framework to monitor +the network state of a device. It is a replacement for [Apple's +Reachability](https://developer.apple.com/library/archive/samplecode/Reachability/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007324) +(written in Objective-C) re-written in Swift with closures. ### Cross Platform This Quickstart supports all Apple platforms including iOS, macOS, tvOS and watchOS. The SwiftUI diff --git a/crashlytics/README.md b/crashlytics/README.md index d773bb720..20d8ac3c1 100644 --- a/crashlytics/README.md +++ b/crashlytics/README.md @@ -3,7 +3,11 @@ Firebase Crashlytics Quickstart The Firebase Crashlytics iOS quickstart demonstrates how to report crashes and log events leading up to those crashes. You can read more about Firebase Crashlytics -[here](https://firebase.google.com/docs/crashlytics/)! +[here](https://firebase.google.com/docs/crashlytics/)! + +To view the older Objective-C and Swift quickstarts, view the +[`LegacyCrashlyticsQuickstart`](https://github.com/firebase/quickstart-ios/tree/main/crashlytics/LegacyCrashlyticsQuickstart) +directory. Getting Started --------------- diff --git a/crashlytics/Shared/CrashlyticsSwiftUIExampleApp.swift b/crashlytics/Shared/CrashlyticsSwiftUIExampleApp.swift index d14df6a7d..8bee05d41 100644 --- a/crashlytics/Shared/CrashlyticsSwiftUIExampleApp.swift +++ b/crashlytics/Shared/CrashlyticsSwiftUIExampleApp.swift @@ -14,14 +14,16 @@ // limitations under the License. // +import SwiftUI import FirebaseCore import FirebaseCrashlytics -import SwiftUI @main struct CrashlyticsSwiftUIExampleApp: App { private var crashlyticsReference = Crashlytics.crashlytics() - let reachabilityHelper = ReachabilityHelper() + #if !os(watchOS) + let reachabilityHelper = ReachabililtyHelper() + #endif func setUserInfo() { let userInfo = [ @@ -44,12 +46,15 @@ struct CrashlyticsSwiftUIExampleApp: App { func setCustomValues() { crashlyticsReference.setCustomValue(42, forKey: "MeaningOfLife") crashlyticsReference.setCustomValue("Test value", forKey: "last_UI_action") - let customKeysObject = [ - "locale": reachabilityHelper.getLocale(), - "network_connection": reachabilityHelper.getNetworkStatus(), - ] as [String: Any] - crashlyticsReference.setCustomKeysAndValues(customKeysObject) - reachabilityHelper.updateAndTrackNetworkStatus() + // Reachability is not compatible with watchOS + #if !os(watchOS) + let customKeysObject = [ + "locale": reachabilityHelper.getLocale(), + "network_connection": reachabilityHelper.getNetworkStatus(), + ] as [String: Any] + crashlyticsReference.setCustomKeysAndValues(customKeysObject) + reachabilityHelper.updateAndTrackNetworkStatus() + #endif Crashlytics.crashlytics().setUserID("123456789") } diff --git a/crashlytics/Shared/ReachabilityHelper.swift b/crashlytics/Shared/ReachabililtyHelper.swift similarity index 53% rename from crashlytics/Shared/ReachabilityHelper.swift rename to crashlytics/Shared/ReachabililtyHelper.swift index c36491a61..5e9a3c587 100644 --- a/crashlytics/Shared/ReachabilityHelper.swift +++ b/crashlytics/Shared/ReachabililtyHelper.swift @@ -14,18 +14,11 @@ // limitations under the License. // -import FirebaseCrashlytics import Foundation -import Network - -class ReachabilityHelper: NSObject { - private let monitor: NWPathMonitor - - override init() { - monitor = NWPathMonitor() - super.init() - } +import FirebaseCrashlytics +import Reachability +class ReachabililtyHelper: NSObject { /** * Retrieve the locale information for the app. */ @@ -37,21 +30,15 @@ class ReachabilityHelper: NSObject { * Retrieve the network status for the app. */ func getNetworkStatus() -> String { - return networkStatus(from: monitor.currentPath) - } - - private func networkStatus(from path: NWPath) -> String { - if path.status == .satisfied { - if path.usesInterfaceType(.wifi) { - return "wifi" - } else if path.usesInterfaceType(.cellular) { - return "cellular" - } else if path.usesInterfaceType(.wiredEthernet) { - return "wired" - } else { - return "other" - } - } else { + guard let reachability = try? Reachability() else { + return "unknown" + } + switch reachability.connection { + case .wifi: + return "wifi" + case .cellular: + return "cellular" + case .unavailable: return "unavailable" } } @@ -60,12 +47,19 @@ class ReachabilityHelper: NSObject { * Add a hook to update network status going forward. */ func updateAndTrackNetworkStatus() { - monitor.pathUpdateHandler = { [weak self] path in - guard let self = self else { return } - let status = self.networkStatus(from: path) - Crashlytics.crashlytics().setCustomValue(status, forKey: "network_connection") + NotificationCenter.default.addObserver(self, + selector: #selector(reachabilityChanged(note:)), + name: .reachabilityChanged, + object: nil) + do { + let reachability = try Reachability() + try reachability.startNotifier() + } catch { + print("Could not start reachability notifier: \(error)") } - let queue = DispatchQueue(label: "NetworkMonitor") - monitor.start(queue: queue) + } + + @objc func reachabilityChanged(note: Notification) { + Crashlytics.crashlytics().setCustomValue(getNetworkStatus(), forKey: "network_connection") } } diff --git a/database/DatabaseExample.xcodeproj/project.pbxproj b/database/DatabaseExample.xcodeproj/project.pbxproj index 12e7ba19a..5e01a28ce 100644 --- a/database/DatabaseExample.xcodeproj/project.pbxproj +++ b/database/DatabaseExample.xcodeproj/project.pbxproj @@ -3,14 +3,27 @@ archiveVersion = 1; classes = { }; - objectVersion = 77; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ + 100116CE1CDD16F100C9256E /* UIViewController+Alerts.m in Sources */ = {isa = PBXBuildFile; fileRef = 100116CD1CDD16F100C9256E /* UIViewController+Alerts.m */; }; 100116CF1CDD16F100C9256E /* UIViewController+Alerts.m in Sources */ = {isa = PBXBuildFile; fileRef = 100116CD1CDD16F100C9256E /* UIViewController+Alerts.m */; }; + 100116D21CDD1CDC00C9256E /* PostDetailTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 100116D11CDD1CDC00C9256E /* PostDetailTableViewController.m */; }; + 100A95E81FCF8AB1009B0140 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 100A95E71FCF8AB1009B0140 /* Images.xcassets */; }; 100A95E91FCF8AD6009B0140 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 100A95E71FCF8AB1009B0140 /* Images.xcassets */; }; 103685821CDD3B13004DC149 /* PostDetailTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 103685811CDD3B13004DC149 /* PostDetailTableViewController.swift */; }; + 1056D9491CD815040061ED72 /* PostListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1056D9481CD815040061ED72 /* PostListViewController.m */; }; + 1056D94C1CD817790061ED72 /* Comment.m in Sources */ = {isa = PBXBuildFile; fileRef = 1056D94B1CD817790061ED72 /* Comment.m */; }; + 1056D9521CD8179F0061ED72 /* User.m in Sources */ = {isa = PBXBuildFile; fileRef = 1056D9511CD8179F0061ED72 /* User.m */; }; + 1056D9581CD81E300061ED72 /* PostTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 1056D9561CD81E300061ED72 /* PostTableViewCell.m */; }; + 1056D95C1CD824C60061ED72 /* PostDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 1056D95B1CD824C60061ED72 /* PostDataSource.m */; }; + 1056D95F1CD829FE0061ED72 /* MyTopPostsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1056D95E1CD829FE0061ED72 /* MyTopPostsViewController.m */; }; + 1056D9621CD82C740061ED72 /* MyPostsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1056D9611CD82C740061ED72 /* MyPostsViewController.m */; }; + 1056D9651CD82CC10061ED72 /* RecentPostsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1056D9641CD82CC10061ED72 /* RecentPostsViewController.m */; }; + 107347492031598A004A66D1 /* DatabaseExampleSwiftUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 107347482031598A004A66D1 /* DatabaseExampleSwiftUITests.swift */; }; 1073483720333B8C004A66D1 /* DatabaseExampleUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1073483620333B8C004A66D1 /* DatabaseExampleUITests.m */; }; + 1073FE0C1CE2742000E2F73F /* TabBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1073FE0B1CE2742000E2F73F /* TabBarController.m */; }; 1073FE101CE2D27700E2F73F /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1073FE0F1CE2D27700E2F73F /* TabBarController.swift */; }; 10B872AE1CDBFB1F00C7D214 /* MyPostsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10B872AD1CDBFB1F00C7D214 /* MyPostsViewController.swift */; }; 10B872B11CDBFB7300C7D214 /* SignInViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10B872B01CDBFB7300C7D214 /* SignInViewController.swift */; }; @@ -22,30 +35,87 @@ 10B872C21CDC0AC200C7D214 /* PostDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10B872C11CDC0AC200C7D214 /* PostDataSource.swift */; }; 10B872C41CDC11F200C7D214 /* RecentPostsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10B872C31CDC11F200C7D214 /* RecentPostsViewController.swift */; }; 10B872C61CDC14C800C7D214 /* MyTopPostsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10B872C51CDC14C800C7D214 /* MyTopPostsViewController.swift */; }; + 10F2262F1CDBEE7C005205F2 /* SignInViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 10F2262E1CDBEE7C005205F2 /* SignInViewController.m */; }; + 10F226321CDBEE95005205F2 /* Post.m in Sources */ = {isa = PBXBuildFile; fileRef = 10F226311CDBEE95005205F2 /* Post.m */; }; + 310C987B3EF0599519449023 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = F644C72A588FB44DD666857B /* GoogleService-Info.plist */; }; 4022DB8C90CB216288A52649 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = F644C72A588FB44DD666857B /* GoogleService-Info.plist */; }; + 5F5A53521ADE670C00F81DF0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53511ADE670C00F81DF0 /* main.m */; }; + 5F5A53551ADE670C00F81DF0 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */; }; + 5F5A53581ADE670C00F81DF0 /* NewPostViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53571ADE670C00F81DF0 /* NewPostViewController.m */; }; + 5F5A535B1ADE670C00F81DF0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5F5A53591ADE670C00F81DF0 /* Main.storyboard */; }; 5F5A537E1ADE67D500F81DF0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */; }; 5F5A53801ADE67D500F81DF0 /* NewPostViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A537F1ADE67D500F81DF0 /* NewPostViewController.swift */; }; 5F5A539C1ADE69AA00F81DF0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5F5A53591ADE670C00F81DF0 /* Main.storyboard */; }; + 5F99610A1AE0CF4F0034F503 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961061AE0CF4F0034F503 /* Images.xcassets */; }; 5F99610B1AE0CF4F0034F503 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961061AE0CF4F0034F503 /* Images.xcassets */; }; + 5F99610C1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */; }; 5F99610D1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */; }; - 8D00BB822D3B0C1F00F6F6DD /* FirebaseAuth in Frameworks */ = {isa = PBXBuildFile; productRef = 8D00BB812D3B0C1F00F6F6DD /* FirebaseAuth */; }; - 8D00BB842D3B0C1F00F6F6DD /* FirebaseDatabase in Frameworks */ = {isa = PBXBuildFile; productRef = 8D00BB832D3B0C1F00F6F6DD /* FirebaseDatabase */; }; - 8D00BB862D3B0C1F00F6F6DD /* FirebaseDatabaseUI in Frameworks */ = {isa = PBXBuildFile; productRef = 8D00BB852D3B0C1F00F6F6DD /* FirebaseDatabaseUI */; }; + 5FDE055D1B0DAA090037B82F /* AppTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FDE055C1B0DAA090037B82F /* AppTests.m */; }; + 67FFF4C737099E866B972B36 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = F644C72A588FB44DD666857B /* GoogleService-Info.plist */; }; A18EF550576A3F1E297EFB56 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = F644C72A588FB44DD666857B /* GoogleService-Info.plist */; }; DEC82E5523AD38E4000EA7B1 /* FIREGSignInHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = DEC82E5223AD38E4000EA7B1 /* FIREGSignInHelper.m */; }; DEC82E5623AD38E4000EA7B1 /* FIREGHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = DEC82E5323AD38E4000EA7B1 /* FIREGHelper.m */; }; + ED9F3B135B98B01518169AD0 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = F644C72A588FB44DD666857B /* GoogleService-Info.plist */; }; EF94DD7B1CE533AC009A635D /* PostTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = EFDCBD531CE4FCC800F68D48 /* PostTableViewCell.xib */; }; + EFDCBD541CE4FCC800F68D48 /* PostTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = EFDCBD531CE4FCC800F68D48 /* PostTableViewCell.xib */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 1073474B2031598A004A66D1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5F5A53781ADE67D500F81DF0; + remoteInfo = DatabaseExampleSwift; + }; + 1073483920333B8C004A66D1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5F5A534B1ADE670C00F81DF0; + remoteInfo = DatabaseExample; + }; + 5FDE055E1B0DAA090037B82F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5F5A534B1ADE670C00F81DF0; + remoteInfo = DatabaseExample; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXFileReference section */ - 100116CB1CDD16F100C9256E /* DatabaseExample-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "DatabaseExample-Bridging-Header.h"; sourceTree = ""; }; + 100116CB1CDD16F100C9256E /* DatabaseExampleSwift-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "DatabaseExampleSwift-Bridging-Header.h"; sourceTree = ""; }; 100116CC1CDD16F100C9256E /* UIViewController+Alerts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+Alerts.h"; sourceTree = ""; }; 100116CD1CDD16F100C9256E /* UIViewController+Alerts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+Alerts.m"; sourceTree = ""; }; + 100116D01CDD1CDC00C9256E /* PostDetailTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PostDetailTableViewController.h; sourceTree = ""; }; + 100116D11CDD1CDC00C9256E /* PostDetailTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PostDetailTableViewController.m; sourceTree = ""; }; 100A95E71FCF8AB1009B0140 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 103685811CDD3B13004DC149 /* PostDetailTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostDetailTableViewController.swift; sourceTree = ""; }; + 1056D9471CD815040061ED72 /* PostListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PostListViewController.h; sourceTree = ""; }; + 1056D9481CD815040061ED72 /* PostListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PostListViewController.m; sourceTree = ""; }; + 1056D94A1CD817790061ED72 /* Comment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Comment.h; sourceTree = ""; }; + 1056D94B1CD817790061ED72 /* Comment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Comment.m; sourceTree = ""; }; + 1056D9501CD8179F0061ED72 /* User.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = User.h; sourceTree = ""; }; + 1056D9511CD8179F0061ED72 /* User.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = User.m; sourceTree = ""; }; + 1056D9551CD81E300061ED72 /* PostTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PostTableViewCell.h; sourceTree = ""; }; + 1056D9561CD81E300061ED72 /* PostTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PostTableViewCell.m; sourceTree = ""; }; + 1056D95A1CD824C60061ED72 /* PostDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PostDataSource.h; sourceTree = ""; }; + 1056D95B1CD824C60061ED72 /* PostDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PostDataSource.m; sourceTree = ""; }; + 1056D95D1CD829FE0061ED72 /* MyTopPostsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyTopPostsViewController.h; sourceTree = ""; }; + 1056D95E1CD829FE0061ED72 /* MyTopPostsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyTopPostsViewController.m; sourceTree = ""; }; + 1056D9601CD82C740061ED72 /* MyPostsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyPostsViewController.h; sourceTree = ""; }; + 1056D9611CD82C740061ED72 /* MyPostsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyPostsViewController.m; sourceTree = ""; }; + 1056D9631CD82CC10061ED72 /* RecentPostsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecentPostsViewController.h; sourceTree = ""; }; + 1056D9641CD82CC10061ED72 /* RecentPostsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RecentPostsViewController.m; sourceTree = ""; }; + 107347462031598A004A66D1 /* DatabaseExampleSwiftUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DatabaseExampleSwiftUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 107347482031598A004A66D1 /* DatabaseExampleSwiftUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseExampleSwiftUITests.swift; sourceTree = ""; }; + 1073474A2031598A004A66D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 1073483420333B8C004A66D1 /* DatabaseExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DatabaseExampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 1073483620333B8C004A66D1 /* DatabaseExampleUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DatabaseExampleUITests.m; sourceTree = ""; }; 1073483820333B8C004A66D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1073FE0A1CE2742000E2F73F /* TabBarController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TabBarController.h; sourceTree = ""; }; + 1073FE0B1CE2742000E2F73F /* TabBarController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TabBarController.m; sourceTree = ""; }; 1073FE0F1CE2D27700E2F73F /* TabBarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = ""; }; 10B872AD1CDBFB1F00C7D214 /* MyPostsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MyPostsViewController.swift; sourceTree = ""; }; 10B872B01CDBFB7300C7D214 /* SignInViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignInViewController.swift; sourceTree = ""; }; @@ -57,13 +127,25 @@ 10B872C11CDC0AC200C7D214 /* PostDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostDataSource.swift; sourceTree = ""; }; 10B872C31CDC11F200C7D214 /* RecentPostsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecentPostsViewController.swift; sourceTree = ""; }; 10B872C51CDC14C800C7D214 /* MyTopPostsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MyTopPostsViewController.swift; sourceTree = ""; }; + 10F2262D1CDBEE7C005205F2 /* SignInViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SignInViewController.h; sourceTree = ""; }; + 10F2262E1CDBEE7C005205F2 /* SignInViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SignInViewController.m; sourceTree = ""; }; + 10F226301CDBEE95005205F2 /* Post.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Post.h; sourceTree = ""; }; + 10F226311CDBEE95005205F2 /* Post.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Post.m; sourceTree = ""; }; + 5F5A534C1ADE670C00F81DF0 /* DatabaseExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DatabaseExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 5F5A53501ADE670C00F81DF0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5F5A53511ADE670C00F81DF0 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 5F5A53531ADE670C00F81DF0 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 5F5A53561ADE670C00F81DF0 /* NewPostViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NewPostViewController.h; sourceTree = ""; }; + 5F5A53571ADE670C00F81DF0 /* NewPostViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NewPostViewController.m; sourceTree = ""; }; 5F5A535A1ADE670C00F81DF0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 5F5A53791ADE67D500F81DF0 /* DatabaseExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DatabaseExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5F5A53791ADE67D500F81DF0 /* DatabaseExampleSwift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DatabaseExampleSwift.app; sourceTree = BUILT_PRODUCTS_DIR; }; 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 5F5A537F1ADE67D500F81DF0 /* NewPostViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewPostViewController.swift; sourceTree = ""; }; 5F9961061AE0CF4F0034F503 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LaunchScreen.xib; sourceTree = ""; }; + 5FDE05581B0DAA090037B82F /* DatabaseExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DatabaseExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5FDE055C1B0DAA090037B82F /* AppTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppTests.m; sourceTree = ""; }; DEC82E5123AD38E4000EA7B1 /* FIREGHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIREGHelper.h; sourceTree = ""; }; DEC82E5223AD38E4000EA7B1 /* FIREGSignInHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIREGSignInHelper.m; sourceTree = ""; }; DEC82E5323AD38E4000EA7B1 /* FIREGHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIREGHelper.m; sourceTree = ""; }; @@ -74,6 +156,13 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 107347432031598A004A66D1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 1073483120333B8C004A66D1 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -81,19 +170,39 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5F5A53491ADE670C00F81DF0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5F5A53761ADE67D500F81DF0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8D00BB842D3B0C1F00F6F6DD /* FirebaseDatabase in Frameworks */, - 8D00BB822D3B0C1F00F6F6DD /* FirebaseAuth in Frameworks */, - 8D00BB862D3B0C1F00F6F6DD /* FirebaseDatabaseUI in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FDE05551B0DAA090037B82F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 107347472031598A004A66D1 /* DatabaseExampleSwiftUITests */ = { + isa = PBXGroup; + children = ( + 107347482031598A004A66D1 /* DatabaseExampleSwiftUITests.swift */, + 1073474A2031598A004A66D1 /* Info.plist */, + ); + path = DatabaseExampleSwiftUITests; + sourceTree = ""; + }; 1073483520333B8C004A66D1 /* DatabaseExampleUITests */ = { isa = PBXGroup; children = ( @@ -128,17 +237,54 @@ name = Models; sourceTree = ""; }; + 10F2262B1CDBE72B005205F2 /* Models */ = { + isa = PBXGroup; + children = ( + 10F226301CDBEE95005205F2 /* Post.h */, + 10F226311CDBEE95005205F2 /* Post.m */, + 1056D94A1CD817790061ED72 /* Comment.h */, + 1056D94B1CD817790061ED72 /* Comment.m */, + 1056D9501CD8179F0061ED72 /* User.h */, + 1056D9511CD8179F0061ED72 /* User.m */, + ); + name = Models; + sourceTree = ""; + }; + 10F2262C1CDBE76D005205F2 /* ViewControllers */ = { + isa = PBXGroup; + children = ( + 1056D9601CD82C740061ED72 /* MyPostsViewController.h */, + 1056D9611CD82C740061ED72 /* MyPostsViewController.m */, + 1056D9631CD82CC10061ED72 /* RecentPostsViewController.h */, + 1056D9641CD82CC10061ED72 /* RecentPostsViewController.m */, + 1056D9471CD815040061ED72 /* PostListViewController.h */, + 1056D9481CD815040061ED72 /* PostListViewController.m */, + 10F2262D1CDBEE7C005205F2 /* SignInViewController.h */, + 10F2262E1CDBEE7C005205F2 /* SignInViewController.m */, + 1056D95D1CD829FE0061ED72 /* MyTopPostsViewController.h */, + 1056D95E1CD829FE0061ED72 /* MyTopPostsViewController.m */, + 5F5A53561ADE670C00F81DF0 /* NewPostViewController.h */, + 5F5A53571ADE670C00F81DF0 /* NewPostViewController.m */, + 100116D01CDD1CDC00C9256E /* PostDetailTableViewController.h */, + 100116D11CDD1CDC00C9256E /* PostDetailTableViewController.m */, + 1073FE0A1CE2742000E2F73F /* TabBarController.h */, + 1073FE0B1CE2742000E2F73F /* TabBarController.m */, + ); + name = ViewControllers; + sourceTree = ""; + }; 5F5A53431ADE670C00F81DF0 = { isa = PBXGroup; children = ( DEC82E5023AD38E4000EA7B1 /* TestUtils */, 5F5A534E1ADE670C00F81DF0 /* DatabaseExample */, - 5F5A537A1ADE67D500F81DF0 /* DatabaseExample */, + 5F5A537A1ADE67D500F81DF0 /* DatabaseExampleSwift */, + 5FDE05591B0DAA090037B82F /* DatabaseExampleTests */, + 107347472031598A004A66D1 /* DatabaseExampleSwiftUITests */, 1073483520333B8C004A66D1 /* DatabaseExampleUITests */, 5F5A534D1ADE670C00F81DF0 /* Products */, 5F9961041AE0CF4F0034F503 /* Shared */, F644C72A588FB44DD666857B /* GoogleService-Info.plist */, - 8D00BB792D3B0BE000F6F6DD /* Frameworks */, ); sourceTree = ""; wrapsLines = 0; @@ -146,7 +292,10 @@ 5F5A534D1ADE670C00F81DF0 /* Products */ = { isa = PBXGroup; children = ( - 5F5A53791ADE67D500F81DF0 /* DatabaseExample.app */, + 5F5A534C1ADE670C00F81DF0 /* DatabaseExample.app */, + 5F5A53791ADE67D500F81DF0 /* DatabaseExampleSwift.app */, + 5FDE05581B0DAA090037B82F /* DatabaseExampleTests.xctest */, + 107347462031598A004A66D1 /* DatabaseExampleSwiftUITests.xctest */, 1073483420333B8C004A66D1 /* DatabaseExampleUITests.xctest */, ); name = Products; @@ -155,7 +304,15 @@ 5F5A534E1ADE670C00F81DF0 /* DatabaseExample */ = { isa = PBXGroup; children = ( + 10F2262C1CDBE76D005205F2 /* ViewControllers */, + 10F2262B1CDBE72B005205F2 /* Models */, + 5F5A53531ADE670C00F81DF0 /* AppDelegate.h */, + 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */, 5F5A534F1ADE670C00F81DF0 /* Supporting Files */, + 1056D9551CD81E300061ED72 /* PostTableViewCell.h */, + 1056D9561CD81E300061ED72 /* PostTableViewCell.m */, + 1056D95A1CD824C60061ED72 /* PostDataSource.h */, + 1056D95B1CD824C60061ED72 /* PostDataSource.m */, ); path = DatabaseExample; sourceTree = ""; @@ -168,13 +325,14 @@ 5F5A53591ADE670C00F81DF0 /* Main.storyboard */, EFDCBD531CE4FCC800F68D48 /* PostTableViewCell.xib */, 5F5A53501ADE670C00F81DF0 /* Info.plist */, - 100116CB1CDD16F100C9256E /* DatabaseExample-Bridging-Header.h */, + 5F5A53511ADE670C00F81DF0 /* main.m */, + 100116CB1CDD16F100C9256E /* DatabaseExampleSwift-Bridging-Header.h */, 100A95E71FCF8AB1009B0140 /* Images.xcassets */, ); name = "Supporting Files"; sourceTree = ""; }; - 5F5A537A1ADE67D500F81DF0 /* DatabaseExample */ = { + 5F5A537A1ADE67D500F81DF0 /* DatabaseExampleSwift */ = { isa = PBXGroup; children = ( 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */, @@ -196,11 +354,12 @@ path = ../shared; sourceTree = ""; }; - 8D00BB792D3B0BE000F6F6DD /* Frameworks */ = { + 5FDE05591B0DAA090037B82F /* DatabaseExampleTests */ = { isa = PBXGroup; children = ( + 5FDE055C1B0DAA090037B82F /* AppTests.m */, ); - name = Frameworks; + path = DatabaseExampleTests; sourceTree = ""; }; DEC82E5023AD38E4000EA7B1 /* TestUtils */ = { @@ -219,6 +378,24 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 107347452031598A004A66D1 /* DatabaseExampleSwiftUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1073474D2031598A004A66D1 /* Build configuration list for PBXNativeTarget "DatabaseExampleSwiftUITests" */; + buildPhases = ( + 107347422031598A004A66D1 /* Sources */, + 107347432031598A004A66D1 /* Frameworks */, + 107347442031598A004A66D1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 1073474C2031598A004A66D1 /* PBXTargetDependency */, + ); + name = DatabaseExampleSwiftUITests; + productName = DatabaseExampleSwiftUITests; + productReference = 107347462031598A004A66D1 /* DatabaseExampleSwiftUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; 1073483320333B8C004A66D1 /* DatabaseExampleUITests */ = { isa = PBXNativeTarget; buildConfigurationList = 1073483B20333B8C004A66D1 /* Build configuration list for PBXNativeTarget "DatabaseExampleUITests" */; @@ -230,15 +407,33 @@ buildRules = ( ); dependencies = ( + 1073483A20333B8C004A66D1 /* PBXTargetDependency */, ); name = DatabaseExampleUITests; productName = DatabaseExampleUITests; productReference = 1073483420333B8C004A66D1 /* DatabaseExampleUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; - 5F5A53781ADE67D500F81DF0 /* DatabaseExample */ = { + 5F5A534B1ADE670C00F81DF0 /* DatabaseExample */ = { isa = PBXNativeTarget; - buildConfigurationList = 5F5A53991ADE67D500F81DF0 /* Build configuration list for PBXNativeTarget "DatabaseExample" */; + buildConfigurationList = 5F5A536F1ADE670C00F81DF0 /* Build configuration list for PBXNativeTarget "DatabaseExample" */; + buildPhases = ( + 5F5A53481ADE670C00F81DF0 /* Sources */, + 5F5A53491ADE670C00F81DF0 /* Frameworks */, + 5F5A534A1ADE670C00F81DF0 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = DatabaseExample; + productName = DatabaseExample; + productReference = 5F5A534C1ADE670C00F81DF0 /* DatabaseExample.app */; + productType = "com.apple.product-type.application"; + }; + 5F5A53781ADE67D500F81DF0 /* DatabaseExampleSwift */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5F5A53991ADE67D500F81DF0 /* Build configuration list for PBXNativeTarget "DatabaseExampleSwift" */; buildPhases = ( 5F5A53751ADE67D500F81DF0 /* Sources */, 5F5A53761ADE67D500F81DF0 /* Frameworks */, @@ -248,35 +443,68 @@ ); dependencies = ( ); - name = DatabaseExample; - productName = DatabaseExample; - productReference = 5F5A53791ADE67D500F81DF0 /* DatabaseExample.app */; + name = DatabaseExampleSwift; + productName = DatabaseExampleSwift; + productReference = 5F5A53791ADE67D500F81DF0 /* DatabaseExampleSwift.app */; productType = "com.apple.product-type.application"; }; + 5FDE05571B0DAA090037B82F /* DatabaseExampleTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5FDE05621B0DAA090037B82F /* Build configuration list for PBXNativeTarget "DatabaseExampleTests" */; + buildPhases = ( + 5FDE05541B0DAA090037B82F /* Sources */, + 5FDE05551B0DAA090037B82F /* Frameworks */, + 5FDE05561B0DAA090037B82F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5FDE055F1B0DAA090037B82F /* PBXTargetDependency */, + ); + name = DatabaseExampleTests; + productName = DatabaseExampleTests; + productReference = 5FDE05581B0DAA090037B82F /* DatabaseExampleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 5F5A53441ADE670C00F81DF0 /* Project object */ = { isa = PBXProject; attributes = { - BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 1610; + LastUpgradeCheck = 1110; ORGANIZATIONNAME = "Google Inc."; TargetAttributes = { + 107347452031598A004A66D1 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1110; + ProvisioningStyle = Automatic; + TestTargetID = 5F5A53781ADE67D500F81DF0; + }; 1073483320333B8C004A66D1 = { CreatedOnToolsVersion = 9.2; ProvisioningStyle = Automatic; TestTargetID = 5F5A534B1ADE670C00F81DF0; }; + 5F5A534B1ADE670C00F81DF0 = { + CreatedOnToolsVersion = 6.3; + ProvisioningStyle = Automatic; + }; 5F5A53781ADE67D500F81DF0 = { CreatedOnToolsVersion = 6.3; LastSwiftMigration = 1110; ProvisioningStyle = Automatic; }; + 5FDE05571B0DAA090037B82F = { + CreatedOnToolsVersion = 6.3.2; + ProvisioningStyle = Automatic; + TestTargetID = 5F5A534B1ADE670C00F81DF0; + }; }; }; buildConfigurationList = 5F5A53471ADE670C00F81DF0 /* Build configuration list for PBXProject "DatabaseExample" */; + compatibilityVersion = "Xcode 3.2"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -284,22 +512,27 @@ Base, ); mainGroup = 5F5A53431ADE670C00F81DF0; - packageReferences = ( - 8D00BB782D3B0BD500F6F6DD /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, - 8D00BB7E2D3B0C0200F6F6DD /* XCRemoteSwiftPackageReference "FirebaseUI-iOS" */, - ); - preferredProjectObjectVersion = 77; productRefGroup = 5F5A534D1ADE670C00F81DF0 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - 5F5A53781ADE67D500F81DF0 /* DatabaseExample */, + 5F5A534B1ADE670C00F81DF0 /* DatabaseExample */, + 5F5A53781ADE67D500F81DF0 /* DatabaseExampleSwift */, + 5FDE05571B0DAA090037B82F /* DatabaseExampleTests */, + 107347452031598A004A66D1 /* DatabaseExampleSwiftUITests */, 1073483320333B8C004A66D1 /* DatabaseExampleUITests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 107347442031598A004A66D1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 1073483220333B8C004A66D1 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -307,6 +540,18 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5F5A534A1ADE670C00F81DF0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F99610C1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */, + 100A95E81FCF8AB1009B0140 /* Images.xcassets in Resources */, + EFDCBD541CE4FCC800F68D48 /* PostTableViewCell.xib in Resources */, + 5F99610A1AE0CF4F0034F503 /* Images.xcassets in Resources */, + 5F5A535B1ADE670C00F81DF0 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5F5A53771ADE67D500F81DF0 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -319,9 +564,25 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5FDE05561B0DAA090037B82F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 107347422031598A004A66D1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 107347492031598A004A66D1 /* DatabaseExampleSwiftUITests.swift in Sources */, + 67FFF4C737099E866B972B36 /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 1073483020333B8C004A66D1 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -333,6 +594,30 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5F5A53481ADE670C00F81DF0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 10F226321CDBEE95005205F2 /* Post.m in Sources */, + 100116CE1CDD16F100C9256E /* UIViewController+Alerts.m in Sources */, + 1056D9491CD815040061ED72 /* PostListViewController.m in Sources */, + 1056D9521CD8179F0061ED72 /* User.m in Sources */, + 5F5A53581ADE670C00F81DF0 /* NewPostViewController.m in Sources */, + 10F2262F1CDBEE7C005205F2 /* SignInViewController.m in Sources */, + 5F5A53551ADE670C00F81DF0 /* AppDelegate.m in Sources */, + 1056D95C1CD824C60061ED72 /* PostDataSource.m in Sources */, + 100116D21CDD1CDC00C9256E /* PostDetailTableViewController.m in Sources */, + 1056D94C1CD817790061ED72 /* Comment.m in Sources */, + 1056D9651CD82CC10061ED72 /* RecentPostsViewController.m in Sources */, + 5F5A53521ADE670C00F81DF0 /* main.m in Sources */, + 1056D9621CD82C740061ED72 /* MyPostsViewController.m in Sources */, + 1073FE0C1CE2742000E2F73F /* TabBarController.m in Sources */, + 1056D95F1CD829FE0061ED72 /* MyTopPostsViewController.m in Sources */, + 1056D9581CD81E300061ED72 /* PostTableViewCell.m in Sources */, + 310C987B3EF0599519449023 /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5F5A53751ADE67D500F81DF0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -356,8 +641,35 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5FDE05541B0DAA090037B82F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5FDE055D1B0DAA090037B82F /* AppTests.m in Sources */, + ED9F3B135B98B01518169AD0 /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 1073474C2031598A004A66D1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5F5A53781ADE67D500F81DF0 /* DatabaseExampleSwift */; + targetProxy = 1073474B2031598A004A66D1 /* PBXContainerItemProxy */; + }; + 1073483A20333B8C004A66D1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5F5A534B1ADE670C00F81DF0 /* DatabaseExample */; + targetProxy = 1073483920333B8C004A66D1 /* PBXContainerItemProxy */; + }; + 5FDE055F1B0DAA090037B82F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5F5A534B1ADE670C00F81DF0 /* DatabaseExample */; + targetProxy = 5FDE055E1B0DAA090037B82F /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin PBXVariantGroup section */ 5F5A53591ADE670C00F81DF0 /* Main.storyboard */ = { isa = PBXVariantGroup; @@ -370,6 +682,54 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 1073474E2031598A004A66D1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = DatabaseExampleSwiftUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseAuth\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseDatabase\" \"${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\" \"${PODS_CONFIGURATION_BUILD_DIR}/leveldb-library\""; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.DatabaseExampleSwiftUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = DatabaseExampleSwift; + }; + name = Debug; + }; + 1073474F2031598A004A66D1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = DatabaseExampleSwiftUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseAuth\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseDatabase\" \"${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\" \"${PODS_CONFIGURATION_BUILD_DIR}/leveldb-library\""; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.DatabaseExampleSwiftUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = DatabaseExampleSwift; + }; + name = Release; + }; 1073483C20333B8C004A66D1 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -384,21 +744,7 @@ GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = DatabaseExampleUITests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - "\"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseAuth\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseDatabase\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/leveldb-library\"", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseAuth\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseDatabase\" \"${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\" \"${PODS_CONFIGURATION_BUILD_DIR}/leveldb-library\""; PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.DatabaseExampleUITests; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; @@ -421,21 +767,7 @@ GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = DatabaseExampleUITests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - "\"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseAuth\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseDatabase\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/leveldb-library\"", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks \"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseAuth\" \"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics\" \"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseDatabase\" \"${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\" \"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\" \"${PODS_CONFIGURATION_BUILD_DIR}/leveldb-library\""; PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.DatabaseExampleUITests; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; @@ -466,7 +798,6 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -477,7 +808,6 @@ ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -525,7 +855,6 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -536,7 +865,6 @@ ENABLE_BITCODE = NO; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -548,13 +876,44 @@ IPHONEOS_DEPLOYMENT_TARGET = 15.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; + 5F5A53701ADE670C00F81DF0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = DatabaseExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.google.firebase.quickstart.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + }; + name = Debug; + }; + 5F5A53711ADE670C00F81DF0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = DatabaseExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.google.firebase.quickstart.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + }; + name = Release; + }; 5F5A53951ADE67D500F81DF0 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -564,10 +923,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "$(SRCROOT)/DatabaseExample/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.DatabaseExample; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -587,24 +943,92 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "$(SRCROOT)/DatabaseExample/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.DatabaseExample; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OBJC_BRIDGING_HEADER = "DatabaseExample/DatabaseExampleSwift-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; }; name = Release; }; + 5FDE05601B0DAA090037B82F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + DatabaseExample, + ); + INFOPLIST_FILE = DatabaseExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.google.firebase.quickstart.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DatabaseExample.app/DatabaseExample"; + }; + name = Debug; + }; + 5FDE05611B0DAA090037B82F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + DatabaseExample, + ); + INFOPLIST_FILE = DatabaseExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.google.firebase.quickstart.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DatabaseExample.app/DatabaseExample"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 1073474D2031598A004A66D1 /* Build configuration list for PBXNativeTarget "DatabaseExampleSwiftUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1073474E2031598A004A66D1 /* Debug */, + 1073474F2031598A004A66D1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 1073483B20333B8C004A66D1 /* Build configuration list for PBXNativeTarget "DatabaseExampleUITests" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -623,7 +1047,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 5F5A53991ADE67D500F81DF0 /* Build configuration list for PBXNativeTarget "DatabaseExample" */ = { + 5F5A536F1ADE670C00F81DF0 /* Build configuration list for PBXNativeTarget "DatabaseExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5F5A53701ADE670C00F81DF0 /* Debug */, + 5F5A53711ADE670C00F81DF0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5F5A53991ADE67D500F81DF0 /* Build configuration list for PBXNativeTarget "DatabaseExampleSwift" */ = { isa = XCConfigurationList; buildConfigurations = ( 5F5A53951ADE67D500F81DF0 /* Debug */, @@ -632,44 +1065,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; -/* End XCConfigurationList section */ - -/* Begin XCRemoteSwiftPackageReference section */ - 8D00BB782D3B0BD500F6F6DD /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/firebase/firebase-ios-sdk"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 11.7.0; - }; - }; - 8D00BB7E2D3B0C0200F6F6DD /* XCRemoteSwiftPackageReference "FirebaseUI-iOS" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/firebase/FirebaseUI-iOS"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 15.0.0; - }; + 5FDE05621B0DAA090037B82F /* Build configuration list for PBXNativeTarget "DatabaseExampleTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5FDE05601B0DAA090037B82F /* Debug */, + 5FDE05611B0DAA090037B82F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 8D00BB812D3B0C1F00F6F6DD /* FirebaseAuth */ = { - isa = XCSwiftPackageProductDependency; - package = 8D00BB782D3B0BD500F6F6DD /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = FirebaseAuth; - }; - 8D00BB832D3B0C1F00F6F6DD /* FirebaseDatabase */ = { - isa = XCSwiftPackageProductDependency; - package = 8D00BB782D3B0BD500F6F6DD /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = FirebaseDatabase; - }; - 8D00BB852D3B0C1F00F6F6DD /* FirebaseDatabaseUI */ = { - isa = XCSwiftPackageProductDependency; - package = 8D00BB7E2D3B0C0200F6F6DD /* XCRemoteSwiftPackageReference "FirebaseUI-iOS" */; - productName = FirebaseDatabaseUI; - }; -/* End XCSwiftPackageProductDependency section */ +/* End XCConfigurationList section */ }; rootObject = 5F5A53441ADE670C00F81DF0 /* Project object */; } diff --git a/database/DatabaseExample.xcodeproj/xcshareddata/xcschemes/DatabaseExample.xcscheme b/database/DatabaseExample.xcodeproj/xcshareddata/xcschemes/DatabaseExample.xcscheme index 686ccc2dc..44f250358 100644 --- a/database/DatabaseExample.xcodeproj/xcshareddata/xcschemes/DatabaseExample.xcscheme +++ b/database/DatabaseExample.xcodeproj/xcshareddata/xcschemes/DatabaseExample.xcscheme @@ -1,6 +1,6 @@ @@ -30,7 +30,7 @@ @@ -41,7 +41,17 @@ skipped = "NO"> + + + + @@ -63,7 +73,7 @@ runnableDebuggingMode = "0"> @@ -80,7 +90,7 @@ runnableDebuggingMode = "0"> diff --git a/database/DatabaseExample.xcodeproj/xcshareddata/xcschemes/DatabaseExampleSwift.xcscheme b/database/DatabaseExample.xcodeproj/xcshareddata/xcschemes/DatabaseExampleSwift.xcscheme new file mode 100644 index 000000000..49ba0fe82 --- /dev/null +++ b/database/DatabaseExample.xcodeproj/xcshareddata/xcschemes/DatabaseExampleSwift.xcscheme @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/database/DatabaseExample/AppDelegate.h b/database/DatabaseExample/AppDelegate.h new file mode 100644 index 000000000..b6060b5c0 --- /dev/null +++ b/database/DatabaseExample/AppDelegate.h @@ -0,0 +1,23 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import UIKit; + +@interface AppDelegate : UIResponder + +@property(nonatomic, strong) UIWindow *window; + +@end diff --git a/database/DatabaseExample/AppDelegate.m b/database/DatabaseExample/AppDelegate.m new file mode 100644 index 000000000..2643e7d22 --- /dev/null +++ b/database/DatabaseExample/AppDelegate.m @@ -0,0 +1,30 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "AppDelegate.h" +@import FirebaseCore; + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // [START initialize_firebase] + [FIRApp configure]; + // [END initialize_firebase] + return YES; +} + +@end diff --git a/database/DatabaseExample/Base.lproj/Main.storyboard b/database/DatabaseExample/Base.lproj/Main.storyboard index b04688233..af653da9c 100644 --- a/database/DatabaseExample/Base.lproj/Main.storyboard +++ b/database/DatabaseExample/Base.lproj/Main.storyboard @@ -1,10 +1,9 @@ - - - + + - - + + @@ -16,47 +15,47 @@ - + - + - - - + - + @@ -92,17 +91,17 @@ - + - + - + - + @@ -112,9 +111,9 @@ - + - + @@ -124,22 +123,22 @@ - - + @@ -164,7 +163,7 @@ - + @@ -194,19 +193,19 @@ - + - + - + - + @@ -240,19 +239,19 @@ - + - + - + - + @@ -275,57 +274,57 @@ - + - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExample/CloudAddCell.h b/functions/LegacyFunctionsQuickstart/FunctionsExample/CloudAddCell.h new file mode 100644 index 000000000..6ce2548be --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExample/CloudAddCell.h @@ -0,0 +1,24 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import MaterialComponents; + +@interface CloudAddCell : MDCCollectionViewCell +@property (weak, nonatomic) IBOutlet MDCTextField *number1Field; +@property (weak, nonatomic) IBOutlet MDCTextField *number2Field; +@property (weak, nonatomic) IBOutlet MDCButton *button; +@end + diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExample/CloudAddCell.m b/functions/LegacyFunctionsQuickstart/FunctionsExample/CloudAddCell.m new file mode 100644 index 000000000..1a58c6d8f --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExample/CloudAddCell.m @@ -0,0 +1,69 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "CloudAddCell.h" + +@import FirebaseFunctions; + +@interface CloudAddCell () +@property (weak, nonatomic) IBOutlet UITextField *resultField; +// [START define_functions_instance] +@property(strong, nonatomic) FIRFunctions *functions; +// [END define_functions_instance] +@end + +@implementation CloudAddCell + +- (instancetype)initWithCoder:(NSCoder *)coder +{ + self = [super initWithCoder:coder]; + if (self) { + // [START initialize_functions_instance] + self.functions = [FIRFunctions functions]; + // [END initialize_functions_instance] + } + return self; +} + +- (IBAction)didTapAdd:(id)sender { + // [START function_add_numbers] + NSDictionary *data = @{@"firstNumber": [NSNumber numberWithInt:_number1Field.text.intValue], + @"secondNumber": [NSNumber numberWithInt:_number2Field.text.intValue]}; + [[_functions HTTPSCallableWithName:@"addNumbers"] callWithObject:data + completion:^(FIRHTTPSCallableResult * _Nullable result, NSError * _Nullable error) { + + // [START function_error] + if (error) { + if ([error.domain isEqual:@"com.firebase.functions"]) { + FIRFunctionsErrorCode code = error.code; + NSString *message = error.localizedDescription; + NSObject *details = error.userInfo[@"details"]; + } + // [START_EXCLUDE] + NSLog(@"%@", error); + return; + // [END_EXCLUDE] + } + // [END function_error] + + + NSNumber *operationResult = result.data[@"operationResult"]; + self->_resultField.text = operationResult.stringValue; + }]; + // [END function_add_numbers] +} + +@end diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExample/CommentCell.h b/functions/LegacyFunctionsQuickstart/FunctionsExample/CommentCell.h new file mode 100644 index 000000000..c8cffaa4a --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExample/CommentCell.h @@ -0,0 +1,22 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import MaterialComponents; + +@interface CommentCell : MDCCollectionViewCell +@property(weak, nonatomic) IBOutlet MDCTextField *inputField; +@property(weak, nonatomic) IBOutlet MDCButton *button; +@end diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExample/CommentCell.m b/functions/LegacyFunctionsQuickstart/FunctionsExample/CommentCell.m new file mode 100644 index 000000000..3bfe77a83 --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExample/CommentCell.m @@ -0,0 +1,63 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "CommentCell.h" + +@import FirebaseFunctions; + +@interface CommentCell () +@property(weak, nonatomic) IBOutlet MDCTextField *resultField; +// [START define_functions_instance] +@property(strong, nonatomic) FIRFunctions *functions; +// [END define_functions_instance] +@end + +@implementation CommentCell + +- (instancetype)initWithCoder:(NSCoder *)coder +{ + self = [super initWithCoder:coder]; + if (self) { + // [START initialize_functions_instance] + self.functions = [FIRFunctions functions]; + // [END initialize_functions_instance] + } + return self; +} + +- (IBAction)didTapAddMessage:(id)sender { + // [START function_add_message] + [[_functions HTTPSCallableWithName:@"addMessage"] callWithObject:@{@"text": _inputField.text} + completion:^(FIRHTTPSCallableResult * _Nullable result, NSError * _Nullable error) { + // [START function_error] + if (error) { + if ([error.domain isEqual:@"com.firebase.functions"]) { + FIRFunctionsErrorCode code = error.code; + NSString *message = error.localizedDescription; + NSObject *details = error.userInfo[@"details"]; + } + // [START_EXCLUDE] + NSLog(@"%@", error); + return; + // [END_EXCLUDE] + } + // [END function_error] + self->_resultField.text = result.data[@"text"]; + }]; + // [END function_add_message] +} + +@end diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExample/FAuthPickerViewController.h b/functions/LegacyFunctionsQuickstart/FunctionsExample/FAuthPickerViewController.h new file mode 100644 index 000000000..3aa95509a --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExample/FAuthPickerViewController.h @@ -0,0 +1,20 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import FirebaseAuthUI; + +@interface FAuthPickerViewController : FUIAuthPickerViewController +@end diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExample/FAuthPickerViewController.m b/functions/LegacyFunctionsQuickstart/FunctionsExample/FAuthPickerViewController.m new file mode 100644 index 000000000..15c84d88d --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExample/FAuthPickerViewController.m @@ -0,0 +1,20 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "FAuthPickerViewController.h" + +@implementation FAuthPickerViewController +@end diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExample/FAuthPickerViewController.xib b/functions/LegacyFunctionsQuickstart/FunctionsExample/FAuthPickerViewController.xib new file mode 100644 index 000000000..0f346148b --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExample/FAuthPickerViewController.xib @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExample/Info.plist b/functions/LegacyFunctionsQuickstart/FunctionsExample/Info.plist new file mode 100644 index 000000000..095fbf948 --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExample/Info.plist @@ -0,0 +1,64 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIcons + + CFBundleIcons~ipad + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + Client + CFBundleURLSchemes + + REVERSED_CLIENT_ID + + + + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExample/MainViewController.h b/functions/LegacyFunctionsQuickstart/FunctionsExample/MainViewController.h new file mode 100644 index 000000000..24df78677 --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExample/MainViewController.h @@ -0,0 +1,22 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +@import MaterialComponents; + +// [START signin_controller] +@interface MainViewController : MDCCollectionViewController +@end diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExample/MainViewController.m b/functions/LegacyFunctionsQuickstart/FunctionsExample/MainViewController.m new file mode 100644 index 000000000..a8cd2d7c6 --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExample/MainViewController.m @@ -0,0 +1,73 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "MainViewController.h" +#import "CloudAddCell.h" +#import "CommentCell.h" +@import MaterialComponents; + +@interface MainViewController () +@property(strong, nonatomic) MDCTextInputControllerUnderline *controller1; +@property(strong, nonatomic) MDCTextInputControllerUnderline *controller2; +@property(strong, nonatomic) MDCTextInputControllerUnderline *controller3; +@end + +@implementation MainViewController +- (void)viewDidLoad { + [super viewDidLoad]; + self.styler.cellStyle = MDCCollectionViewCellStyleCard; + self.styler.cellLayoutType = MDCCollectionViewCellLayoutTypeList; +} + +- (CGFloat)collectionView:(UICollectionView *)collectionView cellHeightAtIndexPath:(NSIndexPath *)indexPath { + if (indexPath.section == 0) { + return 181; + } + return 230; +} + +- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { + return 2; +} + +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { + return 1; +} + +- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { + if (indexPath.section == 0) { + CloudAddCell *addCell = [collectionView dequeueReusableCellWithReuseIdentifier:@"add" forIndexPath:indexPath]; + addCell.number1Field.delegate = self; + _controller1 = [[MDCTextInputControllerUnderline alloc] initWithTextInput:addCell.number1Field]; + addCell.number2Field.delegate = self; + _controller2 = [[MDCTextInputControllerUnderline alloc] initWithTextInput:addCell.number2Field]; + + + [addCell.button setElevation:MDCShadowElevationRaisedButtonResting forState:UIControlStateNormal]; + [addCell.button setElevation:MDCShadowElevationRaisedButtonPressed forState:UIControlStateHighlighted]; + return addCell; + } else { + CommentCell *commentCell = [collectionView dequeueReusableCellWithReuseIdentifier:@"message" forIndexPath:indexPath]; + commentCell.inputField.delegate = self; + _controller3 = [[MDCTextInputControllerUnderline alloc] initWithTextInput:commentCell.inputField]; + + [commentCell.button setElevation:MDCShadowElevationRaisedButtonResting forState:UIControlStateNormal]; + [commentCell.button setElevation:MDCShadowElevationRaisedButtonPressed forState:UIControlStateHighlighted]; + return commentCell; + } +} + +@end diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExample/SignInViewController.h b/functions/LegacyFunctionsQuickstart/FunctionsExample/SignInViewController.h new file mode 100644 index 000000000..7608eb887 --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExample/SignInViewController.h @@ -0,0 +1,20 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import FirebaseAuthUI; + +@interface SignInViewController : UIViewController +@end diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExample/SignInViewController.m b/functions/LegacyFunctionsQuickstart/FunctionsExample/SignInViewController.m new file mode 100644 index 000000000..7412a9995 --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExample/SignInViewController.m @@ -0,0 +1,78 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "SignInViewController.h" +#import "AppDelegate.h" +#import "FAuthPickerViewController.h" + +@import FirebaseAuth; +@import FirebaseAuthUI; +@import FirebaseGoogleAuthUI; + +@interface SignInViewController () + +@end + +@implementation SignInViewController + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + if ([FIRAuth auth].currentUser) { + AppDelegate *appDelegate = (AppDelegate *)UIApplication.sharedApplication.delegate; + appDelegate.window.rootViewController = [[UIStoryboard storyboardWithName:@"Main" + bundle:[NSBundle mainBundle]] instantiateInitialViewController]; + [self dismissViewControllerAnimated:YES completion:nil]; + return; + } + FUIAuth *authUI = [FUIAuth defaultAuthUI]; + authUI.delegate = self; + authUI.TOSURL = [NSURL URLWithString:@"https://firebase.google.com/terms/"]; + authUI.providers = @[[[FUIGoogleAuth alloc] init]]; + UINavigationController *authViewController = authUI.authViewController; + authViewController.navigationBar.hidden = true; + [self presentViewController:authViewController animated:true completion:nil]; +} + +- (void)authUI:(FUIAuth *)authUI didSignInWithAuthDataResult:(FIRAuthDataResult *)authDataResult error:(NSError *)error { + if (error) { + if (error.code == FUIAuthErrorCodeUserCancelledSignIn) { + NSLog(@"User cancelled sign-in"); + } else { + NSError *detailedError = error.userInfo[NSUnderlyingErrorKey]; + if (!detailedError) { + detailedError = error; + } + NSLog(@"Login error: %@", detailedError.localizedDescription); + } + return; + } + [self signedIn:authDataResult.user]; +} + +- (FUIAuthPickerViewController *)authPickerViewControllerForAuthUI:(FUIAuth *)authUI { + return [[FAuthPickerViewController alloc] initWithNibName:@"FAuthPickerViewController" + bundle:[NSBundle mainBundle] + authUI:authUI]; +} + +- (void)signedIn:(FIRUser *)user { + AppDelegate *appDelegate = (AppDelegate *)UIApplication.sharedApplication.delegate; + appDelegate.window.rootViewController = [[UIStoryboard storyboardWithName:@"Main" + bundle:[NSBundle mainBundle]] instantiateInitialViewController]; + [self dismissViewControllerAnimated:YES completion:nil]; +} + +@end diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExample/main.m b/functions/LegacyFunctionsQuickstart/FunctionsExample/main.m new file mode 100644 index 000000000..d4878306b --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExample/main.m @@ -0,0 +1,24 @@ +// +// Copyright (c) 2015 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExampleSwift/AppDelegate.swift b/functions/LegacyFunctionsQuickstart/FunctionsExampleSwift/AppDelegate.swift new file mode 100644 index 000000000..7aaa95c4e --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExampleSwift/AppDelegate.swift @@ -0,0 +1,63 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit + +import FirebaseCore +import FirebaseAuth +import FirebaseAuthUI + +@UIApplicationMain +// [START signin_delegate] +class AppDelegate: UIResponder, UIApplicationDelegate { + // [END signin_delegate] + + var window: UIWindow? + + func application(_ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [ + UIApplication.LaunchOptionsKey: Any + ]?) -> Bool { + // [START firebase_configure] + // Use Firebase library to configure APIs + FirebaseApp.configure() + // [END firebase_configure] + if Auth.auth().currentUser == nil { + window?.rootViewController = SignInViewController() + } + return true + } + + @available(iOS 9.0, *) + func application(_ app: UIApplication, open url: URL, + options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool { + guard let sourceApplication = + options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String else { + return false + } + return handleOpenUrl(url, sourceApplication: sourceApplication) + } + + @available(iOS 8.0, *) + func application(_ application: UIApplication, open url: URL, sourceApplication: String?, + annotation: Any) -> Bool { + return handleOpenUrl(url, sourceApplication: sourceApplication) + } + + func handleOpenUrl(_ url: URL, sourceApplication: String?) -> Bool { + return FUIAuth.defaultAuthUI()?.handleOpen(url, sourceApplication: sourceApplication) ?? false + } +} diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExampleSwift/CloudAddCell.swift b/functions/LegacyFunctionsQuickstart/FunctionsExampleSwift/CloudAddCell.swift new file mode 100644 index 000000000..983639212 --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExampleSwift/CloudAddCell.swift @@ -0,0 +1,54 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import MaterialComponents +import FirebaseFunctions + +@objc(CloudAddCell) +class CloudAddCell: MDCCollectionViewCell { + @IBOutlet var number1Field: MDCTextField! + @IBOutlet var number2Field: MDCTextField! + @IBOutlet var button: MDCButton! + @IBOutlet private var resultField: UITextField! + // [START functions_instance] + lazy var functions = Functions.functions() + // [END functions_instance] + + @IBAction func didTapAdd(_ sender: Any) { + // [START function_add_numbers] + let data = ["firstNumber": Int(number1Field.text!), + "secondNumber": Int(number2Field.text!)] + functions.httpsCallable("addNumbers").call(data) { result, error in + // [START function_error] + if let error = error as NSError? { + if error.domain == FunctionsErrorDomain { + let code = FunctionsErrorCode(rawValue: error.code) + let message = error.localizedDescription + let details = error.userInfo[FunctionsErrorDetailsKey] + } + // [START_EXCLUDE] + print(error) + return + // [END_EXCLUDE] + } + // [END function_error] + if let operationResult = (result?.data as? [String: Any])?["operationResult"] as? Int { + self.resultField.text = "\(operationResult)" + } + } + // [END function_add_numbers] + } +} diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExampleSwift/CommentCell.swift b/functions/LegacyFunctionsQuickstart/FunctionsExampleSwift/CommentCell.swift new file mode 100644 index 000000000..40d1ab447 --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExampleSwift/CommentCell.swift @@ -0,0 +1,51 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import MaterialComponents +import FirebaseFunctions + +@objc(CommentCell) +class CommentCell: MDCCollectionViewCell { + @IBOutlet var inputField: MDCTextField! + @IBOutlet var resultField: UITextField! + @IBOutlet var button: MDCButton! + // [START functions_instance] + lazy var functions = Functions.functions() + // [END functions_instance] + + @IBAction func didTapAddMessage(_ sender: Any) { + // [START function_add_message] + functions.httpsCallable("addMessage").call(["text": inputField.text]) { result, error in + // [START function_error] + if let error = error as NSError? { + if error.domain == FunctionsErrorDomain { + let code = FunctionsErrorCode(rawValue: error.code) + let message = error.localizedDescription + let details = error.userInfo[FunctionsErrorDetailsKey] + } + // [START_EXCLUDE] + print(error) + return + // [END_EXCLUDE] + } + // [END function_error] + if let data = result?.data as? [String: Any], let text = data["text"] as? String { + self.resultField.text = text + } + } + // [END function_add_message] + } +} diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExampleSwift/FAuthPickerViewController.swift b/functions/LegacyFunctionsQuickstart/FunctionsExampleSwift/FAuthPickerViewController.swift new file mode 100644 index 000000000..7e1ff10a9 --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExampleSwift/FAuthPickerViewController.swift @@ -0,0 +1,20 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import FirebaseAuthUI + +@objc(FAuthPickerViewController) +class FAuthPickerViewController: FUIAuthPickerViewController {} diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExampleSwift/MainViewController.swift b/functions/LegacyFunctionsQuickstart/FunctionsExampleSwift/MainViewController.swift new file mode 100644 index 000000000..3af290113 --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExampleSwift/MainViewController.swift @@ -0,0 +1,76 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import MaterialComponents + +@objc(MainViewController) +class MainViewController: MDCCollectionViewController, UITextFieldDelegate { + var controller1: MDCTextInputControllerUnderline! + var controller2: MDCTextInputControllerUnderline! + var controller3: MDCTextInputControllerUnderline! + + override func viewDidLoad() { + super.viewDidLoad() + styler.cellStyle = .card + styler.cellLayoutType = .list + } + + override func collectionView(_ collectionView: UICollectionView, + cellHeightAt indexPath: IndexPath) -> CGFloat { + if indexPath.section == 0 { + return 181 + } + return 230 + } + + override func numberOfSections(in collectionView: UICollectionView) -> Int { + return 2 + } + + override func collectionView(_ collectionView: UICollectionView, + numberOfItemsInSection section: Int) -> Int { + return 1 + } + + override func collectionView(_ collectionView: UICollectionView, + cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + if indexPath.section == 0 { + let addCell = collectionView.dequeueReusableCell( + withReuseIdentifier: "add", + for: indexPath + ) as! CloudAddCell + addCell.number1Field.delegate = self + controller1 = MDCTextInputControllerUnderline(textInput: addCell.number1Field) + addCell.number2Field.delegate = self + controller2 = MDCTextInputControllerUnderline(textInput: addCell.number2Field) + + addCell.button.setElevation(ShadowElevation.raisedButtonResting, for: .normal) + addCell.button.setElevation(ShadowElevation.raisedButtonPressed, for: .highlighted) + return addCell + } else { + let commentCell = collectionView.dequeueReusableCell( + withReuseIdentifier: "message", + for: indexPath + ) as! CommentCell + commentCell.inputField.delegate = self + controller3 = MDCTextInputControllerUnderline(textInput: commentCell.inputField) + + commentCell.button.setElevation(ShadowElevation.raisedButtonResting, for: .normal) + commentCell.button.setElevation(ShadowElevation.raisedButtonPressed, for: .highlighted) + return commentCell + } + } +} diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExampleSwift/SignInViewController.swift b/functions/LegacyFunctionsQuickstart/FunctionsExampleSwift/SignInViewController.swift new file mode 100644 index 000000000..af2b48e57 --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExampleSwift/SignInViewController.swift @@ -0,0 +1,73 @@ +// +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import FirebaseAuth +import FirebaseAuthUI +import FirebaseGoogleAuthUI + +private let kFirebaseTermsOfService = URL(string: "https://firebase.google.com/terms/")! + +@objc(SignInViewController) +class SignInViewController: UIViewController, FUIAuthDelegate { + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + if Auth.auth().currentUser != nil { + let appDelegate = UIApplication.shared.delegate as? AppDelegate + appDelegate?.window?.rootViewController = UIStoryboard(name: "Main", bundle: Bundle.main) + .instantiateInitialViewController() + dismiss(animated: true, completion: nil) + return + } + let authUI = FUIAuth.defaultAuthUI() + authUI?.delegate = self + authUI?.tosurl = kFirebaseTermsOfService + authUI?.providers = [FUIGoogleAuth()] + let authViewController: UINavigationController? = authUI?.authViewController() + authViewController?.navigationBar.isHidden = true + present(authViewController!, animated: true, completion: nil) + } + + func authUI(_ authUI: FUIAuth, didSignInWith authDataResult: AuthDataResult?, error: Error?) { + switch error { + case let .some(error as NSError) + where UInt(error.code) == FUIAuthErrorCode.userCancelledSignIn.rawValue: + print("User cancelled sign-in") + case let .some(error as NSError) where error.userInfo[NSUnderlyingErrorKey] != nil: + print("Login error: \(error.userInfo[NSUnderlyingErrorKey]!)") + case let .some(error): + print("Login error: \(error.localizedDescription)") + case .none: + if let user = authDataResult?.user { + signed(in: user) + } + } + } + + func authPickerViewController(forAuthUI authUI: FUIAuth) -> FUIAuthPickerViewController { + return FAuthPickerViewController( + nibName: "FAuthPickerViewController", + bundle: Bundle.main, + authUI: authUI + ) + } + + func signed(in user: User) { + let appDelegate = UIApplication.shared.delegate as? AppDelegate + appDelegate?.window?.rootViewController = UIStoryboard(name: "Main", bundle: Bundle.main) + .instantiateInitialViewController() + dismiss(animated: true, completion: nil) + } +} diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExampleSwiftUITests/FunctionsExampleSwiftUITests.swift b/functions/LegacyFunctionsQuickstart/FunctionsExampleSwiftUITests/FunctionsExampleSwiftUITests.swift new file mode 100644 index 000000000..0eb8bb77c --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExampleSwiftUITests/FunctionsExampleSwiftUITests.swift @@ -0,0 +1,34 @@ +// +// FunctionsExampleSwiftUITests.swift +// FunctionsExampleSwiftUITests +// +// Created by Ibrahim Ulukaya on 4/18/18. +// Copyright © 2018 Google Inc. All rights reserved. +// + +import XCTest + +class FunctionsExampleSwiftUITests: XCTestCase { + override func setUp() { + super.setUp() + + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. + XCUIApplication().launch() + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } +} diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExampleSwiftUITests/Info.plist b/functions/LegacyFunctionsQuickstart/FunctionsExampleSwiftUITests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExampleSwiftUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExampleTests/FunctionsExampleTests.m b/functions/LegacyFunctionsQuickstart/FunctionsExampleTests/FunctionsExampleTests.m new file mode 100644 index 000000000..4be49cbe9 --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExampleTests/FunctionsExampleTests.m @@ -0,0 +1,47 @@ +// +// Copyright (c) 2019 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +@interface FunctionsExampleTests : XCTestCase + +@end + +@implementation FunctionsExampleTests + +- (void)setUp { + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. +} + +- (void)testPerformanceExample { + // This is an example of a performance test case. + [self measureBlock:^{ + // Put the code you want to measure the time of here. + }]; +} + +@end diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExampleTests/Info.plist b/functions/LegacyFunctionsQuickstart/FunctionsExampleTests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExampleTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExampleUITests/FunctionsExampleUITests.m b/functions/LegacyFunctionsQuickstart/FunctionsExampleUITests/FunctionsExampleUITests.m new file mode 100644 index 000000000..cd168a0b9 --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExampleUITests/FunctionsExampleUITests.m @@ -0,0 +1,104 @@ +// +// Copyright (c) 2019 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import "FIREGHelper.h" +#import "FIREGSignInHelper.h" + +typedef BOOL (^SystemAlertHandler)(XCUIElement*); +static SystemAlertHandler const alertHandler = ^(XCUIElement* element) { + if (element.buttons[@"Continue"].exists) { + [element.buttons[@"Continue"] tap]; + } + return YES; +}; + +static NSString *const signInButton = @"Sign in with Google"; +static NSString *const welcomeMessage = @"HTTPS Callable functions Quickstart"; + +@interface FunctionsExampleUITests : XCTestCase +@end + +@implementation FunctionsExampleUITests { + XCUIApplication *_app; + id signInPermissionMonitor; +} + +- (void)setUp { + [super setUp]; + _app = [[XCUIApplication alloc] init]; + signInPermissionMonitor = + [self addUIInterruptionMonitorWithDescription:@"Allow Google Sign-In" handler:alertHandler]; + [_app launch]; + if (![self signedIn]) { + [[_app buttons][signInButton] tap]; + doGoogleSignIn(_app, YES, YES); + // Make sure main app screen is loaded. + FIRWaitForVisible([[_app collectionViews] firstMatch]); + } +} + +- (void)tearDown { + [self removeUIInterruptionMonitor:signInPermissionMonitor]; + [super tearDown]; +} + +- (void)SKIPtestVerifyAppLaunched { + // Check that main UI elements are present on the screen. + XCTAssertTrue([[_app staticTexts][@"Add two numbers"] exists]); + XCTAssertTrue([[_app staticTexts][@"Sanitize a message"] exists]); +} + +- (void)SKIPtestAddTwoNumbers { + XCUIElement* number1 = [_app textFields][@"Num 1"]; + FIRWaitForVisible(number1); + [number1 tap]; + [number1 typeText:@"14"]; + + XCUIElement* number2 = [_app textFields][@"Num 2"]; + FIRWaitForVisible(number2); + [number2 doubleTap]; + [number2 typeText:@"51"]; + + [[_app buttons][@"Calculate"] tap]; + XCUIElement* result = [_app textFields][@"65"]; + + // Wait till network call is completed. + FIRWaitForVisible(result); + XCTAssert(result.exists); +} + +- (void)SKIPtestChangeMessage { + NSString* testText = @"hello from cloud functions!"; + XCUIElement* input = [_app textFields][@"Add your message"]; + [input tap]; + [input typeText:testText]; + + [[_app buttons][@"Add message"] tap]; + XCUIElement* result = [_app textFields][[testText uppercaseString]]; + + // Wait till network call is completed. + FIRWaitForVisible(result); + XCTAssert(result.exists); +} + +- (BOOL)signedIn { + FIRWaitForVisible(_app.buttons[signInButton]); + return !_app.buttons[signInButton].exists; +} + +@end diff --git a/functions/LegacyFunctionsQuickstart/FunctionsExampleUITests/Info.plist b/functions/LegacyFunctionsQuickstart/FunctionsExampleUITests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/FunctionsExampleUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/functions/LegacyFunctionsQuickstart/Podfile b/functions/LegacyFunctionsQuickstart/Podfile new file mode 100644 index 000000000..7d9497ef1 --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/Podfile @@ -0,0 +1,21 @@ +# FunctionsExample + +use_frameworks! +platform :ios, '15.0' + +pod 'FirebaseAnalytics' +pod 'FirebaseAuth' +pod 'FirebaseUI/Auth', '~> 15.0' +pod 'FirebaseUI/Google', '~> 15.0' +# [START functions_pod] +pod 'FirebaseFunctions' +# [END functions_pod] + +pod 'MaterialComponents/Buttons' +pod 'MaterialComponents/Collections' +pod 'MaterialComponents/TextFields' + +target 'FunctionsExample' do +end +target 'FunctionsExampleSwift' do +end diff --git a/functions/LegacyFunctionsQuickstart/Podfile.lock b/functions/LegacyFunctionsQuickstart/Podfile.lock new file mode 100644 index 000000000..abb4a5c3a --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/Podfile.lock @@ -0,0 +1,317 @@ +PODS: + - AppAuth (1.7.6): + - AppAuth/Core (= 1.7.6) + - AppAuth/ExternalUserAgent (= 1.7.6) + - AppAuth/Core (1.7.6) + - AppAuth/ExternalUserAgent (1.7.6): + - AppAuth/Core + - AppCheckCore (11.2.0): + - GoogleUtilities/Environment (~> 8.0) + - GoogleUtilities/UserDefaults (~> 8.0) + - PromisesObjC (~> 2.4) + - FirebaseAnalytics (12.6.0): + - FirebaseAnalytics/Default (= 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseAnalytics/Default (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleAppMeasurement/Default (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseAppCheckInterop (12.6.0) + - FirebaseAuth (12.6.0): + - FirebaseAppCheckInterop (~> 12.6.0) + - FirebaseAuthInterop (~> 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseCoreExtension (~> 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/Environment (~> 8.1) + - GTMSessionFetcher/Core (< 6.0, >= 3.4) + - RecaptchaInterop (~> 101.0) + - FirebaseAuthInterop (12.6.0) + - FirebaseAuthUI (15.1.0): + - FirebaseAuth (< 13.0, >= 11.0) + - FirebaseCore + - FirebaseCore (12.6.0): + - FirebaseCoreInternal (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreExtension (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseCoreInternal (12.6.0): + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseFunctions (12.6.0): + - FirebaseAppCheckInterop (~> 12.6.0) + - FirebaseAuthInterop (~> 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseCoreExtension (~> 12.6.0) + - FirebaseMessagingInterop (~> 12.6.0) + - FirebaseSharedSwift (~> 12.6.0) + - GTMSessionFetcher/Core (< 6.0, >= 3.4) + - FirebaseGoogleAuthUI (15.1.0): + - FirebaseAuth + - FirebaseAuthUI (~> 15.0) + - FirebaseCore + - GoogleSignIn (~> 8.0) + - FirebaseInstallations (12.6.0): + - FirebaseCore (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - PromisesObjC (~> 2.4) + - FirebaseMessagingInterop (12.6.0) + - FirebaseSharedSwift (12.6.0) + - FirebaseUI/Auth (15.1.0): + - FirebaseAuthUI (~> 15.0) + - FirebaseUI/Google (15.1.0): + - FirebaseGoogleAuthUI (~> 15.0) + - GoogleAdsOnDeviceConversion (3.2.0): + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Core (12.6.0): + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Default (12.6.0): + - GoogleAdsOnDeviceConversion (~> 3.2.0) + - GoogleAppMeasurement/Core (= 12.6.0) + - GoogleAppMeasurement/IdentitySupport (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/IdentitySupport (12.6.0): + - GoogleAppMeasurement/Core (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleSignIn (8.0.0): + - AppAuth (< 2.0, >= 1.7.3) + - AppCheckCore (~> 11.0) + - GTMAppAuth (< 5.0, >= 4.1.1) + - GTMSessionFetcher/Core (~> 3.3) + - GoogleUtilities/AppDelegateSwizzler (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Privacy + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - GoogleUtilities/MethodSwizzler (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/Network (8.1.0): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Privacy + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (8.1.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/Reachability (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/UserDefaults (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GTMAppAuth (4.1.1): + - AppAuth/Core (~> 1.7) + - GTMSessionFetcher/Core (< 4.0, >= 3.3) + - GTMSessionFetcher/Core (3.5.0) + - MaterialComponents/AnimationTiming (124.2.0) + - MaterialComponents/Availability (124.2.0) + - MaterialComponents/Buttons (124.2.0): + - MaterialComponents/Elevation + - MaterialComponents/Ink + - MaterialComponents/private/Math + - MaterialComponents/Ripple + - MaterialComponents/Shadow + - MaterialComponents/ShadowElevations + - MaterialComponents/ShadowLayer + - MaterialComponents/ShapeLibrary + - MaterialComponents/Shapes + - MaterialComponents/Typography + - MDFInternationalization + - MDFTextAccessibility + - MaterialComponents/CollectionCells (124.2.0): + - MaterialComponents/CollectionLayoutAttributes + - MaterialComponents/Ink + - MaterialComponents/Palettes + - MaterialComponents/private/Icons/ic_check + - MaterialComponents/private/Icons/ic_check_circle + - MaterialComponents/private/Icons/ic_chevron_right + - MaterialComponents/private/Icons/ic_info + - MaterialComponents/private/Icons/ic_radio_button_unchecked + - MaterialComponents/private/Icons/ic_reorder + - MaterialComponents/private/Math + - MaterialComponents/Ripple + - MaterialComponents/Typography + - MDFInternationalization + - MaterialComponents/CollectionLayoutAttributes (124.2.0) + - MaterialComponents/Collections (124.2.0): + - MaterialComponents/Availability + - MaterialComponents/CollectionCells + - MaterialComponents/CollectionLayoutAttributes + - MaterialComponents/Ink + - MaterialComponents/Palettes + - MaterialComponents/Ripple + - MaterialComponents/ShadowElevations + - MaterialComponents/ShadowLayer + - MaterialComponents/Typography + - MaterialComponents/Elevation (124.2.0): + - MaterialComponents/Availability + - MaterialComponents/private/Color + - MaterialComponents/private/Math + - MaterialComponents/Ink (124.2.0): + - MaterialComponents/Availability + - MaterialComponents/private/Color + - MaterialComponents/private/Math + - MaterialComponents/Palettes (124.2.0) + - MaterialComponents/private/Application (124.2.0) + - MaterialComponents/private/Color (124.2.0): + - MaterialComponents/Availability + - MaterialComponents/private/Icons/Base (124.2.0) + - MaterialComponents/private/Icons/ic_check (124.2.0): + - MaterialComponents/private/Icons/Base + - MaterialComponents/private/Icons/ic_check_circle (124.2.0): + - MaterialComponents/private/Icons/Base + - MaterialComponents/private/Icons/ic_chevron_right (124.2.0): + - MaterialComponents/private/Icons/Base + - MaterialComponents/private/Icons/ic_info (124.2.0): + - MaterialComponents/private/Icons/Base + - MaterialComponents/private/Icons/ic_radio_button_unchecked (124.2.0): + - MaterialComponents/private/Icons/Base + - MaterialComponents/private/Icons/ic_reorder (124.2.0): + - MaterialComponents/private/Icons/Base + - MaterialComponents/private/Math (124.2.0) + - MaterialComponents/Ripple (124.2.0): + - MaterialComponents/AnimationTiming + - MaterialComponents/Availability + - MaterialComponents/private/Color + - MaterialComponents/private/Math + - MaterialComponents/Shadow (124.2.0): + - MaterialComponents/Availability + - MaterialComponents/ShadowElevations (124.2.0) + - MaterialComponents/ShadowLayer (124.2.0): + - MaterialComponents/ShadowElevations + - MaterialComponents/ShapeLibrary (124.2.0): + - MaterialComponents/private/Math + - MaterialComponents/Shapes + - MaterialComponents/Shapes (124.2.0): + - MaterialComponents/private/Color + - MaterialComponents/private/Math + - MaterialComponents/ShadowLayer + - MaterialComponents/TextFields (124.2.0): + - MaterialComponents/AnimationTiming + - MaterialComponents/Buttons + - MaterialComponents/Elevation + - MaterialComponents/Palettes + - MaterialComponents/private/Math + - MaterialComponents/Typography + - MDFInternationalization + - MaterialComponents/Typography (124.2.0): + - MaterialComponents/private/Application + - MaterialComponents/private/Math + - MDFTextAccessibility + - MDFInternationalization (3.0.0) + - MDFTextAccessibility (2.0.1) + - nanopb (3.30910.0): + - nanopb/decode (= 3.30910.0) + - nanopb/encode (= 3.30910.0) + - nanopb/decode (3.30910.0) + - nanopb/encode (3.30910.0) + - PromisesObjC (2.4.0) + - RecaptchaInterop (101.0.0) + +DEPENDENCIES: + - FirebaseAnalytics + - FirebaseAuth + - FirebaseFunctions + - FirebaseUI/Auth (~> 15.0) + - FirebaseUI/Google (~> 15.0) + - MaterialComponents/Buttons + - MaterialComponents/Collections + - MaterialComponents/TextFields + +SPEC REPOS: + trunk: + - AppAuth + - AppCheckCore + - FirebaseAnalytics + - FirebaseAppCheckInterop + - FirebaseAuth + - FirebaseAuthInterop + - FirebaseAuthUI + - FirebaseCore + - FirebaseCoreExtension + - FirebaseCoreInternal + - FirebaseFunctions + - FirebaseGoogleAuthUI + - FirebaseInstallations + - FirebaseMessagingInterop + - FirebaseSharedSwift + - FirebaseUI + - GoogleAdsOnDeviceConversion + - GoogleAppMeasurement + - GoogleSignIn + - GoogleUtilities + - GTMAppAuth + - GTMSessionFetcher + - MaterialComponents + - MDFInternationalization + - MDFTextAccessibility + - nanopb + - PromisesObjC + - RecaptchaInterop + +SPEC CHECKSUMS: + AppAuth: d4f13a8fe0baf391b2108511793e4b479691fb73 + AppCheckCore: cc8fd0a3a230ddd401f326489c99990b013f0c4f + FirebaseAnalytics: d0a97a0db6425e5a5d966340b87f92ca7b13a557 + FirebaseAppCheckInterop: e2178171b4145013c7c1a3cc464d1d446d3a1896 + FirebaseAuth: 613c463cb43545a7fd2cd99ade09b78ac472c544 + FirebaseAuthInterop: db06756ef028006d034b6004dc0c37c24f7828d4 + FirebaseAuthUI: c574e8904bd14503ff47e55ba2fc9ec64aacaed6 + FirebaseCore: 0e38ad5d62d980a47a64b8e9301ffa311457be04 + FirebaseCoreExtension: 032fd6f8509e591fda8cb76f6651f20d926b121f + FirebaseCoreInternal: 69bf1306a05b8ac43004f6cc1f804bb7b05b229e + FirebaseFunctions: c049fe05d03045fdd2b1ecd014c1345a841fc601 + FirebaseGoogleAuthUI: 740a15519a36b4d15802c4ef1db4aaeb7f7bad0b + FirebaseInstallations: 631b38da2e11a83daa4bfb482f79d286a5dfa7ad + FirebaseMessagingInterop: b18f87820d64e2fffe8e00a9d5f5c2efd430b554 + FirebaseSharedSwift: 79f27fff0addd15c3de19b87fba426f3cc2c964f + FirebaseUI: 1dfcf45d4bb4073380091394c9c555d697ecca11 + GoogleAdsOnDeviceConversion: d68c69dd9581a0f5da02617b6f377e5be483970f + GoogleAppMeasurement: 3bf40aff49a601af5da1c3345702fcb4991d35ee + GoogleSignIn: ce8c89bb9b37fb624b92e7514cc67335d1e277e4 + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + GTMAppAuth: f69bd07d68cd3b766125f7e072c45d7340dea0de + GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 + MaterialComponents: 1a9b2d9d45b1601ae544de85089adc4c464306d4 + MDFInternationalization: d697c55307816222a55685c4ccb1044ffb030c12 + MDFTextAccessibility: f4bb4cc2194286651b59a215fdeaa0e05dc90ba5 + nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + RecaptchaInterop: 11e0b637842dfb48308d242afc3f448062325aba + +PODFILE CHECKSUM: 56b139ff3f9ff3b9dfe39b30951b6aad99eb689e + +COCOAPODS: 1.16.2 diff --git a/functions/LegacyFunctionsQuickstart/README.md b/functions/LegacyFunctionsQuickstart/README.md new file mode 100644 index 000000000..b2f33f89d --- /dev/null +++ b/functions/LegacyFunctionsQuickstart/README.md @@ -0,0 +1,45 @@ +Firebase Functions Quickstart +============================= + +Introduction +------------ + +This quickstart demonstrates **Callable Functions** which are HTTPS Cloud Functions +that can be invoked directly from your mobile application. + +- [Read more about callable functions](https://firebase.google.com/docs/functions/callable) + +Getting Started +--------------- + +- [Add Firebase to your iOS Project](https://firebase.google.com/docs/ios/setup). + +### Google Sign In Setup +- In Xcode, [add a custom URL scheme for your reversed client ID](https://developers.google.com/identity/sign-in/ios/start-integrating). +- You can find this in the `GoogleService-Info.plist` + +Support +------- + +- [Stack Overflow](https://stackoverflow.com/questions/tagged/google-cloud-functions) +- [Firebase Support](https://firebase.google.com/support/) + +License +------- + +Copyright 2018 Google, Inc. + +Licensed to the Apache Software Foundation (ASF) under one or more contributor +license agreements. See the NOTICE file distributed with this work for +additional information regarding copyright ownership. The ASF licenses this +file to you under the Apache License, Version 2.0 (the "License"); you may not +use this file except in compliance with the License. You may obtain a copy of +the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +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/inappmessaging/InAppMessagingExample.xcodeproj/project.pbxproj b/inappmessaging/InAppMessagingExample.xcodeproj/project.pbxproj index 2ff292ae3..02eb110e9 100644 --- a/inappmessaging/InAppMessagingExample.xcodeproj/project.pbxproj +++ b/inappmessaging/InAppMessagingExample.xcodeproj/project.pbxproj @@ -3,29 +3,95 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 51; objects = { /* Begin PBXBuildFile section */ 1CAA5060E4A9D8B55A15EB4E /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 81A2FB070295F56CC0B2D523 /* GoogleService-Info.plist */; }; + 25D462F3CEB6AC4FB7A56DDA /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 81A2FB070295F56CC0B2D523 /* GoogleService-Info.plist */; }; + 37502D98408718BEFDD46841 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 81A2FB070295F56CC0B2D523 /* GoogleService-Info.plist */; }; + 804A5BC592C150CEBA9CE261 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 81A2FB070295F56CC0B2D523 /* GoogleService-Info.plist */; }; 8DB25F8F20BE0C29000ABEE2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DB25F8E20BE0C29000ABEE2 /* AppDelegate.swift */; }; 8DB25F9120BE0C29000ABEE2 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DB25F9020BE0C29000ABEE2 /* ViewController.swift */; }; 8DB25F9420BE0C29000ABEE2 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8DB25F9220BE0C29000ABEE2 /* Main.storyboard */; }; 8DB25F9620BE0C2A000ABEE2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8DB25F9520BE0C2A000ABEE2 /* Assets.xcassets */; }; 8DB25F9920BE0C2A000ABEE2 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8DB25F9720BE0C2A000ABEE2 /* LaunchScreen.storyboard */; }; - 8DC73D7A2D41A90B0092B6EE /* FirebaseInAppMessaging-Beta in Frameworks */ = {isa = PBXBuildFile; productRef = 8DC73D792D41A90B0092B6EE /* FirebaseInAppMessaging-Beta */; }; - 8DC73D7E2D41AA540092B6EE /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 8DC73D7D2D41AA540092B6EE /* FirebaseAnalytics */; }; + 8DECFE4E211CC14500DC99BD /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DECFE4D211CC14500DC99BD /* AppDelegate.m */; }; + 8DECFE51211CC14600DC99BD /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DECFE50211CC14600DC99BD /* ViewController.m */; }; + 8DECFE54211CC14600DC99BD /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8DECFE52211CC14600DC99BD /* Main.storyboard */; }; + 8DECFE56211CC14700DC99BD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8DECFE55211CC14700DC99BD /* Assets.xcassets */; }; + 8DECFE59211CC14700DC99BD /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8DECFE57211CC14700DC99BD /* LaunchScreen.storyboard */; }; + 8DECFE5C211CC14700DC99BD /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DECFE5B211CC14700DC99BD /* main.m */; }; + 8DECFE66211CC14700DC99BD /* InAppMessagingExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DECFE65211CC14700DC99BD /* InAppMessagingExampleTests.m */; }; + 8DECFE71211CC14700DC99BD /* InAppMessagingExampleUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DECFE70211CC14700DC99BD /* InAppMessagingExampleUITests.m */; }; + 8DECFE83211CC15F00DC99BD /* InAppMessagingExampleSwiftTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DECFE82211CC15F00DC99BD /* InAppMessagingExampleSwiftTests.m */; }; + 8DECFE91211CC16F00DC99BD /* InAppMessagingExampleSwiftUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DECFE90211CC16F00DC99BD /* InAppMessagingExampleSwiftUITests.m */; }; + 9670A39716204A41D8E0057C /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 81A2FB070295F56CC0B2D523 /* GoogleService-Info.plist */; }; + EC3960AA137BC0A6EF185169 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 81A2FB070295F56CC0B2D523 /* GoogleService-Info.plist */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 8DECFE62211CC14700DC99BD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8DB25F8320BE0C29000ABEE2 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8DECFE49211CC14500DC99BD; + remoteInfo = InAppMessagingExample; + }; + 8DECFE6D211CC14700DC99BD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8DB25F8320BE0C29000ABEE2 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8DECFE49211CC14500DC99BD; + remoteInfo = InAppMessagingExample; + }; + 8DECFE85211CC15F00DC99BD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8DB25F8320BE0C29000ABEE2 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8DB25F8A20BE0C29000ABEE2; + remoteInfo = InAppMessagingExampleSwift; + }; + 8DECFE93211CC16F00DC99BD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8DB25F8320BE0C29000ABEE2 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8DB25F8A20BE0C29000ABEE2; + remoteInfo = InAppMessagingExampleSwift; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXFileReference section */ 81A2FB070295F56CC0B2D523 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; - 8DB25F8B20BE0C29000ABEE2 /* InAppMessagingExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = InAppMessagingExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 8DB25F8B20BE0C29000ABEE2 /* InAppMessagingExampleSwift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = InAppMessagingExampleSwift.app; sourceTree = BUILT_PRODUCTS_DIR; }; 8DB25F8E20BE0C29000ABEE2 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 8DB25F9020BE0C29000ABEE2 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 8DB25F9320BE0C29000ABEE2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 8DB25F9520BE0C2A000ABEE2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 8DB25F9820BE0C2A000ABEE2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 8DB25F9A20BE0C2A000ABEE2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8DECFE4A211CC14500DC99BD /* InAppMessagingExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = InAppMessagingExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 8DECFE4C211CC14500DC99BD /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 8DECFE4D211CC14500DC99BD /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 8DECFE4F211CC14500DC99BD /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + 8DECFE50211CC14600DC99BD /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 8DECFE53211CC14600DC99BD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 8DECFE55211CC14700DC99BD /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 8DECFE58211CC14700DC99BD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 8DECFE5A211CC14700DC99BD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8DECFE5B211CC14700DC99BD /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 8DECFE61211CC14700DC99BD /* InAppMessagingExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InAppMessagingExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 8DECFE65211CC14700DC99BD /* InAppMessagingExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InAppMessagingExampleTests.m; sourceTree = ""; }; + 8DECFE67211CC14700DC99BD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8DECFE6C211CC14700DC99BD /* InAppMessagingExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InAppMessagingExampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 8DECFE70211CC14700DC99BD /* InAppMessagingExampleUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InAppMessagingExampleUITests.m; sourceTree = ""; }; + 8DECFE72211CC14700DC99BD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8DECFE80211CC15F00DC99BD /* InAppMessagingExampleSwiftTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InAppMessagingExampleSwiftTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 8DECFE82211CC15F00DC99BD /* InAppMessagingExampleSwiftTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InAppMessagingExampleSwiftTests.m; sourceTree = ""; }; + 8DECFE84211CC15F00DC99BD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8DECFE8E211CC16F00DC99BD /* InAppMessagingExampleSwiftUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InAppMessagingExampleSwiftUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 8DECFE90211CC16F00DC99BD /* InAppMessagingExampleSwiftUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InAppMessagingExampleSwiftUITests.m; sourceTree = ""; }; + 8DECFE92211CC16F00DC99BD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -33,8 +99,41 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8DC73D7E2D41AA540092B6EE /* FirebaseAnalytics in Frameworks */, - 8DC73D7A2D41A90B0092B6EE /* FirebaseInAppMessaging-Beta in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DECFE47211CC14500DC99BD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DECFE5E211CC14700DC99BD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DECFE69211CC14700DC99BD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DECFE7D211CC15F00DC99BD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DECFE8B211CC16F00DC99BD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( ); runOnlyForDeploymentPostprocessing = 0; }; @@ -44,22 +143,31 @@ 8DB25F8220BE0C29000ABEE2 = { isa = PBXGroup; children = ( - 8DB25F8D20BE0C29000ABEE2 /* InAppMessagingExample */, + 8DB25F8D20BE0C29000ABEE2 /* InAppMessagingExampleSwift */, + 8DECFE4B211CC14500DC99BD /* InAppMessagingExample */, + 8DECFE64211CC14700DC99BD /* InAppMessagingExampleTests */, + 8DECFE6F211CC14700DC99BD /* InAppMessagingExampleUITests */, + 8DECFE81211CC15F00DC99BD /* InAppMessagingExampleSwiftTests */, + 8DECFE8F211CC16F00DC99BD /* InAppMessagingExampleSwiftUITests */, 8DB25F8C20BE0C29000ABEE2 /* Products */, 81A2FB070295F56CC0B2D523 /* GoogleService-Info.plist */, - 8DC73D782D41A90B0092B6EE /* Frameworks */, ); sourceTree = ""; }; 8DB25F8C20BE0C29000ABEE2 /* Products */ = { isa = PBXGroup; children = ( - 8DB25F8B20BE0C29000ABEE2 /* InAppMessagingExample.app */, + 8DB25F8B20BE0C29000ABEE2 /* InAppMessagingExampleSwift.app */, + 8DECFE4A211CC14500DC99BD /* InAppMessagingExample.app */, + 8DECFE61211CC14700DC99BD /* InAppMessagingExampleTests.xctest */, + 8DECFE6C211CC14700DC99BD /* InAppMessagingExampleUITests.xctest */, + 8DECFE80211CC15F00DC99BD /* InAppMessagingExampleSwiftTests.xctest */, + 8DECFE8E211CC16F00DC99BD /* InAppMessagingExampleSwiftUITests.xctest */, ); name = Products; sourceTree = ""; }; - 8DB25F8D20BE0C29000ABEE2 /* InAppMessagingExample */ = { + 8DB25F8D20BE0C29000ABEE2 /* InAppMessagingExampleSwift */ = { isa = PBXGroup; children = ( 8DB25F8E20BE0C29000ABEE2 /* AppDelegate.swift */, @@ -69,22 +177,67 @@ 8DB25F9720BE0C2A000ABEE2 /* LaunchScreen.storyboard */, 8DB25F9A20BE0C2A000ABEE2 /* Info.plist */, ); + path = InAppMessagingExampleSwift; + sourceTree = ""; + }; + 8DECFE4B211CC14500DC99BD /* InAppMessagingExample */ = { + isa = PBXGroup; + children = ( + 8DECFE4C211CC14500DC99BD /* AppDelegate.h */, + 8DECFE4D211CC14500DC99BD /* AppDelegate.m */, + 8DECFE4F211CC14500DC99BD /* ViewController.h */, + 8DECFE50211CC14600DC99BD /* ViewController.m */, + 8DECFE52211CC14600DC99BD /* Main.storyboard */, + 8DECFE55211CC14700DC99BD /* Assets.xcassets */, + 8DECFE57211CC14700DC99BD /* LaunchScreen.storyboard */, + 8DECFE5A211CC14700DC99BD /* Info.plist */, + 8DECFE5B211CC14700DC99BD /* main.m */, + ); path = InAppMessagingExample; sourceTree = ""; }; - 8DC73D782D41A90B0092B6EE /* Frameworks */ = { + 8DECFE64211CC14700DC99BD /* InAppMessagingExampleTests */ = { + isa = PBXGroup; + children = ( + 8DECFE65211CC14700DC99BD /* InAppMessagingExampleTests.m */, + 8DECFE67211CC14700DC99BD /* Info.plist */, + ); + path = InAppMessagingExampleTests; + sourceTree = ""; + }; + 8DECFE6F211CC14700DC99BD /* InAppMessagingExampleUITests */ = { + isa = PBXGroup; + children = ( + 8DECFE70211CC14700DC99BD /* InAppMessagingExampleUITests.m */, + 8DECFE72211CC14700DC99BD /* Info.plist */, + ); + path = InAppMessagingExampleUITests; + sourceTree = ""; + }; + 8DECFE81211CC15F00DC99BD /* InAppMessagingExampleSwiftTests */ = { + isa = PBXGroup; + children = ( + 8DECFE82211CC15F00DC99BD /* InAppMessagingExampleSwiftTests.m */, + 8DECFE84211CC15F00DC99BD /* Info.plist */, + ); + path = InAppMessagingExampleSwiftTests; + sourceTree = ""; + }; + 8DECFE8F211CC16F00DC99BD /* InAppMessagingExampleSwiftUITests */ = { isa = PBXGroup; children = ( + 8DECFE90211CC16F00DC99BD /* InAppMessagingExampleSwiftUITests.m */, + 8DECFE92211CC16F00DC99BD /* Info.plist */, ); - name = Frameworks; + path = InAppMessagingExampleSwiftUITests; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 8DB25F8A20BE0C29000ABEE2 /* InAppMessagingExample */ = { + 8DB25F8A20BE0C29000ABEE2 /* InAppMessagingExampleSwift */ = { isa = PBXNativeTarget; - buildConfigurationList = 8DB25F9D20BE0C2A000ABEE2 /* Build configuration list for PBXNativeTarget "InAppMessagingExample" */; + buildConfigurationList = 8DB25F9D20BE0C2A000ABEE2 /* Build configuration list for PBXNativeTarget "InAppMessagingExampleSwift" */; buildPhases = ( 8DB25F8720BE0C29000ABEE2 /* Sources */, 8DB25F8820BE0C29000ABEE2 /* Frameworks */, @@ -94,26 +247,133 @@ ); dependencies = ( ); + name = InAppMessagingExampleSwift; + productName = InAppMessagingExampleSwift; + productReference = 8DB25F8B20BE0C29000ABEE2 /* InAppMessagingExampleSwift.app */; + productType = "com.apple.product-type.application"; + }; + 8DECFE49211CC14500DC99BD /* InAppMessagingExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8DECFE79211CC14700DC99BD /* Build configuration list for PBXNativeTarget "InAppMessagingExample" */; + buildPhases = ( + 8DECFE46211CC14500DC99BD /* Sources */, + 8DECFE47211CC14500DC99BD /* Frameworks */, + 8DECFE48211CC14500DC99BD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); name = InAppMessagingExample; productName = InAppMessagingExample; - productReference = 8DB25F8B20BE0C29000ABEE2 /* InAppMessagingExample.app */; + productReference = 8DECFE4A211CC14500DC99BD /* InAppMessagingExample.app */; productType = "com.apple.product-type.application"; }; + 8DECFE60211CC14700DC99BD /* InAppMessagingExampleTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8DECFE7A211CC14700DC99BD /* Build configuration list for PBXNativeTarget "InAppMessagingExampleTests" */; + buildPhases = ( + 8DECFE5D211CC14700DC99BD /* Sources */, + 8DECFE5E211CC14700DC99BD /* Frameworks */, + 8DECFE5F211CC14700DC99BD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 8DECFE63211CC14700DC99BD /* PBXTargetDependency */, + ); + name = InAppMessagingExampleTests; + productName = InAppMessagingExampleTests; + productReference = 8DECFE61211CC14700DC99BD /* InAppMessagingExampleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 8DECFE6B211CC14700DC99BD /* InAppMessagingExampleUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8DECFE7B211CC14700DC99BD /* Build configuration list for PBXNativeTarget "InAppMessagingExampleUITests" */; + buildPhases = ( + 8DECFE68211CC14700DC99BD /* Sources */, + 8DECFE69211CC14700DC99BD /* Frameworks */, + 8DECFE6A211CC14700DC99BD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 8DECFE6E211CC14700DC99BD /* PBXTargetDependency */, + ); + name = InAppMessagingExampleUITests; + productName = InAppMessagingExampleUITests; + productReference = 8DECFE6C211CC14700DC99BD /* InAppMessagingExampleUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + 8DECFE7F211CC15F00DC99BD /* InAppMessagingExampleSwiftTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8DECFE87211CC15F00DC99BD /* Build configuration list for PBXNativeTarget "InAppMessagingExampleSwiftTests" */; + buildPhases = ( + 8DECFE7C211CC15F00DC99BD /* Sources */, + 8DECFE7D211CC15F00DC99BD /* Frameworks */, + 8DECFE7E211CC15F00DC99BD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 8DECFE86211CC15F00DC99BD /* PBXTargetDependency */, + ); + name = InAppMessagingExampleSwiftTests; + productName = InAppMessagingExampleSwiftTests; + productReference = 8DECFE80211CC15F00DC99BD /* InAppMessagingExampleSwiftTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 8DECFE8D211CC16F00DC99BD /* InAppMessagingExampleSwiftUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8DECFE95211CC16F00DC99BD /* Build configuration list for PBXNativeTarget "InAppMessagingExampleSwiftUITests" */; + buildPhases = ( + 8DECFE8A211CC16F00DC99BD /* Sources */, + 8DECFE8B211CC16F00DC99BD /* Frameworks */, + 8DECFE8C211CC16F00DC99BD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 8DECFE94211CC16F00DC99BD /* PBXTargetDependency */, + ); + name = InAppMessagingExampleSwiftUITests; + productName = InAppMessagingExampleSwiftUITests; + productReference = 8DECFE8E211CC16F00DC99BD /* InAppMessagingExampleSwiftUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 8DB25F8320BE0C29000ABEE2 /* Project object */ = { isa = PBXProject; attributes = { - BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 0930; - LastUpgradeCheck = 1610; + LastUpgradeCheck = 0930; ORGANIZATIONNAME = Firebase; TargetAttributes = { 8DB25F8A20BE0C29000ABEE2 = { CreatedOnToolsVersion = 9.3; LastSwiftMigration = 1110; }; + 8DECFE49211CC14500DC99BD = { + CreatedOnToolsVersion = 9.4.1; + }; + 8DECFE60211CC14700DC99BD = { + CreatedOnToolsVersion = 9.4.1; + TestTargetID = 8DECFE49211CC14500DC99BD; + }; + 8DECFE6B211CC14700DC99BD = { + CreatedOnToolsVersion = 9.4.1; + TestTargetID = 8DECFE49211CC14500DC99BD; + }; + 8DECFE7F211CC15F00DC99BD = { + CreatedOnToolsVersion = 9.4.1; + TestTargetID = 8DB25F8A20BE0C29000ABEE2; + }; + 8DECFE8D211CC16F00DC99BD = { + CreatedOnToolsVersion = 9.4.1; + TestTargetID = 8DB25F8A20BE0C29000ABEE2; + }; }; }; buildConfigurationList = 8DB25F8620BE0C29000ABEE2 /* Build configuration list for PBXProject "InAppMessagingExample" */; @@ -125,14 +385,16 @@ Base, ); mainGroup = 8DB25F8220BE0C29000ABEE2; - packageReferences = ( - 8DC73D772D41A89A0092B6EE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, - ); productRefGroup = 8DB25F8C20BE0C29000ABEE2 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - 8DB25F8A20BE0C29000ABEE2 /* InAppMessagingExample */, + 8DB25F8A20BE0C29000ABEE2 /* InAppMessagingExampleSwift */, + 8DECFE7F211CC15F00DC99BD /* InAppMessagingExampleSwiftTests */, + 8DECFE8D211CC16F00DC99BD /* InAppMessagingExampleSwiftUITests */, + 8DECFE49211CC14500DC99BD /* InAppMessagingExample */, + 8DECFE60211CC14700DC99BD /* InAppMessagingExampleTests */, + 8DECFE6B211CC14700DC99BD /* InAppMessagingExampleUITests */, ); }; /* End PBXProject section */ @@ -148,6 +410,44 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 8DECFE48211CC14500DC99BD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8DECFE59211CC14700DC99BD /* LaunchScreen.storyboard in Resources */, + 8DECFE56211CC14700DC99BD /* Assets.xcassets in Resources */, + 8DECFE54211CC14600DC99BD /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DECFE5F211CC14700DC99BD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DECFE6A211CC14700DC99BD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DECFE7E211CC15F00DC99BD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DECFE8C211CC16F00DC99BD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -161,8 +461,78 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 8DECFE46211CC14500DC99BD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8DECFE51211CC14600DC99BD /* ViewController.m in Sources */, + 8DECFE5C211CC14700DC99BD /* main.m in Sources */, + 8DECFE4E211CC14500DC99BD /* AppDelegate.m in Sources */, + 37502D98408718BEFDD46841 /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DECFE5D211CC14700DC99BD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8DECFE66211CC14700DC99BD /* InAppMessagingExampleTests.m in Sources */, + 25D462F3CEB6AC4FB7A56DDA /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DECFE68211CC14700DC99BD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8DECFE71211CC14700DC99BD /* InAppMessagingExampleUITests.m in Sources */, + 9670A39716204A41D8E0057C /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DECFE7C211CC15F00DC99BD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8DECFE83211CC15F00DC99BD /* InAppMessagingExampleSwiftTests.m in Sources */, + 804A5BC592C150CEBA9CE261 /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DECFE8A211CC16F00DC99BD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8DECFE91211CC16F00DC99BD /* InAppMessagingExampleSwiftUITests.m in Sources */, + EC3960AA137BC0A6EF185169 /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 8DECFE63211CC14700DC99BD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8DECFE49211CC14500DC99BD /* InAppMessagingExample */; + targetProxy = 8DECFE62211CC14700DC99BD /* PBXContainerItemProxy */; + }; + 8DECFE6E211CC14700DC99BD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8DECFE49211CC14500DC99BD /* InAppMessagingExample */; + targetProxy = 8DECFE6D211CC14700DC99BD /* PBXContainerItemProxy */; + }; + 8DECFE86211CC15F00DC99BD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8DB25F8A20BE0C29000ABEE2 /* InAppMessagingExampleSwift */; + targetProxy = 8DECFE85211CC15F00DC99BD /* PBXContainerItemProxy */; + }; + 8DECFE94211CC16F00DC99BD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8DB25F8A20BE0C29000ABEE2 /* InAppMessagingExampleSwift */; + targetProxy = 8DECFE93211CC16F00DC99BD /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin PBXVariantGroup section */ 8DB25F9220BE0C29000ABEE2 /* Main.storyboard */ = { isa = PBXVariantGroup; @@ -180,6 +550,22 @@ name = LaunchScreen.storyboard; sourceTree = ""; }; + 8DECFE52211CC14600DC99BD /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 8DECFE53211CC14600DC99BD /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 8DECFE57211CC14700DC99BD /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 8DECFE58211CC14700DC99BD /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ @@ -209,7 +595,6 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -221,7 +606,6 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -271,7 +655,6 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -283,7 +666,6 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -306,12 +688,12 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; - INFOPLIST_FILE = InAppMessagingExample/Info.plist; + INFOPLIST_FILE = InAppMessagingExampleSwift/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.firebase.InAppMessagingExample; + PRODUCT_BUNDLE_IDENTIFIER = com.firebase.InAppMessagingExampleSwift; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -319,20 +701,206 @@ name = Debug; }; 8DB25F9F20BE0C2A000ABEE2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = InAppMessagingExampleSwift/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.firebase.InAppMessagingExampleSwift; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 8DECFE73211CC14700DC99BD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; INFOPLIST_FILE = InAppMessagingExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.firebase.InAppMessagingExample; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; + name = Debug; + }; + 8DECFE74211CC14700DC99BD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = InAppMessagingExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.firebase.InAppMessagingExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 8DECFE75211CC14700DC99BD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = InAppMessagingExampleTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.firebase.InAppMessagingExampleTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/InAppMessagingExample.app/InAppMessagingExample"; + }; + name = Debug; + }; + 8DECFE76211CC14700DC99BD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = InAppMessagingExampleTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.firebase.InAppMessagingExampleTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/InAppMessagingExample.app/InAppMessagingExample"; + }; + name = Release; + }; + 8DECFE77211CC14700DC99BD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = InAppMessagingExampleUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.firebase.InAppMessagingExampleUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = InAppMessagingExample; + }; + name = Debug; + }; + 8DECFE78211CC14700DC99BD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = InAppMessagingExampleUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.firebase.InAppMessagingExampleUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = InAppMessagingExample; + }; + name = Release; + }; + 8DECFE88211CC15F00DC99BD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = InAppMessagingExampleSwiftTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.firebase.InAppMessagingExampleSwiftTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/InAppMessagingExampleSwift.app/InAppMessagingExampleSwift"; + }; + name = Debug; + }; + 8DECFE89211CC15F00DC99BD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = InAppMessagingExampleSwiftTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.firebase.InAppMessagingExampleSwiftTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/InAppMessagingExampleSwift.app/InAppMessagingExampleSwift"; + }; + name = Release; + }; + 8DECFE96211CC16F00DC99BD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = InAppMessagingExampleSwiftUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.firebase.InAppMessagingExampleSwiftUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = InAppMessagingExampleSwift; + }; + name = Debug; + }; + 8DECFE97211CC16F00DC99BD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = InAppMessagingExampleSwiftUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.firebase.InAppMessagingExampleSwiftUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = InAppMessagingExampleSwift; + }; name = Release; }; /* End XCBuildConfiguration section */ @@ -347,7 +915,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 8DB25F9D20BE0C2A000ABEE2 /* Build configuration list for PBXNativeTarget "InAppMessagingExample" */ = { + 8DB25F9D20BE0C2A000ABEE2 /* Build configuration list for PBXNativeTarget "InAppMessagingExampleSwift" */ = { isa = XCConfigurationList; buildConfigurations = ( 8DB25F9E20BE0C2A000ABEE2 /* Debug */, @@ -356,31 +924,52 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; -/* End XCConfigurationList section */ - -/* Begin XCRemoteSwiftPackageReference section */ - 8DC73D772D41A89A0092B6EE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/firebase/firebase-ios-sdk"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 11.7.0; - }; + 8DECFE79211CC14700DC99BD /* Build configuration list for PBXNativeTarget "InAppMessagingExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8DECFE73211CC14700DC99BD /* Debug */, + 8DECFE74211CC14700DC99BD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 8DC73D792D41A90B0092B6EE /* FirebaseInAppMessaging-Beta */ = { - isa = XCSwiftPackageProductDependency; - package = 8DC73D772D41A89A0092B6EE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = "FirebaseInAppMessaging-Beta"; - }; - 8DC73D7D2D41AA540092B6EE /* FirebaseAnalytics */ = { - isa = XCSwiftPackageProductDependency; - package = 8DC73D772D41A89A0092B6EE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = FirebaseAnalytics; - }; -/* End XCSwiftPackageProductDependency section */ + 8DECFE7A211CC14700DC99BD /* Build configuration list for PBXNativeTarget "InAppMessagingExampleTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8DECFE75211CC14700DC99BD /* Debug */, + 8DECFE76211CC14700DC99BD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8DECFE7B211CC14700DC99BD /* Build configuration list for PBXNativeTarget "InAppMessagingExampleUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8DECFE77211CC14700DC99BD /* Debug */, + 8DECFE78211CC14700DC99BD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8DECFE87211CC15F00DC99BD /* Build configuration list for PBXNativeTarget "InAppMessagingExampleSwiftTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8DECFE88211CC15F00DC99BD /* Debug */, + 8DECFE89211CC15F00DC99BD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8DECFE95211CC16F00DC99BD /* Build configuration list for PBXNativeTarget "InAppMessagingExampleSwiftUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8DECFE96211CC16F00DC99BD /* Debug */, + 8DECFE97211CC16F00DC99BD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ }; rootObject = 8DB25F8320BE0C29000ABEE2 /* Project object */; } diff --git a/inappmessaging/InAppMessagingExample.xcodeproj/xcshareddata/xcschemes/InAppMessagingExample.xcscheme b/inappmessaging/InAppMessagingExample.xcodeproj/xcshareddata/xcschemes/InAppMessagingExample.xcscheme deleted file mode 100644 index e2ac35602..000000000 --- a/inappmessaging/InAppMessagingExample.xcodeproj/xcshareddata/xcschemes/InAppMessagingExample.xcscheme +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/inappmessaging/InAppMessagingExample/AppDelegate.h b/inappmessaging/InAppMessagingExample/AppDelegate.h new file mode 100644 index 000000000..013891c90 --- /dev/null +++ b/inappmessaging/InAppMessagingExample/AppDelegate.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 + +@interface AppDelegate : UIResponder + +@property(strong, nonatomic) UIWindow *window; + +@end diff --git a/inappmessaging/InAppMessagingExample/AppDelegate.m b/inappmessaging/InAppMessagingExample/AppDelegate.m new file mode 100644 index 000000000..25625d51c --- /dev/null +++ b/inappmessaging/InAppMessagingExample/AppDelegate.m @@ -0,0 +1,35 @@ +// 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 "AppDelegate.h" + +@import FirebaseCore; +@import FirebaseInAppMessaging; + +@interface AppDelegate () + +@end + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Uncomment the following line to disable In-App Messaging auto-startup. + // [FIRInAppMessaging inAppMessaging].automaticDataCollectionEnabled = NO; + + [FIRApp configure]; + return YES; +} + +@end diff --git a/inappmessaging/InAppMessagingExample/Assets.xcassets/AppIcon.appiconset/Contents.json b/inappmessaging/InAppMessagingExample/Assets.xcassets/AppIcon.appiconset/Contents.json index d8db8d65f..1d060ed28 100644 --- a/inappmessaging/InAppMessagingExample/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/inappmessaging/InAppMessagingExample/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -84,11 +84,6 @@ "idiom" : "ipad", "size" : "83.5x83.5", "scale" : "2x" - }, - { - "idiom" : "ios-marketing", - "size" : "1024x1024", - "scale" : "1x" } ], "info" : { diff --git a/inappmessaging/InAppMessagingExample/Base.lproj/LaunchScreen.storyboard b/inappmessaging/InAppMessagingExample/Base.lproj/LaunchScreen.storyboard index f83f6fd58..acde84d5a 100644 --- a/inappmessaging/InAppMessagingExample/Base.lproj/LaunchScreen.storyboard +++ b/inappmessaging/InAppMessagingExample/Base.lproj/LaunchScreen.storyboard @@ -1,8 +1,11 @@ - - + + + + + - - + + @@ -10,11 +13,14 @@ + + + + - diff --git a/inappmessaging/InAppMessagingExample/Base.lproj/Main.storyboard b/inappmessaging/InAppMessagingExample/Base.lproj/Main.storyboard index 21bc7eb1a..a142520d5 100644 --- a/inappmessaging/InAppMessagingExample/Base.lproj/Main.storyboard +++ b/inappmessaging/InAppMessagingExample/Base.lproj/Main.storyboard @@ -1,54 +1,51 @@ - + - - + + + + + - - + + + - + - - - - - - - - - - - + + diff --git a/inappmessaging/InAppMessagingExample/Info.plist b/inappmessaging/InAppMessagingExample/Info.plist index 16be3b681..573fe261c 100644 --- a/inappmessaging/InAppMessagingExample/Info.plist +++ b/inappmessaging/InAppMessagingExample/Info.plist @@ -4,6 +4,8 @@ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + fiam-external-ios-testing CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -16,6 +18,19 @@ APPL CFBundleShortVersionString 1.0 + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + my-url + CFBundleURLSchemes + + com.google.InAppMessagingExample + + + CFBundleVersion 1 LSRequiresIPhoneOS diff --git a/inappmessaging/InAppMessagingExample/ViewController.h b/inappmessaging/InAppMessagingExample/ViewController.h new file mode 100644 index 000000000..b6115b807 --- /dev/null +++ b/inappmessaging/InAppMessagingExample/ViewController.h @@ -0,0 +1,19 @@ +// 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 + +@interface ViewController : UIViewController + +@end diff --git a/inappmessaging/InAppMessagingExample/ViewController.m b/inappmessaging/InAppMessagingExample/ViewController.m new file mode 100644 index 000000000..7b99392c8 --- /dev/null +++ b/inappmessaging/InAppMessagingExample/ViewController.m @@ -0,0 +1,31 @@ +// 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 "ViewController.h" + +@import FirebaseAnalytics; + +@interface ViewController () +@property(weak, nonatomic) IBOutlet UITextField *urlText; +@end + +@implementation ViewController + +- (IBAction)triggerEvent:(id)sender { + if (self.urlText.text != nil) { + [FIRAnalytics logEventWithName:self.urlText.text parameters:@{}]; + } +} + +@end diff --git a/inappmessaging/InAppMessagingExample/main.m b/inappmessaging/InAppMessagingExample/main.m new file mode 100644 index 000000000..665d544d4 --- /dev/null +++ b/inappmessaging/InAppMessagingExample/main.m @@ -0,0 +1,22 @@ +// 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 "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/inappmessaging/InAppMessagingExample/AppDelegate.swift b/inappmessaging/InAppMessagingExampleSwift/AppDelegate.swift similarity index 100% rename from inappmessaging/InAppMessagingExample/AppDelegate.swift rename to inappmessaging/InAppMessagingExampleSwift/AppDelegate.swift diff --git a/inappmessaging/InAppMessagingExampleSwift/Assets.xcassets/AppIcon.appiconset/Contents.json b/inappmessaging/InAppMessagingExampleSwift/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..d8db8d65f --- /dev/null +++ b/inappmessaging/InAppMessagingExampleSwift/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/inappmessaging/InAppMessagingExampleSwift/Assets.xcassets/Contents.json b/inappmessaging/InAppMessagingExampleSwift/Assets.xcassets/Contents.json new file mode 100644 index 000000000..da4a164c9 --- /dev/null +++ b/inappmessaging/InAppMessagingExampleSwift/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/inappmessaging/InAppMessagingExampleSwift/Base.lproj/LaunchScreen.storyboard b/inappmessaging/InAppMessagingExampleSwift/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 000000000..f83f6fd58 --- /dev/null +++ b/inappmessaging/InAppMessagingExampleSwift/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inappmessaging/InAppMessagingExampleSwift/Base.lproj/Main.storyboard b/inappmessaging/InAppMessagingExampleSwift/Base.lproj/Main.storyboard new file mode 100644 index 000000000..e2a3e0f57 --- /dev/null +++ b/inappmessaging/InAppMessagingExampleSwift/Base.lproj/Main.storyboard @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inappmessaging/InAppMessagingExampleSwift/Info.plist b/inappmessaging/InAppMessagingExampleSwift/Info.plist new file mode 100644 index 000000000..16be3b681 --- /dev/null +++ b/inappmessaging/InAppMessagingExampleSwift/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/inappmessaging/InAppMessagingExample/ViewController.swift b/inappmessaging/InAppMessagingExampleSwift/ViewController.swift similarity index 100% rename from inappmessaging/InAppMessagingExample/ViewController.swift rename to inappmessaging/InAppMessagingExampleSwift/ViewController.swift diff --git a/inappmessaging/InAppMessagingExampleSwiftTests/InAppMessagingExampleSwiftTests.m b/inappmessaging/InAppMessagingExampleSwiftTests/InAppMessagingExampleSwiftTests.m new file mode 100644 index 000000000..b4d3f2c12 --- /dev/null +++ b/inappmessaging/InAppMessagingExampleSwiftTests/InAppMessagingExampleSwiftTests.m @@ -0,0 +1,39 @@ +// +// InAppMessagingExampleSwiftTests.m +// InAppMessagingExampleSwiftTests +// +// Created by Morgan Chen on 8/9/18. +// Copyright © 2018 Firebase. All rights reserved. +// + +#import + +@interface InAppMessagingExampleSwiftTests : XCTestCase + +@end + +@implementation InAppMessagingExampleSwiftTests + +- (void)setUp { + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. +} + +- (void)testPerformanceExample { + // This is an example of a performance test case. + [self measureBlock:^{ + // Put the code you want to measure the time of here. + }]; +} + +@end diff --git a/inappmessaging/InAppMessagingExampleSwiftTests/Info.plist b/inappmessaging/InAppMessagingExampleSwiftTests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/inappmessaging/InAppMessagingExampleSwiftTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/inappmessaging/InAppMessagingExampleSwiftUITests/InAppMessagingExampleSwiftUITests.m b/inappmessaging/InAppMessagingExampleSwiftUITests/InAppMessagingExampleSwiftUITests.m new file mode 100644 index 000000000..e6deddf15 --- /dev/null +++ b/inappmessaging/InAppMessagingExampleSwiftUITests/InAppMessagingExampleSwiftUITests.m @@ -0,0 +1,47 @@ +// Copyright (c) 2019 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +@interface InAppMessagingExampleSwiftUITests : XCTestCase + +@end + +@implementation InAppMessagingExampleSwiftUITests + +- (void)setUp { + [super setUp]; + + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + self.continueAfterFailure = NO; + // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. + [[[XCUIApplication alloc] init] launch]; + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample { + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. +} + +@end diff --git a/inappmessaging/InAppMessagingExampleSwiftUITests/Info.plist b/inappmessaging/InAppMessagingExampleSwiftUITests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/inappmessaging/InAppMessagingExampleSwiftUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/inappmessaging/InAppMessagingExampleTests/InAppMessagingExampleTests.m b/inappmessaging/InAppMessagingExampleTests/InAppMessagingExampleTests.m new file mode 100644 index 000000000..89edd6892 --- /dev/null +++ b/inappmessaging/InAppMessagingExampleTests/InAppMessagingExampleTests.m @@ -0,0 +1,39 @@ +// +// InAppMessagingExampleTests.m +// InAppMessagingExampleTests +// +// Created by Morgan Chen on 8/9/18. +// Copyright © 2018 Firebase. All rights reserved. +// + +#import + +@interface InAppMessagingExampleTests : XCTestCase + +@end + +@implementation InAppMessagingExampleTests + +- (void)setUp { + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. +} + +- (void)testPerformanceExample { + // This is an example of a performance test case. + [self measureBlock:^{ + // Put the code you want to measure the time of here. + }]; +} + +@end diff --git a/inappmessaging/InAppMessagingExampleTests/Info.plist b/inappmessaging/InAppMessagingExampleTests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/inappmessaging/InAppMessagingExampleTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/inappmessaging/InAppMessagingExampleUITests/InAppMessagingExampleUITests.m b/inappmessaging/InAppMessagingExampleUITests/InAppMessagingExampleUITests.m new file mode 100644 index 000000000..6d5167876 --- /dev/null +++ b/inappmessaging/InAppMessagingExampleUITests/InAppMessagingExampleUITests.m @@ -0,0 +1,36 @@ +// Copyright (c) 2019 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +@interface InAppMessagingExampleUITests : XCTestCase + +@end + +@implementation InAppMessagingExampleUITests { + XCUIApplication *_app; +} + +- (void)setUp { + [super setUp]; + _app = [[XCUIApplication alloc] init]; + [_app launch]; +} + +- (void)testVerifyAppLaunched { + XCTAssertTrue(_app.state == XCUIApplicationStateRunningForeground); +} + +@end diff --git a/inappmessaging/InAppMessagingExampleUITests/Info.plist b/inappmessaging/InAppMessagingExampleUITests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/inappmessaging/InAppMessagingExampleUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/inappmessaging/Podfile b/inappmessaging/Podfile new file mode 100644 index 000000000..3e1719da5 --- /dev/null +++ b/inappmessaging/Podfile @@ -0,0 +1,26 @@ +# Uncomment the next line to define a global platform for your project +platform :ios, '15.0' + +use_frameworks! + +target 'InAppMessagingExample' do + pod 'FirebaseAnalytics' + pod 'FirebaseInAppMessaging', "> 8.11-beta" + + target 'InAppMessagingExampleTests' do + end + + target 'InAppMessagingExampleUITests' do + end +end + +target 'InAppMessagingExampleSwift' do + pod 'FirebaseAnalytics' + pod 'FirebaseInAppMessaging', "> 8.11-beta" + + target 'InAppMessagingExampleSwiftTests' do + end + + target 'InAppMessagingExampleSwiftUITests' do + end +end diff --git a/inappmessaging/Podfile.lock b/inappmessaging/Podfile.lock new file mode 100644 index 000000000..d6328f752 --- /dev/null +++ b/inappmessaging/Podfile.lock @@ -0,0 +1,134 @@ +PODS: + - FirebaseABTesting (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseAnalytics (12.6.0): + - FirebaseAnalytics/Default (= 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseAnalytics/Default (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleAppMeasurement/Default (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseCore (12.6.0): + - FirebaseCoreInternal (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreInternal (12.6.0): + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseInAppMessaging (12.6.0-beta): + - FirebaseABTesting (~> 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - nanopb (~> 3.30910.0) + - FirebaseInstallations (12.6.0): + - FirebaseCore (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - PromisesObjC (~> 2.4) + - GoogleAdsOnDeviceConversion (3.2.0): + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Core (12.6.0): + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Default (12.6.0): + - GoogleAdsOnDeviceConversion (~> 3.2.0) + - GoogleAppMeasurement/Core (= 12.6.0) + - GoogleAppMeasurement/IdentitySupport (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/IdentitySupport (12.6.0): + - GoogleAppMeasurement/Core (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleUtilities/AppDelegateSwizzler (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Privacy + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - GoogleUtilities/MethodSwizzler (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/Network (8.1.0): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Privacy + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (8.1.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/Reachability (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/UserDefaults (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - nanopb (3.30910.0): + - nanopb/decode (= 3.30910.0) + - nanopb/encode (= 3.30910.0) + - nanopb/decode (3.30910.0) + - nanopb/encode (3.30910.0) + - PromisesObjC (2.4.0) + +DEPENDENCIES: + - FirebaseAnalytics + - FirebaseInAppMessaging (> 8.11-beta) + +SPEC REPOS: + trunk: + - FirebaseABTesting + - FirebaseAnalytics + - FirebaseCore + - FirebaseCoreInternal + - FirebaseInAppMessaging + - FirebaseInstallations + - GoogleAdsOnDeviceConversion + - GoogleAppMeasurement + - GoogleUtilities + - nanopb + - PromisesObjC + +SPEC CHECKSUMS: + FirebaseABTesting: 119f0a2b2e68b1ae05d248c5adb2455f148f20c1 + FirebaseAnalytics: d0a97a0db6425e5a5d966340b87f92ca7b13a557 + FirebaseCore: 0e38ad5d62d980a47a64b8e9301ffa311457be04 + FirebaseCoreInternal: 69bf1306a05b8ac43004f6cc1f804bb7b05b229e + FirebaseInAppMessaging: f0b968a0bc2d2e6208205865ea973ddc858cb6c9 + FirebaseInstallations: 631b38da2e11a83daa4bfb482f79d286a5dfa7ad + GoogleAdsOnDeviceConversion: d68c69dd9581a0f5da02617b6f377e5be483970f + GoogleAppMeasurement: 3bf40aff49a601af5da1c3345702fcb4991d35ee + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + +PODFILE CHECKSUM: 43743fc155d2f0e660d064b430e21c17089167ba + +COCOAPODS: 1.16.2 diff --git a/installations/InstallationsExample.xcodeproj/project.pbxproj b/installations/InstallationsExample.xcodeproj/project.pbxproj index 92763d0f2..794860fd9 100644 --- a/installations/InstallationsExample.xcodeproj/project.pbxproj +++ b/installations/InstallationsExample.xcodeproj/project.pbxproj @@ -3,19 +3,27 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 50; objects = { /* Begin PBXBuildFile section */ 1D96FE8F5661BCC40ADE48D3 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = AF38C66CDB0155B6F2BDE0FD /* GoogleService-Info.plist */; }; - 8DC73D842D41ABC00092B6EE /* FirebaseInstallations in Frameworks */ = {isa = PBXBuildFile; productRef = 8DC73D832D41ABC00092B6EE /* FirebaseInstallations */; }; + 7AB7C66CB639531B714014CA /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = AF38C66CDB0155B6F2BDE0FD /* GoogleService-Info.plist */; }; 9A0A6EE922CE55B2004CF0FF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0A6EE822CE55B2004CF0FF /* AppDelegate.swift */; }; 9A0A6EEB22CE55B2004CF0FF /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A0A6EEA22CE55B2004CF0FF /* ViewController.swift */; }; 9A0A6EEE22CE55B2004CF0FF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9A0A6EEC22CE55B2004CF0FF /* Main.storyboard */; }; + 9A44BF8122CE73980039A7EE /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A44BF7922CE73980039A7EE /* ViewController.m */; }; + 9A44BF8422CE73980039A7EE /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A44BF7E22CE73980039A7EE /* main.m */; }; + 9A44BF8522CE73980039A7EE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A44BF7F22CE73980039A7EE /* AppDelegate.m */; }; + 9A44BF8B22CE75B90039A7EE /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9A44BF8922CE75B90039A7EE /* Main.storyboard */; }; 9A5908BF23AD479B000CD3B9 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9A5908BA23AD479B000CD3B9 /* LaunchScreen.xib */; }; + 9A5908C023AD479B000CD3B9 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9A5908BA23AD479B000CD3B9 /* LaunchScreen.xib */; }; 9A5908C323AD479B000CD3B9 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9A5908BC23AD479B000CD3B9 /* Images.xcassets */; }; - 9A76AE3122E20A0C0024E473 /* InstallationsExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A76AE3022E20A0C0024E473 /* InstallationsExampleTests.m */; }; + 9A5908C423AD479B000CD3B9 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9A5908BC23AD479B000CD3B9 /* Images.xcassets */; }; + 9A76AE3122E20A0C0024E473 /* InstallationsExampleSwiftTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A76AE3022E20A0C0024E473 /* InstallationsExampleSwiftTests.m */; }; + 9A76AE3F22E20A240024E473 /* InstallationsExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A76AE3E22E20A240024E473 /* InstallationsExampleTests.m */; }; B2B6F60F66458C91106FE457 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = AF38C66CDB0155B6F2BDE0FD /* GoogleService-Info.plist */; }; + C2A411F73C146DCCE70EBE07 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = AF38C66CDB0155B6F2BDE0FD /* GoogleService-Info.plist */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -24,21 +32,39 @@ containerPortal = 9A0A6EDD22CE55B2004CF0FF /* Project object */; proxyType = 1; remoteGlobalIDString = 9A0A6EE422CE55B2004CF0FF; + remoteInfo = InstallationsExampleSwift; + }; + 9A76AE4122E20A240024E473 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 9A0A6EDD22CE55B2004CF0FF /* Project object */; + proxyType = 1; + remoteGlobalIDString = 9A44BF5B22CE72B60039A7EE; remoteInfo = InstallationsExample; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 9A0A6EE522CE55B2004CF0FF /* InstallationsExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = InstallationsExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 9A0A6EE522CE55B2004CF0FF /* InstallationsExampleSwift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = InstallationsExampleSwift.app; sourceTree = BUILT_PRODUCTS_DIR; }; 9A0A6EE822CE55B2004CF0FF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 9A0A6EEA22CE55B2004CF0FF /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 9A0A6EED22CE55B2004CF0FF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 9A44BF5C22CE72B60039A7EE /* InstallationsExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = InstallationsExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 9A44BF7822CE73980039A7EE /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 9A44BF7922CE73980039A7EE /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 9A44BF7E22CE73980039A7EE /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 9A44BF7F22CE73980039A7EE /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9A44BF8022CE73980039A7EE /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + 9A44BF8A22CE75B90039A7EE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 9A5908BA23AD479B000CD3B9 /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LaunchScreen.xib; sourceTree = ""; }; 9A5908BC23AD479B000CD3B9 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 9A76AE2322E206380024E473 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 9A76AE2922E207640024E473 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 9A76AE2E22E20A0C0024E473 /* InstallationsExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InstallationsExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 9A76AE3022E20A0C0024E473 /* InstallationsExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InstallationsExampleTests.m; sourceTree = ""; }; + 9A76AE2E22E20A0C0024E473 /* InstallationsExampleSwiftTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InstallationsExampleSwiftTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 9A76AE3022E20A0C0024E473 /* InstallationsExampleSwiftTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InstallationsExampleSwiftTests.m; sourceTree = ""; }; 9A76AE3222E20A0C0024E473 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9A76AE3C22E20A240024E473 /* InstallationsExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InstallationsExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 9A76AE3E22E20A240024E473 /* InstallationsExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InstallationsExampleTests.m; sourceTree = ""; }; + 9A76AE4022E20A240024E473 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; AF38C66CDB0155B6F2BDE0FD /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -47,7 +73,13 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8DC73D842D41ABC00092B6EE /* FirebaseInstallations in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9A44BF5922CE72B60039A7EE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( ); runOnlyForDeploymentPostprocessing = 0; }; @@ -58,38 +90,42 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 9A76AE3922E20A240024E473 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 8DC73D822D41ABC00092B6EE /* Frameworks */ = { - isa = PBXGroup; - children = ( - ); - name = Frameworks; - sourceTree = ""; - }; 9A0A6EDC22CE55B2004CF0FF = { isa = PBXGroup; children = ( 9A5908B923AD479B000CD3B9 /* shared */, - 9A0A6EE722CE55B2004CF0FF /* InstallationsExample */, - 9A76AE2F22E20A0C0024E473 /* InstallationsExampleTests */, + 9A44BF7722CE73980039A7EE /* InstallationsExample */, + 9A0A6EE722CE55B2004CF0FF /* InstallationsExampleSwift */, + 9A76AE2F22E20A0C0024E473 /* InstallationsExampleSwiftTests */, + 9A76AE3D22E20A240024E473 /* InstallationsExampleTests */, 9A0A6EE622CE55B2004CF0FF /* Products */, + F47D9EFBA47214D7699A8C26 /* Pods */, AF38C66CDB0155B6F2BDE0FD /* GoogleService-Info.plist */, - 8DC73D822D41ABC00092B6EE /* Frameworks */, ); sourceTree = ""; }; 9A0A6EE622CE55B2004CF0FF /* Products */ = { isa = PBXGroup; children = ( - 9A0A6EE522CE55B2004CF0FF /* InstallationsExample.app */, - 9A76AE2E22E20A0C0024E473 /* InstallationsExampleTests.xctest */, + 9A0A6EE522CE55B2004CF0FF /* InstallationsExampleSwift.app */, + 9A44BF5C22CE72B60039A7EE /* InstallationsExample.app */, + 9A76AE2E22E20A0C0024E473 /* InstallationsExampleSwiftTests.xctest */, + 9A76AE3C22E20A240024E473 /* InstallationsExampleTests.xctest */, ); name = Products; sourceTree = ""; }; - 9A0A6EE722CE55B2004CF0FF /* InstallationsExample */ = { + 9A0A6EE722CE55B2004CF0FF /* InstallationsExampleSwift */ = { isa = PBXGroup; children = ( 9A76AE2922E207640024E473 /* Info.plist */, @@ -97,6 +133,20 @@ 9A0A6EE822CE55B2004CF0FF /* AppDelegate.swift */, 9A0A6EEA22CE55B2004CF0FF /* ViewController.swift */, ); + path = InstallationsExampleSwift; + sourceTree = ""; + }; + 9A44BF7722CE73980039A7EE /* InstallationsExample */ = { + isa = PBXGroup; + children = ( + 9A76AE2322E206380024E473 /* Info.plist */, + 9A44BF8922CE75B90039A7EE /* Main.storyboard */, + 9A44BF7822CE73980039A7EE /* AppDelegate.h */, + 9A44BF7F22CE73980039A7EE /* AppDelegate.m */, + 9A44BF8022CE73980039A7EE /* ViewController.h */, + 9A44BF7922CE73980039A7EE /* ViewController.m */, + 9A44BF7E22CE73980039A7EE /* main.m */, + ); path = InstallationsExample; sourceTree = ""; }; @@ -110,21 +160,37 @@ path = ../shared; sourceTree = ""; }; - 9A76AE2F22E20A0C0024E473 /* InstallationsExampleTests */ = { + 9A76AE2F22E20A0C0024E473 /* InstallationsExampleSwiftTests */ = { isa = PBXGroup; children = ( - 9A76AE3022E20A0C0024E473 /* InstallationsExampleTests.m */, + 9A76AE3022E20A0C0024E473 /* InstallationsExampleSwiftTests.m */, 9A76AE3222E20A0C0024E473 /* Info.plist */, ); + path = InstallationsExampleSwiftTests; + sourceTree = ""; + }; + 9A76AE3D22E20A240024E473 /* InstallationsExampleTests */ = { + isa = PBXGroup; + children = ( + 9A76AE3E22E20A240024E473 /* InstallationsExampleTests.m */, + 9A76AE4022E20A240024E473 /* Info.plist */, + ); path = InstallationsExampleTests; sourceTree = ""; }; + F47D9EFBA47214D7699A8C26 /* Pods */ = { + isa = PBXGroup; + children = ( + ); + path = Pods; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 9A0A6EE422CE55B2004CF0FF /* InstallationsExample */ = { + 9A0A6EE422CE55B2004CF0FF /* InstallationsExampleSwift */ = { isa = PBXNativeTarget; - buildConfigurationList = 9A0A6EF722CE55B3004CF0FF /* Build configuration list for PBXNativeTarget "InstallationsExample" */; + buildConfigurationList = 9A0A6EF722CE55B3004CF0FF /* Build configuration list for PBXNativeTarget "InstallationsExampleSwift" */; buildPhases = ( 9A0A6EE122CE55B2004CF0FF /* Sources */, 9A0A6EE222CE55B2004CF0FF /* Frameworks */, @@ -134,14 +200,31 @@ ); dependencies = ( ); + name = InstallationsExampleSwift; + productName = InstallationsExample; + productReference = 9A0A6EE522CE55B2004CF0FF /* InstallationsExampleSwift.app */; + productType = "com.apple.product-type.application"; + }; + 9A44BF5B22CE72B60039A7EE /* InstallationsExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9A44BF6F22CE72B60039A7EE /* Build configuration list for PBXNativeTarget "InstallationsExample" */; + buildPhases = ( + 9A44BF5822CE72B60039A7EE /* Sources */, + 9A44BF5922CE72B60039A7EE /* Frameworks */, + 9A44BF5A22CE72B60039A7EE /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); name = InstallationsExample; productName = InstallationsExample; - productReference = 9A0A6EE522CE55B2004CF0FF /* InstallationsExample.app */; + productReference = 9A44BF5C22CE72B60039A7EE /* InstallationsExample.app */; productType = "com.apple.product-type.application"; }; - 9A76AE2D22E20A0C0024E473 /* InstallationsExampleTests */ = { + 9A76AE2D22E20A0C0024E473 /* InstallationsExampleSwiftTests */ = { isa = PBXNativeTarget; - buildConfigurationList = 9A76AE3722E20A0C0024E473 /* Build configuration list for PBXNativeTarget "InstallationsExampleTests" */; + buildConfigurationList = 9A76AE3722E20A0C0024E473 /* Build configuration list for PBXNativeTarget "InstallationsExampleSwiftTests" */; buildPhases = ( 9A76AE2A22E20A0C0024E473 /* Sources */, 9A76AE2B22E20A0C0024E473 /* Frameworks */, @@ -152,9 +235,27 @@ dependencies = ( 9A76AE3422E20A0C0024E473 /* PBXTargetDependency */, ); + name = InstallationsExampleSwiftTests; + productName = InstallationsExampleSwiftTests; + productReference = 9A76AE2E22E20A0C0024E473 /* InstallationsExampleSwiftTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 9A76AE3B22E20A240024E473 /* InstallationsExampleTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9A76AE4322E20A240024E473 /* Build configuration list for PBXNativeTarget "InstallationsExampleTests" */; + buildPhases = ( + 9A76AE3822E20A240024E473 /* Sources */, + 9A76AE3922E20A240024E473 /* Frameworks */, + 9A76AE3A22E20A240024E473 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 9A76AE4222E20A240024E473 /* PBXTargetDependency */, + ); name = InstallationsExampleTests; productName = InstallationsExampleTests; - productReference = 9A76AE2E22E20A0C0024E473 /* InstallationsExampleTests.xctest */; + productReference = 9A76AE3C22E20A240024E473 /* InstallationsExampleTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ @@ -163,19 +264,25 @@ 9A0A6EDD22CE55B2004CF0FF /* Project object */ = { isa = PBXProject; attributes = { - BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 1020; - LastUpgradeCheck = 1610; + LastUpgradeCheck = 1020; ORGANIZATIONNAME = "Google Inc."; TargetAttributes = { 9A0A6EE422CE55B2004CF0FF = { CreatedOnToolsVersion = 10.2.1; LastSwiftMigration = 1020; }; + 9A44BF5B22CE72B60039A7EE = { + CreatedOnToolsVersion = 10.2.1; + }; 9A76AE2D22E20A0C0024E473 = { CreatedOnToolsVersion = 11.0; TestTargetID = 9A0A6EE422CE55B2004CF0FF; }; + 9A76AE3B22E20A240024E473 = { + CreatedOnToolsVersion = 11.0; + TestTargetID = 9A44BF5B22CE72B60039A7EE; + }; }; }; buildConfigurationList = 9A0A6EE022CE55B2004CF0FF /* Build configuration list for PBXProject "InstallationsExample" */; @@ -187,15 +294,14 @@ Base, ); mainGroup = 9A0A6EDC22CE55B2004CF0FF; - packageReferences = ( - 8DC73D812D41ABB70092B6EE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, - ); productRefGroup = 9A0A6EE622CE55B2004CF0FF /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - 9A0A6EE422CE55B2004CF0FF /* InstallationsExample */, - 9A76AE2D22E20A0C0024E473 /* InstallationsExampleTests */, + 9A0A6EE422CE55B2004CF0FF /* InstallationsExampleSwift */, + 9A44BF5B22CE72B60039A7EE /* InstallationsExample */, + 9A76AE2D22E20A0C0024E473 /* InstallationsExampleSwiftTests */, + 9A76AE3B22E20A240024E473 /* InstallationsExampleTests */, ); }; /* End PBXProject section */ @@ -211,6 +317,16 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 9A44BF5A22CE72B60039A7EE /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9A5908C423AD479B000CD3B9 /* Images.xcassets in Resources */, + 9A5908C023AD479B000CD3B9 /* LaunchScreen.xib in Resources */, + 9A44BF8B22CE75B90039A7EE /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 9A76AE2C22E20A0C0024E473 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -218,6 +334,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 9A76AE3A22E20A240024E473 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -231,23 +354,48 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 9A44BF5822CE72B60039A7EE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9A44BF8422CE73980039A7EE /* main.m in Sources */, + 9A44BF8122CE73980039A7EE /* ViewController.m in Sources */, + 9A44BF8522CE73980039A7EE /* AppDelegate.m in Sources */, + 7AB7C66CB639531B714014CA /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 9A76AE2A22E20A0C0024E473 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 9A76AE3122E20A0C0024E473 /* InstallationsExampleTests.m in Sources */, + 9A76AE3122E20A0C0024E473 /* InstallationsExampleSwiftTests.m in Sources */, 1D96FE8F5661BCC40ADE48D3 /* GoogleService-Info.plist in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; + 9A76AE3822E20A240024E473 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9A76AE3F22E20A240024E473 /* InstallationsExampleTests.m in Sources */, + C2A411F73C146DCCE70EBE07 /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 9A76AE3422E20A0C0024E473 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 9A0A6EE422CE55B2004CF0FF /* InstallationsExample */; + target = 9A0A6EE422CE55B2004CF0FF /* InstallationsExampleSwift */; targetProxy = 9A76AE3322E20A0C0024E473 /* PBXContainerItemProxy */; }; + 9A76AE4222E20A240024E473 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 9A44BF5B22CE72B60039A7EE /* InstallationsExample */; + targetProxy = 9A76AE4122E20A240024E473 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -259,6 +407,14 @@ name = Main.storyboard; sourceTree = ""; }; + 9A44BF8922CE75B90039A7EE /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 9A44BF8A22CE75B90039A7EE /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ @@ -288,7 +444,6 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -300,7 +455,6 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -351,7 +505,6 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -363,7 +516,6 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -387,12 +539,12 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; - INFOPLIST_FILE = InstallationsExample/Info.plist; + INFOPLIST_FILE = InstallationsExampleSwift/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.InstallationExample; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.InstallationExampleSwift; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; @@ -400,6 +552,39 @@ name = Debug; }; 9A0A6EF922CE55B3004CF0FF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = InstallationsExampleSwift/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.InstallationExampleSwift; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 9A44BF7022CE72B60039A7EE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = InstallationsExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.InstallationExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 9A44BF7122CE72B60039A7EE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; @@ -411,12 +596,49 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.InstallationExample; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; 9A76AE3522E20A0C0024E473 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = InstallationsExampleSwiftTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.InstallationsExampleSwiftTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/InstallationsExampleSwift.app/InstallationsExampleSwift"; + }; + name = Debug; + }; + 9A76AE3622E20A0C0024E473 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = InstallationsExampleSwiftTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.InstallationsExampleSwiftTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/InstallationsExampleSwift.app/InstallationsExampleSwift"; + }; + name = Release; + }; + 9A76AE4422E20A240024E473 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; @@ -434,7 +656,7 @@ }; name = Debug; }; - 9A76AE3622E20A0C0024E473 /* Release */ = { + 9A76AE4522E20A240024E473 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; @@ -464,7 +686,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 9A0A6EF722CE55B3004CF0FF /* Build configuration list for PBXNativeTarget "InstallationsExample" */ = { + 9A0A6EF722CE55B3004CF0FF /* Build configuration list for PBXNativeTarget "InstallationsExampleSwift" */ = { isa = XCConfigurationList; buildConfigurations = ( 9A0A6EF822CE55B3004CF0FF /* Debug */, @@ -473,7 +695,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 9A76AE3722E20A0C0024E473 /* Build configuration list for PBXNativeTarget "InstallationsExampleTests" */ = { + 9A44BF6F22CE72B60039A7EE /* Build configuration list for PBXNativeTarget "InstallationsExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9A44BF7022CE72B60039A7EE /* Debug */, + 9A44BF7122CE72B60039A7EE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9A76AE3722E20A0C0024E473 /* Build configuration list for PBXNativeTarget "InstallationsExampleSwiftTests" */ = { isa = XCConfigurationList; buildConfigurations = ( 9A76AE3522E20A0C0024E473 /* Debug */, @@ -482,26 +713,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; -/* End XCConfigurationList section */ - -/* Begin XCRemoteSwiftPackageReference section */ - 8DC73D812D41ABB70092B6EE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/firebase/firebase-ios-sdk"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 11.7.0; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 8DC73D832D41ABC00092B6EE /* FirebaseInstallations */ = { - isa = XCSwiftPackageProductDependency; - package = 8DC73D812D41ABB70092B6EE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = FirebaseInstallations; + 9A76AE4322E20A240024E473 /* Build configuration list for PBXNativeTarget "InstallationsExampleTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9A76AE4422E20A240024E473 /* Debug */, + 9A76AE4522E20A240024E473 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; -/* End XCSwiftPackageProductDependency section */ +/* End XCConfigurationList section */ }; rootObject = 9A0A6EDD22CE55B2004CF0FF /* Project object */; } diff --git a/installations/InstallationsExample/AppDelegate.h b/installations/InstallationsExample/AppDelegate.h new file mode 100644 index 000000000..5354fee74 --- /dev/null +++ b/installations/InstallationsExample/AppDelegate.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 + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/installations/InstallationsExample/AppDelegate.m b/installations/InstallationsExample/AppDelegate.m new file mode 100644 index 000000000..f93418379 --- /dev/null +++ b/installations/InstallationsExample/AppDelegate.m @@ -0,0 +1,34 @@ +/* + * 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 "AppDelegate.h" + +// TODO: Remove once FirebaseInstallations has released. +#import +@import FirebaseCore; + +@interface AppDelegate () + +@end + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [FIRApp configure]; + return YES; +} + +@end diff --git a/installations/InstallationsExample/Base.lproj/Main.storyboard b/installations/InstallationsExample/Base.lproj/Main.storyboard index 651a5ac0b..a10db3079 100644 --- a/installations/InstallationsExample/Base.lproj/Main.storyboard +++ b/installations/InstallationsExample/Base.lproj/Main.storyboard @@ -11,7 +11,7 @@ - + diff --git a/installations/InstallationsExample/ViewController.h b/installations/InstallationsExample/ViewController.h new file mode 100644 index 000000000..7972f0935 --- /dev/null +++ b/installations/InstallationsExample/ViewController.h @@ -0,0 +1,23 @@ +/* + * 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 + +@interface ViewController : UIViewController + + +@end + diff --git a/installations/InstallationsExample/ViewController.m b/installations/InstallationsExample/ViewController.m new file mode 100644 index 000000000..605c58732 --- /dev/null +++ b/installations/InstallationsExample/ViewController.m @@ -0,0 +1,98 @@ +/* + * 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 "ViewController.h" + +// TODO(M61): Remove once `Firebase/Installations` released. +#import +#import + +@import FirebaseInstallations; + +@interface ViewController () +@property (strong, nonatomic) IBOutlet UIButton *getInstallationButton; +@property (strong, nonatomic) IBOutlet UIButton *getAuthTokenButton; +@property (strong, nonatomic) IBOutlet UIButton *deleteInstallationButton; +@property (strong, nonatomic) IBOutlet UITextView *logTextView; + +@property(strong, nonatomic) NSString *log; +@end + +@implementation ViewController + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.log = @""; + + [self subscribeForInstallationsUpdateNotifications]; +} + +- (FIRInstallations *)installations { + return [FIRInstallations installations]; +} + +- (IBAction)getInstallationButtonPressed { + [self logMessage:@"Call [FIRInstallations installationIDWithCompletion:]"]; + [[self installations] installationIDWithCompletion:^(NSString * _Nullable identifier, NSError * _Nullable error) { + NSString *message = [NSString stringWithFormat:@"[FIRInstallations installationIDWithCompletion:] result:\n identifier = %@\nerror = %@", identifier, error]; + [self logMessage:message]; + }]; +} + +- (IBAction)getAuthTokenButtonPressed { + [self logMessage:@"Call [FIRInstallations authTokenWithCompletion:]"]; + [[self installations] authTokenWithCompletion:^(FIRInstallationsAuthTokenResult * _Nullable tokenResult, NSError * _Nullable error) { + NSString *message = [NSString stringWithFormat:@"[FIRInstallations authTokenWithCompletion:] result:\n tokenResult.authToken = %@\ntokenResult.expirationDate%@\nerror = %@", tokenResult.authToken, tokenResult.expirationDate, error]; + [self logMessage:message]; + }]; +} + +- (IBAction)deleteInstallationButtonPressed { + [self logMessage:@"Call [FIRInstallations deleteWithCompletion:]"]; + [[self installations] deleteWithCompletion:^(NSError *_Nullable error) { + NSString *message = [NSString stringWithFormat:@"[FIRInstallations deleteWithCompletion:] result:\n %@", + error ?: @"SUCCESS"]; + [self logMessage:message]; + }]; +} + +- (void)subscribeForInstallationsUpdateNotifications { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(installationUpdateNotificationReceived:) name:FIRInstallationIDDidChangeNotification object:nil]; +} + +- (void)installationUpdateNotificationReceived:(NSNotification *)notification { + NSString *message = [NSString stringWithFormat:@"Notification received: %@", notification]; + [self logMessage:message]; +} + +#pragma mark - Log + +- (void)setLog:(NSString *)log { + _log = log; + self.logTextView.text = log; +} + +- (void)logMessage:(NSString *)message { + NSString *logMessage = [NSString stringWithFormat:@"%@\n---\n", message]; + self.log = [logMessage stringByAppendingString:self.log]; +} + +@end diff --git a/installations/InstallationsExample/main.m b/installations/InstallationsExample/main.m new file mode 100644 index 000000000..84c466ca0 --- /dev/null +++ b/installations/InstallationsExample/main.m @@ -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. + */ + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/installations/InstallationsExample/AppDelegate.swift b/installations/InstallationsExampleSwift/AppDelegate.swift similarity index 100% rename from installations/InstallationsExample/AppDelegate.swift rename to installations/InstallationsExampleSwift/AppDelegate.swift diff --git a/installations/InstallationsExampleSwift/Base.lproj/Main.storyboard b/installations/InstallationsExampleSwift/Base.lproj/Main.storyboard new file mode 100644 index 000000000..4bfcf5861 --- /dev/null +++ b/installations/InstallationsExampleSwift/Base.lproj/Main.storyboard @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/installations/InstallationsExampleSwift/Info.plist b/installations/InstallationsExampleSwift/Info.plist new file mode 100644 index 000000000..16be3b681 --- /dev/null +++ b/installations/InstallationsExampleSwift/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/installations/InstallationsExample/ViewController.swift b/installations/InstallationsExampleSwift/ViewController.swift similarity index 100% rename from installations/InstallationsExample/ViewController.swift rename to installations/InstallationsExampleSwift/ViewController.swift diff --git a/installations/InstallationsExampleSwiftTests/Info.plist b/installations/InstallationsExampleSwiftTests/Info.plist new file mode 100644 index 000000000..64d65ca49 --- /dev/null +++ b/installations/InstallationsExampleSwiftTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/installations/InstallationsExampleSwiftTests/InstallationsExampleSwiftTests.m b/installations/InstallationsExampleSwiftTests/InstallationsExampleSwiftTests.m new file mode 100644 index 000000000..d4cbe3ad2 --- /dev/null +++ b/installations/InstallationsExampleSwiftTests/InstallationsExampleSwiftTests.m @@ -0,0 +1,45 @@ +/* + * 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 + +@interface InstallationsExampleSwiftTests : XCTestCase + +@end + +@implementation InstallationsExampleSwiftTests + +- (void)setUp { + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. +} + +- (void)testExample { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. +} + +- (void)testPerformanceExample { + // This is an example of a performance test case. + [self measureBlock:^{ + // Put the code you want to measure the time of here. + }]; +} + +@end diff --git a/installations/Podfile b/installations/Podfile new file mode 100644 index 000000000..1918fe590 --- /dev/null +++ b/installations/Podfile @@ -0,0 +1,10 @@ +platform :ios, '15.0' +use_frameworks! + +pod 'FirebaseInstallations' + +target 'InstallationsExample' do +end + +target 'InstallationsExampleSwift' do +end diff --git a/installations/Podfile.lock b/installations/Podfile.lock new file mode 100644 index 000000000..b7c653755 --- /dev/null +++ b/installations/Podfile.lock @@ -0,0 +1,46 @@ +PODS: + - FirebaseCore (12.6.0): + - FirebaseCoreInternal (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreInternal (12.6.0): + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseInstallations (12.6.0): + - FirebaseCore (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - PromisesObjC (~> 2.4) + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - "GoogleUtilities/NSData+zlib (8.1.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/UserDefaults (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - PromisesObjC (2.4.0) + +DEPENDENCIES: + - FirebaseInstallations + +SPEC REPOS: + trunk: + - FirebaseCore + - FirebaseCoreInternal + - FirebaseInstallations + - GoogleUtilities + - PromisesObjC + +SPEC CHECKSUMS: + FirebaseCore: 0e38ad5d62d980a47a64b8e9301ffa311457be04 + FirebaseCoreInternal: 69bf1306a05b8ac43004f6cc1f804bb7b05b229e + FirebaseInstallations: 631b38da2e11a83daa4bfb482f79d286a5dfa7ad + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + +PODFILE CHECKSUM: 7dbe56c9bd727dca6546a8afc6fd796cf332831e + +COCOAPODS: 1.16.2 diff --git a/messaging/MessagingExample.xcodeproj/project.pbxproj b/messaging/MessagingExample.xcodeproj/project.pbxproj index 89eac1a2f..7aad36291 100644 --- a/messaging/MessagingExample.xcodeproj/project.pbxproj +++ b/messaging/MessagingExample.xcodeproj/project.pbxproj @@ -3,21 +3,33 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 0718C8BD2E8F256800AA7788 /* NotificationServiceExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 0718C8B62E8F256800AA7788 /* NotificationServiceExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 0738A4882E8F2B2A00680EC4 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0738A4862E8F2B2A00680EC4 /* NotificationService.swift */; }; - 107347AB20315A3A004A66D1 /* MessagingExampleUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 107347AA20315A3A004A66D1 /* MessagingExampleUITests.swift */; }; + 107347AB20315A3A004A66D1 /* MessagingExampleSwiftUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 107347AA20315A3A004A66D1 /* MessagingExampleSwiftUITests.swift */; }; + 1073486120333BF5004A66D1 /* MessagingExampleUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1073486020333BF5004A66D1 /* MessagingExampleUITests.m */; }; 5B334EAC56E0F5E167C81718 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 82E79B6D15A982EAE7B0E31B /* GoogleService-Info.plist */; }; + 5F5A53521ADE670C00F81DF0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53511ADE670C00F81DF0 /* main.m */; }; + 5F5A53551ADE670C00F81DF0 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */; }; + 5F5A53581ADE670C00F81DF0 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53571ADE670C00F81DF0 /* ViewController.m */; }; + 5F5A535B1ADE670C00F81DF0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5F5A53591ADE670C00F81DF0 /* Main.storyboard */; }; 5F5A537E1ADE67D500F81DF0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */; }; 5F5A53801ADE67D500F81DF0 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A537F1ADE67D500F81DF0 /* ViewController.swift */; }; + 5F5A539C1ADE69AA00F81DF0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5F5A53591ADE670C00F81DF0 /* Main.storyboard */; }; + 5F99610A1AE0CF4F0034F503 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961061AE0CF4F0034F503 /* Images.xcassets */; }; 5F99610B1AE0CF4F0034F503 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961061AE0CF4F0034F503 /* Images.xcassets */; }; + 5F99610C1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */; }; 5F99610D1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */; }; - 8DC73D8C2D41AE850092B6EE /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = 8DC73D8B2D41AE850092B6EE /* FirebaseMessaging */; }; + 5FDE055D1B0DAA090037B82F /* AppTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FDE055C1B0DAA090037B82F /* AppTests.m */; }; 978E6F2CAAC2AD673D158985 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 82E79B6D15A982EAE7B0E31B /* GoogleService-Info.plist */; }; - EAC902A32EC6849A000761B8 /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = EAC902A22EC6849A000761B8 /* FirebaseMessaging */; }; + 9EC3C1193ECE4B761399CA62 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 82E79B6D15A982EAE7B0E31B /* GoogleService-Info.plist */; }; + A2448B9D9232B1BAEE1CA86B /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 82E79B6D15A982EAE7B0E31B /* GoogleService-Info.plist */; }; + D5D4832C57250D09E5864463 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 82E79B6D15A982EAE7B0E31B /* GoogleService-Info.plist */; }; + DEB13BC923AEC9DF0066A6F3 /* FIREGSignInHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = DEB13BC623AEC9DF0066A6F3 /* FIREGSignInHelper.m */; }; + DEB13BCA23AEC9DF0066A6F3 /* FIREGHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = DEB13BC723AEC9DF0066A6F3 /* FIREGHelper.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -33,8 +45,22 @@ containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; proxyType = 1; remoteGlobalIDString = 5F5A53781ADE67D500F81DF0; + remoteInfo = MessagingExampleSwift; + }; + 1073486320333BF5004A66D1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5F5A534B1ADE670C00F81DF0; remoteInfo = MessagingExample; }; + 5FDE055E1B0DAA090037B82F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5F5A534B1ADE670C00F81DF0; + remoteInfo = FCM; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -55,21 +81,35 @@ 0718C8B62E8F256800AA7788 /* NotificationServiceExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = NotificationServiceExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 0738A4852E8F2B2A00680EC4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 0738A4862E8F2B2A00680EC4 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = ""; }; - 107347A820315A3A004A66D1 /* MessagingExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MessagingExampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 107347AA20315A3A004A66D1 /* MessagingExampleUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagingExampleUITests.swift; sourceTree = ""; }; + 107347A820315A3A004A66D1 /* MessagingExampleSwiftUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MessagingExampleSwiftUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 107347AA20315A3A004A66D1 /* MessagingExampleSwiftUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagingExampleSwiftUITests.swift; sourceTree = ""; }; 107347AC20315A3A004A66D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 5F5A53791ADE67D500F81DF0 /* MessagingExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MessagingExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1073485E20333BF5004A66D1 /* MessagingExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MessagingExampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 1073486020333BF5004A66D1 /* MessagingExampleUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MessagingExampleUITests.m; sourceTree = ""; }; + 1073486220333BF5004A66D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 321A2C4E1DD5054B009C10E2 /* MessagingExampleSwift.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MessagingExampleSwift.entitlements; sourceTree = ""; }; + 32E04E051DD4EBC6007706A0 /* MessagingExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MessagingExample.entitlements; sourceTree = ""; }; + 5F5A534C1ADE670C00F81DF0 /* MessagingExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MessagingExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5F5A53501ADE670C00F81DF0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5F5A53511ADE670C00F81DF0 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 5F5A53531ADE670C00F81DF0 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 5F5A53561ADE670C00F81DF0 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + 5F5A53571ADE670C00F81DF0 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 5F5A535A1ADE670C00F81DF0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 5F5A53791ADE67D500F81DF0 /* MessagingExampleSwift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MessagingExampleSwift.app; sourceTree = BUILT_PRODUCTS_DIR; }; 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 5F5A537F1ADE67D500F81DF0 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 5F9961061AE0CF4F0034F503 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LaunchScreen.xib; sourceTree = ""; }; + 5FDE05581B0DAA090037B82F /* MessagingExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MessagingExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5FDE055C1B0DAA090037B82F /* AppTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppTests.m; sourceTree = ""; }; 82E79B6D15A982EAE7B0E31B /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; DEB13BC523AEC9DF0066A6F3 /* FIREGHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIREGHelper.h; sourceTree = ""; }; DEB13BC623AEC9DF0066A6F3 /* FIREGSignInHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIREGSignInHelper.m; sourceTree = ""; }; DEB13BC723AEC9DF0066A6F3 /* FIREGHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIREGHelper.m; sourceTree = ""; }; DEB13BC823AEC9DF0066A6F3 /* FIREGSignInHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIREGSignInHelper.h; sourceTree = ""; }; DED65CF723E9DE6400461312 /* FIREGSignInInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FIREGSignInInfo.h; sourceTree = ""; }; - EAE93A8D2E86E558005ABAF0 /* MessagingExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MessagingExample.entitlements; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -77,7 +117,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - EAC902A32EC6849A000761B8 /* FirebaseMessaging in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -88,11 +127,31 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 1073485B20333BF5004A66D1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53491ADE670C00F81DF0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5F5A53761ADE67D500F81DF0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8DC73D8C2D41AE850092B6EE /* FirebaseMessaging in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FDE05551B0DAA090037B82F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( ); runOnlyForDeploymentPostprocessing = 0; }; @@ -108,25 +167,36 @@ path = NotificationServiceExtension; sourceTree = ""; }; - 107347A920315A3A004A66D1 /* MessagingExampleUITests */ = { + 107347A920315A3A004A66D1 /* MessagingExampleSwiftUITests */ = { isa = PBXGroup; children = ( - 107347AA20315A3A004A66D1 /* MessagingExampleUITests.swift */, + 107347AA20315A3A004A66D1 /* MessagingExampleSwiftUITests.swift */, 107347AC20315A3A004A66D1 /* Info.plist */, ); + path = MessagingExampleSwiftUITests; + sourceTree = ""; + }; + 1073485F20333BF5004A66D1 /* MessagingExampleUITests */ = { + isa = PBXGroup; + children = ( + 1073486020333BF5004A66D1 /* MessagingExampleUITests.m */, + 1073486220333BF5004A66D1 /* Info.plist */, + ); path = MessagingExampleUITests; sourceTree = ""; }; 5F5A53431ADE670C00F81DF0 = { isa = PBXGroup; children = ( - EAE93A8A2E86E465005ABAF0 /* MessagingExample */, - 107347A920315A3A004A66D1 /* MessagingExampleUITests */, + 5F5A534E1ADE670C00F81DF0 /* MessagingExample */, + 5F5A537A1ADE67D500F81DF0 /* MessagingExampleSwift */, + 5FDE05591B0DAA090037B82F /* MessagingExampleTests */, + 107347A920315A3A004A66D1 /* MessagingExampleSwiftUITests */, + 1073485F20333BF5004A66D1 /* MessagingExampleUITests */, DEB13BC423AEC9DF0066A6F3 /* TestUtils */, 5F5A534D1ADE670C00F81DF0 /* Products */, 5F9961041AE0CF4F0034F503 /* Shared */, 82E79B6D15A982EAE7B0E31B /* GoogleService-Info.plist */, - 8DC73D882D41AE7E0092B6EE /* Frameworks */, 0738A48A2E8F2BB900680EC4 /* NotificationServiceExtension */, ); sourceTree = ""; @@ -135,13 +205,49 @@ 5F5A534D1ADE670C00F81DF0 /* Products */ = { isa = PBXGroup; children = ( - 5F5A53791ADE67D500F81DF0 /* MessagingExample.app */, - 107347A820315A3A004A66D1 /* MessagingExampleUITests.xctest */, + 5F5A534C1ADE670C00F81DF0 /* MessagingExample.app */, + 5F5A53791ADE67D500F81DF0 /* MessagingExampleSwift.app */, + 5FDE05581B0DAA090037B82F /* MessagingExampleTests.xctest */, + 107347A820315A3A004A66D1 /* MessagingExampleSwiftUITests.xctest */, + 1073485E20333BF5004A66D1 /* MessagingExampleUITests.xctest */, 0718C8B62E8F256800AA7788 /* NotificationServiceExtension.appex */, ); name = Products; sourceTree = ""; }; + 5F5A534E1ADE670C00F81DF0 /* MessagingExample */ = { + isa = PBXGroup; + children = ( + 32E04E051DD4EBC6007706A0 /* MessagingExample.entitlements */, + 5F5A53531ADE670C00F81DF0 /* AppDelegate.h */, + 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */, + 5F5A53561ADE670C00F81DF0 /* ViewController.h */, + 5F5A53571ADE670C00F81DF0 /* ViewController.m */, + 5F5A534F1ADE670C00F81DF0 /* Supporting Files */, + ); + path = MessagingExample; + sourceTree = ""; + }; + 5F5A534F1ADE670C00F81DF0 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 5F5A53591ADE670C00F81DF0 /* Main.storyboard */, + 5F5A53501ADE670C00F81DF0 /* Info.plist */, + 5F5A53511ADE670C00F81DF0 /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 5F5A537A1ADE67D500F81DF0 /* MessagingExampleSwift */ = { + isa = PBXGroup; + children = ( + 321A2C4E1DD5054B009C10E2 /* MessagingExampleSwift.entitlements */, + 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */, + 5F5A537F1ADE67D500F81DF0 /* ViewController.swift */, + ); + path = MessagingExampleSwift; + sourceTree = ""; + }; 5F9961041AE0CF4F0034F503 /* Shared */ = { isa = PBXGroup; children = ( @@ -152,11 +258,12 @@ path = ../shared; sourceTree = ""; }; - 8DC73D882D41AE7E0092B6EE /* Frameworks */ = { + 5FDE05591B0DAA090037B82F /* MessagingExampleTests */ = { isa = PBXGroup; children = ( + 5FDE055C1B0DAA090037B82F /* AppTests.m */, ); - name = Frameworks; + path = MessagingExampleTests; sourceTree = ""; }; DEB13BC423AEC9DF0066A6F3 /* TestUtils */ = { @@ -172,16 +279,6 @@ path = ../TestUtils; sourceTree = ""; }; - EAE93A8A2E86E465005ABAF0 /* MessagingExample */ = { - isa = PBXGroup; - children = ( - EAE93A8D2E86E558005ABAF0 /* MessagingExample.entitlements */, - 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */, - 5F5A537F1ADE67D500F81DF0 /* ViewController.swift */, - ); - path = MessagingExample; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -202,9 +299,9 @@ productReference = 0718C8B62E8F256800AA7788 /* NotificationServiceExtension.appex */; productType = "com.apple.product-type.app-extension"; }; - 107347A720315A3A004A66D1 /* MessagingExampleUITests */ = { + 107347A720315A3A004A66D1 /* MessagingExampleSwiftUITests */ = { isa = PBXNativeTarget; - buildConfigurationList = 107347AF20315A3A004A66D1 /* Build configuration list for PBXNativeTarget "MessagingExampleUITests" */; + buildConfigurationList = 107347AF20315A3A004A66D1 /* Build configuration list for PBXNativeTarget "MessagingExampleSwiftUITests" */; buildPhases = ( 107347A420315A3A004A66D1 /* Sources */, 107347A520315A3A004A66D1 /* Frameworks */, @@ -215,14 +312,49 @@ dependencies = ( 107347AE20315A3A004A66D1 /* PBXTargetDependency */, ); + name = MessagingExampleSwiftUITests; + productName = MessagingExampleSwiftUITests; + productReference = 107347A820315A3A004A66D1 /* MessagingExampleSwiftUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + 1073485D20333BF5004A66D1 /* MessagingExampleUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1073486520333BF5004A66D1 /* Build configuration list for PBXNativeTarget "MessagingExampleUITests" */; + buildPhases = ( + 1073485A20333BF5004A66D1 /* Sources */, + 1073485B20333BF5004A66D1 /* Frameworks */, + 1073485C20333BF5004A66D1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 1073486420333BF5004A66D1 /* PBXTargetDependency */, + ); name = MessagingExampleUITests; productName = MessagingExampleUITests; - productReference = 107347A820315A3A004A66D1 /* MessagingExampleUITests.xctest */; + productReference = 1073485E20333BF5004A66D1 /* MessagingExampleUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; - 5F5A53781ADE67D500F81DF0 /* MessagingExample */ = { + 5F5A534B1ADE670C00F81DF0 /* MessagingExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5F5A536F1ADE670C00F81DF0 /* Build configuration list for PBXNativeTarget "MessagingExample" */; + buildPhases = ( + 5F5A53481ADE670C00F81DF0 /* Sources */, + 5F5A53491ADE670C00F81DF0 /* Frameworks */, + 5F5A534A1ADE670C00F81DF0 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MessagingExample; + productName = FCM; + productReference = 5F5A534C1ADE670C00F81DF0 /* MessagingExample.app */; + productType = "com.apple.product-type.application"; + }; + 5F5A53781ADE67D500F81DF0 /* MessagingExampleSwift */ = { isa = PBXNativeTarget; - buildConfigurationList = 5F5A53991ADE67D500F81DF0 /* Build configuration list for PBXNativeTarget "MessagingExample" */; + buildConfigurationList = 5F5A53991ADE67D500F81DF0 /* Build configuration list for PBXNativeTarget "MessagingExampleSwift" */; buildPhases = ( 5F5A53751ADE67D500F81DF0 /* Sources */, 5F5A53761ADE67D500F81DF0 /* Frameworks */, @@ -234,20 +366,37 @@ dependencies = ( 0718C8BC2E8F256800AA7788 /* PBXTargetDependency */, ); - name = MessagingExample; + name = MessagingExampleSwift; productName = FCMSwift; - productReference = 5F5A53791ADE67D500F81DF0 /* MessagingExample.app */; + productReference = 5F5A53791ADE67D500F81DF0 /* MessagingExampleSwift.app */; productType = "com.apple.product-type.application"; }; + 5FDE05571B0DAA090037B82F /* MessagingExampleTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5FDE05621B0DAA090037B82F /* Build configuration list for PBXNativeTarget "MessagingExampleTests" */; + buildPhases = ( + 5FDE05541B0DAA090037B82F /* Sources */, + 5FDE05551B0DAA090037B82F /* Frameworks */, + 5FDE05561B0DAA090037B82F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5FDE055F1B0DAA090037B82F /* PBXTargetDependency */, + ); + name = MessagingExampleTests; + productName = FCMTests; + productReference = 5FDE05581B0DAA090037B82F /* MessagingExampleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 5F5A53441ADE670C00F81DF0 /* Project object */ = { isa = PBXProject; attributes = { - BuildIndependentTargetsInParallel = YES; - LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 1610; + LastSwiftUpdateCheck = 1640; + LastUpgradeCheck = 1110; ORGANIZATIONNAME = "Google Inc."; TargetAttributes = { 0718C8B52E8F256800AA7788 = { @@ -260,6 +409,21 @@ ProvisioningStyle = Automatic; TestTargetID = 5F5A53781ADE67D500F81DF0; }; + 1073485D20333BF5004A66D1 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Automatic; + TestTargetID = 5F5A534B1ADE670C00F81DF0; + }; + 5F5A534B1ADE670C00F81DF0 = { + CreatedOnToolsVersion = 6.3; + LastSwiftMigration = 0800; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Push = { + enabled = 1; + }; + }; + }; 5F5A53781ADE67D500F81DF0 = { CreatedOnToolsVersion = 6.3; LastSwiftMigration = 1110; @@ -273,6 +437,11 @@ }; }; }; + 5FDE05571B0DAA090037B82F = { + CreatedOnToolsVersion = 6.3.2; + LastSwiftMigration = 0800; + TestTargetID = 5F5A534B1ADE670C00F81DF0; + }; }; }; buildConfigurationList = 5F5A53471ADE670C00F81DF0 /* Build configuration list for PBXProject "MessagingExample" */; @@ -284,15 +453,15 @@ Base, ); mainGroup = 5F5A53431ADE670C00F81DF0; - packageReferences = ( - 8DC73D872D41ADE00092B6EE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, - ); productRefGroup = 5F5A534D1ADE670C00F81DF0 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - 5F5A53781ADE67D500F81DF0 /* MessagingExample */, - 107347A720315A3A004A66D1 /* MessagingExampleUITests */, + 5F5A534B1ADE670C00F81DF0 /* MessagingExample */, + 5F5A53781ADE67D500F81DF0 /* MessagingExampleSwift */, + 5FDE05571B0DAA090037B82F /* MessagingExampleTests */, + 107347A720315A3A004A66D1 /* MessagingExampleSwiftUITests */, + 1073485D20333BF5004A66D1 /* MessagingExampleUITests */, 0718C8B52E8F256800AA7788 /* NotificationServiceExtension */, ); }; @@ -313,15 +482,40 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 1073485C20333BF5004A66D1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A534A1ADE670C00F81DF0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F99610C1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */, + 5F99610A1AE0CF4F0034F503 /* Images.xcassets in Resources */, + 5F5A535B1ADE670C00F81DF0 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5F5A53771ADE67D500F81DF0 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 5F99610D1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */, + 5F5A539C1ADE69AA00F81DF0 /* Main.storyboard in Resources */, 5F99610B1AE0CF4F0034F503 /* Images.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; + 5FDE05561B0DAA090037B82F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -337,11 +531,33 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 107347AB20315A3A004A66D1 /* MessagingExampleUITests.swift in Sources */, + 107347AB20315A3A004A66D1 /* MessagingExampleSwiftUITests.swift in Sources */, 978E6F2CAAC2AD673D158985 /* GoogleService-Info.plist in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; + 1073485A20333BF5004A66D1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1073486120333BF5004A66D1 /* MessagingExampleUITests.m in Sources */, + DEB13BC923AEC9DF0066A6F3 /* FIREGSignInHelper.m in Sources */, + DEB13BCA23AEC9DF0066A6F3 /* FIREGHelper.m in Sources */, + 9EC3C1193ECE4B761399CA62 /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53481ADE670C00F81DF0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F5A53581ADE670C00F81DF0 /* ViewController.m in Sources */, + 5F5A53551ADE670C00F81DF0 /* AppDelegate.m in Sources */, + 5F5A53521ADE670C00F81DF0 /* main.m in Sources */, + A2448B9D9232B1BAEE1CA86B /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5F5A53751ADE67D500F81DF0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -352,6 +568,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5FDE05541B0DAA090037B82F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5FDE055D1B0DAA090037B82F /* AppTests.m in Sources */, + D5D4832C57250D09E5864463 /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -362,11 +587,32 @@ }; 107347AE20315A3A004A66D1 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 5F5A53781ADE67D500F81DF0 /* MessagingExample */; + target = 5F5A53781ADE67D500F81DF0 /* MessagingExampleSwift */; targetProxy = 107347AD20315A3A004A66D1 /* PBXContainerItemProxy */; }; + 1073486420333BF5004A66D1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5F5A534B1ADE670C00F81DF0 /* MessagingExample */; + targetProxy = 1073486320333BF5004A66D1 /* PBXContainerItemProxy */; + }; + 5FDE055F1B0DAA090037B82F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5F5A534B1ADE670C00F81DF0 /* MessagingExample */; + targetProxy = 5FDE055E1B0DAA090037B82F /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ +/* Begin PBXVariantGroup section */ + 5F5A53591ADE670C00F81DF0 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5F5A535A1ADE670C00F81DF0 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + /* Begin XCBuildConfiguration section */ 0718C8C02E8F256800AA7788 /* Debug */ = { isa = XCBuildConfiguration; @@ -391,11 +637,7 @@ INFOPLIST_KEY_CFBundleDisplayName = NotificationServiceExtension; INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2025 Google Inc. All rights reserved."; IPHONEOS_DEPLOYMENT_TARGET = 18.5; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MARKETING_VERSION = 1.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; @@ -435,11 +677,7 @@ INFOPLIST_KEY_CFBundleDisplayName = NotificationServiceExtension; INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2025 Google Inc. All rights reserved."; IPHONEOS_DEPLOYMENT_TARGET = 18.5; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MARKETING_VERSION = 1.0; MTL_FAST_MATH = YES; @@ -465,20 +703,16 @@ CODE_SIGN_STYLE = Automatic; DEBUG_INFORMATION_FORMAT = dwarf; GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = MessagingExampleUITests/Info.plist; + INFOPLIST_FILE = MessagingExampleSwiftUITests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.MessagingExampleUITests; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.MessagingExampleSwiftUITests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_SWIFT3_OBJC_INFERENCE = Off; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = MessagingExample; + TEST_TARGET_NAME = MessagingExampleSwift; }; name = Debug; }; @@ -495,18 +729,59 @@ COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = MessagingExampleUITests/Info.plist; + INFOPLIST_FILE = MessagingExampleSwiftUITests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.MessagingExampleUITests; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.MessagingExampleSwiftUITests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_SWIFT3_OBJC_INFERENCE = Off; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = MessagingExampleSwift; + }; + name = Release; + }; + 1073486620333BF5004A66D1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = MessagingExampleUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.MessagingExampleUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = MessagingExample; + }; + name = Debug; + }; + 1073486720333BF5004A66D1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = MessagingExampleUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.MessagingExampleUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; TEST_TARGET_NAME = MessagingExample; }; name = Release; @@ -534,7 +809,6 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -545,7 +819,6 @@ ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -593,7 +866,6 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -604,7 +876,6 @@ ENABLE_BITCODE = NO; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -616,27 +887,59 @@ IPHONEOS_DEPLOYMENT_TARGET = 15.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; - 5F5A53951ADE67D500F81DF0 /* Debug */ = { + 5F5A53701ADE670C00F81DF0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CODE_SIGN_ENTITLEMENTS = MessagingExample/MessagingExample.entitlements; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = MessagingExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.MessagingExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + }; + name = Debug; + }; + 5F5A53711ADE670C00F81DF0 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CODE_SIGN_ENTITLEMENTS = MessagingExample/MessagingExample.entitlements; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = MessagingExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.MessagingExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + }; + name = Release; + }; + 5F5A53951ADE67D500F81DF0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CODE_SIGN_ENTITLEMENTS = MessagingExampleSwift/MessagingExampleSwift.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = MessagingExample/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.MessagingExample; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -650,25 +953,52 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; - CODE_SIGN_ENTITLEMENTS = MessagingExample/MessagingExample.entitlements; + CODE_SIGN_ENTITLEMENTS = MessagingExampleSwift/MessagingExampleSwift.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = MessagingExample/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.MessagingExample; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_SWIFT3_OBJC_INFERENCE = Off; SWIFT_VERSION = 5.0; }; name = Release; }; + 5FDE05601B0DAA090037B82F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = MessagingExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.MessagingExampleTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MessagingExample.app/MessagingExample"; + }; + name = Debug; + }; + 5FDE05611B0DAA090037B82F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + INFOPLIST_FILE = MessagingExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.MessagingExampleTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MessagingExample.app/MessagingExample"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -681,7 +1011,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 107347AF20315A3A004A66D1 /* Build configuration list for PBXNativeTarget "MessagingExampleUITests" */ = { + 107347AF20315A3A004A66D1 /* Build configuration list for PBXNativeTarget "MessagingExampleSwiftUITests" */ = { isa = XCConfigurationList; buildConfigurations = ( 107347B020315A3A004A66D1 /* Debug */, @@ -690,6 +1020,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 1073486520333BF5004A66D1 /* Build configuration list for PBXNativeTarget "MessagingExampleUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1073486620333BF5004A66D1 /* Debug */, + 1073486720333BF5004A66D1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 5F5A53471ADE670C00F81DF0 /* Build configuration list for PBXProject "MessagingExample" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -699,7 +1038,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 5F5A53991ADE67D500F81DF0 /* Build configuration list for PBXNativeTarget "MessagingExample" */ = { + 5F5A536F1ADE670C00F81DF0 /* Build configuration list for PBXNativeTarget "MessagingExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5F5A53701ADE670C00F81DF0 /* Debug */, + 5F5A53711ADE670C00F81DF0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5F5A53991ADE67D500F81DF0 /* Build configuration list for PBXNativeTarget "MessagingExampleSwift" */ = { isa = XCConfigurationList; buildConfigurations = ( 5F5A53951ADE67D500F81DF0 /* Debug */, @@ -708,31 +1056,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; -/* End XCConfigurationList section */ - -/* Begin XCRemoteSwiftPackageReference section */ - 8DC73D872D41ADE00092B6EE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/firebase/firebase-ios-sdk"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 11.7.0; - }; + 5FDE05621B0DAA090037B82F /* Build configuration list for PBXNativeTarget "MessagingExampleTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5FDE05601B0DAA090037B82F /* Debug */, + 5FDE05611B0DAA090037B82F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 8DC73D8B2D41AE850092B6EE /* FirebaseMessaging */ = { - isa = XCSwiftPackageProductDependency; - package = 8DC73D872D41ADE00092B6EE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = FirebaseMessaging; - }; - EAC902A22EC6849A000761B8 /* FirebaseMessaging */ = { - isa = XCSwiftPackageProductDependency; - package = 8DC73D872D41ADE00092B6EE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = FirebaseMessaging; - }; -/* End XCSwiftPackageProductDependency section */ +/* End XCConfigurationList section */ }; rootObject = 5F5A53441ADE670C00F81DF0 /* Project object */; } diff --git a/messaging/MessagingExample.xcodeproj/xcshareddata/xcschemes/MessagingExample.xcscheme b/messaging/MessagingExample.xcodeproj/xcshareddata/xcschemes/MessagingExample.xcscheme index d27c3d855..420372136 100644 --- a/messaging/MessagingExample.xcodeproj/xcshareddata/xcschemes/MessagingExample.xcscheme +++ b/messaging/MessagingExample.xcodeproj/xcshareddata/xcschemes/MessagingExample.xcscheme @@ -1,6 +1,6 @@ @@ -30,7 +30,7 @@ @@ -41,7 +41,17 @@ skipped = "NO"> + + + + @@ -63,7 +73,7 @@ runnableDebuggingMode = "0"> @@ -86,15 +96,16 @@ savedToolIdentifier = "" useCustomWorkingDirectory = "NO" debugDocumentVersioning = "YES"> - + - + diff --git a/messaging/MessagingExample.xcodeproj/xcshareddata/xcschemes/MessagingExampleSwift.xcscheme b/messaging/MessagingExample.xcodeproj/xcshareddata/xcschemes/MessagingExampleSwift.xcscheme new file mode 100644 index 000000000..416e80f04 --- /dev/null +++ b/messaging/MessagingExample.xcodeproj/xcshareddata/xcschemes/MessagingExampleSwift.xcscheme @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/messaging/MessagingExample/.clang-format b/messaging/MessagingExample/.clang-format new file mode 100644 index 000000000..1f09ce0f2 --- /dev/null +++ b/messaging/MessagingExample/.clang-format @@ -0,0 +1,4 @@ +BasedOnStyle: Google +ColumnLimit: 100 +BinPackParameters: false +AllowAllParametersOfDeclarationOnNextLine: true diff --git a/messaging/MessagingExample/AppDelegate.h b/messaging/MessagingExample/AppDelegate.h new file mode 100644 index 000000000..1ddee9ce4 --- /dev/null +++ b/messaging/MessagingExample/AppDelegate.h @@ -0,0 +1,25 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import UIKit; + +@protocol FIRMessagingDelegate; + +@interface AppDelegate : UIResponder + +@property(nonatomic, strong) UIWindow *window; + +@end diff --git a/messaging/MessagingExample/AppDelegate.m b/messaging/MessagingExample/AppDelegate.m new file mode 100644 index 000000000..4d6bd89fd --- /dev/null +++ b/messaging/MessagingExample/AppDelegate.m @@ -0,0 +1,181 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "AppDelegate.h" + +@import UserNotifications; +@import FirebaseCore; +@import FirebaseMessaging; + +// Implement UNUserNotificationCenterDelegate to receive display notification via APNS for devices +// running iOS 10 and above. +@interface AppDelegate () +@end + +@implementation AppDelegate + +NSString *const kGCMMessageIDKey = @"gcm.message_id"; + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // [START configure_firebase] + [FIRApp configure]; + // [END configure_firebase] + + // [START set_messaging_delegate] + [FIRMessaging messaging].delegate = self; + // [END set_messaging_delegate] + + // Register for remote notifications. This shows a permission dialog on first run, to + // show the dialog at a more appropriate time move this registration accordingly. + // [START register_for_notifications] + + [UNUserNotificationCenter currentNotificationCenter].delegate = self; + UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert | + UNAuthorizationOptionSound | UNAuthorizationOptionBadge; + [[UNUserNotificationCenter currentNotificationCenter] + requestAuthorizationWithOptions:authOptions + completionHandler:^(BOOL granted, NSError * _Nullable error) { + // ... + }]; + + [application registerForRemoteNotifications]; + // [END register_for_notifications] + + return YES; +} + +- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { + // If you are receiving a notification message while your app is in the background, + // this callback will not be fired till the user taps on the notification launching the application. + // TODO: Handle data of notification + + // With swizzling disabled you must let Messaging know about the message, for Analytics + // [[FIRMessaging messaging] appDidReceiveMessage:userInfo]; + + // [START_EXCLUDE] + // Print message ID. + if (userInfo[kGCMMessageIDKey]) { + NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]); + } + // [END_EXCLUDE] + + // Print full message. + NSLog(@"%@", userInfo); +} + +// [START receive_message] +- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo + fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { + // If you are receiving a notification message while your app is in the background, + // this callback will not be fired till the user taps on the notification launching the application. + // TODO: Handle data of notification + + // With swizzling disabled you must let Messaging know about the message, for Analytics + // [[FIRMessaging messaging] appDidReceiveMessage:userInfo]; + + // [START_EXCLUDE] + // Print message ID. + if (userInfo[kGCMMessageIDKey]) { + NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]); + } + // [END_EXCLUDE] + + // Print full message. + NSLog(@"%@", userInfo); + + completionHandler(UIBackgroundFetchResultNewData); +} +// [END receive_message] + +// [START ios_10_message_handling] +// Receive displayed notifications for iOS 10 devices. +// Handle incoming notification messages while app is in the foreground. +- (void)userNotificationCenter:(UNUserNotificationCenter *)center + willPresentNotification:(UNNotification *)notification + withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler { + NSDictionary *userInfo = notification.request.content.userInfo; + + // With swizzling disabled you must let Messaging know about the message, for Analytics + // [[FIRMessaging messaging] appDidReceiveMessage:userInfo]; + + // [START_EXCLUDE] + // Print message ID. + if (userInfo[kGCMMessageIDKey]) { + NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]); + } + // [END_EXCLUDE] + + // Print full message. + NSLog(@"%@", userInfo); + + // Change this to your preferred presentation option + // Note: UNNotificationPresentationOptionAlert has been deprecated. + if (@available(iOS 14.0, *)) { + completionHandler(UNNotificationPresentationOptionList | + UNNotificationPresentationOptionBanner | + UNNotificationPresentationOptionSound); + } else { + completionHandler(UNNotificationPresentationOptionAlert | + UNNotificationPresentationOptionSound); + } +} + +// Handle notification messages after display notification is tapped by the user. +- (void)userNotificationCenter:(UNUserNotificationCenter *)center +didReceiveNotificationResponse:(UNNotificationResponse *)response + withCompletionHandler:(void(^)(void))completionHandler { + NSDictionary *userInfo = response.notification.request.content.userInfo; + if (userInfo[kGCMMessageIDKey]) { + NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]); + } + + // With swizzling disabled you must let Messaging know about the message, for Analytics + // [[FIRMessaging messaging] appDidReceiveMessage:userInfo]; + + // Print full message. + NSLog(@"%@", userInfo); + + completionHandler(); +} + +// [END ios_10_message_handling] + +// [START refresh_token] +- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken { + NSLog(@"FCM registration token: %@", fcmToken); + // Notify about received token. + NSDictionary *dataDict = [NSDictionary dictionaryWithObject:fcmToken forKey:@"token"]; + [[NSNotificationCenter defaultCenter] postNotificationName: + @"FCMToken" object:nil userInfo:dataDict]; + // TODO: If necessary send token to application server. + // Note: This callback is fired at each app startup and whenever a new token is generated. +} +// [END refresh_token] + +- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { + NSLog(@"Unable to register for remote notifications: %@", error); +} + +// This function is added here only for debugging purposes, and can be removed if swizzling is enabled. +// If swizzling is disabled then this function must be implemented so that the APNs device token can be paired to +// the FCM registration token. +- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { + NSLog(@"APNs device token retrieved: %@", deviceToken); + + // With swizzling disabled you must set the APNs device token here. + // [FIRMessaging messaging].APNSToken = deviceToken; +} +@end diff --git a/messaging/MessagingExample/Base.lproj/Main.storyboard b/messaging/MessagingExample/Base.lproj/Main.storyboard new file mode 100644 index 000000000..5734736de --- /dev/null +++ b/messaging/MessagingExample/Base.lproj/Main.storyboard @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/messaging/MessagingExample/ViewController.h b/messaging/MessagingExample/ViewController.h new file mode 100644 index 000000000..b4989ec5f --- /dev/null +++ b/messaging/MessagingExample/ViewController.h @@ -0,0 +1,22 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import UIKit; + +@interface ViewController : UIViewController +@property (weak, nonatomic) IBOutlet UILabel *fcmTokenMessage; +@property (weak, nonatomic) IBOutlet UILabel *remoteFCMTokenMessage; +@end diff --git a/messaging/MessagingExample/ViewController.m b/messaging/MessagingExample/ViewController.m new file mode 100644 index 000000000..b1a1c479d --- /dev/null +++ b/messaging/MessagingExample/ViewController.m @@ -0,0 +1,67 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "ViewController.h" +@import FirebaseMessaging; + +@implementation ViewController + +-(void)viewDidLoad { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(displayFCMToken:) + name:@"FCMToken" + object:nil]; +} + +- (IBAction)handleLogTokenTouch:(id)sender { + // [START log_fcm_reg_token] + NSString *fcmToken = [FIRMessaging messaging].FCMToken; + NSLog(@"Local FCM registration token: %@", fcmToken); + // [END log_fcm_reg_token] + + NSString* displayToken = [NSString stringWithFormat:@"Logged FCM token: %@", fcmToken]; + self.fcmTokenMessage.text = displayToken; + + // [START log_iid_reg_token] + [[FIRMessaging messaging] tokenWithCompletion:^(NSString * _Nullable token, NSError * _Nullable error) { + if (error != nil) { + NSLog(@"Error fetching the remote FCM registration token: %@", error); + } else { + NSLog(@"Remote FCM registration token: %@", token); + NSString* message = + [NSString stringWithFormat:@"FCM registration token: %@", token]; + self.remoteFCMTokenMessage.text = message; + } + }]; + // [END log_iid_reg_token] +} + +- (IBAction)handleSubscribeTouch:(id)sender { + // [START subscribe_topic] + [[FIRMessaging messaging] subscribeToTopic:@"weather" + completion:^(NSError * _Nullable error) { + NSLog(@"Subscribed to weather topic"); + }]; + // [END subscribe_topic] +} + +- (void) displayFCMToken:(NSNotification *) notification { + NSString* message = + [NSString stringWithFormat:@"Received FCM token: %@", notification.userInfo[@"token"]]; + self.fcmTokenMessage.text = message; +} + +@end diff --git a/messaging/MessagingExample/main.m b/messaging/MessagingExample/main.m new file mode 100644 index 000000000..bc10c3ac6 --- /dev/null +++ b/messaging/MessagingExample/main.m @@ -0,0 +1,24 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/messaging/MessagingExample/AppDelegate.swift b/messaging/MessagingExampleSwift/AppDelegate.swift similarity index 100% rename from messaging/MessagingExample/AppDelegate.swift rename to messaging/MessagingExampleSwift/AppDelegate.swift diff --git a/messaging/MessagingExampleSwift/MessagingExampleSwift.entitlements b/messaging/MessagingExampleSwift/MessagingExampleSwift.entitlements new file mode 100644 index 000000000..903def2af --- /dev/null +++ b/messaging/MessagingExampleSwift/MessagingExampleSwift.entitlements @@ -0,0 +1,8 @@ + + + + + aps-environment + development + + diff --git a/messaging/MessagingExample/ViewController.swift b/messaging/MessagingExampleSwift/ViewController.swift similarity index 100% rename from messaging/MessagingExample/ViewController.swift rename to messaging/MessagingExampleSwift/ViewController.swift diff --git a/messaging/MessagingExampleSwiftUITests/Info.plist b/messaging/MessagingExampleSwiftUITests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/messaging/MessagingExampleSwiftUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/messaging/MessagingExampleUITests/MessagingExampleUITests.swift b/messaging/MessagingExampleSwiftUITests/MessagingExampleSwiftUITests.swift similarity index 96% rename from messaging/MessagingExampleUITests/MessagingExampleUITests.swift rename to messaging/MessagingExampleSwiftUITests/MessagingExampleSwiftUITests.swift index cc67f7cc2..6063385b3 100644 --- a/messaging/MessagingExampleUITests/MessagingExampleUITests.swift +++ b/messaging/MessagingExampleSwiftUITests/MessagingExampleSwiftUITests.swift @@ -15,7 +15,7 @@ import XCTest -class MessagingExampleUITests: XCTestCase { +class MessagingExampleSwiftUITests: XCTestCase { override func setUp() { super.setUp() diff --git a/messaging/MessagingExampleTests/AppTests.m b/messaging/MessagingExampleTests/AppTests.m new file mode 100644 index 000000000..4ee604cc6 --- /dev/null +++ b/messaging/MessagingExampleTests/AppTests.m @@ -0,0 +1,40 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +@interface AppTests : XCTestCase +@end + +@implementation AppTests + +- (void)setUp { + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample { + // This is an example of a functional test case. + XCTAssert(YES, @"Pass"); +} + +@end diff --git a/messaging/MessagingExampleUITests/MessagingExampleUITests.m b/messaging/MessagingExampleUITests/MessagingExampleUITests.m new file mode 100644 index 000000000..51129a28b --- /dev/null +++ b/messaging/MessagingExampleUITests/MessagingExampleUITests.m @@ -0,0 +1,66 @@ +// Copyright (c) 2019 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import "FIREGHelper.h" + +typedef BOOL (^SystemAlertHandler)(XCUIElement *); +static SystemAlertHandler const alertHandler = ^(XCUIElement *element) { + if (element.buttons[@"OK"].exists) { + [element.buttons[@"OK"] tap]; + } + if (element.buttons[@"Allow"].exists) { + [element.buttons[@"Allow"] tap]; + } + return YES; +}; + +static NSString *const subscribeButton = @"Subscribe To Weather"; +static NSString *const logButton = @"Log Token"; + +@interface MessagingExampleUITests : XCTestCase +@end + +@implementation MessagingExampleUITests { + XCUIApplication *_app; + id notificationPermissionMonitor; +} + +- (void)setUp { + [super setUp]; + _app = [[XCUIApplication alloc] init]; + notificationPermissionMonitor = + [self addUIInterruptionMonitorWithDescription:@"Allow Notifications" handler:alertHandler]; + [_app launch]; +} + +- (void)tearDown { + [self removeUIInterruptionMonitor:notificationPermissionMonitor]; + [super tearDown]; +} + +- (void)testVerifyAppLaunched { + FIRWaitTillAlertPresent(defaultTimeout); + // Remove the permission request and make sure it's gone. + [[[_app navigationBars] element] tap]; + FIRWaitTillAlertGone(defaultTimeout); + + // Verify that Messaging Example app launched successfully and its title is visible. + XCTAssertTrue(_app.buttons[subscribeButton].exists); + +} + +@end diff --git a/messaging/Podfile b/messaging/Podfile new file mode 100644 index 000000000..c512e85d2 --- /dev/null +++ b/messaging/Podfile @@ -0,0 +1,22 @@ +# Firebase Cloud Messaging (FCM) + +use_frameworks! +platform :ios, '15.0' + +def firebase_pods + pod 'FirebaseAnalytics' + pod 'FirebaseMessaging' +end + +target 'MessagingExample' do + firebase_pods +end +target 'MessagingExampleSwift' do + firebase_pods +end +target 'NotificationServiceExtension' do + firebase_pods +end + +target 'MessagingExampleTests' do +end diff --git a/messaging/Podfile.lock b/messaging/Podfile.lock new file mode 100644 index 000000000..25438d9cf --- /dev/null +++ b/messaging/Podfile.lock @@ -0,0 +1,137 @@ +PODS: + - FirebaseAnalytics (12.6.0): + - FirebaseAnalytics/Default (= 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseAnalytics/Default (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleAppMeasurement/Default (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseCore (12.6.0): + - FirebaseCoreInternal (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreInternal (12.6.0): + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseInstallations (12.6.0): + - FirebaseCore (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - PromisesObjC (~> 2.4) + - FirebaseMessaging (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleDataTransport (~> 10.1) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Reachability (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - nanopb (~> 3.30910.0) + - GoogleAdsOnDeviceConversion (3.2.0): + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Core (12.6.0): + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Default (12.6.0): + - GoogleAdsOnDeviceConversion (~> 3.2.0) + - GoogleAppMeasurement/Core (= 12.6.0) + - GoogleAppMeasurement/IdentitySupport (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/IdentitySupport (12.6.0): + - GoogleAppMeasurement/Core (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleDataTransport (10.1.0): + - nanopb (~> 3.30910.0) + - PromisesObjC (~> 2.4) + - GoogleUtilities/AppDelegateSwizzler (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Privacy + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - GoogleUtilities/MethodSwizzler (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/Network (8.1.0): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Privacy + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (8.1.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/Reachability (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/UserDefaults (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - nanopb (3.30910.0): + - nanopb/decode (= 3.30910.0) + - nanopb/encode (= 3.30910.0) + - nanopb/decode (3.30910.0) + - nanopb/encode (3.30910.0) + - PromisesObjC (2.4.0) + +DEPENDENCIES: + - FirebaseAnalytics + - FirebaseMessaging + +SPEC REPOS: + trunk: + - FirebaseAnalytics + - FirebaseCore + - FirebaseCoreInternal + - FirebaseInstallations + - FirebaseMessaging + - GoogleAdsOnDeviceConversion + - GoogleAppMeasurement + - GoogleDataTransport + - GoogleUtilities + - nanopb + - PromisesObjC + +SPEC CHECKSUMS: + FirebaseAnalytics: d0a97a0db6425e5a5d966340b87f92ca7b13a557 + FirebaseCore: 0e38ad5d62d980a47a64b8e9301ffa311457be04 + FirebaseCoreInternal: 69bf1306a05b8ac43004f6cc1f804bb7b05b229e + FirebaseInstallations: 631b38da2e11a83daa4bfb482f79d286a5dfa7ad + FirebaseMessaging: a61bc42dcab3f7a346d94bbb54dab2c9435b18b2 + GoogleAdsOnDeviceConversion: d68c69dd9581a0f5da02617b6f377e5be483970f + GoogleAppMeasurement: 3bf40aff49a601af5da1c3345702fcb4991d35ee + GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + +PODFILE CHECKSUM: 658e9eb16fd44328e82e0d8dbc800466786e184c + +COCOAPODS: 1.16.2 diff --git a/performance/PerformanceExample.xcodeproj/project.pbxproj b/performance/PerformanceExample.xcodeproj/project.pbxproj index 67b518825..68fb35981 100644 --- a/performance/PerformanceExample.xcodeproj/project.pbxproj +++ b/performance/PerformanceExample.xcodeproj/project.pbxproj @@ -3,18 +3,28 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ - 107347C720315A61004A66D1 /* PerformanceExampleUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 107347C620315A61004A66D1 /* PerformanceExampleUITests.swift */; }; + 107347C720315A61004A66D1 /* PerformanceExampleSwiftUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 107347C620315A61004A66D1 /* PerformanceExampleSwiftUITests.swift */; }; + 1073486F20333C0C004A66D1 /* PerformanceExampleUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1073486E20333C0C004A66D1 /* PerformanceExampleUITests.m */; }; 3AC4EE8864CD2D8B6ADE0A2D /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 664D51F1D2849F1D6A5F39A3 /* GoogleService-Info.plist */; }; + 5F5A53521ADE670C00F81DF0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53511ADE670C00F81DF0 /* main.m */; }; + 5F5A53551ADE670C00F81DF0 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */; }; + 5F5A53581ADE670C00F81DF0 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53571ADE670C00F81DF0 /* ViewController.m */; }; + 5F5A535B1ADE670C00F81DF0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5F5A53591ADE670C00F81DF0 /* Main.storyboard */; }; 5F5A537E1ADE67D500F81DF0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */; }; 5F5A53801ADE67D500F81DF0 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A537F1ADE67D500F81DF0 /* ViewController.swift */; }; + 5F5A539C1ADE69AA00F81DF0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5F5A53591ADE670C00F81DF0 /* Main.storyboard */; }; + 5F99610A1AE0CF4F0034F503 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961061AE0CF4F0034F503 /* Images.xcassets */; }; 5F99610B1AE0CF4F0034F503 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961061AE0CF4F0034F503 /* Images.xcassets */; }; + 5F99610C1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */; }; 5F99610D1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */; }; - 8DC73D942D41B04B0092B6EE /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 8DC73D932D41B04B0092B6EE /* FirebaseAnalytics */; }; - 8DC73D962D41B04B0092B6EE /* FirebasePerformance in Frameworks */ = {isa = PBXBuildFile; productRef = 8DC73D952D41B04B0092B6EE /* FirebasePerformance */; }; + 5FDE055D1B0DAA090037B82F /* AppTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FDE055C1B0DAA090037B82F /* AppTests.m */; }; + 72597C97199D485A8666B65A /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 664D51F1D2849F1D6A5F39A3 /* GoogleService-Info.plist */; }; + 7FBD5A73CBE80CA855DA8E22 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 664D51F1D2849F1D6A5F39A3 /* GoogleService-Info.plist */; }; + A4ADF9F8B0B185014DA28C21 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 664D51F1D2849F1D6A5F39A3 /* GoogleService-Info.plist */; }; B3E22BC95F7192FC5242CC68 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 664D51F1D2849F1D6A5F39A3 /* GoogleService-Info.plist */; }; /* End PBXBuildFile section */ @@ -24,19 +34,46 @@ containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; proxyType = 1; remoteGlobalIDString = 5F5A53781ADE67D500F81DF0; + remoteInfo = PerformanceExampleSwift; + }; + 1073487120333C0C004A66D1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5F5A534B1ADE670C00F81DF0; + remoteInfo = PerformanceExample; + }; + 5FDE055E1B0DAA090037B82F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5F5A534B1ADE670C00F81DF0; remoteInfo = PerformanceExample; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 107347C420315A61004A66D1 /* PerformanceExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PerformanceExampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 107347C620315A61004A66D1 /* PerformanceExampleUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PerformanceExampleUITests.swift; sourceTree = ""; }; + 107347C420315A61004A66D1 /* PerformanceExampleSwiftUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PerformanceExampleSwiftUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 107347C620315A61004A66D1 /* PerformanceExampleSwiftUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PerformanceExampleSwiftUITests.swift; sourceTree = ""; }; 107347C820315A61004A66D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 5F5A53791ADE67D500F81DF0 /* PerformanceExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PerformanceExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1073486C20333C0C004A66D1 /* PerformanceExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PerformanceExampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 1073486E20333C0C004A66D1 /* PerformanceExampleUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PerformanceExampleUITests.m; sourceTree = ""; }; + 1073487020333C0C004A66D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5F5A534C1ADE670C00F81DF0 /* PerformanceExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PerformanceExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5F5A53501ADE670C00F81DF0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5F5A53511ADE670C00F81DF0 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 5F5A53531ADE670C00F81DF0 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 5F5A53561ADE670C00F81DF0 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + 5F5A53571ADE670C00F81DF0 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 5F5A535A1ADE670C00F81DF0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 5F5A53791ADE67D500F81DF0 /* PerformanceExampleSwift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PerformanceExampleSwift.app; sourceTree = BUILT_PRODUCTS_DIR; }; 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 5F5A537F1ADE67D500F81DF0 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 5F9961061AE0CF4F0034F503 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LaunchScreen.xib; sourceTree = ""; }; + 5FDE05581B0DAA090037B82F /* PerformanceExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PerformanceExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5FDE055C1B0DAA090037B82F /* AppTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppTests.m; sourceTree = ""; }; 664D51F1D2849F1D6A5F39A3 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -48,36 +85,66 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 1073486920333C0C004A66D1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53491ADE670C00F81DF0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5F5A53761ADE67D500F81DF0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8DC73D962D41B04B0092B6EE /* FirebasePerformance in Frameworks */, - 8DC73D942D41B04B0092B6EE /* FirebaseAnalytics in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FDE05551B0DAA090037B82F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 107347C520315A61004A66D1 /* PerformanceExampleUITests */ = { + 107347C520315A61004A66D1 /* PerformanceExampleSwiftUITests */ = { isa = PBXGroup; children = ( - 107347C620315A61004A66D1 /* PerformanceExampleUITests.swift */, + 107347C620315A61004A66D1 /* PerformanceExampleSwiftUITests.swift */, 107347C820315A61004A66D1 /* Info.plist */, ); + path = PerformanceExampleSwiftUITests; + sourceTree = ""; + }; + 1073486D20333C0C004A66D1 /* PerformanceExampleUITests */ = { + isa = PBXGroup; + children = ( + 1073486E20333C0C004A66D1 /* PerformanceExampleUITests.m */, + 1073487020333C0C004A66D1 /* Info.plist */, + ); path = PerformanceExampleUITests; sourceTree = ""; }; 5F5A53431ADE670C00F81DF0 = { isa = PBXGroup; children = ( - 5F5A537A1ADE67D500F81DF0 /* PerformanceExample */, - 107347C520315A61004A66D1 /* PerformanceExampleUITests */, + 5F5A534E1ADE670C00F81DF0 /* PerformanceExample */, + 5F5A537A1ADE67D500F81DF0 /* PerformanceExampleSwift */, + 5FDE05591B0DAA090037B82F /* PerformanceExampleTests */, + 107347C520315A61004A66D1 /* PerformanceExampleSwiftUITests */, + 1073486D20333C0C004A66D1 /* PerformanceExampleUITests */, 5F5A534D1ADE670C00F81DF0 /* Products */, 5F9961041AE0CF4F0034F503 /* Shared */, 664D51F1D2849F1D6A5F39A3 /* GoogleService-Info.plist */, - 8DC73D8E2D41B0430092B6EE /* Frameworks */, ); sourceTree = ""; wrapsLines = 0; @@ -85,19 +152,44 @@ 5F5A534D1ADE670C00F81DF0 /* Products */ = { isa = PBXGroup; children = ( - 5F5A53791ADE67D500F81DF0 /* PerformanceExample.app */, - 107347C420315A61004A66D1 /* PerformanceExampleUITests.xctest */, + 5F5A534C1ADE670C00F81DF0 /* PerformanceExample.app */, + 5F5A53791ADE67D500F81DF0 /* PerformanceExampleSwift.app */, + 5FDE05581B0DAA090037B82F /* PerformanceExampleTests.xctest */, + 107347C420315A61004A66D1 /* PerformanceExampleSwiftUITests.xctest */, + 1073486C20333C0C004A66D1 /* PerformanceExampleUITests.xctest */, ); name = Products; sourceTree = ""; }; - 5F5A537A1ADE67D500F81DF0 /* PerformanceExample */ = { + 5F5A534E1ADE670C00F81DF0 /* PerformanceExample */ = { + isa = PBXGroup; + children = ( + 5F5A53531ADE670C00F81DF0 /* AppDelegate.h */, + 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */, + 5F5A53561ADE670C00F81DF0 /* ViewController.h */, + 5F5A53571ADE670C00F81DF0 /* ViewController.m */, + 5F5A534F1ADE670C00F81DF0 /* Supporting Files */, + ); + path = PerformanceExample; + sourceTree = ""; + }; + 5F5A534F1ADE670C00F81DF0 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 5F5A53591ADE670C00F81DF0 /* Main.storyboard */, + 5F5A53501ADE670C00F81DF0 /* Info.plist */, + 5F5A53511ADE670C00F81DF0 /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 5F5A537A1ADE67D500F81DF0 /* PerformanceExampleSwift */ = { isa = PBXGroup; children = ( 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */, 5F5A537F1ADE67D500F81DF0 /* ViewController.swift */, ); - path = PerformanceExample; + path = PerformanceExampleSwift; sourceTree = ""; }; 5F9961041AE0CF4F0034F503 /* Shared */ = { @@ -110,19 +202,20 @@ path = ../shared; sourceTree = ""; }; - 8DC73D8E2D41B0430092B6EE /* Frameworks */ = { + 5FDE05591B0DAA090037B82F /* PerformanceExampleTests */ = { isa = PBXGroup; children = ( + 5FDE055C1B0DAA090037B82F /* AppTests.m */, ); - name = Frameworks; + path = PerformanceExampleTests; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 107347C320315A61004A66D1 /* PerformanceExampleUITests */ = { + 107347C320315A61004A66D1 /* PerformanceExampleSwiftUITests */ = { isa = PBXNativeTarget; - buildConfigurationList = 107347CB20315A61004A66D1 /* Build configuration list for PBXNativeTarget "PerformanceExampleUITests" */; + buildConfigurationList = 107347CB20315A61004A66D1 /* Build configuration list for PBXNativeTarget "PerformanceExampleSwiftUITests" */; buildPhases = ( 107347C020315A61004A66D1 /* Sources */, 107347C120315A61004A66D1 /* Frameworks */, @@ -133,14 +226,49 @@ dependencies = ( 107347CA20315A61004A66D1 /* PBXTargetDependency */, ); + name = PerformanceExampleSwiftUITests; + productName = PerformanceExampleSwiftUITests; + productReference = 107347C420315A61004A66D1 /* PerformanceExampleSwiftUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + 1073486B20333C0C004A66D1 /* PerformanceExampleUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1073487320333C0C004A66D1 /* Build configuration list for PBXNativeTarget "PerformanceExampleUITests" */; + buildPhases = ( + 1073486820333C0C004A66D1 /* Sources */, + 1073486920333C0C004A66D1 /* Frameworks */, + 1073486A20333C0C004A66D1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 1073487220333C0C004A66D1 /* PBXTargetDependency */, + ); name = PerformanceExampleUITests; productName = PerformanceExampleUITests; - productReference = 107347C420315A61004A66D1 /* PerformanceExampleUITests.xctest */; + productReference = 1073486C20333C0C004A66D1 /* PerformanceExampleUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; - 5F5A53781ADE67D500F81DF0 /* PerformanceExample */ = { + 5F5A534B1ADE670C00F81DF0 /* PerformanceExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5F5A536F1ADE670C00F81DF0 /* Build configuration list for PBXNativeTarget "PerformanceExample" */; + buildPhases = ( + 5F5A53481ADE670C00F81DF0 /* Sources */, + 5F5A53491ADE670C00F81DF0 /* Frameworks */, + 5F5A534A1ADE670C00F81DF0 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = PerformanceExample; + productName = PerformanceExample; + productReference = 5F5A534C1ADE670C00F81DF0 /* PerformanceExample.app */; + productType = "com.apple.product-type.application"; + }; + 5F5A53781ADE67D500F81DF0 /* PerformanceExampleSwift */ = { isa = PBXNativeTarget; - buildConfigurationList = 5F5A53991ADE67D500F81DF0 /* Build configuration list for PBXNativeTarget "PerformanceExample" */; + buildConfigurationList = 5F5A53991ADE67D500F81DF0 /* Build configuration list for PBXNativeTarget "PerformanceExampleSwift" */; buildPhases = ( 5F5A53751ADE67D500F81DF0 /* Sources */, 5F5A53761ADE67D500F81DF0 /* Frameworks */, @@ -150,20 +278,37 @@ ); dependencies = ( ); - name = PerformanceExample; - productName = PerformanceExample; - productReference = 5F5A53791ADE67D500F81DF0 /* PerformanceExample.app */; + name = PerformanceExampleSwift; + productName = PerformanceExampleSwift; + productReference = 5F5A53791ADE67D500F81DF0 /* PerformanceExampleSwift.app */; productType = "com.apple.product-type.application"; }; + 5FDE05571B0DAA090037B82F /* PerformanceExampleTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5FDE05621B0DAA090037B82F /* Build configuration list for PBXNativeTarget "PerformanceExampleTests" */; + buildPhases = ( + 5FDE05541B0DAA090037B82F /* Sources */, + 5FDE05551B0DAA090037B82F /* Frameworks */, + 5FDE05561B0DAA090037B82F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5FDE055F1B0DAA090037B82F /* PBXTargetDependency */, + ); + name = PerformanceExampleTests; + productName = PerformanceExampleTests; + productReference = 5FDE05581B0DAA090037B82F /* PerformanceExampleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 5F5A53441ADE670C00F81DF0 /* Project object */ = { isa = PBXProject; attributes = { - BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 1610; + LastUpgradeCheck = 1110; ORGANIZATIONNAME = "Google Inc."; TargetAttributes = { 107347C320315A61004A66D1 = { @@ -172,11 +317,27 @@ ProvisioningStyle = Automatic; TestTargetID = 5F5A53781ADE67D500F81DF0; }; + 1073486B20333C0C004A66D1 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Automatic; + TestTargetID = 5F5A534B1ADE670C00F81DF0; + }; + 5F5A534B1ADE670C00F81DF0 = { + CreatedOnToolsVersion = 6.3; + LastSwiftMigration = 0800; + ProvisioningStyle = Automatic; + }; 5F5A53781ADE67D500F81DF0 = { CreatedOnToolsVersion = 6.3; LastSwiftMigration = 1110; ProvisioningStyle = Automatic; }; + 5FDE05571B0DAA090037B82F = { + CreatedOnToolsVersion = 6.3.2; + LastSwiftMigration = 0800; + ProvisioningStyle = Automatic; + TestTargetID = 5F5A534B1ADE670C00F81DF0; + }; }; }; buildConfigurationList = 5F5A53471ADE670C00F81DF0 /* Build configuration list for PBXProject "PerformanceExample" */; @@ -188,15 +349,15 @@ Base, ); mainGroup = 5F5A53431ADE670C00F81DF0; - packageReferences = ( - 8DC73D8D2D41B01F0092B6EE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, - ); productRefGroup = 5F5A534D1ADE670C00F81DF0 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - 5F5A53781ADE67D500F81DF0 /* PerformanceExample */, - 107347C320315A61004A66D1 /* PerformanceExampleUITests */, + 5F5A534B1ADE670C00F81DF0 /* PerformanceExample */, + 5F5A53781ADE67D500F81DF0 /* PerformanceExampleSwift */, + 5FDE05571B0DAA090037B82F /* PerformanceExampleTests */, + 107347C320315A61004A66D1 /* PerformanceExampleSwiftUITests */, + 1073486B20333C0C004A66D1 /* PerformanceExampleUITests */, ); }; /* End PBXProject section */ @@ -209,15 +370,40 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 1073486A20333C0C004A66D1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A534A1ADE670C00F81DF0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F99610C1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */, + 5F99610A1AE0CF4F0034F503 /* Images.xcassets in Resources */, + 5F5A535B1ADE670C00F81DF0 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5F5A53771ADE67D500F81DF0 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 5F99610D1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */, + 5F5A539C1ADE69AA00F81DF0 /* Main.storyboard in Resources */, 5F99610B1AE0CF4F0034F503 /* Images.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; + 5FDE05561B0DAA090037B82F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -225,11 +411,31 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 107347C720315A61004A66D1 /* PerformanceExampleUITests.swift in Sources */, + 107347C720315A61004A66D1 /* PerformanceExampleSwiftUITests.swift in Sources */, 3AC4EE8864CD2D8B6ADE0A2D /* GoogleService-Info.plist in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; + 1073486820333C0C004A66D1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1073486F20333C0C004A66D1 /* PerformanceExampleUITests.m in Sources */, + 72597C97199D485A8666B65A /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53481ADE670C00F81DF0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F5A53581ADE670C00F81DF0 /* ViewController.m in Sources */, + 5F5A53551ADE670C00F81DF0 /* AppDelegate.m in Sources */, + 5F5A53521ADE670C00F81DF0 /* main.m in Sources */, + A4ADF9F8B0B185014DA28C21 /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5F5A53751ADE67D500F81DF0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -240,16 +446,46 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5FDE05541B0DAA090037B82F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5FDE055D1B0DAA090037B82F /* AppTests.m in Sources */, + 7FBD5A73CBE80CA855DA8E22 /* GoogleService-Info.plist in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 107347CA20315A61004A66D1 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 5F5A53781ADE67D500F81DF0 /* PerformanceExample */; + target = 5F5A53781ADE67D500F81DF0 /* PerformanceExampleSwift */; targetProxy = 107347C920315A61004A66D1 /* PBXContainerItemProxy */; }; + 1073487220333C0C004A66D1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5F5A534B1ADE670C00F81DF0 /* PerformanceExample */; + targetProxy = 1073487120333C0C004A66D1 /* PBXContainerItemProxy */; + }; + 5FDE055F1B0DAA090037B82F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5F5A534B1ADE670C00F81DF0 /* PerformanceExample */; + targetProxy = 5FDE055E1B0DAA090037B82F /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ +/* Begin PBXVariantGroup section */ + 5F5A53591ADE670C00F81DF0 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5F5A535A1ADE670C00F81DF0 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + /* Begin XCBuildConfiguration section */ 107347CC20315A61004A66D1 /* Debug */ = { isa = XCBuildConfiguration; @@ -263,20 +499,16 @@ CODE_SIGN_STYLE = Automatic; DEBUG_INFORMATION_FORMAT = dwarf; GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = PerformanceExampleUITests/Info.plist; + INFOPLIST_FILE = PerformanceExampleSwiftUITests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.PerformanceExampleUITests; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.PerformanceExampleSwiftUITests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = PerformanceExample; + TEST_TARGET_NAME = PerformanceExampleSwift; }; name = Debug; }; @@ -293,18 +525,59 @@ COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = PerformanceExampleUITests/Info.plist; + INFOPLIST_FILE = PerformanceExampleSwiftUITests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.PerformanceExampleUITests; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.PerformanceExampleSwiftUITests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = PerformanceExampleSwift; + }; + name = Release; + }; + 1073487420333C0C004A66D1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = PerformanceExampleUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.PerformanceExampleUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = PerformanceExample; + }; + name = Debug; + }; + 1073487520333C0C004A66D1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = PerformanceExampleUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.PerformanceExampleUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; TEST_TARGET_NAME = PerformanceExample; }; name = Release; @@ -332,7 +605,6 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -343,7 +615,6 @@ ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -391,7 +662,6 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -402,7 +672,6 @@ ENABLE_BITCODE = NO; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -414,24 +683,53 @@ IPHONEOS_DEPLOYMENT_TARGET = 15.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; + 5F5A53701ADE670C00F81DF0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = "$(SRCROOT)/PerformanceExample/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.PerformanceExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + }; + name = Debug; + }; + 5F5A53711ADE670C00F81DF0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = "$(SRCROOT)/PerformanceExample/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.PerformanceExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + }; + name = Release; + }; 5F5A53951ADE67D500F81DF0 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "$(SRCROOT)/PerformanceExample/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.PerformanceExample; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -445,28 +743,78 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "$(SRCROOT)/PerformanceExample/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.PerformanceExample; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OBJC_BRIDGING_HEADER = ""; - SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; }; name = Release; }; + 5FDE05601B0DAA090037B82F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + PerformanceExample, + ); + INFOPLIST_FILE = PerformanceExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PerformanceExample.app/PerformanceExample"; + }; + name = Debug; + }; + 5FDE05611B0DAA090037B82F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + PerformanceExample, + ); + INFOPLIST_FILE = PerformanceExample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PerformanceExample.app/PerformanceExample"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 107347CB20315A61004A66D1 /* Build configuration list for PBXNativeTarget "PerformanceExampleUITests" */ = { + 107347CB20315A61004A66D1 /* Build configuration list for PBXNativeTarget "PerformanceExampleSwiftUITests" */ = { isa = XCConfigurationList; buildConfigurations = ( 107347CC20315A61004A66D1 /* Debug */, @@ -475,6 +823,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 1073487320333C0C004A66D1 /* Build configuration list for PBXNativeTarget "PerformanceExampleUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1073487420333C0C004A66D1 /* Debug */, + 1073487520333C0C004A66D1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 5F5A53471ADE670C00F81DF0 /* Build configuration list for PBXProject "PerformanceExample" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -484,7 +841,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 5F5A53991ADE67D500F81DF0 /* Build configuration list for PBXNativeTarget "PerformanceExample" */ = { + 5F5A536F1ADE670C00F81DF0 /* Build configuration list for PBXNativeTarget "PerformanceExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5F5A53701ADE670C00F81DF0 /* Debug */, + 5F5A53711ADE670C00F81DF0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5F5A53991ADE67D500F81DF0 /* Build configuration list for PBXNativeTarget "PerformanceExampleSwift" */ = { isa = XCConfigurationList; buildConfigurations = ( 5F5A53951ADE67D500F81DF0 /* Debug */, @@ -493,31 +859,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; -/* End XCConfigurationList section */ - -/* Begin XCRemoteSwiftPackageReference section */ - 8DC73D8D2D41B01F0092B6EE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/firebase/firebase-ios-sdk"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 11.7.0; - }; + 5FDE05621B0DAA090037B82F /* Build configuration list for PBXNativeTarget "PerformanceExampleTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5FDE05601B0DAA090037B82F /* Debug */, + 5FDE05611B0DAA090037B82F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 8DC73D932D41B04B0092B6EE /* FirebaseAnalytics */ = { - isa = XCSwiftPackageProductDependency; - package = 8DC73D8D2D41B01F0092B6EE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = FirebaseAnalytics; - }; - 8DC73D952D41B04B0092B6EE /* FirebasePerformance */ = { - isa = XCSwiftPackageProductDependency; - package = 8DC73D8D2D41B01F0092B6EE /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = FirebasePerformance; - }; -/* End XCSwiftPackageProductDependency section */ +/* End XCConfigurationList section */ }; rootObject = 5F5A53441ADE670C00F81DF0 /* Project object */; } diff --git a/performance/PerformanceExample.xcodeproj/xcshareddata/xcschemes/PerformanceExampleUITests.xcscheme b/performance/PerformanceExample.xcodeproj/xcshareddata/xcschemes/PerformanceExampleUITests.xcscheme deleted file mode 100644 index a7a3ccb40..000000000 --- a/performance/PerformanceExample.xcodeproj/xcshareddata/xcschemes/PerformanceExampleUITests.xcscheme +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/performance/PerformanceExample/.clang-format b/performance/PerformanceExample/.clang-format new file mode 100644 index 000000000..1f09ce0f2 --- /dev/null +++ b/performance/PerformanceExample/.clang-format @@ -0,0 +1,4 @@ +BasedOnStyle: Google +ColumnLimit: 100 +BinPackParameters: false +AllowAllParametersOfDeclarationOnNextLine: true diff --git a/performance/PerformanceExample/AppDelegate.h b/performance/PerformanceExample/AppDelegate.h new file mode 100644 index 000000000..66dc0c1c6 --- /dev/null +++ b/performance/PerformanceExample/AppDelegate.h @@ -0,0 +1,23 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import UIKit; + +@interface AppDelegate : UIResponder + +@property(nonatomic, strong) UIWindow *window; + +@end diff --git a/performance/PerformanceExample/AppDelegate.m b/performance/PerformanceExample/AppDelegate.m new file mode 100644 index 000000000..b7659c4d5 --- /dev/null +++ b/performance/PerformanceExample/AppDelegate.m @@ -0,0 +1,29 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "AppDelegate.h" + +@import FirebaseCore; + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [FIRApp configure]; + return YES; +} + +@end diff --git a/performance/PerformanceExample/Base.lproj/Main.storyboard b/performance/PerformanceExample/Base.lproj/Main.storyboard new file mode 100644 index 000000000..56fb38619 --- /dev/null +++ b/performance/PerformanceExample/Base.lproj/Main.storyboard @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/performance/PerformanceExample/Info.plist b/performance/PerformanceExample/Info.plist index 28c2da91a..30d7c4861 100644 --- a/performance/PerformanceExample/Info.plist +++ b/performance/PerformanceExample/Info.plist @@ -28,6 +28,8 @@ UILaunchStoryboardName LaunchScreen + UIMainStoryboardFile + Main UIRequiredDeviceCapabilities armv7 diff --git a/performance/PerformanceExample/ViewController.h b/performance/PerformanceExample/ViewController.h new file mode 100644 index 000000000..2c7d24b3c --- /dev/null +++ b/performance/PerformanceExample/ViewController.h @@ -0,0 +1,20 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import UIKit; + +@interface ViewController : UIViewController +@end diff --git a/performance/PerformanceExample/ViewController.m b/performance/PerformanceExample/ViewController.m new file mode 100644 index 000000000..3cd8a313c --- /dev/null +++ b/performance/PerformanceExample/ViewController.m @@ -0,0 +1,115 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + + +#import "ViewController.h" + +@import FirebasePerformance; +@import AVFoundation; +@import AVKit; + +@interface ViewController() +@property (strong, nonatomic) IBOutlet UIImageView *imageView; +@end + +@implementation ViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + NSArray *paths = NSSearchPathForDirectoriesInDomains + (NSDocumentDirectory, NSUserDomainMask, YES); + NSString *documentsDirectory = paths[0]; + + //make a file name to write the data to using the documents directory + NSString *fileName = [NSString stringWithFormat:@"%@/perfsamplelog.txt", + documentsDirectory]; + + // Start tracing + FIRTrace *trace = [FIRPerformance startTraceWithName:@"request_trace"]; + + NSError *fileReadError; + NSString *contents = [NSString stringWithContentsOfFile:fileName + encoding:NSUTF8StringEncoding + error:&fileReadError]; + + if (fileReadError != nil) { + NSLog(@"Log file doesn't exist yet %@: %@", fileName, fileReadError); + } + + NSUInteger fileLength = 0; + if (contents) { + fileLength = contents.length; + } + + [trace incrementMetric:@"log_file_size" byInt:fileLength]; + + + NSString *target = @"https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"; + NSURL *targetUrl = [NSURL URLWithString:target]; + FIRHTTPMetric *metric = [[FIRHTTPMetric alloc] initWithURL:targetUrl HTTPMethod:FIRHTTPMethodGET]; + [metric start]; + + NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:targetUrl]; + request.HTTPMethod = @"GET"; + + [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler: + ^(NSData * _Nullable data, + NSURLResponse * _Nullable response, + NSError * _Nullable error) { + if (response) { + NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response; + metric.responseCode = httpResponse.statusCode; + } + [metric stop]; + + if (error) { + NSLog(@"%@", error.localizedDescription); + } + + dispatch_async(dispatch_get_main_queue(), ^{ + self->_imageView.image = [UIImage imageWithData:data]; + }); + + [trace stop]; + + NSString *contentToWrite = [contents stringByAppendingFormat: @"\n%@", response.URL.absoluteString]; + [contentToWrite writeToFile:fileName + atomically:NO + encoding:NSUTF8StringEncoding + error:nil]; + }] resume]; + + [trace incrementMetric:@"request_sent" byInt:1]; + + if (@available(iOS 10, *)) { + AVURLAsset *asset = [AVURLAsset assetWithURL: + [NSURL URLWithString:@"https://upload.wikimedia.org/wikipedia/commons/thumb/3/36/Two_red_dice_01.svg/220px-Two_red_dice_01.svg.png"]]; + + AVAssetDownloadURLSession *downloadSession = + [AVAssetDownloadURLSession sessionWithConfiguration: + [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"avasset"] + assetDownloadDelegate:nil delegateQueue:[NSOperationQueue mainQueue]]; + + AVAssetDownloadTask *task = [downloadSession assetDownloadTaskWithURLAsset:asset assetTitle: + @"something" assetArtworkData:nil options:nil]; + + [task resume]; + [trace incrementMetric:@"av_request_sent" byInt:1]; + } +} + +@end diff --git a/performance/PerformanceExample/main.m b/performance/PerformanceExample/main.m new file mode 100644 index 000000000..bc10c3ac6 --- /dev/null +++ b/performance/PerformanceExample/main.m @@ -0,0 +1,24 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/performance/PerformanceExample/AppDelegate.swift b/performance/PerformanceExampleSwift/AppDelegate.swift similarity index 89% rename from performance/PerformanceExample/AppDelegate.swift rename to performance/PerformanceExampleSwift/AppDelegate.swift index eeacc913a..0e127cd11 100644 --- a/performance/PerformanceExample/AppDelegate.swift +++ b/performance/PerformanceExampleSwift/AppDelegate.swift @@ -29,9 +29,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // Use Firebase library to configure APIs FirebaseApp.configure() // [END firebase_configure] - window = UIWindow(frame: UIScreen.main.bounds) - window?.rootViewController = ViewController() - window?.makeKeyAndVisible() return true } } diff --git a/performance/PerformanceExample/ViewController.swift b/performance/PerformanceExampleSwift/ViewController.swift similarity index 100% rename from performance/PerformanceExample/ViewController.swift rename to performance/PerformanceExampleSwift/ViewController.swift diff --git a/performance/PerformanceExampleSwiftUITests/Info.plist b/performance/PerformanceExampleSwiftUITests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/performance/PerformanceExampleSwiftUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/performance/PerformanceExampleSwiftUITests/PerformanceExampleSwiftUITests.swift b/performance/PerformanceExampleSwiftUITests/PerformanceExampleSwiftUITests.swift new file mode 100644 index 000000000..d9f41826e --- /dev/null +++ b/performance/PerformanceExampleSwiftUITests/PerformanceExampleSwiftUITests.swift @@ -0,0 +1,42 @@ +// +// Copyright (c) 2019 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import XCTest + +class PerformanceExampleSwiftUITests: XCTestCase { + override func setUp() { + super.setUp() + + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. + XCUIApplication().launch() + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } +} diff --git a/performance/PerformanceExampleTests/AppTests.m b/performance/PerformanceExampleTests/AppTests.m new file mode 100644 index 000000000..4ee604cc6 --- /dev/null +++ b/performance/PerformanceExampleTests/AppTests.m @@ -0,0 +1,40 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +@interface AppTests : XCTestCase +@end + +@implementation AppTests + +- (void)setUp { + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample { + // This is an example of a functional test case. + XCTAssert(YES, @"Pass"); +} + +@end diff --git a/performance/PerformanceExampleUITests/PerformanceExampleUITests.m b/performance/PerformanceExampleUITests/PerformanceExampleUITests.m new file mode 100644 index 000000000..0ec27ae51 --- /dev/null +++ b/performance/PerformanceExampleUITests/PerformanceExampleUITests.m @@ -0,0 +1,41 @@ +// +// Copyright (c) 2019 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +@interface PerformanceExampleUITests : XCTestCase + +@end + +@implementation PerformanceExampleUITests{ + XCUIApplication *_app; +} + +- (void)setUp { + [super setUp]; + _app = [[XCUIApplication alloc] init]; + [_app launch]; +} + +- (void)testVerifyAppLaunched { + // Verify that Performance Example app launched successfully and its title is visible. + XCTAssertTrue([_app navigationBars][@"Firebase Performance Example"].exists); + + // Make sure Google logo is loaded. + XCTAssertTrue([[[_app images] elementBoundByIndex:0] exists]); +} + +@end diff --git a/performance/Podfile b/performance/Podfile new file mode 100644 index 000000000..3022a8ab8 --- /dev/null +++ b/performance/Podfile @@ -0,0 +1,13 @@ +# PerformanceExample +use_frameworks! +platform :ios, '15.0' + +pod 'FirebaseAnalytics' +pod 'FirebasePerformance' + +target 'PerformanceExample' do +end +target 'PerformanceExampleSwift' do +end +target 'PerformanceExampleTests' do +end diff --git a/performance/Podfile.lock b/performance/Podfile.lock new file mode 100644 index 000000000..668b69676 --- /dev/null +++ b/performance/Podfile.lock @@ -0,0 +1,177 @@ +PODS: + - FirebaseABTesting (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseAnalytics (12.6.0): + - FirebaseAnalytics/Default (= 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseAnalytics/Default (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleAppMeasurement/Default (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseCore (12.6.0): + - FirebaseCoreInternal (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreExtension (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseCoreInternal (12.6.0): + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseInstallations (12.6.0): + - FirebaseCore (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - PromisesObjC (~> 2.4) + - FirebasePerformance (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - FirebaseRemoteConfig (~> 12.6.0) + - FirebaseSessions (~> 12.6.0) + - GoogleDataTransport (~> 10.1) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - nanopb (~> 3.30910.0) + - FirebaseRemoteConfig (12.6.0): + - FirebaseABTesting (~> 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - FirebaseRemoteConfigInterop (~> 12.6.0) + - FirebaseSharedSwift (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseRemoteConfigInterop (12.6.0) + - FirebaseSessions (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseCoreExtension (~> 12.6.0) + - FirebaseInstallations (~> 12.6.0) + - GoogleDataTransport (~> 10.1) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - nanopb (~> 3.30910.0) + - PromisesSwift (~> 2.1) + - FirebaseSharedSwift (12.6.0) + - GoogleAdsOnDeviceConversion (3.2.0): + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Core (12.6.0): + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Default (12.6.0): + - GoogleAdsOnDeviceConversion (~> 3.2.0) + - GoogleAppMeasurement/Core (= 12.6.0) + - GoogleAppMeasurement/IdentitySupport (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/IdentitySupport (12.6.0): + - GoogleAppMeasurement/Core (= 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleDataTransport (10.1.0): + - nanopb (~> 3.30910.0) + - PromisesObjC (~> 2.4) + - GoogleUtilities/AppDelegateSwizzler (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Privacy + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - GoogleUtilities/MethodSwizzler (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/Network (8.1.0): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Privacy + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (8.1.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/Reachability (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/UserDefaults (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - nanopb (3.30910.0): + - nanopb/decode (= 3.30910.0) + - nanopb/encode (= 3.30910.0) + - nanopb/decode (3.30910.0) + - nanopb/encode (3.30910.0) + - PromisesObjC (2.4.0) + - PromisesSwift (2.4.0): + - PromisesObjC (= 2.4.0) + +DEPENDENCIES: + - FirebaseAnalytics + - FirebasePerformance + +SPEC REPOS: + trunk: + - FirebaseABTesting + - FirebaseAnalytics + - FirebaseCore + - FirebaseCoreExtension + - FirebaseCoreInternal + - FirebaseInstallations + - FirebasePerformance + - FirebaseRemoteConfig + - FirebaseRemoteConfigInterop + - FirebaseSessions + - FirebaseSharedSwift + - GoogleAdsOnDeviceConversion + - GoogleAppMeasurement + - GoogleDataTransport + - GoogleUtilities + - nanopb + - PromisesObjC + - PromisesSwift + +SPEC CHECKSUMS: + FirebaseABTesting: 119f0a2b2e68b1ae05d248c5adb2455f148f20c1 + FirebaseAnalytics: d0a97a0db6425e5a5d966340b87f92ca7b13a557 + FirebaseCore: 0e38ad5d62d980a47a64b8e9301ffa311457be04 + FirebaseCoreExtension: 032fd6f8509e591fda8cb76f6651f20d926b121f + FirebaseCoreInternal: 69bf1306a05b8ac43004f6cc1f804bb7b05b229e + FirebaseInstallations: 631b38da2e11a83daa4bfb482f79d286a5dfa7ad + FirebasePerformance: 9a73b170cefb06e5da537682e30f86c9865880c5 + FirebaseRemoteConfig: c5dfe22828a7ae7673d16224ea92743687e993df + FirebaseRemoteConfigInterop: 3443b8cb8fffd76bb3e03b2a84bfd3db952fcda4 + FirebaseSessions: 2e8f808347e665dff3e5843f275715f07045297d + FirebaseSharedSwift: 79f27fff0addd15c3de19b87fba426f3cc2c964f + GoogleAdsOnDeviceConversion: d68c69dd9581a0f5da02617b6f377e5be483970f + GoogleAppMeasurement: 3bf40aff49a601af5da1c3345702fcb4991d35ee + GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851 + +PODFILE CHECKSUM: 9ae3315de91091ce87b423f997f50a0fd64d537e + +COCOAPODS: 1.16.2 diff --git a/scripts/add_framework_script.rb b/scripts/add_framework_script.rb index 5f5e36b36..4fc735093 100755 --- a/scripts/add_framework_script.rb +++ b/scripts/add_framework_script.rb @@ -29,22 +29,12 @@ opt.on('--file_ext FILE_EXT') { |o| options[:file_ext] = o} end.parse! sdk = options[:sdk] -target_name = options[:target] +target = options[:target] framework_path = options[:framework_path] source_tree = options[:source_tree] file_ext = options[:file_ext] project_path = "#{sdk}Example.xcodeproj" project = Xcodeproj::Project.open(project_path) - -# Find the target. -target = project.targets.find { |t| t.name == target_name } - -# Check if the target exists. -unless target - STDERR.puts "Error: Target '#{target_name}' not found in project '#{project_path}'." - exit 1 -end - project_framework_group = project.frameworks_group def add_ref(group, path, source_tree, phase_list) @@ -66,31 +56,40 @@ def add_ref(group, path, source_tree, phase_list) if File.directory?(framework_path) if framework_path.end_with?("bundle") - puts "The following bundle is added to #{target.name}" - add_ref(project.main_group, - framework_path, - source_tree, - [target.resources_build_phase]) + project.targets.each do |project_target| + next unless project_target.name == target + puts "The following bundle is added to #{project_target}" + add_ref(project.main_group, + framework_path, + source_tree, + [project_target.resources_build_phase]) + end else framework_group = Dir.glob(File.join(framework_path, "*.{#{file_ext}}")) - framework_set = target.frameworks_build_phase.files.to_set - puts "The following frameworks are added to #{target.name}" - embed_frameworks_phase = target.new_copy_files_build_phase("Embed Frameworks") - embed_frameworks_phase.dst_subfolder_spec = "10" # `Frameworks` directory - framework_group.each do |framework| - next if framework_set.size == framework_set.add(framework).size - add_ref(project_framework_group, - framework, - source_tree, - [target.frameworks_build_phase, embed_frameworks_phase]) + project.targets.each do |project_target| + next unless project_target.name == target + framework_set = project_target.frameworks_build_phase.files.to_set + puts "The following frameworks are added to #{project_target}" + embed_frameworks_phase = project_target.new_copy_files_build_phase("Embed Frameworks") + embed_frameworks_phase.dst_subfolder_spec = "10" # `Frameworks` directory + framework_group.each do |framework| + next if framework_set.size == framework_set.add(framework).size + add_ref(project_framework_group, + framework, + source_tree, + [project_target.frameworks_build_phase, embed_frameworks_phase]) + end end end else - puts "The following file is added to #{target.name}" - add_ref(project_framework_group, - framework_path, - source_tree, - [target.frameworks_build_phase]) + project.targets.each do |project_target| + next unless project_target.name == target + puts "The following file is added to #{project_target}" + add_ref(project_framework_group, + framework_path, + source_tree, + [project_target.frameworks_build_phase]) + end end project.save() diff --git a/scripts/build-for-testing.sh b/scripts/build-for-testing.sh index d5fdf0978..b36acbac8 100755 --- a/scripts/build-for-testing.sh +++ b/scripts/build-for-testing.sh @@ -26,6 +26,10 @@ set -euo pipefail if [[ -z "${SPM:-}" ]]; then SPM=false echo "Defaulting to SPM=$SPM" + if [[ -z "${LEGACY:-}" ]]; then + LEGACY=false + echo "Defaulting to LEGACY=$LEGACY" + fi fi # Set have_secrets to true or false. @@ -38,7 +42,11 @@ flags=() if [[ "$SPM" == true ]];then flags+=( -project "${DIR}/${SAMPLE}Example.xcodeproj" ) else - WORKSPACE="${SAMPLE}/${SAMPLE}Example.xcworkspace" + if [[ "$LEGACY" == true ]]; then + WORKSPACE="${SAMPLE}/Legacy${SAMPLE}Quickstart/${SAMPLE}Example.xcworkspace" + else + WORKSPACE="${SAMPLE}/${SAMPLE}Example.xcworkspace" + fi flags+=( -workspace "$WORKSPACE" ) fi diff --git a/scripts/framework_test.sh b/scripts/framework_test.sh index bf9b1f858..e155504fc 100755 --- a/scripts/framework_test.sh +++ b/scripts/framework_test.sh @@ -29,6 +29,10 @@ EXIT_STATUS=0 cd "${SAMPLE}" +if [[ ! -z "$LEGACY" ]]; then + cd "Legacy${SAMPLE}Quickstart" +fi + if [[ "$have_secrets" == true ]]; then ( xcodebuild \ diff --git a/scripts/info_script.rb b/scripts/info_script.rb index 31c877d21..23ef9d942 100755 --- a/scripts/info_script.rb +++ b/scripts/info_script.rb @@ -16,8 +16,13 @@ require 'xcodeproj' sample = ARGV[0] +legacy = ARGV[1] project_path = "#{sample}Example.xcodeproj" file_name = 'GoogleService-Info.plist' +unless legacy.nil? || legacy.empty? + project_path = "Legacy#{sample}Quickstart/" + project_path + file_name = "../" + file_name +end project = Xcodeproj::Project.open(project_path) # Add a file to the project in the main group diff --git a/scripts/install_prereqs/functions.sh b/scripts/install_prereqs/functions.sh index f39a0b231..ced5e903b 100755 --- a/scripts/install_prereqs/functions.sh +++ b/scripts/install_prereqs/functions.sh @@ -16,5 +16,4 @@ DIRECTORY=functions \ PROJECT=Functions \ . ../scripts/prereq_core.sh -# TODO(ncooke3): FunctionsExample/Info.plist path DNE. -# sed -i '' 's/REVERSED_CLIENT_ID/com.googleusercontent.apps.1025801074639-6p6ebi8amuklcjrto20gvpe295smm8u6/' FunctionsExample/Info.plist +sed -i '' 's/REVERSED_CLIENT_ID/com.googleusercontent.apps.1025801074639-6p6ebi8amuklcjrto20gvpe295smm8u6/' LegacyFunctionsQuickstart/FunctionsExample/Info.plist diff --git a/scripts/test.sh b/scripts/test.sh index cdd4c93e0..6fcf43687 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -35,8 +35,12 @@ fi # Set default parameters if [[ -z "${SPM:-}" ]]; then - SPM=true + SPM=false echo "Defaulting to SPM=$SPM" + if [[ -z "${LEGACY:-}" ]]; then + LEGACY=false + echo "Defaulting to LEGACY=$LEGACY" + fi fi if [[ -z "${OS:-}" ]]; then OS=iOS @@ -59,33 +63,18 @@ flags=() if [[ "$SPM" == true ]];then flags+=( -project "${DIR}/${SAMPLE}Example.xcodeproj" ) else - WORKSPACE="${SAMPLE}/${SAMPLE}Example.xcworkspace" + if [[ "$LEGACY" == true ]]; then + WORKSPACE="${SAMPLE}/Legacy${SAMPLE}Quickstart/${SAMPLE}Example.xcworkspace" + else + WORKSPACE="${SAMPLE}/${SAMPLE}Example.xcworkspace" + fi flags+=( -workspace "$WORKSPACE" ) fi # Set scheme if [[ -z "${SCHEME:-}" ]]; then if [[ "$SPM" == true ]];then - # Get the list of schemes - schemes=$(xcodebuild -list -project "${DIR}/${SAMPLE}Example.xcodeproj" | - grep -E '^\s+' | - sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') - - # Check for the OS-suffixed scheme name - if echo "$schemes" | grep -q "^${SAMPLE}Example (${OS})$"; then - SCHEME="${SAMPLE}Example (${OS})" - # Check for the Swift-suffixed scheme - elif echo "$schemes" | grep -q "^${SAMPLE}ExampleSwift$"; then - SCHEME="${SAMPLE}ExampleSwift" - # Check for the base scheme name - elif echo "$schemes" | grep -q "^${SAMPLE}Example$"; then - SCHEME="${SAMPLE}Example" - else - echo "Error: Could not find a suitable scheme for ${SAMPLE}Example in ${OS}." - echo "Available schemes:" - echo "$schemes" - exit 1 - fi + SCHEME="${SAMPLE}Example (${OS})" else SCHEME="${SAMPLE}Example${SWIFT_SUFFIX:-}" fi @@ -148,8 +137,6 @@ function xcb() { } # Run xcodebuild -if [[ "${GITHUB_ACTIONS:-}" == "true" ]]; then - sudo xcode-select -s "/Applications/Xcode_${xcode_version}.app/Contents/Developer" -fi +sudo xcode-select -s "/Applications/Xcode_${xcode_version}.app/Contents/Developer" xcb "${flags[@]}" echo "$message" diff --git a/storage/LegacyStorageQuickstart/Podfile b/storage/LegacyStorageQuickstart/Podfile new file mode 100644 index 000000000..20b5bace6 --- /dev/null +++ b/storage/LegacyStorageQuickstart/Podfile @@ -0,0 +1,14 @@ +# StorageExample + +use_frameworks! +platform :ios, '15.0' + +pod 'FirebaseAuth' +pod 'FirebaseStorage' + +target 'StorageExample' do +end +target 'StorageExampleSwift' do +end +target 'StorageExampleTests' do +end diff --git a/storage/LegacyStorageQuickstart/Podfile.lock b/storage/LegacyStorageQuickstart/Podfile.lock new file mode 100644 index 000000000..5e96096e2 --- /dev/null +++ b/storage/LegacyStorageQuickstart/Podfile.lock @@ -0,0 +1,83 @@ +PODS: + - FirebaseAppCheckInterop (12.6.0) + - FirebaseAuth (12.6.0): + - FirebaseAppCheckInterop (~> 12.6.0) + - FirebaseAuthInterop (~> 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseCoreExtension (~> 12.6.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/Environment (~> 8.1) + - GTMSessionFetcher/Core (< 6.0, >= 3.4) + - RecaptchaInterop (~> 101.0) + - FirebaseAuthInterop (12.6.0) + - FirebaseCore (12.6.0): + - FirebaseCoreInternal (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreExtension (12.6.0): + - FirebaseCore (~> 12.6.0) + - FirebaseCoreInternal (12.6.0): + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseStorage (12.6.0): + - FirebaseAppCheckInterop (~> 12.6.0) + - FirebaseAuthInterop (~> 12.6.0) + - FirebaseCore (~> 12.6.0) + - FirebaseCoreExtension (~> 12.6.0) + - GoogleUtilities/Environment (~> 8.1) + - GTMSessionFetcher/Core (< 6.0, >= 3.4) + - GoogleUtilities/AppDelegateSwizzler (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Privacy + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - GoogleUtilities/Network (8.1.0): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Privacy + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (8.1.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/Reachability (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GTMSessionFetcher/Core (5.0.0) + - RecaptchaInterop (101.0.0) + +DEPENDENCIES: + - FirebaseAuth + - FirebaseStorage + +SPEC REPOS: + trunk: + - FirebaseAppCheckInterop + - FirebaseAuth + - FirebaseAuthInterop + - FirebaseCore + - FirebaseCoreExtension + - FirebaseCoreInternal + - FirebaseStorage + - GoogleUtilities + - GTMSessionFetcher + - RecaptchaInterop + +SPEC CHECKSUMS: + FirebaseAppCheckInterop: e2178171b4145013c7c1a3cc464d1d446d3a1896 + FirebaseAuth: 613c463cb43545a7fd2cd99ade09b78ac472c544 + FirebaseAuthInterop: db06756ef028006d034b6004dc0c37c24f7828d4 + FirebaseCore: 0e38ad5d62d980a47a64b8e9301ffa311457be04 + FirebaseCoreExtension: 032fd6f8509e591fda8cb76f6651f20d926b121f + FirebaseCoreInternal: 69bf1306a05b8ac43004f6cc1f804bb7b05b229e + FirebaseStorage: 550349b1e8f7315834ea08308696e9469d77135d + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + GTMSessionFetcher: 02d6e866e90bc236f48a703a041dfe43e6221a29 + RecaptchaInterop: 11e0b637842dfb48308d242afc3f448062325aba + +PODFILE CHECKSUM: ab7e96bd254ded22f9c3af22b218999e9c2c4919 + +COCOAPODS: 1.16.2 diff --git a/storage/LegacyStorageQuickstart/README.md b/storage/LegacyStorageQuickstart/README.md new file mode 100644 index 000000000..c20b96c92 --- /dev/null +++ b/storage/LegacyStorageQuickstart/README.md @@ -0,0 +1,44 @@ +Cloud Storage for Firebase Quickstart +============================= + +The Cloud Storage for Firebase iOS quickstart demonstrates how to upload data to a Cloud Storage bucket, and retrieve a download URL. + +Introduction +------------ + +- [Read more about Cloud Storage for Firebase](https://firebase.google.com/docs/storage) +- The APIs involving the Swift Result type are in beta and may change in future releases. + +Getting Started +--------------- + +- [Add Firebase to your iOS Project](https://firebase.google.com/docs/ios/setup). The package name you'll use is `com.google.firebase.quickstart.StorageExample`. +- Enable Anonymous auth in the **Auth > SIGN IN METHOD** tab. +![Alt text](https://github.com/firebase/quickstart-js/blob/main/storage/pics/enable.png?raw=true "Enable auth") +- Run the sample on your iOS device or simulator. + + +Support +------- + +- [Firebase Support](https://firebase.google.com/support/) + +License +------- + +Copyright 2016 Google, Inc. + +Licensed to the Apache Software Foundation (ASF) under one or more contributor +license agreements. See the NOTICE file distributed with this work for +additional information regarding copyright ownership. The ASF licenses this +file to you under the Apache License, Version 2.0 (the "License"); you may not +use this file except in compliance with the License. You may obtain a copy of +the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +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/storage/LegacyStorageQuickstart/StorageExample.xcodeproj/project.pbxproj b/storage/LegacyStorageQuickstart/StorageExample.xcodeproj/project.pbxproj new file mode 100644 index 000000000..c5a25a469 --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExample.xcodeproj/project.pbxproj @@ -0,0 +1,926 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 107347E320315A84004A66D1 /* StorageExampleSwiftUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 107347E220315A84004A66D1 /* StorageExampleSwiftUITests.swift */; }; + 1073487D20333C27004A66D1 /* StorageExampleUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1073487C20333C27004A66D1 /* StorageExampleUITests.m */; }; + 10D187C31C8640E300D0DC91 /* DownloadViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 10D187C21C8640E300D0DC91 /* DownloadViewController.m */; }; + 10D187C51C87608900D0DC91 /* DownloadViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10D187C41C87608900D0DC91 /* DownloadViewController.swift */; }; + 5F5A53521ADE670C00F81DF0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53511ADE670C00F81DF0 /* main.m */; }; + 5F5A53551ADE670C00F81DF0 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */; }; + 5F5A53581ADE670C00F81DF0 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A53571ADE670C00F81DF0 /* ViewController.m */; }; + 5F5A535B1ADE670C00F81DF0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5F5A53591ADE670C00F81DF0 /* Main.storyboard */; }; + 5F5A537E1ADE67D500F81DF0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */; }; + 5F5A53801ADE67D500F81DF0 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F5A537F1ADE67D500F81DF0 /* ViewController.swift */; }; + 5F5A539C1ADE69AA00F81DF0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5F5A53591ADE670C00F81DF0 /* Main.storyboard */; }; + 5F99610A1AE0CF4F0034F503 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961061AE0CF4F0034F503 /* Images.xcassets */; }; + 5F99610B1AE0CF4F0034F503 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961061AE0CF4F0034F503 /* Images.xcassets */; }; + 5F99610C1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */; }; + 5F99610D1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */; }; + 5FDE055D1B0DAA090037B82F /* AppTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FDE055C1B0DAA090037B82F /* AppTests.m */; }; + B9A598CC27E3D940003BCFD0 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B9A598CB27E3D940003BCFD0 /* GoogleService-Info.plist */; }; + B9A598CD27E3D940003BCFD0 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B9A598CB27E3D940003BCFD0 /* GoogleService-Info.plist */; }; + DE8564A823AECBB800611383 /* FIREGSignInHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = DE8564A523AECBB700611383 /* FIREGSignInHelper.m */; }; + DE8564A923AECBB800611383 /* FIREGHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = DE8564A623AECBB700611383 /* FIREGHelper.m */; }; + DEFC92E62B7D8E0F004F7638 /* Placeholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEFC92E52B7D8E0E004F7638 /* Placeholder.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 107347E520315A84004A66D1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5F5A53781ADE67D500F81DF0; + remoteInfo = StorageExampleSwift; + }; + 1073487F20333C27004A66D1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5F5A534B1ADE670C00F81DF0; + remoteInfo = StorageExample; + }; + 5FDE055E1B0DAA090037B82F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5F5A534B1ADE670C00F81DF0; + remoteInfo = StorageExample; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 107347E020315A84004A66D1 /* StorageExampleSwiftUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StorageExampleSwiftUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 107347E220315A84004A66D1 /* StorageExampleSwiftUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorageExampleSwiftUITests.swift; sourceTree = ""; }; + 107347E420315A84004A66D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1073487A20333C27004A66D1 /* StorageExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StorageExampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 1073487C20333C27004A66D1 /* StorageExampleUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StorageExampleUITests.m; sourceTree = ""; }; + 1073487E20333C27004A66D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 10D187C11C8640E300D0DC91 /* DownloadViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DownloadViewController.h; sourceTree = ""; }; + 10D187C21C8640E300D0DC91 /* DownloadViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DownloadViewController.m; sourceTree = ""; }; + 10D187C41C87608900D0DC91 /* DownloadViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownloadViewController.swift; sourceTree = ""; }; + 5F5A534C1ADE670C00F81DF0 /* StorageExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = StorageExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5F5A53501ADE670C00F81DF0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5F5A53511ADE670C00F81DF0 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 5F5A53531ADE670C00F81DF0 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 5F5A53561ADE670C00F81DF0 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + 5F5A53571ADE670C00F81DF0 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 5F5A535A1ADE670C00F81DF0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 5F5A53791ADE67D500F81DF0 /* StorageExampleSwift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = StorageExampleSwift.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 5F5A537F1ADE67D500F81DF0 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 5F9961061AE0CF4F0034F503 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LaunchScreen.xib; sourceTree = ""; }; + 5FDE05581B0DAA090037B82F /* StorageExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StorageExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5FDE055C1B0DAA090037B82F /* AppTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppTests.m; sourceTree = ""; }; + B9A598CB27E3D940003BCFD0 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "../GoogleService-Info.plist"; sourceTree = ""; }; + DE8564A423AECBB700611383 /* FIREGHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIREGHelper.h; sourceTree = ""; }; + DE8564A523AECBB700611383 /* FIREGSignInHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIREGSignInHelper.m; sourceTree = ""; }; + DE8564A623AECBB700611383 /* FIREGHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIREGHelper.m; sourceTree = ""; }; + DE8564A723AECBB700611383 /* FIREGSignInHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIREGSignInHelper.h; sourceTree = ""; }; + DEFC92E52B7D8E0E004F7638 /* Placeholder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Placeholder.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 107347DD20315A84004A66D1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1073487720333C27004A66D1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53491ADE670C00F81DF0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53761ADE67D500F81DF0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FDE05551B0DAA090037B82F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 107347E120315A84004A66D1 /* StorageExampleSwiftUITests */ = { + isa = PBXGroup; + children = ( + 107347E220315A84004A66D1 /* StorageExampleSwiftUITests.swift */, + 107347E420315A84004A66D1 /* Info.plist */, + ); + path = StorageExampleSwiftUITests; + sourceTree = ""; + }; + 1073487B20333C27004A66D1 /* StorageExampleUITests */ = { + isa = PBXGroup; + children = ( + 1073487C20333C27004A66D1 /* StorageExampleUITests.m */, + 1073487E20333C27004A66D1 /* Info.plist */, + ); + path = StorageExampleUITests; + sourceTree = ""; + }; + 5F5A53431ADE670C00F81DF0 = { + isa = PBXGroup; + children = ( + B9A598CB27E3D940003BCFD0 /* GoogleService-Info.plist */, + 5F5A534E1ADE670C00F81DF0 /* StorageExample */, + 5F5A537A1ADE67D500F81DF0 /* StorageExampleSwift */, + 5FDE05591B0DAA090037B82F /* StorageExampleTests */, + 107347E120315A84004A66D1 /* StorageExampleSwiftUITests */, + 1073487B20333C27004A66D1 /* StorageExampleUITests */, + DE8564A323AECBB700611383 /* TestUtils */, + 5F5A534D1ADE670C00F81DF0 /* Products */, + 5F9961041AE0CF4F0034F503 /* Shared */, + 9044C0653BC73B0667DE6CE1 /* Pods */, + ); + sourceTree = ""; + wrapsLines = 0; + }; + 5F5A534D1ADE670C00F81DF0 /* Products */ = { + isa = PBXGroup; + children = ( + 5F5A534C1ADE670C00F81DF0 /* StorageExample.app */, + 5F5A53791ADE67D500F81DF0 /* StorageExampleSwift.app */, + 5FDE05581B0DAA090037B82F /* StorageExampleTests.xctest */, + 107347E020315A84004A66D1 /* StorageExampleSwiftUITests.xctest */, + 1073487A20333C27004A66D1 /* StorageExampleUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 5F5A534E1ADE670C00F81DF0 /* StorageExample */ = { + isa = PBXGroup; + children = ( + 5F5A53531ADE670C00F81DF0 /* AppDelegate.h */, + 5F5A53541ADE670C00F81DF0 /* AppDelegate.m */, + 10D187C11C8640E300D0DC91 /* DownloadViewController.h */, + 10D187C21C8640E300D0DC91 /* DownloadViewController.m */, + 5F5A53561ADE670C00F81DF0 /* ViewController.h */, + 5F5A53571ADE670C00F81DF0 /* ViewController.m */, + 5F5A534F1ADE670C00F81DF0 /* Supporting Files */, + DEFC92E52B7D8E0E004F7638 /* Placeholder.swift */, + ); + path = StorageExample; + sourceTree = ""; + }; + 5F5A534F1ADE670C00F81DF0 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 5F5A53591ADE670C00F81DF0 /* Main.storyboard */, + 5F5A53501ADE670C00F81DF0 /* Info.plist */, + 5F5A53511ADE670C00F81DF0 /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 5F5A537A1ADE67D500F81DF0 /* StorageExampleSwift */ = { + isa = PBXGroup; + children = ( + 5F5A537D1ADE67D500F81DF0 /* AppDelegate.swift */, + 10D187C41C87608900D0DC91 /* DownloadViewController.swift */, + 5F5A537F1ADE67D500F81DF0 /* ViewController.swift */, + ); + path = StorageExampleSwift; + sourceTree = ""; + }; + 5F9961041AE0CF4F0034F503 /* Shared */ = { + isa = PBXGroup; + children = ( + 5F9961061AE0CF4F0034F503 /* Images.xcassets */, + 5F9961071AE0CF4F0034F503 /* LaunchScreen.xib */, + ); + name = Shared; + path = ../../shared; + sourceTree = ""; + }; + 5FDE05591B0DAA090037B82F /* StorageExampleTests */ = { + isa = PBXGroup; + children = ( + 5FDE055C1B0DAA090037B82F /* AppTests.m */, + ); + path = StorageExampleTests; + sourceTree = ""; + }; + 9044C0653BC73B0667DE6CE1 /* Pods */ = { + isa = PBXGroup; + children = ( + ); + path = Pods; + sourceTree = ""; + }; + DE8564A323AECBB700611383 /* TestUtils */ = { + isa = PBXGroup; + children = ( + DE8564A423AECBB700611383 /* FIREGHelper.h */, + DE8564A523AECBB700611383 /* FIREGSignInHelper.m */, + DE8564A623AECBB700611383 /* FIREGHelper.m */, + DE8564A723AECBB700611383 /* FIREGSignInHelper.h */, + ); + name = TestUtils; + path = ../../TestUtils; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 107347DF20315A84004A66D1 /* StorageExampleSwiftUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 107347E720315A84004A66D1 /* Build configuration list for PBXNativeTarget "StorageExampleSwiftUITests" */; + buildPhases = ( + 107347DC20315A84004A66D1 /* Sources */, + 107347DD20315A84004A66D1 /* Frameworks */, + 107347DE20315A84004A66D1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 107347E620315A84004A66D1 /* PBXTargetDependency */, + ); + name = StorageExampleSwiftUITests; + productName = StorageExampleSwiftUITests; + productReference = 107347E020315A84004A66D1 /* StorageExampleSwiftUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + 1073487920333C27004A66D1 /* StorageExampleUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1073488120333C27004A66D1 /* Build configuration list for PBXNativeTarget "StorageExampleUITests" */; + buildPhases = ( + 1073487620333C27004A66D1 /* Sources */, + 1073487720333C27004A66D1 /* Frameworks */, + 1073487820333C27004A66D1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 1073488020333C27004A66D1 /* PBXTargetDependency */, + ); + name = StorageExampleUITests; + productName = StorageExampleUITests; + productReference = 1073487A20333C27004A66D1 /* StorageExampleUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + 5F5A534B1ADE670C00F81DF0 /* StorageExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5F5A536F1ADE670C00F81DF0 /* Build configuration list for PBXNativeTarget "StorageExample" */; + buildPhases = ( + 5F5A53481ADE670C00F81DF0 /* Sources */, + 5F5A53491ADE670C00F81DF0 /* Frameworks */, + 5F5A534A1ADE670C00F81DF0 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = StorageExample; + productName = StorageExample; + productReference = 5F5A534C1ADE670C00F81DF0 /* StorageExample.app */; + productType = "com.apple.product-type.application"; + }; + 5F5A53781ADE67D500F81DF0 /* StorageExampleSwift */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5F5A53991ADE67D500F81DF0 /* Build configuration list for PBXNativeTarget "StorageExampleSwift" */; + buildPhases = ( + 5F5A53751ADE67D500F81DF0 /* Sources */, + 5F5A53761ADE67D500F81DF0 /* Frameworks */, + 5F5A53771ADE67D500F81DF0 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = StorageExampleSwift; + productName = StorageExampleSwift; + productReference = 5F5A53791ADE67D500F81DF0 /* StorageExampleSwift.app */; + productType = "com.apple.product-type.application"; + }; + 5FDE05571B0DAA090037B82F /* StorageExampleTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5FDE05621B0DAA090037B82F /* Build configuration list for PBXNativeTarget "StorageExampleTests" */; + buildPhases = ( + 5FDE05541B0DAA090037B82F /* Sources */, + 5FDE05551B0DAA090037B82F /* Frameworks */, + 5FDE05561B0DAA090037B82F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5FDE055F1B0DAA090037B82F /* PBXTargetDependency */, + ); + name = StorageExampleTests; + productName = StorageExampleTests; + productReference = 5FDE05581B0DAA090037B82F /* StorageExampleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5F5A53441ADE670C00F81DF0 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1110; + ORGANIZATIONNAME = "Google Inc."; + TargetAttributes = { + 107347DF20315A84004A66D1 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1110; + ProvisioningStyle = Automatic; + TestTargetID = 5F5A53781ADE67D500F81DF0; + }; + 1073487920333C27004A66D1 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Automatic; + TestTargetID = 5F5A534B1ADE670C00F81DF0; + }; + 5F5A534B1ADE670C00F81DF0 = { + CreatedOnToolsVersion = 6.3; + LastSwiftMigration = 1530; + ProvisioningStyle = Automatic; + }; + 5F5A53781ADE67D500F81DF0 = { + CreatedOnToolsVersion = 6.3; + LastSwiftMigration = 1110; + ProvisioningStyle = Automatic; + }; + 5FDE05571B0DAA090037B82F = { + CreatedOnToolsVersion = 6.3.2; + LastSwiftMigration = 0800; + ProvisioningStyle = Automatic; + TestTargetID = 5F5A534B1ADE670C00F81DF0; + }; + }; + }; + buildConfigurationList = 5F5A53471ADE670C00F81DF0 /* Build configuration list for PBXProject "StorageExample" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 5F5A53431ADE670C00F81DF0; + productRefGroup = 5F5A534D1ADE670C00F81DF0 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5F5A534B1ADE670C00F81DF0 /* StorageExample */, + 5F5A53781ADE67D500F81DF0 /* StorageExampleSwift */, + 5FDE05571B0DAA090037B82F /* StorageExampleTests */, + 107347DF20315A84004A66D1 /* StorageExampleSwiftUITests */, + 1073487920333C27004A66D1 /* StorageExampleUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 107347DE20315A84004A66D1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1073487820333C27004A66D1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A534A1ADE670C00F81DF0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F99610C1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */, + B9A598CC27E3D940003BCFD0 /* GoogleService-Info.plist in Resources */, + 5F99610A1AE0CF4F0034F503 /* Images.xcassets in Resources */, + 5F5A535B1ADE670C00F81DF0 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53771ADE67D500F81DF0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F99610D1AE0CF4F0034F503 /* LaunchScreen.xib in Resources */, + B9A598CD27E3D940003BCFD0 /* GoogleService-Info.plist in Resources */, + 5F5A539C1ADE69AA00F81DF0 /* Main.storyboard in Resources */, + 5F99610B1AE0CF4F0034F503 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FDE05561B0DAA090037B82F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 107347DC20315A84004A66D1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 107347E320315A84004A66D1 /* StorageExampleSwiftUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1073487620333C27004A66D1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1073487D20333C27004A66D1 /* StorageExampleUITests.m in Sources */, + DE8564A823AECBB800611383 /* FIREGSignInHelper.m in Sources */, + DE8564A923AECBB800611383 /* FIREGHelper.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53481ADE670C00F81DF0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F5A53581ADE670C00F81DF0 /* ViewController.m in Sources */, + DEFC92E62B7D8E0F004F7638 /* Placeholder.swift in Sources */, + 5F5A53551ADE670C00F81DF0 /* AppDelegate.m in Sources */, + 10D187C31C8640E300D0DC91 /* DownloadViewController.m in Sources */, + 5F5A53521ADE670C00F81DF0 /* main.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F5A53751ADE67D500F81DF0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F5A53801ADE67D500F81DF0 /* ViewController.swift in Sources */, + 10D187C51C87608900D0DC91 /* DownloadViewController.swift in Sources */, + 5F5A537E1ADE67D500F81DF0 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FDE05541B0DAA090037B82F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5FDE055D1B0DAA090037B82F /* AppTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 107347E620315A84004A66D1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5F5A53781ADE67D500F81DF0 /* StorageExampleSwift */; + targetProxy = 107347E520315A84004A66D1 /* PBXContainerItemProxy */; + }; + 1073488020333C27004A66D1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5F5A534B1ADE670C00F81DF0 /* StorageExample */; + targetProxy = 1073487F20333C27004A66D1 /* PBXContainerItemProxy */; + }; + 5FDE055F1B0DAA090037B82F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5F5A534B1ADE670C00F81DF0 /* StorageExample */; + targetProxy = 5FDE055E1B0DAA090037B82F /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 5F5A53591ADE670C00F81DF0 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5F5A535A1ADE670C00F81DF0 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 107347E820315A84004A66D1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = StorageExampleSwiftUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.StorageExampleSwiftUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = StorageExampleSwift; + }; + name = Debug; + }; + 107347E920315A84004A66D1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = StorageExampleSwiftUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.StorageExampleSwiftUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = StorageExampleSwift; + }; + name = Release; + }; + 1073488220333C27004A66D1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = StorageExampleUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.StorageExampleUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = StorageExample; + }; + name = Debug; + }; + 1073488320333C27004A66D1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = StorageExampleUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.StorageExampleUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = StorageExample; + }; + name = Release; + }; + 5F5A536D1ADE670C00F81DF0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + ENABLE_BITCODE = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5F5A536E1ADE670C00F81DF0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + ENABLE_BITCODE = NO; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5F5A53701ADE670C00F81DF0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = StorageExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.StorageExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 5F5A53711ADE670C00F81DF0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = StorageExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.StorageExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 5F5A53951ADE67D500F81DF0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "$(SRCROOT)/StorageExample/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.StorageExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 5F5A53961ADE67D500F81DF0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "$(SRCROOT)/StorageExample/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.StorageExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 5FDE05601B0DAA090037B82F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + StorageExample, + ); + INFOPLIST_FILE = StorageExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StorageExample.app/StorageExample"; + }; + name = Debug; + }; + 5FDE05611B0DAA090037B82F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + StorageExample, + ); + INFOPLIST_FILE = StorageExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StorageExample.app/StorageExample"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 107347E720315A84004A66D1 /* Build configuration list for PBXNativeTarget "StorageExampleSwiftUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 107347E820315A84004A66D1 /* Debug */, + 107347E920315A84004A66D1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1073488120333C27004A66D1 /* Build configuration list for PBXNativeTarget "StorageExampleUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1073488220333C27004A66D1 /* Debug */, + 1073488320333C27004A66D1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5F5A53471ADE670C00F81DF0 /* Build configuration list for PBXProject "StorageExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5F5A536D1ADE670C00F81DF0 /* Debug */, + 5F5A536E1ADE670C00F81DF0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5F5A536F1ADE670C00F81DF0 /* Build configuration list for PBXNativeTarget "StorageExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5F5A53701ADE670C00F81DF0 /* Debug */, + 5F5A53711ADE670C00F81DF0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5F5A53991ADE67D500F81DF0 /* Build configuration list for PBXNativeTarget "StorageExampleSwift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5F5A53951ADE67D500F81DF0 /* Debug */, + 5F5A53961ADE67D500F81DF0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5FDE05621B0DAA090037B82F /* Build configuration list for PBXNativeTarget "StorageExampleTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5FDE05601B0DAA090037B82F /* Debug */, + 5FDE05611B0DAA090037B82F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5F5A53441ADE670C00F81DF0 /* Project object */; +} diff --git a/storage/LegacyStorageQuickstart/StorageExample.xcodeproj/xcshareddata/xcschemes/StorageExample.xcscheme b/storage/LegacyStorageQuickstart/StorageExample.xcodeproj/xcshareddata/xcschemes/StorageExample.xcscheme new file mode 100644 index 000000000..067a3caad --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExample.xcodeproj/xcshareddata/xcschemes/StorageExample.xcscheme @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/installations/InstallationsExample.xcodeproj/xcshareddata/xcschemes/InstallationsExample.xcscheme b/storage/LegacyStorageQuickstart/StorageExample.xcodeproj/xcshareddata/xcschemes/StorageExampleSwift.xcscheme similarity index 60% rename from installations/InstallationsExample.xcodeproj/xcshareddata/xcschemes/InstallationsExample.xcscheme rename to storage/LegacyStorageQuickstart/StorageExample.xcodeproj/xcshareddata/xcschemes/StorageExampleSwift.xcscheme index 13776b1ec..6ef2adc73 100644 --- a/installations/InstallationsExample.xcodeproj/xcshareddata/xcschemes/InstallationsExample.xcscheme +++ b/storage/LegacyStorageQuickstart/StorageExample.xcodeproj/xcshareddata/xcschemes/StorageExampleSwift.xcscheme @@ -1,11 +1,10 @@ + LastUpgradeVersion = "1110" + version = "1.3"> + buildImplicitDependencies = "YES"> + BlueprintIdentifier = "5F5A53781ADE67D500F81DF0" + BuildableName = "StorageExampleSwift.app" + BlueprintName = "StorageExampleSwift" + ReferencedContainer = "container:StorageExample.xcodeproj"> @@ -27,17 +26,25 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES" - shouldAutocreateTestPlan = "YES"> + shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + BlueprintIdentifier = "107347DF20315A84004A66D1" + BuildableName = "StorageExampleSwiftUITests.xctest" + BlueprintName = "StorageExampleSwiftUITests" + ReferencedContainer = "container:StorageExample.xcodeproj"> @@ -56,10 +63,10 @@ runnableDebuggingMode = "0"> + BlueprintIdentifier = "5F5A53781ADE67D500F81DF0" + BuildableName = "StorageExampleSwift.app" + BlueprintName = "StorageExampleSwift" + ReferencedContainer = "container:StorageExample.xcodeproj"> @@ -73,10 +80,10 @@ runnableDebuggingMode = "0"> + BlueprintIdentifier = "5F5A53781ADE67D500F81DF0" + BuildableName = "StorageExampleSwift.app" + BlueprintName = "StorageExampleSwift" + ReferencedContainer = "container:StorageExample.xcodeproj"> diff --git a/storage/LegacyStorageQuickstart/StorageExample/.clang-format b/storage/LegacyStorageQuickstart/StorageExample/.clang-format new file mode 100644 index 000000000..1f09ce0f2 --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExample/.clang-format @@ -0,0 +1,4 @@ +BasedOnStyle: Google +ColumnLimit: 100 +BinPackParameters: false +AllowAllParametersOfDeclarationOnNextLine: true diff --git a/storage/LegacyStorageQuickstart/StorageExample/AppDelegate.h b/storage/LegacyStorageQuickstart/StorageExample/AppDelegate.h new file mode 100644 index 000000000..70b752761 --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExample/AppDelegate.h @@ -0,0 +1,22 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +@import UIKit; + +@interface AppDelegate : UIResponder + +@property(nonatomic, strong) UIWindow *window; + +@end diff --git a/storage/LegacyStorageQuickstart/StorageExample/AppDelegate.m b/storage/LegacyStorageQuickstart/StorageExample/AppDelegate.m new file mode 100644 index 000000000..d9426ff36 --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExample/AppDelegate.m @@ -0,0 +1,28 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "AppDelegate.h" +@import FirebaseCore; + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [FIRApp configure]; + return YES; +} + +@end diff --git a/storage/LegacyStorageQuickstart/StorageExample/Base.lproj/Main.storyboard b/storage/LegacyStorageQuickstart/StorageExample/Base.lproj/Main.storyboard new file mode 100644 index 000000000..c0d1532db --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExample/Base.lproj/Main.storyboard @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/storage/LegacyStorageQuickstart/StorageExample/DownloadViewController.h b/storage/LegacyStorageQuickstart/StorageExample/DownloadViewController.h new file mode 100644 index 000000000..56c19e146 --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExample/DownloadViewController.h @@ -0,0 +1,20 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import UIKit; + +@interface DownloadViewController : UIViewController +@end diff --git a/storage/LegacyStorageQuickstart/StorageExample/DownloadViewController.m b/storage/LegacyStorageQuickstart/StorageExample/DownloadViewController.m new file mode 100644 index 000000000..ba9fdd36e --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExample/DownloadViewController.m @@ -0,0 +1,53 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "DownloadViewController.h" +@import FirebaseStorage; + +@interface DownloadViewController () +@property (weak, nonatomic) IBOutlet UIImageView *imageView; +@property (weak, nonatomic) IBOutlet UITextView *statusTextView; +@property (strong, nonatomic) FIRStorageReference *storageRef; +@end + +@implementation DownloadViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + self.storageRef = [[FIRStorage storage] reference]; + + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *documentsDirectory = paths[0]; + NSString *filePath = [NSString stringWithFormat:@"file:%@/myimage.jpg", documentsDirectory]; + NSURL *fileURL = [NSURL URLWithString:filePath]; + NSString *storagePath = [[NSUserDefaults standardUserDefaults] objectForKey:@"storagePath"]; + + // [START downloadimage] + [[_storageRef child:storagePath] + writeToFile:fileURL + completion:^(NSURL * _Nullable URL, NSError * _Nullable error) { + if (error) { + NSLog(@"Error downloading: %@", error); + self->_statusTextView.text = @"Download Failed"; + return; + } else if (URL) { + self->_statusTextView.text = @"Download Succeeded!"; + self->_imageView.image = [UIImage imageWithContentsOfFile:URL.path]; + } + }]; + // [END downloadimage] +} +@end diff --git a/storage/LegacyStorageQuickstart/StorageExample/Info.plist b/storage/LegacyStorageQuickstart/StorageExample/Info.plist new file mode 100644 index 000000000..6444796fa --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExample/Info.plist @@ -0,0 +1,55 @@ + + + + + NSCameraUsageDescription + Take and upload photos to Cloud Storage + NSPhotoLibraryUsageDescription + Upload photo to Cloud Storage + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIcons + + CFBundleIcons~ipad + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/storage/LegacyStorageQuickstart/StorageExample/Placeholder.swift b/storage/LegacyStorageQuickstart/StorageExample/Placeholder.swift new file mode 100644 index 000000000..63a135a85 --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExample/Placeholder.swift @@ -0,0 +1,15 @@ +// 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. + +// Intentionally empty. Force the linker to link Swift libraries. diff --git a/storage/LegacyStorageQuickstart/StorageExample/ViewController.h b/storage/LegacyStorageQuickstart/StorageExample/ViewController.h new file mode 100644 index 000000000..2c7d24b3c --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExample/ViewController.h @@ -0,0 +1,20 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import UIKit; + +@interface ViewController : UIViewController +@end diff --git a/storage/LegacyStorageQuickstart/StorageExample/ViewController.m b/storage/LegacyStorageQuickstart/StorageExample/ViewController.m new file mode 100644 index 000000000..4edf3e95d --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExample/ViewController.m @@ -0,0 +1,152 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import Photos; +#import "ViewController.h" +#import "DownloadViewController.h" + +@import FirebaseAuth; +@import FirebaseStorage; + +@interface ViewController () + +@property (weak, nonatomic) IBOutlet UIButton *takePicButton; +@property (weak, nonatomic) IBOutlet UIButton *downloadPicButton; +@property (weak, nonatomic) IBOutlet UITextView *urlTextView; + +@property (strong, nonatomic) FIRStorage *storage; + +@end + +@implementation ViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + // [START configurestorage] + self.storage = [FIRStorage storage]; + // [END configurestorage] + + // [START storageauth] + // Using Cloud Storage for Firebase requires the user be authenticated. Here we are using + // anonymous authentication. + if (![FIRAuth auth].currentUser) { + [[FIRAuth auth] signInAnonymouslyWithCompletion:^(FIRAuthDataResult * _Nullable authResult, + NSError * _Nullable error) { + if (error) { + self->_urlTextView.text = error.description; + self->_takePicButton.enabled = NO; + } else { + self->_takePicButton.enabled = YES; + self->_urlTextView.text = @""; + } + }]; + } + // [END storageauth] +} + +# pragma mark - Image Picker + +- (IBAction)didTapTakePicture:(id)sender { + UIImagePickerController * picker = [[UIImagePickerController alloc] init]; + picker.delegate = self; + if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { + picker.sourceType = UIImagePickerControllerSourceTypeCamera; + } else { + picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; + } + + [self presentViewController:picker animated:YES completion:NULL]; +} + +- (void)imagePickerController:(UIImagePickerController *)picker + didFinishPickingMediaWithInfo:(NSDictionary *)info { + [picker dismissViewControllerAnimated:YES completion:NULL]; + + _urlTextView.text = @"Beginning Upload"; + NSURL *referenceUrl = info[UIImagePickerControllerReferenceURL]; + // if it's a photo from the library, not an image from the camera + if (referenceUrl) { + PHFetchResult* assets = [PHAsset fetchAssetsWithALAssetURLs:@[referenceUrl] options:nil]; + PHAsset *asset = assets.firstObject; + [asset requestContentEditingInputWithOptions:nil + completionHandler:^(PHContentEditingInput *contentEditingInput, + NSDictionary *info) { + NSURL *imageFile = contentEditingInput.fullSizeImageURL; + NSString *filePath = + [NSString stringWithFormat:@"%@/%lld/%@", + [FIRAuth auth].currentUser.uid, + (long long)([NSDate date].timeIntervalSince1970 * 1000.0), + imageFile.lastPathComponent]; + FIRStorageReference *storageRef = [self->_storage referenceWithPath:filePath]; + // [START uploadimage] + [storageRef putFile:imageFile + metadata:nil + completion:^(FIRStorageMetadata *metadata, NSError *error) { + if (error) { + NSLog(@"Error uploading: %@", error); + self->_urlTextView.text = @"Upload Failed"; + return; + } + [self uploadSuccess:storageRef storagePath:filePath]; + }]; + // [END uploadimage] + }]; + + } else { + UIImage *image = info[UIImagePickerControllerOriginalImage]; + NSData *imageData = UIImageJPEGRepresentation(image, 0.8); + NSString *imagePath = + [NSString stringWithFormat:@"%@/%lld.jpg", + [FIRAuth auth].currentUser.uid, + (long long)([NSDate date].timeIntervalSince1970 * 1000.0)]; + FIRStorageMetadata *metadata = [FIRStorageMetadata new]; + metadata.contentType = @"image/jpeg"; + FIRStorageReference *storageRef = [_storage referenceWithPath:imagePath]; + [storageRef putData:imageData + metadata:metadata + completion:^(FIRStorageMetadata * _Nullable metadata, NSError * _Nullable error) { + if (error) { + NSLog(@"Error uploading: %@", error); + self->_urlTextView.text = @"Upload Failed"; + return; + } + [self uploadSuccess:storageRef storagePath:imagePath]; + }]; + } +} + +- (void)uploadSuccess:(FIRStorageReference *) storageRef storagePath: (NSString *) storagePath { + NSLog(@"Upload Succeeded!"); + [storageRef downloadURLWithCompletion:^(NSURL * _Nullable URL, NSError * _Nullable error) { + if (error) { + NSLog(@"Error getting download URL: %@", error); + self->_urlTextView.text = @"Can't get download URL"; + return; + } + self->_urlTextView.text = URL.absoluteString; + [[NSUserDefaults standardUserDefaults] setObject:storagePath forKey:@"storagePath"]; + [[NSUserDefaults standardUserDefaults] synchronize]; + self->_downloadPicButton.enabled = YES; + }]; +} + +- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { + [picker dismissViewControllerAnimated:YES completion:NULL]; +} + + +@end diff --git a/storage/LegacyStorageQuickstart/StorageExample/main.m b/storage/LegacyStorageQuickstart/StorageExample/main.m new file mode 100644 index 000000000..bc10c3ac6 --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExample/main.m @@ -0,0 +1,24 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/storage/LegacyStorageQuickstart/StorageExampleSwift/AppDelegate.swift b/storage/LegacyStorageQuickstart/StorageExampleSwift/AppDelegate.swift new file mode 100644 index 000000000..0e127cd11 --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExampleSwift/AppDelegate.swift @@ -0,0 +1,34 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit +import FirebaseCore + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? + + func application(_ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [ + UIApplication.LaunchOptionsKey: Any + ]?) -> Bool { + // [START firebase_configure] + // Use Firebase library to configure APIs + FirebaseApp.configure() + // [END firebase_configure] + return true + } +} diff --git a/storage/LegacyStorageQuickstart/StorageExampleSwift/DownloadViewController.swift b/storage/LegacyStorageQuickstart/StorageExampleSwift/DownloadViewController.swift new file mode 100644 index 000000000..8b7707065 --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExampleSwift/DownloadViewController.swift @@ -0,0 +1,51 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit +import FirebaseStorage + +@objc(DownloadViewController) +class DownloadViewController: UIViewController { + @IBOutlet var imageView: UIImageView! + @IBOutlet var statusTextView: UITextView! + var storageRef: StorageReference! + + override func viewDidLoad() { + super.viewDidLoad() + storageRef = Storage.storage().reference() + + let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) + let documentsDirectory = paths[0] + let filePath = "file:\(documentsDirectory)/myimage.jpg" + guard let fileURL = URL(string: filePath) else { return } + guard let storagePath = UserDefaults.standard.object(forKey: "storagePath") as? String else { + return + } + + // [START downloadimage] + storageRef.child(storagePath).write(toFile: fileURL) { result in + switch result { + case let .success(url): + self.statusTextView.text = "Download Succeeded!" + self.imageView.image = UIImage(contentsOfFile: url.path) + case let .failure(error): + print("Error downloading:\(error)") + self.statusTextView.text = "Download Failed" + } + } + // [END downloadimage] + } +} diff --git a/storage/LegacyStorageQuickstart/StorageExampleSwift/ViewController.swift b/storage/LegacyStorageQuickstart/StorageExampleSwift/ViewController.swift new file mode 100644 index 000000000..810c36c13 --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExampleSwift/ViewController.swift @@ -0,0 +1,153 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit +import Photos +import FirebaseAuth +import FirebaseStorage + +@objc(ViewController) +class ViewController: UIViewController, + UIImagePickerControllerDelegate, UINavigationControllerDelegate { + @IBOutlet var takePicButton: UIButton! + @IBOutlet var downloadPicButton: UIButton! + @IBOutlet var urlTextView: UITextField! + + // [START configurestorage] + lazy var storage = Storage.storage() + // [END configurestorage] + + override func viewDidLoad() { + super.viewDidLoad() + + // [START storageauth] + // Using Cloud Storage for Firebase requires the user be authenticated. Here we are using + // anonymous authentication. + if Auth.auth().currentUser == nil { + Auth.auth().signInAnonymously(completion: { authResult, error in + if let error = error { + self.urlTextView.text = error.localizedDescription + self.takePicButton.isEnabled = false + } else { + self.urlTextView.text = "" + self.takePicButton.isEnabled = true + } + }) + } + // [END storageauth] + } + + // MARK: - Image Picker + + @IBAction func didTapTakePicture(_: AnyObject) { + let picker = UIImagePickerController() + picker.delegate = self + if UIImagePickerController.isSourceTypeAvailable(.camera) { + picker.sourceType = .camera + } else { + picker.sourceType = .photoLibrary + } + + present(picker, animated: true, completion: nil) + } + + func imagePickerController(_ picker: UIImagePickerController, + didFinishPickingMediaWithInfo info: [ + UIImagePickerController.InfoKey: Any + ]) { + // Local variable inserted by Swift 4.2 migrator. + let info = convertFromUIImagePickerControllerInfoKeyDictionary(info) + + picker.dismiss(animated: true, completion: nil) + + urlTextView.text = "Beginning Upload" + // if it's a photo from the library, not an image from the camera + if let referenceUrl = + info[convertFromUIImagePickerControllerInfoKey(UIImagePickerController.InfoKey + .referenceURL)] as? URL { + let assets = PHAsset.fetchAssets(withALAssetURLs: [referenceUrl], options: nil) + let asset = assets.firstObject + asset?.requestContentEditingInput(with: nil, completionHandler: { contentEditingInput, info in + let imageFile = contentEditingInput?.fullSizeImageURL + let filePath = Auth.auth().currentUser!.uid + + "/\(Int(Date.timeIntervalSinceReferenceDate * 1000))/\(imageFile!.lastPathComponent)" + // [START uploadimage] + let storageRef = self.storage.reference(withPath: filePath) + storageRef.putFile(from: imageFile!) { result in + switch result { + case .success: + self.uploadSuccess(storageRef, storagePath: filePath) + case let .failure(error): + print("Error uploading: \(error)") + self.urlTextView.text = "Upload Failed" + } + } + // [END uploadimage] + }) + } else { + guard let image = + info[convertFromUIImagePickerControllerInfoKey(UIImagePickerController.InfoKey + .originalImage)] as? UIImage else { return } + guard let imageData = image.jpegData(compressionQuality: 0.8) else { return } + let imagePath = Auth.auth().currentUser!.uid + + "/\(Int(Date.timeIntervalSinceReferenceDate * 1000)).jpg" + let metadata = StorageMetadata() + metadata.contentType = "image/jpeg" + let storageRef = storage.reference(withPath: imagePath) + storageRef.putData(imageData, metadata: metadata) { result in + switch result { + case .success: + self.uploadSuccess(storageRef, storagePath: imagePath) + case let .failure(error): + print("Error uploading: \(error)") + self.urlTextView.text = "Upload Failed" + } + } + } + } + + func uploadSuccess(_ storageRef: StorageReference, storagePath: String) { + print("Upload Succeeded!") + storageRef.downloadURL { result in + switch result { + case let .success(url): + self.urlTextView.text = url.absoluteString + UserDefaults.standard.set(storagePath, forKey: "storagePath") + UserDefaults.standard.synchronize() + self.downloadPicButton.isEnabled = true + case let .failure(error): + print("Error getting download URL: \(error)") + self.urlTextView.text = "Can't get download URL" + } + } + } + + func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { + picker.dismiss(animated: true, completion: nil) + } +} + +// Helper function inserted by Swift 4.2 migrator. +private func convertFromUIImagePickerControllerInfoKeyDictionary(_ input: [UIImagePickerController + .InfoKey: Any]) -> [String: Any] { + return Dictionary(uniqueKeysWithValues: input.map { key, value in (key.rawValue, value) }) +} + +// Helper function inserted by Swift 4.2 migrator. +private func convertFromUIImagePickerControllerInfoKey(_ input: UIImagePickerController + .InfoKey) -> String { + return input.rawValue +} diff --git a/storage/LegacyStorageQuickstart/StorageExampleSwiftUITests/Info.plist b/storage/LegacyStorageQuickstart/StorageExampleSwiftUITests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExampleSwiftUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/storage/LegacyStorageQuickstart/StorageExampleSwiftUITests/StorageExampleSwiftUITests.swift b/storage/LegacyStorageQuickstart/StorageExampleSwiftUITests/StorageExampleSwiftUITests.swift new file mode 100644 index 000000000..bba6ec411 --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExampleSwiftUITests/StorageExampleSwiftUITests.swift @@ -0,0 +1,42 @@ +// +// Copyright (c) 2019 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import XCTest + +class StorageExampleSwiftUITests: XCTestCase { + override func setUp() { + super.setUp() + + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. + XCUIApplication().launch() + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } +} diff --git a/storage/LegacyStorageQuickstart/StorageExampleTests/AppTests.m b/storage/LegacyStorageQuickstart/StorageExampleTests/AppTests.m new file mode 100644 index 000000000..4ee604cc6 --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExampleTests/AppTests.m @@ -0,0 +1,40 @@ +// +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import +#import + +@interface AppTests : XCTestCase +@end + +@implementation AppTests + +- (void)setUp { + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample { + // This is an example of a functional test case. + XCTAssert(YES, @"Pass"); +} + +@end diff --git a/storage/LegacyStorageQuickstart/StorageExampleUITests/Info.plist b/storage/LegacyStorageQuickstart/StorageExampleUITests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExampleUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/storage/LegacyStorageQuickstart/StorageExampleUITests/StorageExampleUITests.m b/storage/LegacyStorageQuickstart/StorageExampleUITests/StorageExampleUITests.m new file mode 100644 index 000000000..decb20b0a --- /dev/null +++ b/storage/LegacyStorageQuickstart/StorageExampleUITests/StorageExampleUITests.m @@ -0,0 +1,136 @@ +// +// Copyright (c) 2019 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import "FIREGHelper.h" + +typedef BOOL (^SystemAlertHandler)(XCUIElement *); +static SystemAlertHandler const alertHandler = ^(XCUIElement *element) { + if (element.buttons[@"OK"].exists) { + [element.buttons[@"OK"] tap]; + } + if (element.buttons[@"Allow"].exists) { + [element.buttons[@"Allow"] tap]; + } + return YES; +}; +static NSString *const header = @"Cloud Storage for Firebase Example"; +static NSString *const downloadHeader = @"Photos"; +static NSString *const takePictureButton = @"Take Picture"; +static NSString *const downloadPictureButton = @"Download Picture"; +static NSString *const cancelButton = @"Cancel"; +static NSString *const momentsHeader = @"Moments"; +static NSString *const uploadStartedTrait = @"Beginning upload"; + +@interface StorageExampleUITests : XCTestCase +@end + +@implementation StorageExampleUITests { + XCUIApplication *_app; + id cameraPermissionMonitor; +} + +- (void)setUp { + [super setUp]; + self.continueAfterFailure = NO; + _app = [[XCUIApplication alloc] init]; + cameraPermissionMonitor = + [self addUIInterruptionMonitorWithDescription:@"Allow camera or photos" handler:alertHandler]; + [_app launch]; +} + +- (void)tearDown { + [self removeUIInterruptionMonitor:cameraPermissionMonitor]; + [super tearDown]; +} + +- (void)SKIP_testNavigateToDownloadViewAndBack_simulator { + // Verify that Storage Example app launched successfully and its title is visible. + [self checkHeaderIsPresent:header]; + + // Verify that user can open and then dismiss DownloadViewController. + [_app.buttons[takePictureButton] tap]; + + FIRWaitForVisible(_app.navigationBars[downloadHeader]); + XCTAssertTrue(_app.navigationBars[downloadHeader].exists); + + // Navigate back. + [_app.navigationBars.buttons[cancelButton] tap]; + + // Make sure user is taken back. + [self checkHeaderIsPresent:header]; +} + +// The Photos UI changed in Xcode 12 and this function needs to be updated. +- (void)SKIP_testUploadFromPhotoLibraryAndDownload_simulator { + // Try to select an existing image. + [self selectImageFromLibrary]; + + // Request for permission could appear here. + FIRWaitTillAlertPresent(10); + + // If permission request appears - we need to remove it and select image once again. + if (FIRSystemAlertShown()) { + // Required for triggering SystemAlertHandler logic. + [_app tap]; + // Select the image one more time, see b/74081132 + [self selectImageFromLibrary]; + } + // Make sure main screen is present. + [self checkHeaderIsPresent:header]; + + // Wait till upload is finished. + XCUIElement *downloadButton = _app.buttons[downloadPictureButton]; + NSPredicate *hittable = [NSPredicate predicateWithFormat:@"hittable == true"]; + FIRWaitForPredicateWithTimeout(hittable, downloadButton, 20); + + // Navigate to image screen. + [_app.buttons[downloadPictureButton] tap]; + + // Check that image downloaded. + FIRWaitForVisibleWithTimeout(_app.textViews[@"Download Succeeded!"], 30); + XCTAssertTrue(_app.textViews[@"Download Succeeded!"].exists); +} + +#pragma mark - Helpers + +// Common way to detect what screen is displayed now. +- (void)checkHeaderIsPresent:(NSString *)header { + FIRWaitForVisible(_app.navigationBars[header]); + XCTAssertTrue(_app.navigationBars[header].exists); +} + +// Select an image from existing photo library. +- (void)selectImageFromLibrary { + FIRWaitForVisible(_app.buttons[takePictureButton]); + [_app.buttons[takePictureButton] tap]; + + // Select the "Moments" folder. + XCUIElement *momentsLink = [[[[_app tables] cells] matchingIdentifier:momentsHeader] element]; + FIRWaitForVisible(momentsLink); + [momentsLink tap]; + + // Wait till UIImagePickerController has loaded photo library. + XCUIElement *momentsTitle = [_app navigationBars][momentsHeader]; + FIRWaitForVisible(momentsTitle); + + // Select some image from the list of images. + XCUIElement *image = [[_app cells] elementBoundByIndex:1]; + [image tap]; +} + +@end diff --git a/storage/Shared/ContentView.swift b/storage/StorageExample/Shared/ContentView.swift similarity index 100% rename from storage/Shared/ContentView.swift rename to storage/StorageExample/Shared/ContentView.swift diff --git a/storage/Shared/ImagePicker.swift b/storage/StorageExample/Shared/ImagePicker.swift similarity index 100% rename from storage/Shared/ImagePicker.swift rename to storage/StorageExample/Shared/ImagePicker.swift diff --git a/storage/Shared/StorageExampleApp.swift b/storage/StorageExample/Shared/StorageExampleApp.swift similarity index 100% rename from storage/Shared/StorageExampleApp.swift rename to storage/StorageExample/Shared/StorageExampleApp.swift diff --git a/storage/Shared/ViewModel.swift b/storage/StorageExample/Shared/ViewModel.swift similarity index 100% rename from storage/Shared/ViewModel.swift rename to storage/StorageExample/Shared/ViewModel.swift diff --git a/storage/StorageExample (iOS)/Assets.xcassets/AccentColor.colorset/Contents.json b/storage/StorageExample/StorageExample (iOS)/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from storage/StorageExample (iOS)/Assets.xcassets/AccentColor.colorset/Contents.json rename to storage/StorageExample/StorageExample (iOS)/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/storage/StorageExample (iOS)/Assets.xcassets/AppIcon.appiconset/Contents.json b/storage/StorageExample/StorageExample (iOS)/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from storage/StorageExample (iOS)/Assets.xcassets/AppIcon.appiconset/Contents.json rename to storage/StorageExample/StorageExample (iOS)/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/storage/StorageExample (iOS)/Assets.xcassets/Contents.json b/storage/StorageExample/StorageExample (iOS)/Assets.xcassets/Contents.json similarity index 100% rename from storage/StorageExample (iOS)/Assets.xcassets/Contents.json rename to storage/StorageExample/StorageExample (iOS)/Assets.xcassets/Contents.json diff --git a/storage/StorageExample (iOS)/Preview Content/Preview Assets.xcassets/Contents.json b/storage/StorageExample/StorageExample (iOS)/Preview Content/Preview Assets.xcassets/Contents.json similarity index 100% rename from storage/StorageExample (iOS)/Preview Content/Preview Assets.xcassets/Contents.json rename to storage/StorageExample/StorageExample (iOS)/Preview Content/Preview Assets.xcassets/Contents.json diff --git a/storage/StorageExample (macOS)/Assets.xcassets/AccentColor.colorset/Contents.json b/storage/StorageExample/StorageExample (macOS)/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from storage/StorageExample (macOS)/Assets.xcassets/AccentColor.colorset/Contents.json rename to storage/StorageExample/StorageExample (macOS)/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/storage/StorageExample (macOS)/Assets.xcassets/AppIcon.appiconset/Contents.json b/storage/StorageExample/StorageExample (macOS)/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from storage/StorageExample (macOS)/Assets.xcassets/AppIcon.appiconset/Contents.json rename to storage/StorageExample/StorageExample (macOS)/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/storage/StorageExample (macOS)/Assets.xcassets/Contents.json b/storage/StorageExample/StorageExample (macOS)/Assets.xcassets/Contents.json similarity index 100% rename from storage/StorageExample (macOS)/Assets.xcassets/Contents.json rename to storage/StorageExample/StorageExample (macOS)/Assets.xcassets/Contents.json diff --git a/storage/StorageExample (macOS)/Preview Content/Preview Assets.xcassets/Contents.json b/storage/StorageExample/StorageExample (macOS)/Preview Content/Preview Assets.xcassets/Contents.json similarity index 100% rename from storage/StorageExample (macOS)/Preview Content/Preview Assets.xcassets/Contents.json rename to storage/StorageExample/StorageExample (macOS)/Preview Content/Preview Assets.xcassets/Contents.json diff --git a/storage/StorageExample (macOS)/StorageExample__macOS_.entitlements b/storage/StorageExample/StorageExample (macOS)/StorageExample__macOS_.entitlements similarity index 100% rename from storage/StorageExample (macOS)/StorageExample__macOS_.entitlements rename to storage/StorageExample/StorageExample (macOS)/StorageExample__macOS_.entitlements diff --git a/storage/StorageExample (tvOS)/Assets.xcassets/AccentColor.colorset/Contents.json b/storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from storage/StorageExample (tvOS)/Assets.xcassets/AccentColor.colorset/Contents.json rename to storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json rename to storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json diff --git a/storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json b/storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json similarity index 100% rename from storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json rename to storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json diff --git a/storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json b/storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json similarity index 100% rename from storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json rename to storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json diff --git a/storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json rename to storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json diff --git a/storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json b/storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json similarity index 100% rename from storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json rename to storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json diff --git a/storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json rename to storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json diff --git a/storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json b/storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json similarity index 100% rename from storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json rename to storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json diff --git a/storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json rename to storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json diff --git a/storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json b/storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json similarity index 100% rename from storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json rename to storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json diff --git a/storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json b/storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json similarity index 100% rename from storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json rename to storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json diff --git a/storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json rename to storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json diff --git a/storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json b/storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json similarity index 100% rename from storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json rename to storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json diff --git a/storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json similarity index 100% rename from storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json rename to storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json diff --git a/storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json b/storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json similarity index 100% rename from storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json rename to storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json diff --git a/storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json b/storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json similarity index 100% rename from storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json rename to storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json diff --git a/storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json b/storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json similarity index 100% rename from storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json rename to storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json diff --git a/storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json b/storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json similarity index 100% rename from storage/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json rename to storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json diff --git a/storage/StorageExample (tvOS)/Assets.xcassets/Contents.json b/storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/Contents.json similarity index 100% rename from storage/StorageExample (tvOS)/Assets.xcassets/Contents.json rename to storage/StorageExample/StorageExample (tvOS)/Assets.xcassets/Contents.json diff --git a/storage/StorageExample (tvOS)/Preview Content/Preview Assets.xcassets/Contents.json b/storage/StorageExample/StorageExample (tvOS)/Preview Content/Preview Assets.xcassets/Contents.json similarity index 100% rename from storage/StorageExample (tvOS)/Preview Content/Preview Assets.xcassets/Contents.json rename to storage/StorageExample/StorageExample (tvOS)/Preview Content/Preview Assets.xcassets/Contents.json diff --git a/storage/StorageExample.xcodeproj/project.pbxproj b/storage/StorageExample/StorageExample.xcodeproj/project.pbxproj similarity index 96% rename from storage/StorageExample.xcodeproj/project.pbxproj rename to storage/StorageExample/StorageExample.xcodeproj/project.pbxproj index 58948f61c..eb6b98ba3 100644 --- a/storage/StorageExample.xcodeproj/project.pbxproj +++ b/storage/StorageExample/StorageExample.xcodeproj/project.pbxproj @@ -11,12 +11,14 @@ 864F1ABA2A964D27009743F2 /* FirebaseStorage in Frameworks */ = {isa = PBXBuildFile; productRef = 864F1AB92A964D27009743F2 /* FirebaseStorage */; }; 864F1ABC2A964D31009743F2 /* FirebaseStorage in Frameworks */ = {isa = PBXBuildFile; productRef = 864F1ABB2A964D31009743F2 /* FirebaseStorage */; }; B9380F7627E3EEBD00B5C769 /* FirebaseAuth in Frameworks */ = {isa = PBXBuildFile; productRef = B9380F7527E3EEBD00B5C769 /* FirebaseAuth */; }; + B9380F7A27E3FABA00B5C769 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B9380F7927E3FABA00B5C769 /* GoogleService-Info.plist */; }; B94D0AC327F5060D00753EEA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B94D0AC227F5060D00753EEA /* Assets.xcassets */; }; B94D0AC627F5060D00753EEA /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B94D0AC527F5060D00753EEA /* Preview Assets.xcassets */; }; B94D0ACB27F506C000753EEA /* StorageExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = B983CA1527F21B1D00E4E201 /* StorageExampleApp.swift */; }; B94D0ACC27F506C600753EEA /* ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B983CA1627F21B1D00E4E201 /* ViewModel.swift */; }; B94D0ACD27F506CC00753EEA /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B983CA1827F21B1D00E4E201 /* ContentView.swift */; }; B94D0ACF27F5075900753EEA /* FirebaseAuth in Frameworks */ = {isa = PBXBuildFile; productRef = B94D0ACE27F5075900753EEA /* FirebaseAuth */; }; + B94D0AD227F5157400753EEA /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B9380F7927E3FABA00B5C769 /* GoogleService-Info.plist */; }; B94D0AD327F52FBB00753EEA /* ImagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B983CA1727F21B1D00E4E201 /* ImagePicker.swift */; }; B983CA1927F21B1D00E4E201 /* StorageExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = B983CA1527F21B1D00E4E201 /* StorageExampleApp.swift */; }; B983CA1A27F21B1D00E4E201 /* ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B983CA1627F21B1D00E4E201 /* ViewModel.swift */; }; @@ -31,12 +33,11 @@ B9EABE3527FB83CD00E055FD /* ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B983CA1627F21B1D00E4E201 /* ViewModel.swift */; }; B9EABE3627FB83D100E055FD /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B983CA1827F21B1D00E4E201 /* ContentView.swift */; }; B9EABE3727FB83D100E055FD /* ImagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B983CA1727F21B1D00E4E201 /* ImagePicker.swift */; }; - EA4A29E82E6F543800B647BC /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = EA4A29E72E6F543800B647BC /* GoogleService-Info.plist */; }; - EA4A29E92E6F543800B647BC /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = EA4A29E72E6F543800B647BC /* GoogleService-Info.plist */; }; - EA4A29EA2E6F543800B647BC /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = EA4A29E72E6F543800B647BC /* GoogleService-Info.plist */; }; + B9EABE3827FB9B2700E055FD /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B9380F7927E3FABA00B5C769 /* GoogleService-Info.plist */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + B9380F7927E3FABA00B5C769 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "../GoogleService-Info.plist"; sourceTree = ""; }; B94D0ABC27F5060C00753EEA /* StorageExample (macOS).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "StorageExample (macOS).app"; sourceTree = BUILT_PRODUCTS_DIR; }; B94D0AC227F5060D00753EEA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; B94D0AC527F5060D00753EEA /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; @@ -51,7 +52,6 @@ B9EABE2127FB82B200E055FD /* StorageExample (tvOS).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "StorageExample (tvOS).app"; sourceTree = BUILT_PRODUCTS_DIR; }; B9EABE2727FB82B300E055FD /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; B9EABE2A27FB82B300E055FD /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - EA4A29E72E6F543800B647BC /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -117,7 +117,7 @@ B9A598B127E3D169003BCFD0 = { isa = PBXGroup; children = ( - EA4A29E72E6F543800B647BC /* GoogleService-Info.plist */, + B9380F7927E3FABA00B5C769 /* GoogleService-Info.plist */, B983CA1427F21B1D00E4E201 /* Shared */, B9A598BC27E3D169003BCFD0 /* StorageExample (iOS) */, B94D0ABD27F5060C00753EEA /* StorageExample (macOS) */, @@ -202,9 +202,9 @@ productReference = B94D0ABC27F5060C00753EEA /* StorageExample (macOS).app */; productType = "com.apple.product-type.application"; }; - B9A598B927E3D169003BCFD0 /* StorageExample */ = { + B9A598B927E3D169003BCFD0 /* StorageExample (iOS) */ = { isa = PBXNativeTarget; - buildConfigurationList = B9A598C827E3D16A003BCFD0 /* Build configuration list for PBXNativeTarget "StorageExample" */; + buildConfigurationList = B9A598C827E3D16A003BCFD0 /* Build configuration list for PBXNativeTarget "StorageExample (iOS)" */; buildPhases = ( B9A598B627E3D169003BCFD0 /* Sources */, B9A598B727E3D169003BCFD0 /* Frameworks */, @@ -214,7 +214,7 @@ ); dependencies = ( ); - name = StorageExample; + name = "StorageExample (iOS)"; packageProductDependencies = ( B9380F7527E3EEBD00B5C769 /* FirebaseAuth */, 864F1AB72A964D11009743F2 /* FirebaseStorage */, @@ -252,7 +252,7 @@ attributes = { BuildIndependentTargetsInParallel = 1; LastSwiftUpdateCheck = 1330; - LastUpgradeCheck = 1610; + LastUpgradeCheck = 1330; TargetAttributes = { B94D0ABB27F5060C00753EEA = { CreatedOnToolsVersion = 13.3; @@ -282,7 +282,7 @@ projectDirPath = ""; projectRoot = ""; targets = ( - B9A598B927E3D169003BCFD0 /* StorageExample */, + B9A598B927E3D169003BCFD0 /* StorageExample (iOS) */, B94D0ABB27F5060C00753EEA /* StorageExample (macOS) */, B9EABE2027FB82B200E055FD /* StorageExample (tvOS) */, ); @@ -296,7 +296,7 @@ files = ( B94D0AC627F5060D00753EEA /* Preview Assets.xcassets in Resources */, B94D0AC327F5060D00753EEA /* Assets.xcassets in Resources */, - EA4A29EA2E6F543800B647BC /* GoogleService-Info.plist in Resources */, + B94D0AD227F5157400753EEA /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -306,7 +306,7 @@ files = ( B9A598C527E3D16A003BCFD0 /* Preview Assets.xcassets in Resources */, B9A598C227E3D16A003BCFD0 /* Assets.xcassets in Resources */, - EA4A29E92E6F543800B647BC /* GoogleService-Info.plist in Resources */, + B9380F7A27E3FABA00B5C769 /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -316,7 +316,7 @@ files = ( B9EABE2B27FB82B300E055FD /* Preview Assets.xcassets in Resources */, B9EABE2827FB82B300E055FD /* Assets.xcassets in Resources */, - EA4A29E82E6F543800B647BC /* GoogleService-Info.plist in Resources */, + B9EABE3827FB9B2700E055FD /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -368,7 +368,6 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; - DEAD_CODE_STRIPPING = YES; DEVELOPMENT_ASSET_PATHS = "\"StorageExample (macOS)/Preview Content\""; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; @@ -396,7 +395,6 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; - DEAD_CODE_STRIPPING = YES; DEVELOPMENT_ASSET_PATHS = "\"StorageExample (macOS)/Preview Content\""; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; @@ -451,7 +449,6 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -512,7 +509,6 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -673,7 +669,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - B9A598C827E3D16A003BCFD0 /* Build configuration list for PBXNativeTarget "StorageExample" */ = { + B9A598C827E3D16A003BCFD0 /* Build configuration list for PBXNativeTarget "StorageExample (iOS)" */ = { isa = XCConfigurationList; buildConfigurations = ( B9A598C927E3D16A003BCFD0 /* Debug */, @@ -699,7 +695,7 @@ repositoryURL = "https://github.com/firebase/firebase-ios-sdk"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 11.0.0; + minimumVersion = 10.0.0; }; }; /* End XCRemoteSwiftPackageReference section */