diff --git a/.github/workflows/release-ecosystem-from-main.yml b/.github/workflows/release-ecosystem-from-main.yml new file mode 100644 index 000000000..b6e67fd8a --- /dev/null +++ b/.github/workflows/release-ecosystem-from-main.yml @@ -0,0 +1,180 @@ +name: Release mParticle Ecosystem + +on: + push: + # TODO: Remove ci/** after testing + branches: + - main + - "ci/**" + paths: + - "VERSION" + - ".github/workflows/release-ecosystem-from-main.yml" + workflow_dispatch: + inputs: + dry_run: + description: "Dry run — skip creating real releases/tags" + type: boolean + default: true + +env: + # TODO: Remove after testing + DRY_RUN: true + +permissions: + contents: write + +jobs: + prepare: + runs-on: ubuntu-latest + outputs: + version: ${{ steps.version.outputs.version }} + tag: ${{ steps.version.outputs.tag }} + steps: + - uses: actions/checkout@v6 + + - name: Get ecosystem version + id: version + run: | + VERSION=$(head -n 1 VERSION | tr -d '\r\n ') + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "tag=v$VERSION" >> $GITHUB_OUTPUT + echo "📌 Ecosystem version: $VERSION" + + mirror-and-release-kits: + needs: prepare + runs-on: macOS-15 + env: + DEST_ORG: mparticle-integrations + XCODE_VERSION: "16.4" + strategy: + fail-fast: false + matrix: + kit: + - name: braze-12 + local_path: kits/braze/braze-12 + dest_repo: mparticle-apple-integration-braze-12 + ios_scheme: mParticle-Appboy + module: mParticle_Appboy + # - name: braze-13 + # local_path: kits/braze/braze-13 + # dest_repo: mparticle-apple-integration-braze-13 + # ios_scheme: mParticle-Appboy + # module: mParticle_Appboy + # - name: braze-14 + # local_path: kits/braze/braze-14 + # dest_repo: mparticle-apple-integration-braze-14 + # ios_scheme: mParticle-Appboy + # module: mParticle_Appboy + + steps: + - name: Checkout monorepo + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Select Xcode + run: sudo xcode-select -s /Applications/Xcode_${{ env.XCODE_VERSION }}.app + + - name: Build kit xcframework from Package.swift + working-directory: ${{ matrix.kit.local_path }} + run: | + MODULE="${{ matrix.kit.module }}" + SCHEME="${{ matrix.kit.ios_scheme }}" + + xcodebuild archive -scheme "$SCHEME" \ + -destination "generic/platform=iOS" -archivePath "archives/iOS" + xcodebuild archive -scheme "$SCHEME" \ + -destination "generic/platform=iOS Simulator" -archivePath "archives/iOS_Simulator" + + XCFRAMEWORK_ARGS=( + -archive archives/iOS.xcarchive -framework "${MODULE}.framework" + -archive archives/iOS_Simulator.xcarchive -framework "${MODULE}.framework" + ) + + xcodebuild -create-xcframework "${XCFRAMEWORK_ARGS[@]}" -output "${MODULE}.xcframework" + zip -r "${MODULE}.xcframework.zip" "${MODULE}.xcframework" + rm -rf archives "${MODULE}.xcframework" + + - name: Configure Git + run: | + git config user.name "mParticle Bot" + git config user.email "developers@mparticle.com" + + - name: Generate GitHub App Token + id: generate-token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ secrets.SDK_RELEASE_GITHUB_APP_ID }} + private-key: ${{ secrets.SDK_RELEASE_GITHUB_APP_PRIVATE_KEY }} + owner: ${{ env.DEST_ORG }} + repositories: ${{ matrix.kit.dest_repo }} + permission-contents: write + + - name: Extract kit release notes + id: release-notes + uses: ffurrer2/extract-release-notes@202313ec7461b6b9e401996714484690ab1ae105 # v3.0.0 + with: + changelog_file: ${{ matrix.kit.local_path }}/CHANGELOG.md + + - name: Split kit and push to mirror + id: mirror + run: | + SPLIT_BRANCH="split/${{ matrix.kit.name }}" + git subtree split --prefix ${{ matrix.kit.local_path }} -b "${SPLIT_BRANCH}" + + - name: Checkout destination repo + uses: actions/checkout@v6 + with: + repository: ${{ env.DEST_ORG }}/${{ matrix.kit.dest_repo }} + token: ${{ steps.generate-token.outputs.token }} + path: dest + + - name: Push split to destination + if: env.DRY_RUN != 'true' + id: push + run: | + git -C dest fetch "$GITHUB_WORKSPACE" "split/${{ matrix.kit.name }}:refs/heads/incoming" + git -C dest reset --hard incoming + git -C dest push origin main --force + echo "sha=$(git -C dest rev-parse HEAD)" >> $GITHUB_OUTPUT + + - name: Create GitHub release on mirror + if: env.DRY_RUN != 'true' + uses: ncipollo/release-action@b7eabc95ff50cbeeedec83973935c8f306dfcd0b # v1.20.0 + with: + tag: ${{ needs.prepare.outputs.tag }} + commit: ${{ steps.push.outputs.sha }} + owner: ${{ env.DEST_ORG }} + repo: ${{ matrix.kit.dest_repo }} + token: ${{ steps.generate-token.outputs.token }} + artifacts: ${{ matrix.kit.local_path }}/${{ matrix.kit.module }}.xcframework.zip + body: | + ${{ steps.release-notes.outputs.release_notes }} + + - name: Dry run summary + if: env.DRY_RUN == 'true' + run: | + COMMITS=$(git log "split/${{ matrix.kit.name }}" --oneline -5) + cat >> $GITHUB_STEP_SUMMARY </dev/null | sed 's/^v//' || echo "0.0.0") + echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT + + - name: Bump version + id: bump-version + uses: actions-ecosystem/action-bump-semver@v1 + with: + current_version: ${{ steps.current-version.outputs.version }} + level: ${{ github.event.inputs.bump-type }} + + - name: Set version environment variables + run: | + VERSION=$(echo "${{ steps.bump-version.outputs.new_version }}" | sed 's/^v//') + MAJOR=$(echo "$VERSION" | cut -d. -f1) + echo "VERSION=$VERSION" >> $GITHUB_ENV + echo "MAJOR=$MAJOR" >> $GITHUB_ENV + echo "📌 ${{ steps.current-version.outputs.version }} → $VERSION (${{ github.event.inputs.bump-type }})" + + - name: Setup git config + run: | + git config user.email "developers@mparticle.com" + git config user.name "mParticle Automation" + + - name: Create release branch + run: | + git push origin --delete chore/release-v${VERSION} 2>/dev/null || true + git checkout -b chore/release-v${VERSION} + + - name: Generate changelog entry + run: | + PREV_TAG="v${{ steps.current-version.outputs.version }}" + if [ "$PREV_TAG" = "v0.0.0" ]; then PREV_TAG=""; fi + DATE=$(date +%Y-%m-%d) + + echo "# [${VERSION}](https://github.com/mParticle/mparticle-apple-sdk/compare/${PREV_TAG}...v${VERSION}) (${DATE})" > /tmp/changelog_entry.md + echo "" >> /tmp/changelog_entry.md + + if [ -n "$PREV_TAG" ]; then + FIXES=$(git log ${PREV_TAG}..HEAD --pretty=format:"- %s ([%h](https://github.com/mParticle/mparticle-apple-sdk/commit/%H))" --grep="^fix" --regexp-ignore-case 2>/dev/null || true) + if [ -n "$FIXES" ]; then + echo -e "### Bug Fixes\n\n$FIXES\n" >> /tmp/changelog_entry.md + fi + + FEATURES=$(git log ${PREV_TAG}..HEAD --pretty=format:"- %s ([%h](https://github.com/mParticle/mparticle-apple-sdk/commit/%H))" --grep="^feat" --regexp-ignore-case 2>/dev/null || true) + if [ -n "$FEATURES" ]; then + echo -e "### Features\n\n$FEATURES\n" >> /tmp/changelog_entry.md + fi + + if [ -z "$FIXES" ] && [ -z "$FEATURES" ]; then + OTHER=$(git log ${PREV_TAG}..HEAD --pretty=format:"- %s ([%h](https://github.com/mParticle/mparticle-apple-sdk/commit/%H))" 2>/dev/null || true) + if [ -n "$OTHER" ]; then + echo -e "### Changes\n\n$OTHER\n" >> /tmp/changelog_entry.md + fi + fi + else + echo -e "### Initial Release\n" >> /tmp/changelog_entry.md + fi + + if [ -f CHANGELOG.md ]; then + cat /tmp/changelog_entry.md CHANGELOG.md > /tmp/new_changelog.md + mv /tmp/new_changelog.md CHANGELOG.md + else + mv /tmp/changelog_entry.md CHANGELOG.md + fi + + - name: Update VERSION file + run: echo "$VERSION" > VERSION + + - name: Update version in all podspecs + run: | + find . -name "*.podspec" -exec \ + sed -i '' 's/\(s\.version[^=]*=[[:space:]]*\)"[^"]*"/\1"'"${VERSION}"'"/' {} + + + - name: Update version in MPIConstants.m + run: sed -i '' "s/kMParticleSDKVersion = @\"[^\"]*\"/kMParticleSDKVersion = @\"${VERSION}\"/" mParticle-Apple-SDK/MPIConstants.m + + - name: Update version in MPConstants.swift + run: sed -i '' "s/let kMParticleSDKVersion = \"[^\"]*\"/let kMParticleSDKVersion = \"${VERSION}\"/" mParticle-Apple-SDK/MPConstants.swift + + - name: Update version in Info.plist + run: /usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${VERSION}" Framework/Info.plist + + - name: Update SDK version in integration test mappings + run: ./Scripts/update_mapping_versions.sh "${VERSION}" + + - name: Update kit dependency on core SDK for major release + if: github.event.inputs.bump-type == 'major' + run: | + # Podspec: '~> X.Y' → '~> MAJOR.0' + find kits -name "*.podspec" -exec \ + sed -i '' "s/'mParticle-Apple-SDK', '~> [^']*'/'mParticle-Apple-SDK', '~> ${MAJOR}.0'/" {} + + + # Package.swift: .upToNextMajor(from: "X.Y.Z") → .upToNextMajor(from: "MAJOR.0.0") + find kits -name "Package.swift" -exec \ + sed -i '' "/mparticle-apple-sdk/{ + n + s/.upToNextMajor(from: \"[^\"]*\")/.upToNextMajor(from: \"${MAJOR}.0.0\")/ + s/branch: \"[^\"]*\"/.upToNextMajor(from: \"${MAJOR}.0.0\")/ + }" {} + + + # --- Commit, push, and create PR --- + + - name: Commit version changes + run: | + trunk fmt + git add \ + VERSION \ + CHANGELOG.md \ + Framework/Info.plist \ + mParticle-Apple-SDK.podspec \ + mParticle-Apple-SDK-Swift/mParticle-Apple-SDK-Swift.podspec \ + mParticle-Apple-SDK/MPConstants.swift \ + mParticle-Apple-SDK/MPIConstants.m \ + IntegrationTests/wiremock-recordings/mappings/*.json \ + kits/ + + git commit -m "chore: (release) ${VERSION} + + Updates version to ${VERSION} across the mParticle ecosystem." + + - name: Push release branch + run: git push origin chore/release-v${VERSION} + + - name: Create Pull Request + env: + GH_TOKEN: ${{ secrets.MP_SEMANTIC_RELEASE_BOT }} + run: | + gh pr create \ + --base main \ + --head chore/release-v${VERSION} \ + --title "chore: Release v${VERSION}" \ + --body "## Release v${VERSION} + + ### Bump type: \`${{ github.event.inputs.bump-type }}\` + + This PR contains the version bump and changelog updates for release ${VERSION}. + + ### Files updated + - All podspecs (core, Swift, kits) → \`${VERSION}\` + - \`mParticle-Apple-SDK/MPIConstants.m\` + - \`mParticle-Apple-SDK/MPConstants.swift\` + - \`Framework/Info.plist\` + - \`CHANGELOG.md\` + - Integration test mappings + + --- + + **On merge:** The [Release mParticle Ecosystem](https://github.com/mParticle/mparticle-apple-sdk/actions/workflows/release-ecosystem-from-main.yml) workflow will automatically create tags and GitHub releases for the core SDK and all mirrored kit repos." \ + --reviewer mParticle/sdk-team diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 2f9171511..a7d72f3e4 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -72,6 +72,7 @@ lint: - linters: [markdownlint] paths: - CHANGELOG.md # Standard changelog format violates MD001, MD024, MD025 + - kits/braze/braze-12/CHANGELOG.md actions: enabled: diff --git a/VERSION b/VERSION new file mode 100644 index 000000000..9d39066d3 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +8.42.2 diff --git a/kits/braze/braze-12/AppboyTestHost/AppDelegate.swift b/kits/braze/braze-12/AppboyTestHost/AppDelegate.swift new file mode 100644 index 000000000..7a5212c6f --- /dev/null +++ b/kits/braze/braze-12/AppboyTestHost/AppDelegate.swift @@ -0,0 +1,23 @@ +// +// AppDelegate.swift +// AppboyTestHost +// +// Created by Ben Baron on 5/16/23. +// Copyright © 2023 mParticle. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + // Override point for customization after application launch. + return true + } +} diff --git a/kits/braze/braze-12/AppboyTestHost/Assets.xcassets/AccentColor.colorset/Contents.json b/kits/braze/braze-12/AppboyTestHost/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 000000000..0afb3cf0e --- /dev/null +++ b/kits/braze/braze-12/AppboyTestHost/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors": [ + { + "idiom": "universal" + } + ], + "info": { + "author": "xcode", + "version": 1 + } +} diff --git a/kits/braze/braze-12/AppboyTestHost/Assets.xcassets/AppIcon.appiconset/Contents.json b/kits/braze/braze-12/AppboyTestHost/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..b121e3bce --- /dev/null +++ b/kits/braze/braze-12/AppboyTestHost/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,13 @@ +{ + "images": [ + { + "idiom": "universal", + "platform": "ios", + "size": "1024x1024" + } + ], + "info": { + "author": "xcode", + "version": 1 + } +} diff --git a/kits/braze/braze-12/AppboyTestHost/Assets.xcassets/Contents.json b/kits/braze/braze-12/AppboyTestHost/Assets.xcassets/Contents.json new file mode 100644 index 000000000..74d6a722c --- /dev/null +++ b/kits/braze/braze-12/AppboyTestHost/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info": { + "author": "xcode", + "version": 1 + } +} diff --git a/kits/braze/braze-12/AppboyTestHost/Base.lproj/LaunchScreen.storyboard b/kits/braze/braze-12/AppboyTestHost/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 000000000..865e9329f --- /dev/null +++ b/kits/braze/braze-12/AppboyTestHost/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kits/braze/braze-12/AppboyTestHost/Base.lproj/Main.storyboard b/kits/braze/braze-12/AppboyTestHost/Base.lproj/Main.storyboard new file mode 100644 index 000000000..25a763858 --- /dev/null +++ b/kits/braze/braze-12/AppboyTestHost/Base.lproj/Main.storyboard @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kits/braze/braze-12/AppboyTestHost/Info.plist b/kits/braze/braze-12/AppboyTestHost/Info.plist new file mode 100644 index 000000000..0c67376eb --- /dev/null +++ b/kits/braze/braze-12/AppboyTestHost/Info.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/kits/braze/braze-12/AppboyTestHost/ViewController.swift b/kits/braze/braze-12/AppboyTestHost/ViewController.swift new file mode 100644 index 000000000..b9a63bbde --- /dev/null +++ b/kits/braze/braze-12/AppboyTestHost/ViewController.swift @@ -0,0 +1,4 @@ +import UIKit + +class ViewController: UIViewController { +} diff --git a/kits/braze/braze-12/CHANGELOG.md b/kits/braze/braze-12/CHANGELOG.md new file mode 100644 index 000000000..6ee59f592 --- /dev/null +++ b/kits/braze/braze-12/CHANGELOG.md @@ -0,0 +1,111 @@ +# [8.11.0](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/compare/v8.10.2...v8.11.0) (2024-11-19) + +### Bug Fixes + +- Bump min Braze SDK to 11.2 ([#102](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/issues/102)) ([03c3ab2](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/commit/03c3ab265131364e7caf00f7b67e017698916bb7)) + +### Features + +- Add sendProductName Option to Braze ([#100](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/issues/100)) ([f8deb1e](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/commit/f8deb1ea38ed016939e1ea9f25cfeacbaf8d7834)) + +## [8.10.2](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/compare/v8.10.1...v8.10.2) (2024-11-06) + +### Bug Fixes + +- prevent mpid with value 0 to forward to Braze ([#99](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/issues/99)) ([69255c2](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/commit/69255c28df2376fdf47b5fff25c3d67a6383069d)) + +## [8.10.1](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/compare/v8.10.0...v8.10.1) (2024-10-18) + +### Bug Fixes + +- Update consent attributes after kit is initialized ([#98](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/issues/98)) ([0d74b3c](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/commit/0d74b3c925e7c014c8d236a30bcf335d4dc4a4d5)) + +# [8.10.0](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/compare/v8.9.0...v8.10.0) (2024-10-16) + +### Features + +- Update Braze Kit to V11 ([#97](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/issues/97)) ([d93e071](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/commit/d93e0718f420c5a175c9e78d9387d021684cd351)) + +# [8.9.0](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/compare/v8.8.1...v8.9.0) (2024-10-02) + +### Features + +- Support workspace switching ([#95](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/issues/95)) ([a80ce1d](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/commit/a80ce1d35ee3b42e971849bf09e68c922901876c)) + +## [8.8.1](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/compare/v8.8.0...v8.8.1) (2024-09-30) + +### Bug Fixes + +- Update Package.swift to match Podspec ([#96](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/issues/96)) ([eddc5e5](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/commit/eddc5e57dfa24841fc2228109931994ff039bff0)) + +# [8.8.0](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/compare/v8.7.2...v8.8.0) (2024-09-09) + +### Features + +- Implement Google EU Consent ([#94](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/issues/94)) ([2f97151](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/commit/2f971517f1b6c7f25d0f489539c765510e1931d9)) + +## [8.7.2](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/compare/v8.7.1...v8.7.2) (2024-06-24) + +### Bug Fixes + +- Kit fails to start due to missing kitApi property ([#93](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/issues/93)) ([10bf509](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/commit/10bf5091b2e29b7e60a0b214b1b205fa8b360c05)) + +## [8.7.1](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/compare/v8.7.0...v8.7.1) (2024-06-18) + +### Bug Fixes + +- Forward screen events and collect IDFA configs when using an external Braze instance ([#92](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/issues/92)) ([a8c4706](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/commit/a8c4706518c804b977831b33d071f8fbbce61d54)) + +# [8.7.0](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/compare/v8.6.1...v8.7.0) (2024-06-12) + +### Features + +- Update External iD on Initialization ([#91](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/issues/91)) ([5e1d301](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/commit/5e1d301aacb2efa1a5c4dcd1686012da5bc24654)) + +## [8.6.1](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/compare/v8.6.0...v8.6.1) (2024-05-28) + +### Bug Fixes + +- Setting urlDelegate on Braze instance ([#90](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/issues/90)) ([596c250](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/commit/596c250ba2b6543cfbb534af4bc74781eed2b12d)) + +# [8.6.0](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/compare/v8.5.0...v8.6.0) (2024-05-01) + +### Features + +- Update to Braze 9.x.x SDK, improve privacy manifest support ([#89](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/issues/89)) ([979b259](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/commit/979b259de22c31fe4b1a8686756bcf5093b9642f)) + +# [8.5.0](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/compare/v8.4.0...v8.5.0) (2024-03-07) + +### Features + +- Update Braze with Privacy Manifest ([#88](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/issues/88)) ([8eb56d3](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/commit/8eb56d3a039ae3d7dd6ad33071743c084c5f585a)) + +# [8.4.0](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/compare/v8.3.1...v8.4.0) (2024-02-21) + +### Features + +- Allow setting Braze instance and override notification handling ([#87](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/issues/87)) ([c3c76c1](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/commit/c3c76c1724ce3c822b9c62cb40582871c7e032fe)) + +## [8.3.1](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/compare/v8.3.0...v8.3.1) (2024-02-07) + +### Bug Fixes + +- Deleting property stripping from product when sent unbundled ([#86](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/issues/86)) ([d0b477b](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/commit/d0b477b78b6e3364de9b5f0eaeabdf64c9ec45a0)) + +# [8.3.0](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/compare/v8.2.5...v8.3.0) (2023-12-13) + +### Features + +- Update Braze to Latest Version ([#85](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/issues/85)) ([559937b](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/commit/559937be481b2018d0a549efc6d077178e2e4aaf)) + +## [8.2.5](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/compare/v8.2.4...v8.2.5) (2023-12-08) + +### Bug Fixes + +- Use Umbrella Imports ([#84](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/issues/84)) ([2782055](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/commit/278205520c7bcfbadd9d08b40555cb422a316490)) + +## [8.2.4](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/compare/v8.2.3...v8.2.4) (2023-11-02) + +### Bug Fixes + +- Bundle commerce event setting ([#83](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/issues/83)) ([1fc5f40](https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/commit/1fc5f401b4eed836c47d9e0705a5b66d38c9df1f)) diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/Podfile b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/Podfile new file mode 100644 index 000000000..b96a87f8c --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/Podfile @@ -0,0 +1,21 @@ +# Uncomment the next line to define a global platform for your project +# platform :ios, '9.0' + +target 'mParticle-Appboy-tvOS-Example' do + # Uncomment the next line if you're using Swift or would like to use dynamic frameworks + # use_frameworks! + + # Pods for mParticle-Appboy-tvOS-Example + pod 'mParticle-Appboy', :path => '../..' + + target 'mParticle-Appboy-tvOS-ExampleTests' do + inherit! :search_paths + # Pods for testing + end + + target 'mParticle-Appboy-tvOS-ExampleUITests' do + inherit! :search_paths + # Pods for testing + end + +end diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example.xcodeproj/project.pbxproj b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example.xcodeproj/project.pbxproj new file mode 100644 index 000000000..5e5d7a460 --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example.xcodeproj/project.pbxproj @@ -0,0 +1,673 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 17535475A2413657C2C1E785 /* libPods-mParticle-Appboy-tvOS-ExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A0C82FBA52E1027516742AD /* libPods-mParticle-Appboy-tvOS-ExampleTests.a */; }; + B577EC88F9901EAC4D5558DE /* libPods-mParticle-Appboy-tvOS-ExampleUITests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B7870024D5801479AF064BAA /* libPods-mParticle-Appboy-tvOS-ExampleUITests.a */; }; + DBDEDDB6209BAAC000DD3B9B /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DBDEDDB5209BAAC000DD3B9B /* AppDelegate.m */; }; + DBDEDDB9209BAAC000DD3B9B /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DBDEDDB8209BAAC000DD3B9B /* ViewController.m */; }; + DBDEDDBC209BAAC000DD3B9B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DBDEDDBA209BAAC000DD3B9B /* Main.storyboard */; }; + DBDEDDBE209BAAC200DD3B9B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DBDEDDBD209BAAC200DD3B9B /* Assets.xcassets */; }; + DBDEDDC1209BAAC200DD3B9B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DBDEDDC0209BAAC200DD3B9B /* main.m */; }; + DBDEDDCB209BAAC200DD3B9B /* mParticle_Appboy_tvOS_ExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DBDEDDCA209BAAC200DD3B9B /* mParticle_Appboy_tvOS_ExampleTests.m */; }; + DBDEDDD6209BAAC200DD3B9B /* mParticle_Appboy_tvOS_ExampleUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = DBDEDDD5209BAAC200DD3B9B /* mParticle_Appboy_tvOS_ExampleUITests.m */; }; + E16C876314712579B07EFBDE /* libPods-mParticle-Appboy-tvOS-Example.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 10B9F0B06F3654507683F9D3 /* libPods-mParticle-Appboy-tvOS-Example.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + DBDEDDC7209BAAC200DD3B9B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DBDEDDA9209BAAC000DD3B9B /* Project object */; + proxyType = 1; + remoteGlobalIDString = DBDEDDB0209BAAC000DD3B9B; + remoteInfo = "mParticle-Appboy-tvOS-Example"; + }; + DBDEDDD2209BAAC200DD3B9B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DBDEDDA9209BAAC000DD3B9B /* Project object */; + proxyType = 1; + remoteGlobalIDString = DBDEDDB0209BAAC000DD3B9B; + remoteInfo = "mParticle-Appboy-tvOS-Example"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 0A5A1A7877715F30E127818E /* Pods-mParticle-Appboy-tvOS-ExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-mParticle-Appboy-tvOS-ExampleTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-mParticle-Appboy-tvOS-ExampleTests/Pods-mParticle-Appboy-tvOS-ExampleTests.release.xcconfig"; sourceTree = ""; }; + 10B9F0B06F3654507683F9D3 /* libPods-mParticle-Appboy-tvOS-Example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-mParticle-Appboy-tvOS-Example.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 23DACD9BFFDB7DB5EB8C3840 /* Pods-mParticle-Appboy-tvOS-ExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-mParticle-Appboy-tvOS-ExampleTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-mParticle-Appboy-tvOS-ExampleTests/Pods-mParticle-Appboy-tvOS-ExampleTests.debug.xcconfig"; sourceTree = ""; }; + 38243F334A614C276053E3E9 /* Pods-mParticle-Appboy-tvOS-ExampleUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-mParticle-Appboy-tvOS-ExampleUITests.release.xcconfig"; path = "Pods/Target Support Files/Pods-mParticle-Appboy-tvOS-ExampleUITests/Pods-mParticle-Appboy-tvOS-ExampleUITests.release.xcconfig"; sourceTree = ""; }; + 4550D0252B2DED98A6F071B5 /* Pods-mParticle-Appboy-tvOS-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-mParticle-Appboy-tvOS-Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-mParticle-Appboy-tvOS-Example/Pods-mParticle-Appboy-tvOS-Example.debug.xcconfig"; sourceTree = ""; }; + 9A0C82FBA52E1027516742AD /* libPods-mParticle-Appboy-tvOS-ExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-mParticle-Appboy-tvOS-ExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + A09B15360B87FF411E2ACE43 /* Pods-mParticle-Appboy-tvOS-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-mParticle-Appboy-tvOS-Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-mParticle-Appboy-tvOS-Example/Pods-mParticle-Appboy-tvOS-Example.release.xcconfig"; sourceTree = ""; }; + A2C8A5663E5E53DDF96C3294 /* Pods-mParticle-Appboy-tvOS-ExampleUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-mParticle-Appboy-tvOS-ExampleUITests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-mParticle-Appboy-tvOS-ExampleUITests/Pods-mParticle-Appboy-tvOS-ExampleUITests.debug.xcconfig"; sourceTree = ""; }; + B7870024D5801479AF064BAA /* libPods-mParticle-Appboy-tvOS-ExampleUITests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-mParticle-Appboy-tvOS-ExampleUITests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + DBDEDDB1209BAAC000DD3B9B /* mParticle-Appboy-tvOS-Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "mParticle-Appboy-tvOS-Example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + DBDEDDB4209BAAC000DD3B9B /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + DBDEDDB5209BAAC000DD3B9B /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + DBDEDDB7209BAAC000DD3B9B /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + DBDEDDB8209BAAC000DD3B9B /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + DBDEDDBB209BAAC000DD3B9B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + DBDEDDBD209BAAC200DD3B9B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + DBDEDDBF209BAAC200DD3B9B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + DBDEDDC0209BAAC200DD3B9B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + DBDEDDC6209BAAC200DD3B9B /* mParticle-Appboy-tvOS-ExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "mParticle-Appboy-tvOS-ExampleTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + DBDEDDCA209BAAC200DD3B9B /* mParticle_Appboy_tvOS_ExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = mParticle_Appboy_tvOS_ExampleTests.m; sourceTree = ""; }; + DBDEDDCC209BAAC200DD3B9B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + DBDEDDD1209BAAC200DD3B9B /* mParticle-Appboy-tvOS-ExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "mParticle-Appboy-tvOS-ExampleUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + DBDEDDD5209BAAC200DD3B9B /* mParticle_Appboy_tvOS_ExampleUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = mParticle_Appboy_tvOS_ExampleUITests.m; sourceTree = ""; }; + DBDEDDD7209BAAC200DD3B9B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + DBDEDDAE209BAAC000DD3B9B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + E16C876314712579B07EFBDE /* libPods-mParticle-Appboy-tvOS-Example.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DBDEDDC3209BAAC200DD3B9B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 17535475A2413657C2C1E785 /* libPods-mParticle-Appboy-tvOS-ExampleTests.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DBDEDDCE209BAAC200DD3B9B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + B577EC88F9901EAC4D5558DE /* libPods-mParticle-Appboy-tvOS-ExampleUITests.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1EA442DBF7A01F2FB0710150 /* Pods */ = { + isa = PBXGroup; + children = ( + 4550D0252B2DED98A6F071B5 /* Pods-mParticle-Appboy-tvOS-Example.debug.xcconfig */, + A09B15360B87FF411E2ACE43 /* Pods-mParticle-Appboy-tvOS-Example.release.xcconfig */, + 23DACD9BFFDB7DB5EB8C3840 /* Pods-mParticle-Appboy-tvOS-ExampleTests.debug.xcconfig */, + 0A5A1A7877715F30E127818E /* Pods-mParticle-Appboy-tvOS-ExampleTests.release.xcconfig */, + A2C8A5663E5E53DDF96C3294 /* Pods-mParticle-Appboy-tvOS-ExampleUITests.debug.xcconfig */, + 38243F334A614C276053E3E9 /* Pods-mParticle-Appboy-tvOS-ExampleUITests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 4292DB86733A67864F4E47AE /* Frameworks */ = { + isa = PBXGroup; + children = ( + 10B9F0B06F3654507683F9D3 /* libPods-mParticle-Appboy-tvOS-Example.a */, + 9A0C82FBA52E1027516742AD /* libPods-mParticle-Appboy-tvOS-ExampleTests.a */, + B7870024D5801479AF064BAA /* libPods-mParticle-Appboy-tvOS-ExampleUITests.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + DBDEDDA8209BAAC000DD3B9B = { + isa = PBXGroup; + children = ( + DBDEDDB3209BAAC000DD3B9B /* mParticle-Appboy-tvOS-Example */, + DBDEDDC9209BAAC200DD3B9B /* mParticle-Appboy-tvOS-ExampleTests */, + DBDEDDD4209BAAC200DD3B9B /* mParticle-Appboy-tvOS-ExampleUITests */, + DBDEDDB2209BAAC000DD3B9B /* Products */, + 1EA442DBF7A01F2FB0710150 /* Pods */, + 4292DB86733A67864F4E47AE /* Frameworks */, + ); + sourceTree = ""; + }; + DBDEDDB2209BAAC000DD3B9B /* Products */ = { + isa = PBXGroup; + children = ( + DBDEDDB1209BAAC000DD3B9B /* mParticle-Appboy-tvOS-Example.app */, + DBDEDDC6209BAAC200DD3B9B /* mParticle-Appboy-tvOS-ExampleTests.xctest */, + DBDEDDD1209BAAC200DD3B9B /* mParticle-Appboy-tvOS-ExampleUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + DBDEDDB3209BAAC000DD3B9B /* mParticle-Appboy-tvOS-Example */ = { + isa = PBXGroup; + children = ( + DBDEDDB4209BAAC000DD3B9B /* AppDelegate.h */, + DBDEDDB5209BAAC000DD3B9B /* AppDelegate.m */, + DBDEDDB7209BAAC000DD3B9B /* ViewController.h */, + DBDEDDB8209BAAC000DD3B9B /* ViewController.m */, + DBDEDDBA209BAAC000DD3B9B /* Main.storyboard */, + DBDEDDBD209BAAC200DD3B9B /* Assets.xcassets */, + DBDEDDBF209BAAC200DD3B9B /* Info.plist */, + DBDEDDC0209BAAC200DD3B9B /* main.m */, + ); + path = "mParticle-Appboy-tvOS-Example"; + sourceTree = ""; + }; + DBDEDDC9209BAAC200DD3B9B /* mParticle-Appboy-tvOS-ExampleTests */ = { + isa = PBXGroup; + children = ( + DBDEDDCA209BAAC200DD3B9B /* mParticle_Appboy_tvOS_ExampleTests.m */, + DBDEDDCC209BAAC200DD3B9B /* Info.plist */, + ); + path = "mParticle-Appboy-tvOS-ExampleTests"; + sourceTree = ""; + }; + DBDEDDD4209BAAC200DD3B9B /* mParticle-Appboy-tvOS-ExampleUITests */ = { + isa = PBXGroup; + children = ( + DBDEDDD5209BAAC200DD3B9B /* mParticle_Appboy_tvOS_ExampleUITests.m */, + DBDEDDD7209BAAC200DD3B9B /* Info.plist */, + ); + path = "mParticle-Appboy-tvOS-ExampleUITests"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + DBDEDDB0209BAAC000DD3B9B /* mParticle-Appboy-tvOS-Example */ = { + isa = PBXNativeTarget; + buildConfigurationList = DBDEDDDA209BAAC200DD3B9B /* Build configuration list for PBXNativeTarget "mParticle-Appboy-tvOS-Example" */; + buildPhases = ( + 1716C4EADAF842D0634982C9 /* [CP] Check Pods Manifest.lock */, + DBDEDDAD209BAAC000DD3B9B /* Sources */, + DBDEDDAE209BAAC000DD3B9B /* Frameworks */, + DBDEDDAF209BAAC000DD3B9B /* Resources */, + 872CFDFE9BF7619112AADFB1 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "mParticle-Appboy-tvOS-Example"; + productName = "mParticle-Appboy-tvOS-Example"; + productReference = DBDEDDB1209BAAC000DD3B9B /* mParticle-Appboy-tvOS-Example.app */; + productType = "com.apple.product-type.application"; + }; + DBDEDDC5209BAAC200DD3B9B /* mParticle-Appboy-tvOS-ExampleTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = DBDEDDDD209BAAC200DD3B9B /* Build configuration list for PBXNativeTarget "mParticle-Appboy-tvOS-ExampleTests" */; + buildPhases = ( + 29D5CFFE2FC2EB1A86219020 /* [CP] Check Pods Manifest.lock */, + DBDEDDC2209BAAC200DD3B9B /* Sources */, + DBDEDDC3209BAAC200DD3B9B /* Frameworks */, + DBDEDDC4209BAAC200DD3B9B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + DBDEDDC8209BAAC200DD3B9B /* PBXTargetDependency */, + ); + name = "mParticle-Appboy-tvOS-ExampleTests"; + productName = "mParticle-Appboy-tvOS-ExampleTests"; + productReference = DBDEDDC6209BAAC200DD3B9B /* mParticle-Appboy-tvOS-ExampleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + DBDEDDD0209BAAC200DD3B9B /* mParticle-Appboy-tvOS-ExampleUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = DBDEDDE0209BAAC200DD3B9B /* Build configuration list for PBXNativeTarget "mParticle-Appboy-tvOS-ExampleUITests" */; + buildPhases = ( + D5DBAE90505F00E3A3FC886B /* [CP] Check Pods Manifest.lock */, + DBDEDDCD209BAAC200DD3B9B /* Sources */, + DBDEDDCE209BAAC200DD3B9B /* Frameworks */, + DBDEDDCF209BAAC200DD3B9B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + DBDEDDD3209BAAC200DD3B9B /* PBXTargetDependency */, + ); + name = "mParticle-Appboy-tvOS-ExampleUITests"; + productName = "mParticle-Appboy-tvOS-ExampleUITests"; + productReference = DBDEDDD1209BAAC200DD3B9B /* mParticle-Appboy-tvOS-ExampleUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + DBDEDDA9209BAAC000DD3B9B /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0930; + ORGANIZATIONNAME = mParticle; + TargetAttributes = { + DBDEDDB0209BAAC000DD3B9B = { + CreatedOnToolsVersion = 9.3; + }; + DBDEDDC5209BAAC200DD3B9B = { + CreatedOnToolsVersion = 9.3; + TestTargetID = DBDEDDB0209BAAC000DD3B9B; + }; + DBDEDDD0209BAAC200DD3B9B = { + CreatedOnToolsVersion = 9.3; + TestTargetID = DBDEDDB0209BAAC000DD3B9B; + }; + }; + }; + buildConfigurationList = DBDEDDAC209BAAC000DD3B9B /* Build configuration list for PBXProject "mParticle-Appboy-tvOS-Example" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = DBDEDDA8209BAAC000DD3B9B; + productRefGroup = DBDEDDB2209BAAC000DD3B9B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + DBDEDDB0209BAAC000DD3B9B /* mParticle-Appboy-tvOS-Example */, + DBDEDDC5209BAAC200DD3B9B /* mParticle-Appboy-tvOS-ExampleTests */, + DBDEDDD0209BAAC200DD3B9B /* mParticle-Appboy-tvOS-ExampleUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + DBDEDDAF209BAAC000DD3B9B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DBDEDDBE209BAAC200DD3B9B /* Assets.xcassets in Resources */, + DBDEDDBC209BAAC000DD3B9B /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DBDEDDC4209BAAC200DD3B9B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DBDEDDCF209BAAC200DD3B9B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 1716C4EADAF842D0634982C9 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-mParticle-Appboy-tvOS-Example-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 29D5CFFE2FC2EB1A86219020 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-mParticle-Appboy-tvOS-ExampleTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 872CFDFE9BF7619112AADFB1 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-mParticle-Appboy-tvOS-Example/Pods-mParticle-Appboy-tvOS-Example-frameworks.sh", + "${PODS_ROOT}/Appboy-tvOS-SDK/Appboy-tvOS-SDK/AppboyTVOSKit.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AppboyTVOSKit.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-mParticle-Appboy-tvOS-Example/Pods-mParticle-Appboy-tvOS-Example-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + D5DBAE90505F00E3A3FC886B /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-mParticle-Appboy-tvOS-ExampleUITests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + DBDEDDAD209BAAC000DD3B9B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DBDEDDB9209BAAC000DD3B9B /* ViewController.m in Sources */, + DBDEDDC1209BAAC200DD3B9B /* main.m in Sources */, + DBDEDDB6209BAAC000DD3B9B /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DBDEDDC2209BAAC200DD3B9B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DBDEDDCB209BAAC200DD3B9B /* mParticle_Appboy_tvOS_ExampleTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DBDEDDCD209BAAC200DD3B9B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DBDEDDD6209BAAC200DD3B9B /* mParticle_Appboy_tvOS_ExampleUITests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + DBDEDDC8209BAAC200DD3B9B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DBDEDDB0209BAAC000DD3B9B /* mParticle-Appboy-tvOS-Example */; + targetProxy = DBDEDDC7209BAAC200DD3B9B /* PBXContainerItemProxy */; + }; + DBDEDDD3209BAAC200DD3B9B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DBDEDDB0209BAAC000DD3B9B /* mParticle-Appboy-tvOS-Example */; + targetProxy = DBDEDDD2209BAAC200DD3B9B /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + DBDEDDBA209BAAC000DD3B9B /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + DBDEDDBB209BAAC000DD3B9B /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + DBDEDDD8209BAAC200DD3B9B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "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; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = appletvos; + TVOS_DEPLOYMENT_TARGET = 11.3; + }; + name = Debug; + }; + DBDEDDD9209BAAC200DD3B9B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_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; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = appletvos; + TVOS_DEPLOYMENT_TARGET = 11.3; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + DBDEDDDB209BAAC200DD3B9B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4550D0252B2DED98A6F071B5 /* Pods-mParticle-Appboy-tvOS-Example.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = Q948K5LXGZ; + INFOPLIST_FILE = "mParticle-Appboy-tvOS-Example/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.mparticle.mParticle-Appboy-tvOS-Example"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = 3; + }; + name = Debug; + }; + DBDEDDDC209BAAC200DD3B9B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A09B15360B87FF411E2ACE43 /* Pods-mParticle-Appboy-tvOS-Example.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = Q948K5LXGZ; + INFOPLIST_FILE = "mParticle-Appboy-tvOS-Example/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.mparticle.mParticle-Appboy-tvOS-Example"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = 3; + }; + name = Release; + }; + DBDEDDDE209BAAC200DD3B9B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 23DACD9BFFDB7DB5EB8C3840 /* Pods-mParticle-Appboy-tvOS-ExampleTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = DLD43Y3TRP; + INFOPLIST_FILE = "mParticle-Appboy-tvOS-ExampleTests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.mparticle.mParticle-Appboy-tvOS-ExampleTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = 3; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/mParticle-Appboy-tvOS-Example.app/mParticle-Appboy-tvOS-Example"; + }; + name = Debug; + }; + DBDEDDDF209BAAC200DD3B9B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0A5A1A7877715F30E127818E /* Pods-mParticle-Appboy-tvOS-ExampleTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = DLD43Y3TRP; + INFOPLIST_FILE = "mParticle-Appboy-tvOS-ExampleTests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.mparticle.mParticle-Appboy-tvOS-ExampleTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = 3; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/mParticle-Appboy-tvOS-Example.app/mParticle-Appboy-tvOS-Example"; + }; + name = Release; + }; + DBDEDDE1209BAAC200DD3B9B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A2C8A5663E5E53DDF96C3294 /* Pods-mParticle-Appboy-tvOS-ExampleUITests.debug.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = DLD43Y3TRP; + INFOPLIST_FILE = "mParticle-Appboy-tvOS-ExampleUITests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.mparticle.mParticle-Appboy-tvOS-ExampleUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = 3; + TEST_TARGET_NAME = "mParticle-Appboy-tvOS-Example"; + }; + name = Debug; + }; + DBDEDDE2209BAAC200DD3B9B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 38243F334A614C276053E3E9 /* Pods-mParticle-Appboy-tvOS-ExampleUITests.release.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = DLD43Y3TRP; + INFOPLIST_FILE = "mParticle-Appboy-tvOS-ExampleUITests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.mparticle.mParticle-Appboy-tvOS-ExampleUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = 3; + TEST_TARGET_NAME = "mParticle-Appboy-tvOS-Example"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + DBDEDDAC209BAAC000DD3B9B /* Build configuration list for PBXProject "mParticle-Appboy-tvOS-Example" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DBDEDDD8209BAAC200DD3B9B /* Debug */, + DBDEDDD9209BAAC200DD3B9B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DBDEDDDA209BAAC200DD3B9B /* Build configuration list for PBXNativeTarget "mParticle-Appboy-tvOS-Example" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DBDEDDDB209BAAC200DD3B9B /* Debug */, + DBDEDDDC209BAAC200DD3B9B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DBDEDDDD209BAAC200DD3B9B /* Build configuration list for PBXNativeTarget "mParticle-Appboy-tvOS-ExampleTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DBDEDDDE209BAAC200DD3B9B /* Debug */, + DBDEDDDF209BAAC200DD3B9B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DBDEDDE0209BAAC200DD3B9B /* Build configuration list for PBXNativeTarget "mParticle-Appboy-tvOS-ExampleUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DBDEDDE1209BAAC200DD3B9B /* Debug */, + DBDEDDE2209BAAC200DD3B9B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = DBDEDDA9209BAAC000DD3B9B /* Project object */; +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/AppDelegate.h b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/AppDelegate.h new file mode 100644 index 000000000..3ac1941db --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/AppDelegate.h @@ -0,0 +1,17 @@ +// +// AppDelegate.h +// mParticle-Appboy-tvOS-Example +// +// Created by Peter Jenkins on 5/3/18. +// Copyright © 2018 mParticle. All rights reserved. +// + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/AppDelegate.m b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/AppDelegate.m new file mode 100644 index 000000000..b06f71862 --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/AppDelegate.m @@ -0,0 +1,57 @@ +// +// AppDelegate.m +// mParticle-Appboy-tvOS-Example +// +// Created by Peter Jenkins on 5/3/18. +// Copyright © 2018 mParticle. All rights reserved. +// + +#import "AppDelegate.h" +#import "mParticle.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + [[MParticle sharedInstance] startWithOptions:[MParticleOptions optionsWithKey:@"REPLACE WITH YOUR MPARTICLE API KEY" secret:@"REPLACE WITH YOUR MPARTICLE API SECRET"]]; + [MParticle sharedInstance].logLevel = MPILogLevelVerbose; + + [[MParticle sharedInstance] logEvent:[[MPEvent alloc] initWithName:@"foo" type:MPEventTypeOther]]; + + return YES; +} + + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. +} + + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + + +@end diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 000000000..3b1a0cb9d --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,11 @@ +{ + "images": [ + { + "idiom": "tv" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json new file mode 100644 index 000000000..97a8662eb --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info": { + "version": 1, + "author": "xcode" + } +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json new file mode 100644 index 000000000..8e6e0c6ec --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json @@ -0,0 +1,17 @@ +{ + "layers": [ + { + "filename": "Front.imagestacklayer" + }, + { + "filename": "Middle.imagestacklayer" + }, + { + "filename": "Back.imagestacklayer" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 000000000..3b1a0cb9d --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,11 @@ +{ + "images": [ + { + "idiom": "tv" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json new file mode 100644 index 000000000..97a8662eb --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info": { + "version": 1, + "author": "xcode" + } +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 000000000..3b1a0cb9d --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,11 @@ +{ + "images": [ + { + "idiom": "tv" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json new file mode 100644 index 000000000..97a8662eb --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info": { + "version": 1, + "author": "xcode" + } +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 000000000..94575ead3 --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images": [ + { + "idiom": "tv", + "scale": "1x" + }, + { + "idiom": "tv", + "scale": "2x" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json new file mode 100644 index 000000000..97a8662eb --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info": { + "version": 1, + "author": "xcode" + } +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json new file mode 100644 index 000000000..8e6e0c6ec --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json @@ -0,0 +1,17 @@ +{ + "layers": [ + { + "filename": "Front.imagestacklayer" + }, + { + "filename": "Middle.imagestacklayer" + }, + { + "filename": "Back.imagestacklayer" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 000000000..94575ead3 --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images": [ + { + "idiom": "tv", + "scale": "1x" + }, + { + "idiom": "tv", + "scale": "2x" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json new file mode 100644 index 000000000..97a8662eb --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info": { + "version": 1, + "author": "xcode" + } +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json new file mode 100644 index 000000000..94575ead3 --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images": [ + { + "idiom": "tv", + "scale": "1x" + }, + { + "idiom": "tv", + "scale": "2x" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json new file mode 100644 index 000000000..97a8662eb --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info": { + "version": 1, + "author": "xcode" + } +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json new file mode 100644 index 000000000..ed2bb421a --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json @@ -0,0 +1,32 @@ +{ + "assets": [ + { + "size": "1280x768", + "idiom": "tv", + "filename": "App Icon - App Store.imagestack", + "role": "primary-app-icon" + }, + { + "size": "400x240", + "idiom": "tv", + "filename": "App Icon.imagestack", + "role": "primary-app-icon" + }, + { + "size": "2320x720", + "idiom": "tv", + "filename": "Top Shelf Image Wide.imageset", + "role": "top-shelf-image-wide" + }, + { + "size": "1920x720", + "idiom": "tv", + "filename": "Top Shelf Image.imageset", + "role": "top-shelf-image" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json new file mode 100644 index 000000000..94575ead3 --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images": [ + { + "idiom": "tv", + "scale": "1x" + }, + { + "idiom": "tv", + "scale": "2x" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json new file mode 100644 index 000000000..94575ead3 --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images": [ + { + "idiom": "tv", + "scale": "1x" + }, + { + "idiom": "tv", + "scale": "2x" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/Contents.json b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/Contents.json new file mode 100644 index 000000000..97a8662eb --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info": { + "version": 1, + "author": "xcode" + } +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/Launch Image.launchimage/Contents.json b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/Launch Image.launchimage/Contents.json new file mode 100644 index 000000000..6a5b772bb --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Assets.xcassets/Launch Image.launchimage/Contents.json @@ -0,0 +1,22 @@ +{ + "images": [ + { + "orientation": "landscape", + "idiom": "tv", + "extent": "full-screen", + "minimum-system-version": "11.0", + "scale": "2x" + }, + { + "orientation": "landscape", + "idiom": "tv", + "extent": "full-screen", + "minimum-system-version": "9.0", + "scale": "1x" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Base.lproj/Main.storyboard b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Base.lproj/Main.storyboard new file mode 100644 index 000000000..72d5e2239 --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Base.lproj/Main.storyboard @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Info.plist b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Info.plist new file mode 100644 index 000000000..02942a34f --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + arm64 + + UIUserInterfaceStyle + Automatic + + diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/ViewController.h b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/ViewController.h new file mode 100644 index 000000000..c58839fc1 --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/ViewController.h @@ -0,0 +1,15 @@ +// +// ViewController.h +// mParticle-Appboy-tvOS-Example +// +// Created by Peter Jenkins on 5/3/18. +// Copyright © 2018 mParticle. All rights reserved. +// + +#import + +@interface ViewController : UIViewController + + +@end + diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/ViewController.m b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/ViewController.m new file mode 100644 index 000000000..83de8c737 --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/ViewController.m @@ -0,0 +1,29 @@ +// +// ViewController.m +// mParticle-Appboy-tvOS-Example +// +// Created by Peter Jenkins on 5/3/18. +// Copyright © 2018 mParticle. All rights reserved. +// + +#import "ViewController.h" + +@interface ViewController () + +@end + +@implementation ViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view, typically from a nib. +} + + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + + +@end diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/main.m b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/main.m new file mode 100644 index 000000000..1c7219ab3 --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-Example/main.m @@ -0,0 +1,16 @@ +// +// main.m +// mParticle-Appboy-tvOS-Example +// +// Created by Peter Jenkins on 5/3/18. +// Copyright © 2018 mParticle. All rights reserved. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-ExampleTests/Info.plist b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-ExampleTests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-ExampleTests/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/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-ExampleTests/mParticle_Appboy_tvOS_ExampleTests.m b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-ExampleTests/mParticle_Appboy_tvOS_ExampleTests.m new file mode 100644 index 000000000..c5c9eff90 --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-ExampleTests/mParticle_Appboy_tvOS_ExampleTests.m @@ -0,0 +1,39 @@ +// +// mParticle_Appboy_tvOS_ExampleTests.m +// mParticle-Appboy-tvOS-ExampleTests +// +// Created by Peter Jenkins on 5/3/18. +// Copyright © 2018 mParticle. All rights reserved. +// + +#import + +@interface mParticle_Appboy_tvOS_ExampleTests : XCTestCase + +@end + +@implementation mParticle_Appboy_tvOS_ExampleTests + +- (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/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-ExampleUITests/Info.plist b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-ExampleUITests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-ExampleUITests/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/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-ExampleUITests/mParticle_Appboy_tvOS_ExampleUITests.m b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-ExampleUITests/mParticle_Appboy_tvOS_ExampleUITests.m new file mode 100644 index 000000000..131d328f7 --- /dev/null +++ b/kits/braze/braze-12/Examples/mParticle-Appboy-tvOS-Example-CocoaPods/mParticle-Appboy-tvOS-ExampleUITests/mParticle_Appboy_tvOS_ExampleUITests.m @@ -0,0 +1,40 @@ +// +// mParticle_Appboy_tvOS_ExampleUITests.m +// mParticle-Appboy-tvOS-ExampleUITests +// +// Created by Peter Jenkins on 5/3/18. +// Copyright © 2018 mParticle. All rights reserved. +// + +#import + +@interface mParticle_Appboy_tvOS_ExampleUITests : XCTestCase + +@end + +@implementation mParticle_Appboy_tvOS_ExampleUITests + +- (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/kits/braze/braze-12/LICENSE b/kits/braze/braze-12/LICENSE new file mode 100644 index 000000000..1bccc65a9 --- /dev/null +++ b/kits/braze/braze-12/LICENSE @@ -0,0 +1,191 @@ +Copyright 2019 mParticle, 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. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/kits/braze/braze-12/Package.resolved b/kits/braze/braze-12/Package.resolved new file mode 100644 index 000000000..03960fc88 --- /dev/null +++ b/kits/braze/braze-12/Package.resolved @@ -0,0 +1,25 @@ +{ + "object": { + "pins": [ + { + "package": "braze-swift-sdk", + "repositoryURL": "https://github.com/braze-inc/braze-swift-sdk", + "state": { + "branch": null, + "revision": "c630122e490fb156be2971b1f24d790488d33ac5", + "version": "12.1.0" + } + }, + { + "package": "SDWebImage", + "repositoryURL": "https://github.com/SDWebImage/SDWebImage.git", + "state": { + "branch": null, + "revision": "b62cb63bf4ed1f04c961a56c9c6c9d5ab8524ec6",#import + "version": "5.21.1" + } + } + ] + }, + "version": 1 +} diff --git a/kits/braze/braze-12/Package.swift b/kits/braze/braze-12/Package.swift new file mode 100644 index 000000000..314b652ca --- /dev/null +++ b/kits/braze/braze-12/Package.swift @@ -0,0 +1,37 @@ +// swift-tools-version:5.9 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "mParticle-Appboy", + platforms: [ .iOS(.v15), .tvOS(.v15) ], + products: [ + .library( + name: "mParticle-Appboy", + targets: ["mParticle-Appboy"] + ) + ], + dependencies: [ + .package( + url: "https://github.com/mParticle/mparticle-apple-sdk", + branch: "workstation/9.0-Release" + ), + .package( + url: "https://github.com/braze-inc/braze-swift-sdk", + .upToNextMajor(from: "12.0.0") + ) + ], + targets: [ + .target( + name: "mParticle-Appboy", + dependencies: [ + .product(name: "mParticle-Apple-SDK", package: "mParticle-Apple-SDK"), + .product(name: "BrazeUI", package: "braze-swift-sdk", condition: .when(platforms: [.iOS])), + .product(name: "BrazeKit", package: "braze-swift-sdk"), + .product(name: "BrazeKitCompat", package: "braze-swift-sdk") + ], + resources: [.process("PrivacyInfo.xcprivacy")] + ) + ] +) diff --git a/kits/braze/braze-12/README.md b/kits/braze/braze-12/README.md new file mode 100644 index 000000000..e77a2c908 --- /dev/null +++ b/kits/braze/braze-12/README.md @@ -0,0 +1,33 @@ +# Braze (formerly Appboy) Kit Integration + +This repository contains the [Braze](https://www.braze.com) integration for the [mParticle Apple SDK](https://github.com/mParticle/mparticle-apple-sdk) using the latest [Braze Swift SDK](https://github.com/braze-inc/braze-swift-sdk/). + +## Adding the integration + +1. Add the kit dependency using SPM or add it to your app's Podfile or Cartfile: + + ```ruby + pod 'mParticle-Appboy', '~> 8.0' + ``` + + OR + + ```swift + github "mparticle-integrations/mparticle-apple-integration-appboy" ~> 8.0 + ``` + +2. If using SPM, make sure to add the `-ObjC` flag to the target's `Other Linker Flags` setting in Xcode, according to the [Braze documentation](https://www.braze.com/docs/developer_guide/platform_integration_guides/ios/initial_sdk_setup/installation_methods/swift_package_manager#step-2-configuring-your-project). + +3. Follow the mParticle iOS SDK [quick-start](https://github.com/mParticle/mparticle-apple-sdk), then rebuild and launch your app, and verify that you see `"Included kits: { Appboy }"` in your Xcode console + +> (This requires your mParticle log level to be at least Debug) + +4. Reference mParticle's integration docs below to enable the integration. + +## Documentation + +[Braze integration](https://docs.mparticle.com/integrations/braze/event/) + +## License + +[Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0) diff --git a/kits/braze/braze-12/Scripts/release.sh b/kits/braze/braze-12/Scripts/release.sh new file mode 100755 index 000000000..07a494397 --- /dev/null +++ b/kits/braze/braze-12/Scripts/release.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +VERSION="$1" +NOTES="$2" + +# Update version number +# + +# Update CocoaPods podspec file +sed -i '' 's/\(^ s.version[^=]*= \).*/\1"'"${VERSION}"'"/' mParticle-Appboy.podspec + +# Make the release commit in git +# + +git add mParticle-Appboy.podspec +git add mParticle_Appboy.json +git add CHANGELOG.md +git commit -m "chore(release): ${VERSION} [skip ci] + +${NOTES}" diff --git a/kits/braze/braze-12/Sources/Info.plist b/kits/braze/braze-12/Sources/Info.plist new file mode 100644 index 000000000..d3de8eefb --- /dev/null +++ b/kits/braze/braze-12/Sources/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/kits/braze/braze-12/Sources/mParticle-Appboy/MPKitAppboy.m b/kits/braze/braze-12/Sources/mParticle-Appboy/MPKitAppboy.m new file mode 100644 index 000000000..27fcf20b0 --- /dev/null +++ b/kits/braze/braze-12/Sources/mParticle-Appboy/MPKitAppboy.m @@ -0,0 +1,1308 @@ +#import "MPKitAppboy.h" + +#if TARGET_OS_IOS + @import BrazeKit; + @import BrazeKitCompat; + @import BrazeUI; +#else + @import BrazeKit; + @import BrazeKitCompat; +#endif + +static NSString *const eabAPIKey = @"apiKey"; +static NSString *const eabOptions = @"options"; +static NSString *const hostConfigKey = @"host"; +static NSString *const userIdTypeKey = @"userIdentificationType"; +static NSString *const emailIdTypeKey = @"emailIdentificationType"; +static NSString *const enableTypeDetectionKey = @"enableTypeDetection"; +static NSString *const bundleCommerceEventData = @"bundleCommerceEventData"; +static NSString *const replaceSkuWithProductName = @"replaceSkuWithProductName"; +static NSString *const subscriptionGroupMapping = @"subscriptionGroupMapping"; + +// The possible values for userIdentificationType +static NSString *const userIdValueOther = @"Other"; +static NSString *const userIdValueOther2 = @"Other2"; +static NSString *const userIdValueOther3 = @"Other3"; +static NSString *const userIdValueOther4 = @"Other4"; +static NSString *const userIdValueOther5 = @"Other5"; +static NSString *const userIdValueOther6 = @"Other6"; +static NSString *const userIdValueOther7 = @"Other7"; +static NSString *const userIdValueOther8 = @"Other8"; +static NSString *const userIdValueOther9 = @"Other9"; +static NSString *const userIdValueOther10 = @"Other10"; +static NSString *const userIdValueCustomerId = @"CustomerId"; +static NSString *const userIdValueFacebook = @"Facebook"; +static NSString *const userIdValueTwitter = @"Twitter"; +static NSString *const userIdValueGoogle = @"Google"; +static NSString *const userIdValueMicrosoft = @"Microsoft"; +static NSString *const userIdValueYahoo = @"Yahoo"; +static NSString *const userIdValueEmail = @"Email"; +static NSString *const userIdValueAlias = @"Alias"; +static NSString *const userIdValueMPID = @"MPID"; + +// User Attribute key with reserved functionality for Braze kit +static NSString *const brazeUserAttributeDob = @"dob"; +static NSString *const brazeUserAttributeEmailSubscribe = @"email_subscribe"; +static NSString *const brazeUserAttributePushSubscribe = @"push_subscribe"; + +// Strings used when sending enhanced commerce events +static NSString *const attributesKey = @"Attributes"; +static NSString *const productKey = @"products"; +static NSString *const promotionKey = @"promotions"; +static NSString *const impressionKey = @"impressions"; + +// Strings used for Google Consent +static NSString *const MPMapKey = @"map"; +static NSString *const MPValueKey = @"value"; +static NSString *const MPConsentMappingSDKKey = @"consentMappingSDK"; +static NSString *const MPGoogleAdUserDataKey = @"google_ad_user_data"; +static NSString *const MPGoogleAdPersonalizationKey = @"google_ad_personalization"; +static NSString *const BGoogleAdUserDataKey = @"$google_ad_user_data"; +static NSString *const BGoogleAdPersonalizationKey = @"$google_ad_personalization"; + +#if TARGET_OS_IOS +static id inAppMessageControllerDelegate = nil; +static BOOL shouldDisableNotificationHandling = NO; +#endif +static id urlDelegate = nil; +static Braze *brazeInstance = nil; +static id brazeLocationProvider = nil; +static NSSet *brazeTrackingPropertyAllowList; + +@interface MPKitAppboy() { + Braze *appboyInstance; + BOOL collectIDFA; + BOOL forwardScreenViews; + NSMutableDictionary *subscriptionGroupDictionary; +} + +@property (nonatomic) NSString *host; +@property (nonatomic) BOOL enableTypeDetection; + +@end + + +@implementation MPKitAppboy + ++ (NSNumber *)kitCode { + return @28; +} + ++ (void)load { + MPKitRegister *kitRegister = [[MPKitRegister alloc] initWithName:@"Appboy" className:@"MPKitAppboy"]; + [MParticle registerExtension:kitRegister]; +} + +#if TARGET_OS_IOS ++ (void)setInAppMessageControllerDelegate:(id)delegate { + inAppMessageControllerDelegate = (id)delegate; +} + ++ (id)inAppMessageControllerDelegate { + return inAppMessageControllerDelegate; +} + ++ (void)setShouldDisableNotificationHandling:(BOOL)isDisabled { + shouldDisableNotificationHandling = isDisabled; +} + ++ (BOOL)shouldDisableNotificationHandling { + return shouldDisableNotificationHandling; +} + +#endif + ++ (void)setURLDelegate:(id)delegate { + urlDelegate = (id)delegate; +} + ++ (id)urlDelegate { + return urlDelegate; +} + ++ (void)setBrazeInstance:(id)instance { + if ([instance isKindOfClass:[Braze class]]) { + brazeInstance = instance; + } +} + ++ (Braze *)brazeInstance { + return brazeInstance; +} + ++ (void)setBrazeLocationProvider:(nonnull id)instance { + brazeLocationProvider = instance; +} + ++ (void)setBrazeTrackingPropertyAllowList:(nonnull NSSet *)allowList { + for (id property in allowList) { + if (![property isKindOfClass:[BRZTrackingProperty class]]) { + return; + } + } + brazeTrackingPropertyAllowList = allowList; +} + +#pragma mark Private methods +- (NSString *)stringRepresentation:(id)value { + NSString *stringRepresentation = nil; + + if ([value isKindOfClass:[NSString class]]) { + stringRepresentation = value; + } else if ([value isKindOfClass:[NSNumber class]]) { + stringRepresentation = [(NSNumber *)value stringValue]; + } else if ([value isKindOfClass:[NSDate class]]) { + stringRepresentation = [MPKitAPI stringFromDateRFC3339:value]; + } else if ([value isKindOfClass:[NSData class]]) { + stringRepresentation = [[NSString alloc] initWithData:value encoding:NSUTF8StringEncoding]; + } else { + return nil; + } + + return stringRepresentation; +} + +- (Braze *)appboyInstance { + return self->appboyInstance; +} + +- (void)setAppboyInstance:(Braze *)instance { + self->appboyInstance = instance; +} + +- (NSString *)stripCharacter:(NSString *)character fromString:(NSString *)originalString { + NSRange range = [originalString rangeOfString:character]; + + if (range.location == 0) { + NSMutableString *strippedString = [originalString mutableCopy]; + [strippedString replaceOccurrencesOfString:character withString:@"" options:NSCaseInsensitiveSearch range:range]; + return [strippedString copy]; + } else { + return originalString; + } +} + +- (NSMutableDictionary *)getSubscriptionGroupIds:(NSString *)subscriptionGroupMap { + NSMutableDictionary *subscriptionGroupDictionary = [NSMutableDictionary dictionary]; + + if (!subscriptionGroupMap.length) { + return subscriptionGroupDictionary; + } + + NSData *subsctiprionGroupData = [subscriptionGroupMap dataUsingEncoding:NSUTF8StringEncoding]; + + NSError *error = nil; + NSArray *subsctiprionGroupDataArray = [NSJSONSerialization JSONObjectWithData:subsctiprionGroupData options:0 error:&error]; + + for (NSDictionary *item in subsctiprionGroupDataArray) { + NSString *key = item[@"map"]; + NSString *value = item[@"value"]; + subscriptionGroupDictionary[key] = value; + } + + return subscriptionGroupDictionary; +} + +- (MPKitExecStatus *)logAppboyCustomEvent:(MPEvent *)event eventType:(NSUInteger)eventType { + void (^logCustomEvent)(void) = ^{ + NSDictionary *transformedEventInfo = [event.customAttributes transformValuesToString]; + + NSMutableDictionary *eventInfo = [[NSMutableDictionary alloc] initWithCapacity:event.customAttributes.count]; + [transformedEventInfo enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { + NSString *strippedKey = [self stripCharacter:@"$" fromString:key]; + eventInfo[strippedKey] = obj; + }]; + + NSDictionary *detectedEventInfo = eventInfo; + if (self->_enableTypeDetection) { + detectedEventInfo = [self simplifiedDictionary:eventInfo]; + } + + // Appboy expects that the properties are non empty when present. + if (detectedEventInfo && detectedEventInfo.count > 0) { + [self->appboyInstance logCustomEvent:event.name properties:detectedEventInfo]; + } else { + [self->appboyInstance logCustomEvent:event.name]; + } + + NSString *eventTypeString = [@(eventType) stringValue]; + + for (NSString *key in eventInfo) { + NSString *eventTypePlusNamePlusKey = [[NSString stringWithFormat:@"%@%@%@", eventTypeString, event.name, key] lowercaseString]; + NSString *hashValue = [MPKitAPI hashString:eventTypePlusNamePlusKey]; + + NSDictionary *forwardUserAttributes; + + // Delete from array + forwardUserAttributes = self.configuration[@"ear"]; + if (forwardUserAttributes[hashValue]) { + [self->appboyInstance.user removeFromCustomAttributeStringArrayWithKey:forwardUserAttributes[hashValue] value:eventInfo[key]]; + } + + // Add to array + forwardUserAttributes = self.configuration[@"eaa"]; + if (forwardUserAttributes[hashValue]) { + [self->appboyInstance.user addToCustomAttributeStringArrayWithKey:forwardUserAttributes[hashValue] value:eventInfo[key]]; + } + + // Add key/value pair + forwardUserAttributes = self.configuration[@"eas"]; + if (forwardUserAttributes[hashValue]) { + [self setUserAttribute:forwardUserAttributes[hashValue] value:eventInfo[key]]; + } + } + }; + + if ([NSThread isMainThread]) { + logCustomEvent(); + } else { + dispatch_async(dispatch_get_main_queue(), logCustomEvent); + } + + MPKitExecStatus *execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeSuccess]; + return execStatus; +} + +- (BOOL)isAdvertisingTrackingEnabled { + BOOL advertisingTrackingEnabled = NO; + Class MPIdentifierManager = NSClassFromString(@"ASIdentifierManager"); + + if (MPIdentifierManager) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundeclared-selector" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + SEL selector = NSSelectorFromString(@"sharedManager"); + id adIdentityManager = [MPIdentifierManager performSelector:selector]; + selector = NSSelectorFromString(@"isAdvertisingTrackingEnabled"); + advertisingTrackingEnabled = (BOOL)[adIdentityManager performSelector:selector]; +#pragma clang diagnostic pop +#pragma clang diagnostic pop + } + + return advertisingTrackingEnabled && collectIDFA; +} + +- (NSString *)advertisingIdentifierString { + NSString *_advertiserId = nil; + Class MPIdentifierManager = NSClassFromString(@"ASIdentifierManager"); + + if (MPIdentifierManager) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundeclared-selector" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + SEL selector = NSSelectorFromString(@"sharedManager"); + id adIdentityManager = [MPIdentifierManager performSelector:selector]; + + selector = NSSelectorFromString(@"isAdvertisingTrackingEnabled"); + BOOL advertisingTrackingEnabled = (BOOL)[adIdentityManager performSelector:selector]; + if (advertisingTrackingEnabled) { + selector = NSSelectorFromString(@"advertisingIdentifier"); + _advertiserId = [[adIdentityManager performSelector:selector] UUIDString]; + } +#pragma clang diagnostic pop +#pragma clang diagnostic pop + } + + return _advertiserId; +} + +- (BOOL)isAppTrackingEnabled { + BOOL appTrackingEnabled = NO; + Class ATTrackingManager = NSClassFromString(@"ATTrackingManager"); + + if (ATTrackingManager) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundeclared-selector" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + SEL selector = NSSelectorFromString(@"trackingAuthorizationStatus"); + NSUInteger trackingAuthorizationStatus = (NSUInteger)[ATTrackingManager performSelector:selector]; + appTrackingEnabled = (trackingAuthorizationStatus == 3); // ATTrackingManagerAuthorizationStatusAuthorized +#pragma clang diagnostic pop +#pragma clang diagnostic pop + } + + return appTrackingEnabled; +} + +#pragma mark MPKitInstanceProtocol methods +- (MPKitExecStatus *)didFinishLaunchingWithConfiguration:(NSDictionary *)configuration { + + // Use the static braze instance if set + [self setAppboyInstance:brazeInstance]; + + MPKitExecStatus *execStatus = nil; + + if (!configuration[eabAPIKey]) { + execStatus = [[MPKitExecStatus alloc] initWithSDKCode:[[self class] kitCode] returnCode:MPKitReturnCodeRequirementsNotMet]; + return execStatus; + } + + _configuration = configuration; + + collectIDFA = NO; + forwardScreenViews = NO; + + _host = configuration[hostConfigKey]; + _enableTypeDetection = [configuration[enableTypeDetectionKey] boolValue]; + + //If Braze is already initialized, immediately "start" the kit, this + //is here for: + // 1. Apps that initialize Braze prior to mParticle, and/or + // 2. Apps that initialize mParticle too late, causing the SDK to miss + // the launch notification which would otherwise trigger start(). + if (self->appboyInstance) { + NSLog(@"mParticle -> Warning: Braze SDK initialized outside of mParticle kit, this will mean Braze settings within the mParticle dashboard such as API key, endpoint URL, flush interval and others will not be respected."); + [self start]; + } else { + _started = NO; + } + + execStatus = [[MPKitExecStatus alloc] initWithSDKCode:[[self class] kitCode] returnCode:MPKitReturnCodeSuccess]; + return execStatus; +} + +- (id const)providerKitInstance { + return [self started] ? appboyInstance : nil; +} + +- (void)start { + if (!self->appboyInstance) { + NSDictionary *optionsDict = [self optionsDictionary]; + BRZConfiguration *configuration = [[BRZConfiguration alloc] initWithApiKey:self.configuration[eabAPIKey] endpoint:optionsDict[ABKEndpointKey]]; + + [configuration.api addSDKMetadata:@[BRZSDKMetadata.mparticle]]; + configuration.api.sdkFlavor = ((NSNumber *)optionsDict[ABKSDKFlavorKey]).intValue; + configuration.api.requestPolicy = ((NSNumber *)optionsDict[ABKRequestProcessingPolicyOptionKey]).intValue; + NSNumber *flushIntervalOption = (NSNumber *)optionsDict[ABKFlushIntervalOptionKey] ?: @10; // If not set, use the default 10 seconds specified in Braze SDK header + configuration.api.flushInterval = flushIntervalOption.doubleValue < 1.0 ? 1.0 : flushIntervalOption.doubleValue; // Ensure value is above the minimum of 1.0 per run time warning from Braze SDK + configuration.api.trackingPropertyAllowList = brazeTrackingPropertyAllowList; + + configuration.sessionTimeout = ((NSNumber *)optionsDict[ABKSessionTimeoutKey]).doubleValue; + + configuration.triggerMinimumTimeInterval = ((NSNumber *)optionsDict[ABKMinimumTriggerTimeIntervalKey]).doubleValue; + + NSNumber *automaticLocationTrackingOption = (NSNumber *)optionsDict[ABKEnableAutomaticLocationCollectionKey]; + if (automaticLocationTrackingOption != nil && automaticLocationTrackingOption.boolValue && brazeLocationProvider) { + configuration.location.automaticLocationCollection = YES; + configuration.location.brazeLocationProvider = brazeLocationProvider; + } + + self->appboyInstance = [[Braze alloc] initWithConfiguration:configuration]; + } + + if (!self->appboyInstance) { + return; + } + + self->forwardScreenViews = self.configuration[@"forwardScreenViews"] && [self.configuration[@"forwardScreenViews"] caseInsensitiveCompare:@"true"] == NSOrderedSame; + + self->collectIDFA = self.configuration[@"ABKCollectIDFA"] && [self.configuration[@"ABKCollectIDFA"] caseInsensitiveCompare:@"true"] == NSOrderedSame; + + if (self->collectIDFA) { + [self->appboyInstance setIdentifierForAdvertiser:[self advertisingIdentifierString]]; + } + [self->appboyInstance setAdTrackingEnabled:[self isAppTrackingEnabled]]; + + if ([MPKitAppboy urlDelegate]) { + self->appboyInstance.delegate = [MPKitAppboy urlDelegate]; + } + + self->subscriptionGroupDictionary = [self getSubscriptionGroupIds:self.configuration[subscriptionGroupMapping]]; + +#if TARGET_OS_IOS + BrazeInAppMessageUI *inAppMessageUI = [[BrazeInAppMessageUI alloc] init]; + inAppMessageUI.delegate = [MPKitAppboy inAppMessageControllerDelegate]; + [self->appboyInstance setInAppMessagePresenter:inAppMessageUI]; +#endif + + FilteredMParticleUser *currentUser = [[self kitApi] getCurrentUserWithKit:self]; + if (currentUser.userId.integerValue != 0) { + [self updateUser:currentUser request:currentUser.userIdentities]; + } + + self->_started = YES; + + // Update Consent on start + [self updateConsent]; + + dispatch_async(dispatch_get_main_queue(), ^{ + NSDictionary *userInfo = @{mParticleKitInstanceKey:[[self class] kitCode]}; + + [[NSNotificationCenter defaultCenter] postNotificationName:mParticleKitDidBecomeActiveNotification + object:nil + userInfo:userInfo]; + }); +} + +- (void)stop { + self->appboyInstance = nil; + _started = NO; + _configuration = nil; +} + +- (NSMutableDictionary *)optionsDictionary { + NSArray *serverKeys = @[@"ABKRequestProcessingPolicyOptionKey", @"ABKFlushIntervalOptionKey", @"ABKSessionTimeoutKey", @"ABKMinimumTriggerTimeIntervalKey"]; + NSArray *appboyKeys = @[ABKRequestProcessingPolicyOptionKey, ABKFlushIntervalOptionKey, ABKSessionTimeoutKey, ABKMinimumTriggerTimeIntervalKey]; + NSMutableDictionary *optionsDictionary = [[NSMutableDictionary alloc] initWithCapacity:serverKeys.count]; + NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; + numberFormatter.numberStyle = NSNumberFormatterNoStyle; + + [serverKeys enumerateObjectsUsingBlock:^(NSString * _Nonnull serverKey, NSUInteger idx, BOOL * _Nonnull stop) { + NSString *optionValue = self.configuration[serverKey]; + + if (optionValue != nil && (NSNull *)optionValue != [NSNull null]) { + NSString *appboyKey = appboyKeys[idx]; + NSNumber *numberValue = nil; + @try { + numberValue = [numberFormatter numberFromString:optionValue]; + } @catch (NSException *exception) { + numberValue = nil; + } + if (numberValue != nil) { + optionsDictionary[appboyKey] = numberValue; + } + } + }]; + + if (self.host.length) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wincompatible-pointer-types" + optionsDictionary[ABKEndpointKey] = self.host; +#pragma clang diagnostic pop + } + + if (optionsDictionary.count == 0) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wincompatible-pointer-types" + optionsDictionary = [[NSMutableDictionary alloc] initWithCapacity:serverKeys.count]; + } + optionsDictionary[ABKSDKFlavorKey] = @(MPARTICLE); +#pragma clang diagnostic pop + +#if TARGET_OS_IOS + optionsDictionary[ABKEnableAutomaticLocationCollectionKey] = @(YES); + if (self.configuration[@"ABKDisableAutomaticLocationCollectionKey"]) { + if ([self.configuration[@"ABKDisableAutomaticLocationCollectionKey"] caseInsensitiveCompare:@"true"] == NSOrderedSame) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wincompatible-pointer-types" + optionsDictionary[ABKEnableAutomaticLocationCollectionKey] = @(NO); +#pragma clang diagnostic pop + } + } +#endif + + return optionsDictionary; +} + +- (MPKitExecStatus *)incrementUserAttribute:(NSString *)key byValue:(NSNumber *)value { + [appboyInstance.user incrementCustomUserAttribute:key by:[value integerValue]]; + + MPKitExecStatus *execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeSuccess]; + return execStatus; +} + +- (nonnull MPKitExecStatus *)logBaseEvent:(nonnull MPBaseEvent *)event { + if ([event isKindOfClass:[MPEvent class]]) { + return [self routeEvent:(MPEvent *)event]; + } else if ([event isKindOfClass:[MPCommerceEvent class]]) { + return [self routeCommerceEvent:(MPCommerceEvent *)event]; + } else { + return [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeUnavailable]; + } +} + +- (MPKitExecStatus *)routeCommerceEvent:(MPCommerceEvent *)commerceEvent { + MPKitExecStatus *execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeSuccess forwardCount:0]; + + if (commerceEvent.action == MPCommerceEventActionPurchase) { + NSMutableDictionary *baseProductAttributes = [[NSMutableDictionary alloc] init]; + NSDictionary *transactionAttributes = [self simplifiedDictionary:[commerceEvent.transactionAttributes beautifiedDictionaryRepresentation]]; + + if (transactionAttributes) { + [baseProductAttributes addEntriesFromDictionary:transactionAttributes]; + } + + NSDictionary *commerceEventAttributes = [commerceEvent beautifiedAttributes]; + NSArray *keys = @[kMPExpCECheckoutOptions, kMPExpCECheckoutStep, kMPExpCEProductListName, kMPExpCEProductListSource]; + + for (NSString *key in keys) { + if (commerceEventAttributes[key]) { + baseProductAttributes[key] = commerceEventAttributes[key]; + } + } + + NSDictionary *commerceCustomAttribues = [commerceEvent.customAttributes transformValuesToString]; + for (NSString *key in commerceCustomAttribues) { + baseProductAttributes[key] = commerceCustomAttribues[key]; + } + + NSArray *products = commerceEvent.products; + NSString *currency = commerceEvent.currency ? : @"USD"; + NSMutableDictionary *properties; + + // Add relevant attributes from the commerce event + properties = [[NSMutableDictionary alloc] init]; + if (baseProductAttributes.count > 0) { + [properties addEntriesFromDictionary:baseProductAttributes]; + } + + if ([_configuration[bundleCommerceEventData] boolValue]) { + if (commerceEvent.customAttributes.count > 0) { + [properties removeObjectsForKeys:[commerceEvent.customAttributes allKeys]]; + [properties setValue:commerceEvent.customAttributes forKey:attributesKey]; + } + NSArray *productArray = [self getProductListParameters:products]; + if (productArray.count > 0) { + [properties setValue:productArray forKey:productKey]; + } + NSArray *promotionArray = [self getPromotionListParameters:commerceEvent.promotionContainer.promotions]; + if (promotionArray.count > 0) { + [properties setValue:promotionArray forKey:promotionKey]; + } + NSArray *impressionArray = [self getImpressionListParameters:commerceEvent.impressions]; + if (impressionArray.count > 0) { + [properties setValue:impressionArray forKey:impressionKey]; + } + + NSString *eventName = [NSString stringWithFormat:@"eCommerce - %@", [self eventNameForAction:commerceEvent.action]]; + + [appboyInstance logPurchase:eventName + currency:currency + price:[commerceEvent.transactionAttributes.revenue doubleValue] + properties:properties]; + + [execStatus incrementForwardCount]; + } else { + for (MPProduct *product in products) { + // Add attributes from the product itself + NSDictionary *productDictionary = [product beautifiedDictionaryRepresentation]; + if (productDictionary) { + [properties addEntriesFromDictionary:productDictionary]; + } + + NSString *sanitizedProductName = product.sku; + if ([@"True" isEqualToString:_configuration[replaceSkuWithProductName]]) { + sanitizedProductName = product.name; + } + + // Strips key/values already being passed to Appboy, plus key/values initialized to default values + keys = @[kMPExpProductSKU, kMPProductCurrency, kMPExpProductUnitPrice, kMPExpProductQuantity]; + [properties removeObjectsForKeys:keys]; + + [appboyInstance logPurchase:sanitizedProductName + currency:currency + price:[product.price doubleValue] + quantity:[product.quantity integerValue] + properties:properties]; + + [execStatus incrementForwardCount]; + } + } + } else { + if ([_configuration[bundleCommerceEventData] boolValue]) { + NSDictionary *transformedEventInfo = [commerceEvent.customAttributes transformValuesToString]; + + NSMutableDictionary *eventInfo = [[NSMutableDictionary alloc] initWithCapacity:commerceEvent.customAttributes.count]; + [transformedEventInfo enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { + NSString *strippedKey = [self stripCharacter:@"$" fromString:key]; + eventInfo[strippedKey] = obj; + }]; + + if (self->_enableTypeDetection) { + eventInfo = [[self simplifiedDictionary:eventInfo] mutableCopy]; + } + + if (commerceEvent.customAttributes.count > 0) { + [eventInfo removeObjectsForKeys:[commerceEvent.customAttributes allKeys]]; + [eventInfo setValue:commerceEvent.customAttributes forKey:attributesKey]; + } + NSArray *productArray = [self getProductListParameters:commerceEvent.products]; + if (productArray.count > 0) { + [eventInfo setValue:productArray forKey:productKey]; + } + NSArray *promotionArray = [self getPromotionListParameters:commerceEvent.promotionContainer.promotions]; + if (promotionArray.count > 0) { + [eventInfo setValue:promotionArray forKey:promotionKey]; + } + NSArray *impressionArray = [self getImpressionListParameters:commerceEvent.impressions]; + if (impressionArray.count > 0) { + [eventInfo setValue:impressionArray forKey:impressionKey]; + } + + NSString *eventName = [NSString stringWithFormat:@"eCommerce - %@", [self eventNameForAction:commerceEvent.action]]; + if ([eventName isEqualToString:@"eCommerce - unknown"]) { + if (commerceEvent.impressions) { + eventName = @"eCommerce - impression"; + } else if (commerceEvent.promotionContainer.action) { + eventName = [NSString stringWithFormat:@"eCommerce - %@", [self eventNameForPromotionAction:commerceEvent.promotionContainer.action]]; + } + } + + // Appboy expects that the properties are non empty when present. + if (eventInfo.count > 0) { + [self->appboyInstance logCustomEvent:eventName properties:eventInfo]; + } else { + [self->appboyInstance logCustomEvent:eventName]; + } + [execStatus incrementForwardCount]; + } else { + NSArray *expandedInstructions = [commerceEvent expandedInstructions]; + + for (MPCommerceEventInstruction *commerceEventInstruction in expandedInstructions) { + [self logBaseEvent:commerceEventInstruction.event]; + [execStatus incrementForwardCount]; + } + } + } + + return execStatus; +} + +- (MPKitExecStatus *)routeEvent:(MPEvent *)event { + return [self logAppboyCustomEvent:event eventType:event.type]; +} + +- (MPKitExecStatus *)logScreen:(MPEvent *)event { + MPKitExecStatus *execStatus = nil; + + if (forwardScreenViews) { + execStatus = [self logAppboyCustomEvent:event eventType:0]; + } else { + execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeCannotExecute]; + } + + return execStatus; +} + +- (MPKitExecStatus *)receivedUserNotification:(NSDictionary *)userInfo { + MPKitExecStatus *execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeSuccess]; + +#if TARGET_OS_IOS + if (shouldDisableNotificationHandling) { + return execStatus; + } + + if (![appboyInstance.notifications handleBackgroundNotificationWithUserInfo:userInfo fetchCompletionHandler:^(UIBackgroundFetchResult fetchResult) {}]) { + NSLog(@"mParticle -> Invalid Braze remote notification: %@", userInfo); + } +#endif + + return execStatus; +} + +- (MPKitExecStatus *)removeUserAttribute:(NSString *)key { + [appboyInstance.user unsetCustomAttributeWithKey:key]; + + MPKitExecStatus *execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeSuccess]; + return execStatus; +} + +- (MPKitExecStatus *)setDeviceToken:(NSData *)deviceToken { + MPKitExecStatus *execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeSuccess]; + +#if TARGET_OS_IOS + if (shouldDisableNotificationHandling) { + return execStatus; + } + + [appboyInstance.notifications registerDeviceToken:deviceToken]; +#endif + + return execStatus; +} + +- (MPKitExecStatus *)setOptOut:(BOOL)optOut { + MPKitReturnCode returnCode; + + if (optOut) { + [appboyInstance.user setEmailSubscriptionState:BRZUserSubscriptionStateSubscribed]; + returnCode = MPKitReturnCodeSuccess; + } else { + returnCode = MPKitReturnCodeCannotExecute; + } + + MPKitExecStatus *execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:returnCode]; + return execStatus; +} + +- (MPKitExecStatus *)setUserAttribute:(NSString *)key value:(NSString *)value { + MPKitExecStatus *execStatus; + + if (!value) { + [appboyInstance.user unsetCustomAttributeWithKey:key]; + execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeSuccess]; + return execStatus; + } + + value = [self stringRepresentation:value]; + + if (!value) { + execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeFail]; + return execStatus; + } + + if ([key isEqualToString:mParticleUserAttributeFirstName]) { + [appboyInstance.user setFirstName:value]; + } else if ([key isEqualToString:mParticleUserAttributeLastName]) { + [appboyInstance.user setLastName:value]; + } else if ([key isEqualToString:mParticleUserAttributeAge]) { + NSDate *now = [NSDate date]; + NSCalendar *calendar = [NSCalendar currentCalendar]; + NSDateComponents *dateComponents = [calendar components:NSCalendarUnitYear fromDate:now]; + NSInteger age = 0; + + @try { + age = [value integerValue]; + } @catch (NSException *exception) { + NSLog(@"mParticle -> Invalid age: %@", value); + execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeFail]; + return execStatus; + } + + NSDateComponents *birthComponents = [[NSDateComponents alloc] init]; + birthComponents.year = dateComponents.year - age; + birthComponents.month = 01; + birthComponents.day = 01; + + [appboyInstance.user setDateOfBirth:[calendar dateFromComponents:birthComponents]]; + } else if ([key isEqualToString:brazeUserAttributeDob]) { + // Expected Date Format @"yyyy'-'MM'-'dd" + NSCalendar *calendar = [NSCalendar currentCalendar]; + + NSString *yearString = [value substringToIndex:4]; + NSRange monthRange = NSMakeRange(5, 2); + NSString *monthString = [value substringWithRange:monthRange]; + NSRange dayRange = NSMakeRange(8, 2); + NSString *dayString = [value substringWithRange:dayRange]; + + NSInteger year = 0; + NSInteger month = 0; + NSInteger day = 0; + + @try { + year = [yearString integerValue]; + } @catch (NSException *exception) { + NSLog(@"mParticle -> Invalid dob year: %@ \nPlease use this date format @\"yyyy'-'MM'-'dd\"", yearString); + execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeFail]; + return execStatus; + } + + @try { + month = [monthString integerValue]; + } @catch (NSException *exception) { + NSLog(@"mParticle -> Invalid dob month: %@ \nPlease use this date format @\"yyyy'-'MM'-'dd\"", monthString); + execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeFail]; + return execStatus; + } + + @try { + day = [dayString integerValue]; + } @catch (NSException *exception) { + NSLog(@"mParticle -> Invalid dob day: %@ \nPlease use this date format @\"yyyy'-'MM'-'dd\"", dayString); + execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeFail]; + return execStatus; + } + + NSDateComponents *birthComponents = [[NSDateComponents alloc] init]; + birthComponents.year = year; + birthComponents.month = month; + birthComponents.day = day; + + [appboyInstance.user setDateOfBirth:[calendar dateFromComponents:birthComponents]]; + } else if ([key isEqualToString:mParticleUserAttributeCountry]) { + [appboyInstance.user setCountry:value]; + } else if ([key isEqualToString:mParticleUserAttributeCity]) { + [appboyInstance.user setHomeCity:value]; + } else if ([key isEqualToString:mParticleUserAttributeGender]) { + [appboyInstance.user setGender:BRZUserGender.other]; + if ([value isEqualToString:mParticleGenderMale]) { + [appboyInstance.user setGender:BRZUserGender.male]; + } else if ([value isEqualToString:mParticleGenderFemale]) { + [appboyInstance.user setGender:BRZUserGender.female]; + } else if ([value isEqualToString:mParticleGenderNotAvailable]) { + [appboyInstance.user setGender:BRZUserGender.notApplicable]; + } + } else if ([key isEqualToString:mParticleUserAttributeMobileNumber] || [key isEqualToString:@"$MPUserMobile"]) { + [appboyInstance.user setPhoneNumber:value]; + } else if ([key isEqualToString:mParticleUserAttributeZip]){ + [appboyInstance.user setCustomAttributeWithKey:@"Zip" stringValue:value]; + } else if ([key isEqualToString:brazeUserAttributeEmailSubscribe]) { + if([value isEqualToString:@"opted_in"]) { + [appboyInstance.user setEmailSubscriptionState:BRZUserSubscriptionStateOptedIn]; + } else if ([value isEqualToString:@"unsubscribed"]) { + [appboyInstance.user setEmailSubscriptionState:BRZUserSubscriptionStateUnsubscribed]; + } else if ([value isEqualToString:@"subscribed"]) { + [appboyInstance.user setEmailSubscriptionState:BRZUserSubscriptionStateSubscribed]; + } else { + NSLog(@"mParticle -> Invalid email_subscribe value: %@", value); + execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeFail]; + return execStatus; + } + } else if ([key isEqualToString:brazeUserAttributePushSubscribe]) { + if([value isEqualToString:@"opted_in"]) { + [appboyInstance.user setPushNotificationSubscriptionState:BRZUserSubscriptionStateOptedIn]; + } else if ([value isEqualToString:@"unsubscribed"]) { + [appboyInstance.user setPushNotificationSubscriptionState:BRZUserSubscriptionStateUnsubscribed]; + } else if ([value isEqualToString:@"subscribed"]) { + [appboyInstance.user setPushNotificationSubscriptionState:BRZUserSubscriptionStateSubscribed]; + } else { + NSLog(@"mParticle -> Invalid push_subscribe value: %@", value); + execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeFail]; + return execStatus; + } + } else if (subscriptionGroupDictionary[key]){ + NSString *subscriptionGroupId = subscriptionGroupDictionary[key]; + if ([value isEqualToString:@"1"]) { + [appboyInstance.user addToSubscriptionGroupWithGroupId:subscriptionGroupId]; + } else if ([value isEqualToString:@"0"]) { + [appboyInstance.user removeFromSubscriptionGroupWithGroupId:subscriptionGroupId]; + } else { + NSLog(@"mParticle -> Invalid value type for subscriptionGroupId mapped user attribute key: %@, expected value should be of type BOOL", key); + execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeFail]; + return execStatus; + } + } else { + key = [self stripCharacter:@"$" fromString:key]; + + if (!_enableTypeDetection) { + [appboyInstance.user setCustomAttributeWithKey:key stringValue:value]; + } else { + NSDictionary *tempConversionDictionary = @{key: value}; + tempConversionDictionary = [self simplifiedDictionary:tempConversionDictionary]; + id obj = tempConversionDictionary[key]; + if ([obj isKindOfClass:[NSString class]]) { + [appboyInstance.user setCustomAttributeWithKey:key stringValue:obj]; + } else if ([obj isKindOfClass:[NSNumber class]]) { + if ([self isBoolNumber:obj]) { + [appboyInstance.user setCustomAttributeWithKey:key boolValue:((NSNumber *)obj).boolValue]; + } else if ([self isInteger:value]) { + [appboyInstance.user setCustomAttributeWithKey:key intValue:((NSNumber *)obj).intValue]; + } else if ([self isFloat:value]) { + [appboyInstance.user setCustomAttributeWithKey:key doubleValue:((NSNumber *)obj).doubleValue]; + } + } else if ([obj isKindOfClass:[NSDate class]]) { + [appboyInstance.user setCustomAttributeWithKey:key dateValue:obj]; + } + } + } + + execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeSuccess]; + return execStatus; +} + +- (nonnull MPKitExecStatus *)setUserAttribute:(nonnull NSString *)key values:(nonnull NSArray *)values { + MPKitExecStatus *execStatus; + + if (!values) { + execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeFail]; + } else { + [appboyInstance.user setCustomAttributeArrayWithKey:key array:values]; + execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeSuccess]; + } + + return execStatus; +} + +- (nonnull MPKitExecStatus *)onIdentifyComplete:(FilteredMParticleUser *)user request:(FilteredMPIdentityApiRequest *)request { + return [self updateUser:user request:request.userIdentities]; +} + +- (nonnull MPKitExecStatus *)onLoginComplete:(FilteredMParticleUser *)user request:(FilteredMPIdentityApiRequest *)request { + return [self updateUser:user request:request.userIdentities]; +} + +- (nonnull MPKitExecStatus *)onLogoutComplete:(FilteredMParticleUser *)user request:(FilteredMPIdentityApiRequest *)request { + return [self updateUser:user request:request.userIdentities]; +} + +- (nonnull MPKitExecStatus *)onModifyComplete:(FilteredMParticleUser *)user request:(FilteredMPIdentityApiRequest *)request { + return [self updateUser:user request:request.userIdentities]; +} + +- (nonnull MPKitExecStatus *)updateUser:(FilteredMParticleUser *)user request:(NSDictionary *)userIdentities { + MPKitExecStatus *execStatus = nil; + + if (userIdentities) { + NSMutableDictionary *userIDsCopy = [userIdentities copy]; + NSString *userId; + + if (_configuration[userIdTypeKey]) { + NSString *userIdKey = _configuration[userIdTypeKey]; + if ([userIdKey isEqualToString:userIdValueOther]) { + if (userIDsCopy[@(MPUserIdentityOther)]) { + userId = userIDsCopy[@(MPUserIdentityOther)]; + } + } else if ([userIdKey isEqualToString:userIdValueOther2]) { + if (userIDsCopy[@(MPUserIdentityOther2)]) { + userId = userIDsCopy[@(MPUserIdentityOther2)]; + } + } else if ([userIdKey isEqualToString:userIdValueOther3]) { + if (userIDsCopy[@(MPUserIdentityOther3)]) { + userId = userIDsCopy[@(MPUserIdentityOther3)]; + } + } else if ([userIdKey isEqualToString:userIdValueOther4]) { + if (userIDsCopy[@(MPUserIdentityOther4)]) { + userId = userIDsCopy[@(MPUserIdentityOther4)]; + } + } else if ([userIdKey isEqualToString:userIdValueOther5]) { + if (userIDsCopy[@(MPUserIdentityOther5)]) { + userId = userIDsCopy[@(MPUserIdentityOther5)]; + } + } else if ([userIdKey isEqualToString:userIdValueOther6]) { + if (userIDsCopy[@(MPUserIdentityOther6)]) { + userId = userIDsCopy[@(MPUserIdentityOther6)]; + } + } else if ([userIdKey isEqualToString:userIdValueOther7]) { + if (userIDsCopy[@(MPUserIdentityOther7)]) { + userId = userIDsCopy[@(MPUserIdentityOther7)]; + } + } else if ([userIdKey isEqualToString:userIdValueOther8]) { + if (userIDsCopy[@(MPUserIdentityOther8)]) { + userId = userIDsCopy[@(MPUserIdentityOther8)]; + } + } else if ([userIdKey isEqualToString:userIdValueOther9]) { + if (userIDsCopy[@(MPUserIdentityOther9)]) { + userId = userIDsCopy[@(MPUserIdentityOther9)]; + } + } else if ([userIdKey isEqualToString:userIdValueOther10]) { + if (userIDsCopy[@(MPUserIdentityOther10)]) { + userId = userIDsCopy[@(MPUserIdentityOther10)]; + } + } else if ([userIdKey isEqualToString:userIdValueCustomerId]) { + if (userIDsCopy[@(MPUserIdentityCustomerId)]) { + userId = userIDsCopy[@(MPUserIdentityCustomerId)]; + } + } else if ([userIdKey isEqualToString:userIdValueFacebook]) { + if (userIDsCopy[@(MPUserIdentityFacebook)]) { + userId = userIDsCopy[@(MPUserIdentityFacebook)]; + } + } else if ([userIdKey isEqualToString:userIdValueTwitter]) { + if (userIDsCopy[@(MPUserIdentityTwitter)]) { + userId = userIDsCopy[@(MPUserIdentityTwitter)]; + } + } else if ([userIdKey isEqualToString:userIdValueGoogle]) { + if (userIDsCopy[@(MPUserIdentityGoogle)]) { + userId = userIDsCopy[@(MPUserIdentityGoogle)]; + } + } else if ([userIdKey isEqualToString:userIdValueMicrosoft]) { + if (userIDsCopy[@(MPUserIdentityMicrosoft)]) { + userId = userIDsCopy[@(MPUserIdentityMicrosoft)]; + } + } else if ([userIdKey isEqualToString:userIdValueYahoo]) { + if (userIDsCopy[@(MPUserIdentityYahoo)]) { + userId = userIDsCopy[@(MPUserIdentityYahoo)]; + } + } else if ([userIdKey isEqualToString:userIdValueEmail]) { + if (userIDsCopy[@(MPUserIdentityEmail)]) { + userId = userIDsCopy[@(MPUserIdentityEmail)]; + } + } else if ([userIdKey isEqualToString:userIdValueAlias]) { + if (userIDsCopy[@(MPUserIdentityAlias)]) { + userId = userIDsCopy[@(MPUserIdentityAlias)]; + } + } else if ([userIdKey isEqualToString:userIdValueMPID]) { + if (user != nil) { + userId = user.userId.stringValue; + } + } else { + if (userIDsCopy[@(MPUserIdentityCustomerId)]) { + userId = userIDsCopy[@(MPUserIdentityCustomerId)]; + } + } + } + + if (userId && ![userId isKindOfClass: [NSNull class]]) { + void (^changeUser)(void) = ^ { + [self->appboyInstance changeUser:userId]; + }; + + if ([NSThread isMainThread]) { + changeUser(); + } else { + dispatch_async(dispatch_get_main_queue(), changeUser); + } + execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeSuccess]; + } + + NSString *userEmail; + + if (_configuration[emailIdTypeKey]) { + NSString *emailIdKey = _configuration[emailIdTypeKey]; + if ([emailIdKey isEqualToString:userIdValueOther]) { + if (userIDsCopy[@(MPUserIdentityOther)]) { + userEmail = userIDsCopy[@(MPUserIdentityOther)]; + } + } else if ([emailIdKey isEqualToString:userIdValueOther2]) { + if (userIDsCopy[@(MPUserIdentityOther2)]) { + userEmail = userIDsCopy[@(MPUserIdentityOther2)]; + } + } else if ([emailIdKey isEqualToString:userIdValueOther3]) { + if (userIDsCopy[@(MPUserIdentityOther3)]) { + userEmail = userIDsCopy[@(MPUserIdentityOther3)]; + } + } else if ([emailIdKey isEqualToString:userIdValueOther4]) { + if (userIDsCopy[@(MPUserIdentityOther4)]) { + userEmail = userIDsCopy[@(MPUserIdentityOther4)]; + } + } else if ([emailIdKey isEqualToString:userIdValueOther5]) { + if (userIDsCopy[@(MPUserIdentityOther5)]) { + userEmail = userIDsCopy[@(MPUserIdentityOther5)]; + } + } else if ([emailIdKey isEqualToString:userIdValueOther6]) { + if (userIDsCopy[@(MPUserIdentityOther6)]) { + userEmail = userIDsCopy[@(MPUserIdentityOther6)]; + } + } else if ([emailIdKey isEqualToString:userIdValueOther7]) { + if (userIDsCopy[@(MPUserIdentityOther7)]) { + userEmail = userIDsCopy[@(MPUserIdentityOther7)]; + } + } else if ([emailIdKey isEqualToString:userIdValueOther8]) { + if (userIDsCopy[@(MPUserIdentityOther8)]) { + userEmail = userIDsCopy[@(MPUserIdentityOther8)]; + } + } else if ([emailIdKey isEqualToString:userIdValueOther9]) { + if (userIDsCopy[@(MPUserIdentityOther9)]) { + userEmail = userIDsCopy[@(MPUserIdentityOther9)]; + } + } else if ([emailIdKey isEqualToString:userIdValueOther10]) { + if (userIDsCopy[@(MPUserIdentityOther10)]) { + userEmail = userIDsCopy[@(MPUserIdentityOther10)]; + } + } else if ([emailIdKey isEqualToString:userIdValueEmail]) { + if (userIDsCopy[@(MPUserIdentityEmail)]) { + userEmail = userIDsCopy[@(MPUserIdentityEmail)]; + } + } else { + if (userIDsCopy[@(MPUserIdentityEmail)]) { + userEmail = userIDsCopy[@(MPUserIdentityEmail)]; + } + } + } + + if (userEmail && ![userEmail isKindOfClass: [NSNull class]]) { + [appboyInstance.user setEmail:userEmail]; + execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeSuccess]; + } + } + + return execStatus; +} + +- (MPKitExecStatus *)setUserIdentity:(NSString *)identityString identityType:(MPUserIdentity)identityType { + return [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeSuccess]; +} + +#if TARGET_OS_IOS +- (nonnull MPKitExecStatus *)userNotificationCenter:(nonnull UNUserNotificationCenter *)center willPresentNotification:(nonnull UNNotification *)notification { + MPKitExecStatus *execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeSuccess]; + + if (shouldDisableNotificationHandling) { + return execStatus; + } + + if (![appboyInstance.notifications handleBackgroundNotificationWithUserInfo:notification.request.content.userInfo fetchCompletionHandler:^(UIBackgroundFetchResult fetchResult) {}]) { + NSLog(@"mParticle -> Invalid Braze remote notification: %@", notification.request.content.userInfo); + } + + return execStatus; +} + +- (nonnull MPKitExecStatus *)userNotificationCenter:(nonnull UNUserNotificationCenter *)center didReceiveNotificationResponse:(nonnull UNNotificationResponse *)response API_AVAILABLE(ios(10.0)) { + MPKitExecStatus *execStatus = [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeSuccess]; + + if (shouldDisableNotificationHandling) { + return execStatus; + } + + if (![appboyInstance.notifications handleUserNotificationWithResponse:response withCompletionHandler:^{}]) { + NSLog(@"mParticle -> Notification Response rejected by Braze: %@", response); + } + + return execStatus; +} +#endif + +- (MPKitExecStatus *)setATTStatus:(MPATTAuthorizationStatus)status withATTStatusTimestampMillis:(NSNumber *)attStatusTimestampMillis { + BOOL isEnabled = status == MPATTAuthorizationStatusAuthorized; + [appboyInstance setAdTrackingEnabled:isEnabled]; + return [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeSuccess]; +} + +- (MPKitExecStatus *)setConsentState:(nullable MPConsentState *)state { + [self updateConsent]; + + return [[MPKitExecStatus alloc] initWithSDKCode:@(MPKitInstanceAppboy) returnCode:MPKitReturnCodeSuccess]; +} + +- (void)updateConsent { + MParticleUser *currentUser = [[[MParticle sharedInstance] identity] currentUser]; + NSDictionary *userConsentMap = currentUser.consentState.gdprConsentState; + + // Update from mParticle consent + if (self.configuration && self.configuration[MPConsentMappingSDKKey]) { + // Retrieve the array of Consent Map Dictionaries from the Config + NSData *objectData = [self.configuration[MPConsentMappingSDKKey] dataUsingEncoding:NSUTF8StringEncoding]; + NSArray *consentMappingArray = [NSJSONSerialization JSONObjectWithData:objectData + options:NSJSONReadingMutableContainers + error:nil]; + + // For each valid Consent Map check if mParticle has a corresponding consent setting and, if so, send to Braze + for (NSDictionary *consentMappingDict in consentMappingArray) { + NSString *consentPurpose = consentMappingDict[MPMapKey]; + if (consentMappingDict[MPValueKey] && userConsentMap[consentPurpose.lowercaseString]) { + NSString *brazeConsentName = consentMappingDict[MPValueKey]; + MPGDPRConsent *consent = userConsentMap[consentPurpose.lowercaseString]; + if ([brazeConsentName isEqualToString:MPGoogleAdUserDataKey]) { + [appboyInstance.user setCustomAttributeWithKey:BGoogleAdUserDataKey boolValue:consent.consented]; + } else if ([brazeConsentName isEqualToString:MPGoogleAdPersonalizationKey]) { + [appboyInstance.user setCustomAttributeWithKey:BGoogleAdPersonalizationKey boolValue:consent.consented]; + } + } + } + } +} + +#pragma mark Configuration Dictionary + +- (NSMutableDictionary *)simplifiedDictionary:(NSDictionary *)originalDictionary { + __block NSMutableDictionary *transformedDictionary = [[NSMutableDictionary alloc] init]; + + [originalDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { + if ([value isKindOfClass:[NSString class]]) { + NSString *stringValue = (NSString *)value; + NSDate *dateValue = [MPKitAPI dateFromStringRFC3339:stringValue]; + if (dateValue) { + transformedDictionary[key] = dateValue; + } else if ([self isInteger:stringValue]) { + transformedDictionary[key] = [NSNumber numberWithInteger:[stringValue integerValue]]; + } else if ([self isFloat:stringValue]) { + transformedDictionary[key] = [NSNumber numberWithFloat:[stringValue floatValue]]; + } else if ([stringValue caseInsensitiveCompare:@"true"] == NSOrderedSame) { + transformedDictionary[key] = @YES; + } else if ([stringValue caseInsensitiveCompare:@"false"] == NSOrderedSame) { + transformedDictionary[key] = @NO; + } + else { + transformedDictionary[key] = stringValue; + } + } else if ([value isKindOfClass:[NSNumber class]]) { + transformedDictionary[key] = (NSNumber *)value; + } else if ([value isKindOfClass:[NSDate class]]) { + transformedDictionary[key] = (NSDate *)value; + } + }]; + + return transformedDictionary; +} + +- (BOOL) isInteger:(NSString *)string { + NSCharacterSet* nonNumbers = [[NSCharacterSet decimalDigitCharacterSet] invertedSet]; + + if([string hasPrefix:@"-"]) { + NSString *absoluteString = [string stringByReplacingOccurrencesOfString:@"-" withString:@""]; + NSRange r = [absoluteString rangeOfCharacterFromSet: nonNumbers]; + + return r.location == NSNotFound && absoluteString.length > 0; + } else { + NSRange r = [string rangeOfCharacterFromSet: nonNumbers]; + + return r.location == NSNotFound && string.length > 0; + } +} + +- (BOOL) isFloat:(NSString *)string { + NSArray *numList = [string componentsSeparatedByString:@"."]; + + if (numList.count == 2) { + if ([self isInteger:numList[0]] && [self isInteger:numList[1]]) { + return true; + } + } + + return false; +} + +- (BOOL) isBoolNumber:(NSNumber *)num { + CFTypeID boolID = CFBooleanGetTypeID(); + CFTypeID numID = CFGetTypeID((__bridge CFTypeRef)(num)); + return numID == boolID; +} + +- (void)setEnableTypeDetection:(BOOL)enableTypeDetection { + _enableTypeDetection = enableTypeDetection; +} + +- (NSArray *)getProductListParameters:(NSArray *)products { + NSMutableArray *productArray = [[NSMutableArray alloc] init]; + for (MPProduct *product in products) { + // Add attributes from the products themselves + NSMutableDictionary *productDictionary = [[product beautifiedDictionaryRepresentation] mutableCopy]; + + if (product.userDefinedAttributes.count > 0) { + [productDictionary removeObjectsForKeys:[product.userDefinedAttributes allKeys]]; + [productDictionary setValue:product.userDefinedAttributes forKey:attributesKey]; + } + + // Adds the product dictionary to the product array being supplied to Braze + if (productDictionary) { + [productArray addObject:productDictionary]; + } + } + return productArray; +} + +- (NSArray *)getPromotionListParameters:(NSArray *)promotions { + NSMutableArray *promotionArray = [[NSMutableArray alloc] init]; + for (MPPromotion *promotion in promotions) { + // Add attributes from the promotions themselves + NSMutableDictionary *promotionDictionary = [[NSMutableDictionary alloc] init]; + promotionDictionary[@"Creative"] = promotion.creative; + promotionDictionary[@"Name"] = promotion.name; + promotionDictionary[@"Position"] = promotion.position; + promotionDictionary[@"Id"] = promotion.promotionId; + + // Adds the promotion dictionary to the promotion array being supplied to Braze + [promotionArray addObject:promotionDictionary]; + } + return promotionArray; +} + +- (NSArray *)getImpressionListParameters:(NSDictionary *> *)impressions { + NSMutableArray *impressionArray = [[NSMutableArray alloc] init]; + for (NSString *impressionName in impressions.allKeys) { + // Add attributes from the products themselves + NSMutableDictionary *impressionDictionary = [[NSMutableDictionary alloc] init]; + impressionDictionary[@"Product Impression List"] = impressionName; + NSArray *impressionProducts = [[impressions[impressionName] allObjects] copy]; + impressionDictionary[productKey] = [self getProductListParameters:impressionProducts]; + + // Adds the impression dictionary to the impression array being supplied to Braze + [impressionArray addObject:impressionDictionary]; + } + return impressionArray; +} + +- (NSString *)eventNameForAction:(MPCommerceEventAction)action { + NSArray *actionNames = @[@"add_to_cart", @"remove_from_cart", @"add_to_wishlist", @"remove_from_wishlist", @"checkout", @"checkout_option", @"click", @"view_detail", @"purchase", @"refund"]; + + if (action >= actionNames.count) { + return @"unknown"; + } + + return actionNames[(NSUInteger)action]; +} + +- (NSString *)eventNameForPromotionAction:(MPPromotionAction)action { + NSArray *actionNames = @[@"click", @"view"]; + + if (action >= actionNames.count) { + return @"unknown"; + } + + return actionNames[(NSUInteger)action]; +} + +@end diff --git a/kits/braze/braze-12/Sources/mParticle-Appboy/PrivacyInfo.xcprivacy b/kits/braze/braze-12/Sources/mParticle-Appboy/PrivacyInfo.xcprivacy new file mode 100644 index 000000000..e08a130bc --- /dev/null +++ b/kits/braze/braze-12/Sources/mParticle-Appboy/PrivacyInfo.xcprivacy @@ -0,0 +1,14 @@ + + + + + NSPrivacyTracking + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + NSPrivacyAccessedAPITypes + + + diff --git a/kits/braze/braze-12/Sources/mParticle-Appboy/include/MPKitAppboy.h b/kits/braze/braze-12/Sources/mParticle-Appboy/include/MPKitAppboy.h new file mode 100644 index 000000000..26b7c78e2 --- /dev/null +++ b/kits/braze/braze-12/Sources/mParticle-Appboy/include/MPKitAppboy.h @@ -0,0 +1,29 @@ +#import +#if defined(__has_include) && __has_include() + #import +#else + #import "mParticle.h" +#endif + +#if defined(__has_include) && __has_include() + #import +#else + #import BrazeKit-Swift.h +#endif + +@interface MPKitAppboy : NSObject + +@property (nonatomic, strong, nonnull) NSDictionary *configuration; +@property (nonatomic, strong, nullable) NSDictionary *launchOptions; +@property (nonatomic, unsafe_unretained, readonly) BOOL started; +@property (nonatomic, strong, nullable) MPKitAPI *kitApi; + +#if TARGET_OS_IOS ++ (void)setInAppMessageControllerDelegate:(nonnull id)delegate; ++ (void)setShouldDisableNotificationHandling:(BOOL)isDisabled; +#endif ++ (void)setURLDelegate:(nonnull id)delegate; ++ (void)setBrazeInstance:(nonnull id)instance; ++ (void)setBrazeLocationProvider:(nonnull id)instance; ++ (void)setBrazeTrackingPropertyAllowList:(nonnull NSSet *)allowList; +@end diff --git a/kits/braze/braze-12/Sources/mParticle-Appboy/include/mParticle_Appboy.h b/kits/braze/braze-12/Sources/mParticle-Appboy/include/mParticle_Appboy.h new file mode 100644 index 000000000..829f2c83e --- /dev/null +++ b/kits/braze/braze-12/Sources/mParticle-Appboy/include/mParticle_Appboy.h @@ -0,0 +1,17 @@ +#import + +//! Project version number for mParticle-Appboy. +FOUNDATION_EXPORT double mParticle_AppboyVersionNumber; + +//! Project version string for mParticle-Appboy. +FOUNDATION_EXPORT const unsigned char mParticle_AppboyVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + +#if defined(__has_include) && __has_include() + #import +#elif defined(__has_include) && __has_include() + #import +#else + #import "MPKitAppboy.h" +#endif diff --git a/kits/braze/braze-12/mParticle-Appboy-tvOS/Info.plist b/kits/braze/braze-12/mParticle-Appboy-tvOS/Info.plist new file mode 100644 index 000000000..1007fd9dd --- /dev/null +++ b/kits/braze/braze-12/mParticle-Appboy-tvOS/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/kits/braze/braze-12/mParticle-Appboy-tvOS/mParticle_Appboy_tvOS.h b/kits/braze/braze-12/mParticle-Appboy-tvOS/mParticle_Appboy_tvOS.h new file mode 100644 index 000000000..1674a2e7c --- /dev/null +++ b/kits/braze/braze-12/mParticle-Appboy-tvOS/mParticle_Appboy_tvOS.h @@ -0,0 +1,12 @@ +#import + +//! Project version number for mParticle_Appboy_tvOS. +FOUNDATION_EXPORT double mParticle_Appboy_tvOSVersionNumber; + +//! Project version string for mParticle_Appboy_tvOS. +FOUNDATION_EXPORT const unsigned char mParticle_Appboy_tvOSVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + +#import diff --git a/kits/braze/braze-12/mParticle-Appboy.podspec b/kits/braze/braze-12/mParticle-Appboy.podspec new file mode 100755 index 000000000..42d787142 --- /dev/null +++ b/kits/braze/braze-12/mParticle-Appboy.podspec @@ -0,0 +1,34 @@ +Pod::Spec.new do |s| + s.name = "mParticle-Appboy" + s.version = "8.13.2" + s.summary = "Appboy integration for mParticle" + + s.description = <<-DESC + This is the Appboy integration for mParticle. + DESC + + s.homepage = "https://www.mparticle.com" + s.license = { :type => 'Apache 2.0', :file => 'LICENSE' } + s.author = { "mParticle" => "support@mparticle.com" } + s.source = { :git => "https://github.com/mparticle-integrations/mparticle-apple-integration-appboy.git", :tag => "v" + s.version.to_s } + s.social_media_url = "https://twitter.com/mparticle" + s.static_framework = true + s.swift_version = '5.3' + + s.ios.deployment_target = "12.0" + s.ios.source_files = 'Sources/**/*.{h,m,mm}' + s.ios.resource_bundles = { 'mParticle-Appboy-Privacy' => ['Sources/mParticle-Appboy/PrivacyInfo.xcprivacy'] } + s.ios.dependency 'mParticle-Apple-SDK', '~> 8.19' + s.ios.dependency 'BrazeKit', '~> 12.0' + s.ios.dependency 'BrazeKitCompat', '~> 12.0' + s.ios.dependency 'BrazeUI', '~> 12.0' + + s.tvos.deployment_target = "12.0" + s.tvos.source_files = 'Sources/**/*.{h,m,mm}' + s.tvos.resource_bundles = { 'mParticle-Appboy-Privacy' => ['Sources/mParticle-Appboy/PrivacyInfo.xcprivacy'] } + s.tvos.dependency 'mParticle-Apple-SDK', '~> 8.19' + s.tvos.dependency 'BrazeKit', '~> 12.0' + s.tvos.dependency 'BrazeKitCompat', '~> 12.0' + + +end diff --git a/kits/braze/braze-12/mParticle-Appboy.xcodeproj/project.pbxproj b/kits/braze/braze-12/mParticle-Appboy.xcodeproj/project.pbxproj new file mode 100644 index 000000000..bd5840805 --- /dev/null +++ b/kits/braze/braze-12/mParticle-Appboy.xcodeproj/project.pbxproj @@ -0,0 +1,981 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 60; + objects = { + +/* Begin PBXBuildFile section */ + 351557782F43A6AF006096E1 /* mParticle-Apple-SDK in Frameworks */ = {isa = PBXBuildFile; productRef = 351557772F43A6AF006096E1 /* mParticle-Apple-SDK */; }; + 3515577A2F43A6CA006096E1 /* mParticle-Apple-SDK in Frameworks */ = {isa = PBXBuildFile; productRef = 351557792F43A6CA006096E1 /* mParticle-Apple-SDK */; }; + 531861FF2A13E147006FFE90 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 531861FE2A13E147006FFE90 /* AppDelegate.swift */; }; + 531862032A13E147006FFE90 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 531862022A13E147006FFE90 /* ViewController.swift */; }; + 531862062A13E147006FFE90 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 531862042A13E147006FFE90 /* Main.storyboard */; }; + 531862082A13E14A006FFE90 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 531862072A13E14A006FFE90 /* Assets.xcassets */; }; + 5318620B2A13E14A006FFE90 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 531862092A13E14A006FFE90 /* LaunchScreen.storyboard */; }; + 5387EC002A18050500219E89 /* BrazeKit in Frameworks */ = {isa = PBXBuildFile; productRef = 5387EBFF2A18050500219E89 /* BrazeKit */; }; + 5387EC022A18051200219E89 /* BrazeKit in Frameworks */ = {isa = PBXBuildFile; productRef = 5387EC012A18051200219E89 /* BrazeKit */; }; + 539B2E952A13D62200C8339D /* OCMock in Frameworks */ = {isa = PBXBuildFile; productRef = 539B2E942A13D62200C8339D /* OCMock */; }; + 539B2E9D2A13D69F00C8339D /* BrazeKitCompat in Frameworks */ = {isa = PBXBuildFile; productRef = 539B2E9C2A13D69F00C8339D /* BrazeKitCompat */; }; + 539B2E9F2A13D69F00C8339D /* BrazeUI in Frameworks */ = {isa = PBXBuildFile; productRef = 539B2E9E2A13D69F00C8339D /* BrazeUI */; }; + 539B2EA12A13D6AB00C8339D /* BrazeKitCompat in Frameworks */ = {isa = PBXBuildFile; productRef = 539B2EA02A13D6AB00C8339D /* BrazeKitCompat */; }; + D31A98A92153F73400358293 /* mParticle_AppboyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D31A98A82153F73400358293 /* mParticle_AppboyTests.m */; }; + D31A98AB2153F73400358293 /* mParticle_Appboy.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB94016C1CB703F2007ABB18 /* mParticle_Appboy.framework */; }; + D34423302B960F44006CD046 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = D344232F2B960F44006CD046 /* PrivacyInfo.xcprivacy */; }; + D34423312B960F44006CD046 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = D344232F2B960F44006CD046 /* PrivacyInfo.xcprivacy */; }; + DB76F1CF25D2E71D00CAB3EB /* MPKitAppboy.h in Headers */ = {isa = PBXBuildFile; fileRef = DB76F1CB25D2E71D00CAB3EB /* MPKitAppboy.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DB76F1D025D2E71D00CAB3EB /* mParticle_Appboy.h in Headers */ = {isa = PBXBuildFile; fileRef = DB76F1CC25D2E71D00CAB3EB /* mParticle_Appboy.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DB76F1D125D2E71D00CAB3EB /* MPKitAppboy.m in Sources */ = {isa = PBXBuildFile; fileRef = DB76F1CD25D2E71D00CAB3EB /* MPKitAppboy.m */; }; + DB76F1D225D2E71D00CAB3EB /* MPKitAppboy.m in Sources */ = {isa = PBXBuildFile; fileRef = DB76F1CD25D2E71D00CAB3EB /* MPKitAppboy.m */; }; + DB76F1DB25D2E73700CAB3EB /* MPKitAppboy.m in Sources */ = {isa = PBXBuildFile; fileRef = DB76F1CD25D2E71D00CAB3EB /* MPKitAppboy.m */; }; + DB76F1DF25D2E74900CAB3EB /* MPKitAppboy.h in Headers */ = {isa = PBXBuildFile; fileRef = DB76F1CB25D2E71D00CAB3EB /* MPKitAppboy.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DBDEDD9C209B8FD600DD3B9B /* mParticle_Appboy_tvOS.h in Headers */ = {isa = PBXBuildFile; fileRef = DBDEDD9A209B8FD600DD3B9B /* mParticle_Appboy_tvOS.h */; settings = {ATTRIBUTES = (Public, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 531862102A13E17D006FFE90 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DB9401631CB703F2007ABB18 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 531861FB2A13E147006FFE90; + remoteInfo = AppboyTestHost; + }; + D31A98AC2153F73400358293 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DB9401631CB703F2007ABB18 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DB94016B1CB703F2007ABB18; + remoteInfo = "mParticle-Appboy"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 531861FC2A13E147006FFE90 /* AppboyTestHost.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AppboyTestHost.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 531861FE2A13E147006FFE90 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 531862022A13E147006FFE90 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 531862052A13E147006FFE90 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 531862072A13E14A006FFE90 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 5318620A2A13E14A006FFE90 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 5318620C2A13E14A006FFE90 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D31A98A62153F73400358293 /* mParticle_AppboyTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = mParticle_AppboyTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + D31A98A82153F73400358293 /* mParticle_AppboyTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = mParticle_AppboyTests.m; sourceTree = ""; }; + D31A98AA2153F73400358293 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D344232F2B960F44006CD046 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; + DB76F1CB25D2E71D00CAB3EB /* MPKitAppboy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPKitAppboy.h; sourceTree = ""; }; + DB76F1CC25D2E71D00CAB3EB /* mParticle_Appboy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mParticle_Appboy.h; sourceTree = ""; }; + DB76F1CD25D2E71D00CAB3EB /* MPKitAppboy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPKitAppboy.m; sourceTree = ""; }; + DB76F1CE25D2E71D00CAB3EB /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + DB94016C1CB703F2007ABB18 /* mParticle_Appboy.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = mParticle_Appboy.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + DBDEDD98209B8FD600DD3B9B /* mParticle_Appboy.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = mParticle_Appboy.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + DBDEDD9A209B8FD600DD3B9B /* mParticle_Appboy_tvOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mParticle_Appboy_tvOS.h; sourceTree = ""; }; + DBDEDD9B209B8FD600DD3B9B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + DBDEDDA5209BA36900DD3B9B /* mParticle_Apple_SDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mParticle_Apple_SDK.framework; path = Carthage/Build/tvOS/mParticle_Apple_SDK.framework; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 531861F92A13E147006FFE90 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D31A98A32153F73400358293 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 539B2E952A13D62200C8339D /* OCMock in Frameworks */, + D31A98AB2153F73400358293 /* mParticle_Appboy.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DB9401681CB703F2007ABB18 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5387EC022A18051200219E89 /* BrazeKit in Frameworks */, + 539B2E9F2A13D69F00C8339D /* BrazeUI in Frameworks */, + 351557782F43A6AF006096E1 /* mParticle-Apple-SDK in Frameworks */, + 539B2E9D2A13D69F00C8339D /* BrazeKitCompat in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DBDEDD94209B8FD600DD3B9B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 539B2EA12A13D6AB00C8339D /* BrazeKitCompat in Frameworks */, + 3515577A2F43A6CA006096E1 /* mParticle-Apple-SDK in Frameworks */, + 5387EC002A18050500219E89 /* BrazeKit in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 531861FD2A13E147006FFE90 /* AppboyTestHost */ = { + isa = PBXGroup; + children = ( + 531861FE2A13E147006FFE90 /* AppDelegate.swift */, + 531862022A13E147006FFE90 /* ViewController.swift */, + 531862042A13E147006FFE90 /* Main.storyboard */, + 531862072A13E14A006FFE90 /* Assets.xcassets */, + 531862092A13E14A006FFE90 /* LaunchScreen.storyboard */, + 5318620C2A13E14A006FFE90 /* Info.plist */, + ); + path = AppboyTestHost; + sourceTree = ""; + }; + D31A98A72153F73400358293 /* mParticle_AppboyTests */ = { + isa = PBXGroup; + children = ( + D31A98A82153F73400358293 /* mParticle_AppboyTests.m */, + D31A98AA2153F73400358293 /* Info.plist */, + ); + path = mParticle_AppboyTests; + sourceTree = ""; + }; + DB76F1C825D2E71D00CAB3EB /* Sources */ = { + isa = PBXGroup; + children = ( + DB76F1C925D2E71D00CAB3EB /* mParticle-Appboy */, + DB76F1CE25D2E71D00CAB3EB /* Info.plist */, + ); + path = Sources; + sourceTree = ""; + }; + DB76F1C925D2E71D00CAB3EB /* mParticle-Appboy */ = { + isa = PBXGroup; + children = ( + DB76F1CA25D2E71D00CAB3EB /* include */, + DB76F1CD25D2E71D00CAB3EB /* MPKitAppboy.m */, + D344232F2B960F44006CD046 /* PrivacyInfo.xcprivacy */, + ); + path = "mParticle-Appboy"; + sourceTree = ""; + }; + DB76F1CA25D2E71D00CAB3EB /* include */ = { + isa = PBXGroup; + children = ( + DB76F1CB25D2E71D00CAB3EB /* MPKitAppboy.h */, + DB76F1CC25D2E71D00CAB3EB /* mParticle_Appboy.h */, + ); + path = include; + sourceTree = ""; + }; + DB9401621CB703F2007ABB18 = { + isa = PBXGroup; + children = ( + DB76F1C825D2E71D00CAB3EB /* Sources */, + DBDEDD99209B8FD600DD3B9B /* mParticle-Appboy-tvOS */, + D31A98A72153F73400358293 /* mParticle_AppboyTests */, + 531861FD2A13E147006FFE90 /* AppboyTestHost */, + DB94016D1CB703F2007ABB18 /* Products */, + DBDEDDA3209BA34E00DD3B9B /* Frameworks */, + ); + sourceTree = ""; + }; + DB94016D1CB703F2007ABB18 /* Products */ = { + isa = PBXGroup; + children = ( + DB94016C1CB703F2007ABB18 /* mParticle_Appboy.framework */, + DBDEDD98209B8FD600DD3B9B /* mParticle_Appboy.framework */, + D31A98A62153F73400358293 /* mParticle_AppboyTests.xctest */, + 531861FC2A13E147006FFE90 /* AppboyTestHost.app */, + ); + name = Products; + sourceTree = ""; + }; + DBDEDD99209B8FD600DD3B9B /* mParticle-Appboy-tvOS */ = { + isa = PBXGroup; + children = ( + DBDEDD9A209B8FD600DD3B9B /* mParticle_Appboy_tvOS.h */, + DBDEDD9B209B8FD600DD3B9B /* Info.plist */, + ); + path = "mParticle-Appboy-tvOS"; + sourceTree = ""; + }; + DBDEDDA3209BA34E00DD3B9B /* Frameworks */ = { + isa = PBXGroup; + children = ( + DBDEDDA5209BA36900DD3B9B /* mParticle_Apple_SDK.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + DB9401691CB703F2007ABB18 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + DB76F1CF25D2E71D00CAB3EB /* MPKitAppboy.h in Headers */, + DB76F1D025D2E71D00CAB3EB /* mParticle_Appboy.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DBDEDD95209B8FD600DD3B9B /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + DB76F1DF25D2E74900CAB3EB /* MPKitAppboy.h in Headers */, + DBDEDD9C209B8FD600DD3B9B /* mParticle_Appboy_tvOS.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 531861FB2A13E147006FFE90 /* AppboyTestHost */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5318620D2A13E14A006FFE90 /* Build configuration list for PBXNativeTarget "AppboyTestHost" */; + buildPhases = ( + 531861F82A13E147006FFE90 /* Sources */, + 531861F92A13E147006FFE90 /* Frameworks */, + 531861FA2A13E147006FFE90 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AppboyTestHost; + productName = AppboyTestHost; + productReference = 531861FC2A13E147006FFE90 /* AppboyTestHost.app */; + productType = "com.apple.product-type.application"; + }; + D31A98A52153F73400358293 /* mParticle_AppboyTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = D31A98B02153F73400358293 /* Build configuration list for PBXNativeTarget "mParticle_AppboyTests" */; + buildPhases = ( + D31A98A22153F73400358293 /* Sources */, + D31A98A32153F73400358293 /* Frameworks */, + D31A98A42153F73400358293 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 539B2EA52A13D95200C8339D /* PBXTargetDependency */, + 539B2EA32A13D94E00C8339D /* PBXTargetDependency */, + D31A98AD2153F73400358293 /* PBXTargetDependency */, + 531862112A13E17D006FFE90 /* PBXTargetDependency */, + ); + name = mParticle_AppboyTests; + packageProductDependencies = ( + 539B2E942A13D62200C8339D /* OCMock */, + ); + productName = mParticle_AppboyTests; + productReference = D31A98A62153F73400358293 /* mParticle_AppboyTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + DB94016B1CB703F2007ABB18 /* mParticle-Appboy */ = { + isa = PBXNativeTarget; + buildConfigurationList = DB9401741CB703F2007ABB18 /* Build configuration list for PBXNativeTarget "mParticle-Appboy" */; + buildPhases = ( + DB9401671CB703F2007ABB18 /* Sources */, + DB9401681CB703F2007ABB18 /* Frameworks */, + DB9401691CB703F2007ABB18 /* Headers */, + DB94016A1CB703F2007ABB18 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "mParticle-Appboy"; + packageProductDependencies = ( + 539B2E9C2A13D69F00C8339D /* BrazeKitCompat */, + 539B2E9E2A13D69F00C8339D /* BrazeUI */, + 5387EC012A18051200219E89 /* BrazeKit */, + 351557772F43A6AF006096E1 /* mParticle-Apple-SDK */, + ); + productName = "mParticle-Appboy"; + productReference = DB94016C1CB703F2007ABB18 /* mParticle_Appboy.framework */; + productType = "com.apple.product-type.framework"; + }; + DBDEDD97209B8FD600DD3B9B /* mParticle-Appboy-tvOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = DBDEDD9F209B8FD600DD3B9B /* Build configuration list for PBXNativeTarget "mParticle-Appboy-tvOS" */; + buildPhases = ( + DBDEDD93209B8FD600DD3B9B /* Sources */, + DBDEDD94209B8FD600DD3B9B /* Frameworks */, + DBDEDD95209B8FD600DD3B9B /* Headers */, + DBDEDD96209B8FD600DD3B9B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "mParticle-Appboy-tvOS"; + packageProductDependencies = ( + 539B2EA02A13D6AB00C8339D /* BrazeKitCompat */, + 5387EBFF2A18050500219E89 /* BrazeKit */, + 351557792F43A6CA006096E1 /* mParticle-Apple-SDK */, + ); + productName = "mParticle-Appboy-tvOS"; + productReference = DBDEDD98209B8FD600DD3B9B /* mParticle_Appboy.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + DB9401631CB703F2007ABB18 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1430; + LastUpgradeCheck = 1200; + ORGANIZATIONNAME = mParticle; + TargetAttributes = { + 531861FB2A13E147006FFE90 = { + CreatedOnToolsVersion = 14.3; + }; + D31A98A52153F73400358293 = { + CreatedOnToolsVersion = 10.0; + ProvisioningStyle = Automatic; + TestTargetID = 531861FB2A13E147006FFE90; + }; + DB94016B1CB703F2007ABB18 = { + CreatedOnToolsVersion = 7.3; + DevelopmentTeam = Q948K5LXGZ; + }; + DBDEDD97209B8FD600DD3B9B = { + CreatedOnToolsVersion = 9.3; + DevelopmentTeam = DLD43Y3TRP; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = DB9401661CB703F2007ABB18 /* Build configuration list for PBXProject "mParticle-Appboy" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = DB9401621CB703F2007ABB18; + packageReferences = ( + 539B2E932A13D62200C8339D /* XCRemoteSwiftPackageReference "ocmock" */, + 539B2E9B2A13D69F00C8339D /* XCRemoteSwiftPackageReference "braze-swift-sdk" */, + 351557762F43A6AF006096E1 /* XCLocalSwiftPackageReference "../../../../mparticle-apple-sdk" */, + ); + productRefGroup = DB94016D1CB703F2007ABB18 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + DB94016B1CB703F2007ABB18 /* mParticle-Appboy */, + DBDEDD97209B8FD600DD3B9B /* mParticle-Appboy-tvOS */, + D31A98A52153F73400358293 /* mParticle_AppboyTests */, + 531861FB2A13E147006FFE90 /* AppboyTestHost */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 531861FA2A13E147006FFE90 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5318620B2A13E14A006FFE90 /* LaunchScreen.storyboard in Resources */, + 531862082A13E14A006FFE90 /* Assets.xcassets in Resources */, + 531862062A13E147006FFE90 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D31A98A42153F73400358293 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DB94016A1CB703F2007ABB18 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D34423302B960F44006CD046 /* PrivacyInfo.xcprivacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DBDEDD96209B8FD600DD3B9B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D34423312B960F44006CD046 /* PrivacyInfo.xcprivacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 531861F82A13E147006FFE90 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 531862032A13E147006FFE90 /* ViewController.swift in Sources */, + 531861FF2A13E147006FFE90 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D31A98A22153F73400358293 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DB76F1D225D2E71D00CAB3EB /* MPKitAppboy.m in Sources */, + D31A98A92153F73400358293 /* mParticle_AppboyTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DB9401671CB703F2007ABB18 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DB76F1D125D2E71D00CAB3EB /* MPKitAppboy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DBDEDD93209B8FD600DD3B9B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DB76F1DB25D2E73700CAB3EB /* MPKitAppboy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 531862112A13E17D006FFE90 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 531861FB2A13E147006FFE90 /* AppboyTestHost */; + targetProxy = 531862102A13E17D006FFE90 /* PBXContainerItemProxy */; + }; + 539B2EA32A13D94E00C8339D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + productRef = 539B2EA22A13D94E00C8339D /* BrazeKitCompat */; + }; + 539B2EA52A13D95200C8339D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + productRef = 539B2EA42A13D95200C8339D /* BrazeUI */; + }; + D31A98AD2153F73400358293 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DB94016B1CB703F2007ABB18 /* mParticle-Appboy */; + targetProxy = D31A98AC2153F73400358293 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 531862042A13E147006FFE90 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 531862052A13E147006FFE90 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 531862092A13E14A006FFE90 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5318620A2A13E14A006FFE90 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 5318620E2A13E14A006FFE90 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GCC_C_LANGUAGE_STANDARD = gnu11; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = AppboyTestHost/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.mparticle.AppboyTestHost; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TVOS_DEPLOYMENT_TARGET = 15.6; + }; + name = Debug; + }; + 5318620F2A13E14A006FFE90 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GCC_C_LANGUAGE_STANDARD = gnu11; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = AppboyTestHost/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; + MARKETING_VERSION = 1.0; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.mparticle.AppboyTestHost; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TVOS_DEPLOYMENT_TARGET = 15.6; + }; + name = Release; + }; + D31A98AE2153F73400358293 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = mParticle_AppboyTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.mparticle.mParticle-AppboyTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AppboyTestHost.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/AppboyTestHost"; + TVOS_DEPLOYMENT_TARGET = 15.6; + }; + name = Debug; + }; + D31A98AF2153F73400358293 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = mParticle_AppboyTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.mparticle.mParticle-AppboyTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AppboyTestHost.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/AppboyTestHost"; + TVOS_DEPLOYMENT_TARGET = 15.6; + }; + name = Release; + }; + DB9401721CB703F2007ABB18 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO; + 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; + CURRENT_PROJECT_VERSION = 1; + 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 = 11.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + TVOS_DEPLOYMENT_TARGET = 11.0; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + DB9401731CB703F2007ABB18 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO; + 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; + CURRENT_PROJECT_VERSION = 1; + 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 = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + TVOS_DEPLOYMENT_TARGET = 11.0; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + DB9401751CB703F2007ABB18 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Sources/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; + PRODUCT_BUNDLE_IDENTIFIER = "com.mparticle.mParticle-Appboy"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + TVOS_DEPLOYMENT_TARGET = 15.6; + }; + name = Debug; + }; + DB9401761CB703F2007ABB18 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = Sources/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; + PRODUCT_BUNDLE_IDENTIFIER = "com.mparticle.mParticle-Appboy"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + TVOS_DEPLOYMENT_TARGET = 15.6; + }; + name = Release; + }; + DBDEDD9D209B8FD600DD3B9B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = DLD43Y3TRP; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = "mParticle-Appboy-tvOS/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; + OTHER_LDFLAGS = ( + "-ObjC", + "-all_load", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.mparticle.mParticle-Appboy-tvOS"; + PRODUCT_NAME = mParticle_Appboy; + SDKROOT = appletvos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 15.6; + }; + name = Debug; + }; + DBDEDD9E209B8FD600DD3B9B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = DLD43Y3TRP; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = "mParticle-Appboy-tvOS/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; + OTHER_LDFLAGS = ( + "-ObjC", + "-all_load", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.mparticle.mParticle-Appboy-tvOS"; + PRODUCT_NAME = mParticle_Appboy; + SDKROOT = appletvos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 15.6; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 5318620D2A13E14A006FFE90 /* Build configuration list for PBXNativeTarget "AppboyTestHost" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5318620E2A13E14A006FFE90 /* Debug */, + 5318620F2A13E14A006FFE90 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D31A98B02153F73400358293 /* Build configuration list for PBXNativeTarget "mParticle_AppboyTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D31A98AE2153F73400358293 /* Debug */, + D31A98AF2153F73400358293 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DB9401661CB703F2007ABB18 /* Build configuration list for PBXProject "mParticle-Appboy" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DB9401721CB703F2007ABB18 /* Debug */, + DB9401731CB703F2007ABB18 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DB9401741CB703F2007ABB18 /* Build configuration list for PBXNativeTarget "mParticle-Appboy" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DB9401751CB703F2007ABB18 /* Debug */, + DB9401761CB703F2007ABB18 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DBDEDD9F209B8FD600DD3B9B /* Build configuration list for PBXNativeTarget "mParticle-Appboy-tvOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DBDEDD9D209B8FD600DD3B9B /* Debug */, + DBDEDD9E209B8FD600DD3B9B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCLocalSwiftPackageReference section */ + 351557762F43A6AF006096E1 /* XCLocalSwiftPackageReference "../../../../mparticle-apple-sdk" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = "../../../../mparticle-apple-sdk"; + }; +/* End XCLocalSwiftPackageReference section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 539B2E932A13D62200C8339D /* XCRemoteSwiftPackageReference "ocmock" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/erikdoe/ocmock"; + requirement = { + branch = master; + kind = branch; + }; + }; + 539B2E9B2A13D69F00C8339D /* XCRemoteSwiftPackageReference "braze-swift-sdk" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/braze-inc/braze-swift-sdk"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 9.0.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 351557772F43A6AF006096E1 /* mParticle-Apple-SDK */ = { + isa = XCSwiftPackageProductDependency; + productName = "mParticle-Apple-SDK"; + }; + 351557792F43A6CA006096E1 /* mParticle-Apple-SDK */ = { + isa = XCSwiftPackageProductDependency; + package = 351557762F43A6AF006096E1 /* XCLocalSwiftPackageReference "../../../../mparticle-apple-sdk" */; + productName = "mParticle-Apple-SDK"; + }; + 5387EBFF2A18050500219E89 /* BrazeKit */ = { + isa = XCSwiftPackageProductDependency; + package = 539B2E9B2A13D69F00C8339D /* XCRemoteSwiftPackageReference "braze-swift-sdk" */; + productName = BrazeKit; + }; + 5387EC012A18051200219E89 /* BrazeKit */ = { + isa = XCSwiftPackageProductDependency; + package = 539B2E9B2A13D69F00C8339D /* XCRemoteSwiftPackageReference "braze-swift-sdk" */; + productName = BrazeKit; + }; + 539B2E942A13D62200C8339D /* OCMock */ = { + isa = XCSwiftPackageProductDependency; + package = 539B2E932A13D62200C8339D /* XCRemoteSwiftPackageReference "ocmock" */; + productName = OCMock; + }; + 539B2E9C2A13D69F00C8339D /* BrazeKitCompat */ = { + isa = XCSwiftPackageProductDependency; + package = 539B2E9B2A13D69F00C8339D /* XCRemoteSwiftPackageReference "braze-swift-sdk" */; + productName = BrazeKitCompat; + }; + 539B2E9E2A13D69F00C8339D /* BrazeUI */ = { + isa = XCSwiftPackageProductDependency; + package = 539B2E9B2A13D69F00C8339D /* XCRemoteSwiftPackageReference "braze-swift-sdk" */; + productName = BrazeUI; + }; + 539B2EA02A13D6AB00C8339D /* BrazeKitCompat */ = { + isa = XCSwiftPackageProductDependency; + package = 539B2E9B2A13D69F00C8339D /* XCRemoteSwiftPackageReference "braze-swift-sdk" */; + productName = BrazeKitCompat; + }; + 539B2EA22A13D94E00C8339D /* BrazeKitCompat */ = { + isa = XCSwiftPackageProductDependency; + package = 539B2E9B2A13D69F00C8339D /* XCRemoteSwiftPackageReference "braze-swift-sdk" */; + productName = BrazeKitCompat; + }; + 539B2EA42A13D95200C8339D /* BrazeUI */ = { + isa = XCSwiftPackageProductDependency; + package = 539B2E9B2A13D69F00C8339D /* XCRemoteSwiftPackageReference "braze-swift-sdk" */; + productName = BrazeUI; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = DB9401631CB703F2007ABB18 /* Project object */; +} diff --git a/kits/braze/braze-12/mParticle-Appboy.xcodeproj/xcshareddata/xcschemes/mParticle-Appboy-tvOS.xcscheme b/kits/braze/braze-12/mParticle-Appboy.xcodeproj/xcshareddata/xcschemes/mParticle-Appboy-tvOS.xcscheme new file mode 100644 index 000000000..abc83a0ff --- /dev/null +++ b/kits/braze/braze-12/mParticle-Appboy.xcodeproj/xcshareddata/xcschemes/mParticle-Appboy-tvOS.xcscheme @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kits/braze/braze-12/mParticle-Appboy.xcodeproj/xcshareddata/xcschemes/mParticle-Appboy.xcscheme b/kits/braze/braze-12/mParticle-Appboy.xcodeproj/xcshareddata/xcschemes/mParticle-Appboy.xcscheme new file mode 100644 index 000000000..8df0b6d08 --- /dev/null +++ b/kits/braze/braze-12/mParticle-Appboy.xcodeproj/xcshareddata/xcschemes/mParticle-Appboy.xcscheme @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kits/braze/braze-12/mParticle-Appboy.xcodeproj/xcshareddata/xcschemes/mParticle_AppboyTests.xcscheme b/kits/braze/braze-12/mParticle-Appboy.xcodeproj/xcshareddata/xcschemes/mParticle_AppboyTests.xcscheme new file mode 100644 index 000000000..431d9a6d0 --- /dev/null +++ b/kits/braze/braze-12/mParticle-Appboy.xcodeproj/xcshareddata/xcschemes/mParticle_AppboyTests.xcscheme @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/kits/braze/braze-12/mParticle_Appboy.json b/kits/braze/braze-12/mParticle_Appboy.json new file mode 100644 index 000000000..581feef6c --- /dev/null +++ b/kits/braze/braze-12/mParticle_Appboy.json @@ -0,0 +1,13 @@ +{ + "7.7.4": "https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/releases/download/7.7.4/mParticle_Appboy.framework.zip", + "7.7.5": "https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/releases/download/7.7.5/mParticle_Appboy.framework.zip", + "7.8.0": "https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/releases/download/7.8.0/mParticle_Appboy.framework.zip", + "7.8.1": "https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/releases/download/7.8.1/mParticle_Appboy.framework.zip", + "7.8.2": "https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/releases/download/7.8.2/mParticle_Appboy.framework.zip", + "7.8.3": "https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/releases/download/7.8.3/mParticle_Appboy.framework.zip", + "7.8.4": "https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/releases/download/7.8.4/mParticle_Appboy.framework.zip", + "7.8.5": "https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/releases/download/7.8.5/mParticle_Appboy.framework.zip", + "7.8.6": "https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/releases/download/7.8.6/mParticle_Appboy.framework.zip", + "7.9.0": "https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/releases/download/7.9.0/mParticle_Appboy.framework.zip", + "7.9.1": "https://github.com/mparticle-integrations/mparticle-apple-integration-appboy/releases/download/7.9.1/mParticle_Appboy.framework.zip" +} diff --git a/kits/braze/braze-12/mParticle_AppboyTests/Info.plist b/kits/braze/braze-12/mParticle_AppboyTests/Info.plist new file mode 100644 index 000000000..6c40a6cd0 --- /dev/null +++ b/kits/braze/braze-12/mParticle_AppboyTests/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/kits/braze/braze-12/mParticle_AppboyTests/mParticle_AppboyTests.m b/kits/braze/braze-12/mParticle_AppboyTests/mParticle_AppboyTests.m new file mode 100644 index 000000000..0e1cd3429 --- /dev/null +++ b/kits/braze/braze-12/mParticle_AppboyTests/mParticle_AppboyTests.m @@ -0,0 +1,1065 @@ +@import mParticle_Apple_SDK; +@import mParticle_Appboy; +@import XCTest; +@import OCMock; +#if TARGET_OS_IOS + @import BrazeKitCompat; + @import BrazeUI; +#else + @import BrazeKitCompat; +#endif + +@interface MPKitAppboy () + +- (Braze *)appboyInstance; +- (void)setAppboyInstance:(Braze *)instance; +- (NSMutableDictionary *)optionsDictionary; ++ (id)inAppMessageControllerDelegate; +- (void)setEnableTypeDetection:(BOOL)enableTypeDetection; ++ (BOOL)shouldDisableNotificationHandling; ++ (Braze *)brazeInstance; ++ (MPKitExecStatus *)updateUser:(FilteredMParticleUser *)user request:(NSDictionary *)userIdentities; ++ (MPKitExecStatus *)setUserAttribute:(NSString *)key value:(NSString *)value; + +@end + +@interface mParticle_AppboyTests : XCTestCase + +@end + +@implementation mParticle_AppboyTests + +- (void)setUp { + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. + [MPKitAppboy setBrazeInstance:nil]; + [MPKitAppboy setURLDelegate:nil]; +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testStartwithSimpleConfig { + MPKitAppboy *appBoy = [[MPKitAppboy alloc] init]; + + NSDictionary *kitConfiguration = @{@"apiKey":@"BrazeID", + @"id":@42 + }; + + [appBoy didFinishLaunchingWithConfiguration:kitConfiguration]; + + NSDictionary *testOptionsDictionary = @{ABKEnableAutomaticLocationCollectionKey:@(YES), + ABKSDKFlavorKey:@7 + }; + + NSDictionary *optionsDictionary = [appBoy optionsDictionary]; + XCTAssertEqualObjects(optionsDictionary, testOptionsDictionary); +} + +- (void)testStartwithAdvancedConfig { + MPKitAppboy *appBoy = [[MPKitAppboy alloc] init]; + + NSDictionary *kitConfiguration = @{@"apiKey":@"BrazeID", + @"id":@42, + @"ABKCollectIDFA":@"true", + @"ABKRequestProcessingPolicyOptionKey": @"1", + @"ABKFlushIntervalOptionKey":@"2", + @"ABKSessionTimeoutKey":@"3", + @"ABKMinimumTriggerTimeIntervalKey":@"4", + @"userIdentificationType":@"CustomerId" + }; + + [appBoy didFinishLaunchingWithConfiguration:kitConfiguration]; + + NSDictionary *testOptionsDictionary = @{ABKEnableAutomaticLocationCollectionKey:@(YES), + ABKSDKFlavorKey:@7, + @"ABKRquestProcessingPolicy": @(1), + @"ABKFlushInterval":@(2), + @"ABKSessionTimeout":@(3), + @"ABKMinimumTriggerTimeInterval":@(4) + }; + + NSDictionary *optionsDictionary = [appBoy optionsDictionary]; + XCTAssertEqualObjects(optionsDictionary, testOptionsDictionary); +} + +- (void)testMpidForwardingOnStartUserIdZero { + NSDictionary *kitConfiguration = @{@"apiKey":@"BrazeID", + @"id":@42, + @"ABKCollectIDFA":@"true", + @"ABKRequestProcessingPolicyOptionKey": @"1", + @"ABKFlushIntervalOptionKey":@"2", + @"ABKSessionTimeoutKey":@"3", + @"ABKMinimumTriggerTimeIntervalKey":@"4", + @"userIdentificationType":@"MPID" + }; + + MPKitAppboy *kitInstance = [[MPKitAppboy alloc] init]; + + [kitInstance didFinishLaunchingWithConfiguration:kitConfiguration]; + + MParticleUser *testUser = [[MParticleUser alloc] init]; + [testUser setValue:@(0) forKey:@"userId"]; + + FilteredMParticleUser *filteredUser = [[FilteredMParticleUser alloc] initWithMParticleUser:testUser kitConfiguration:kitConfiguration]; + id mockKitApi = OCMClassMock([MPKitAPI class]); + OCMStub([mockKitApi getCurrentUserWithKit:kitInstance]).andReturn(filteredUser); + kitInstance.kitApi = mockKitApi; + + id mockKitInstance = OCMPartialMock(kitInstance); + [[mockKitInstance reject] updateUser:[OCMArg any] request:[OCMArg any]]; + [kitInstance start]; + [mockKitInstance verify]; +} + +- (void)testMpidForwardingOnStartUserIdPositive { + NSDictionary *kitConfiguration = @{@"apiKey":@"BrazeID", + @"id":@42, + @"ABKCollectIDFA":@"true", + @"ABKRequestProcessingPolicyOptionKey": @"1", + @"ABKFlushIntervalOptionKey":@"2", + @"ABKSessionTimeoutKey":@"3", + @"ABKMinimumTriggerTimeIntervalKey":@"4", + @"userIdentificationType":@"MPID" + }; + + MPKitAppboy *kitInstance = [[MPKitAppboy alloc] init]; + + [kitInstance didFinishLaunchingWithConfiguration:kitConfiguration]; + + MParticleUser *testUser = [[MParticleUser alloc] init]; + [testUser setValue:@(1) forKey:@"userId"]; + + FilteredMParticleUser *filteredUser = [[FilteredMParticleUser alloc] initWithMParticleUser:testUser kitConfiguration:kitConfiguration]; + id mockKitApi = OCMClassMock([MPKitAPI class]); + OCMStub([mockKitApi getCurrentUserWithKit:kitInstance]).andReturn(filteredUser); + kitInstance.kitApi = mockKitApi; + + id mockKitInstance = OCMPartialMock(kitInstance); + [[mockKitInstance expect] updateUser:[OCMArg any] request:[OCMArg any]]; + [kitInstance start]; + [mockKitInstance verify]; +} + +- (void)testMpidForwardingOnStartUserIdNegative { + NSDictionary *kitConfiguration = @{@"apiKey":@"BrazeID", + @"id":@42, + @"ABKCollectIDFA":@"true", + @"ABKRequestProcessingPolicyOptionKey": @"1", + @"ABKFlushIntervalOptionKey":@"2", + @"ABKSessionTimeoutKey":@"3", + @"ABKMinimumTriggerTimeIntervalKey":@"4", + @"userIdentificationType":@"MPID" + }; + + MPKitAppboy *kitInstance = [[MPKitAppboy alloc] init]; + + [kitInstance didFinishLaunchingWithConfiguration:kitConfiguration]; + + MParticleUser *testUser = [[MParticleUser alloc] init]; + [testUser setValue:@(-1) forKey:@"userId"]; + + FilteredMParticleUser *filteredUser = [[FilteredMParticleUser alloc] initWithMParticleUser:testUser kitConfiguration:kitConfiguration]; + id mockKitApi = OCMClassMock([MPKitAPI class]); + OCMStub([mockKitApi getCurrentUserWithKit:kitInstance]).andReturn(filteredUser); + kitInstance.kitApi = mockKitApi; + + id mockKitInstance = OCMPartialMock(kitInstance); + [[mockKitInstance expect] updateUser:[OCMArg any] request:[OCMArg any]]; + [kitInstance start]; + [mockKitInstance verify]; +} + +- (void)testEmailSubscribtionUserAttribute { + NSDictionary *kitConfiguration = @{@"apiKey":@"BrazeID", + @"id":@42, + @"ABKCollectIDFA":@"true", + @"ABKRequestProcessingPolicyOptionKey": @"1", + @"ABKFlushIntervalOptionKey":@"2", + @"ABKSessionTimeoutKey":@"3", + @"ABKMinimumTriggerTimeIntervalKey":@"4", + @"userIdentificationType":@"MPID" + }; + MPKitAppboy *kitInstance = [[MPKitAppboy alloc] init]; + [kitInstance didFinishLaunchingWithConfiguration:kitConfiguration]; + + BRZConfiguration *configuration = [[BRZConfiguration alloc] init]; + Braze *testClient = [[Braze alloc] initWithConfiguration:configuration]; + id mockClient = OCMPartialMock(testClient); + [kitInstance setAppboyInstance:mockClient]; + XCTAssertEqualObjects(mockClient, [kitInstance appboyInstance]); + + // Should succeed since opted_in is a valid value + MPKitExecStatus *execStatus1 = [kitInstance setUserAttribute:@"email_subscribe" value:@"opted_in"]; + XCTAssertEqual(execStatus1.returnCode, MPKitReturnCodeSuccess); + // Should fail since testValue is an invalid value + MPKitExecStatus *execStatus2 = [kitInstance setUserAttribute:@"email_subscribe" value:@"testValue"]; + XCTAssertEqual(execStatus2.returnCode, MPKitReturnCodeFail); + + [mockClient verify]; + + [mockClient stopMocking]; +} + +- (void)testPushSubscribtionUserAttribute { + NSDictionary *kitConfiguration = @{@"apiKey":@"BrazeID", + @"id":@42, + @"ABKCollectIDFA":@"true", + @"ABKRequestProcessingPolicyOptionKey": @"1", + @"ABKFlushIntervalOptionKey":@"2", + @"ABKSessionTimeoutKey":@"3", + @"ABKMinimumTriggerTimeIntervalKey":@"4", + @"userIdentificationType":@"MPID" + }; + MPKitAppboy *kitInstance = [[MPKitAppboy alloc] init]; + [kitInstance didFinishLaunchingWithConfiguration:kitConfiguration]; + + BRZConfiguration *configuration = [[BRZConfiguration alloc] init]; + Braze *testClient = [[Braze alloc] initWithConfiguration:configuration]; + id mockClient = OCMPartialMock(testClient); + [kitInstance setAppboyInstance:mockClient]; + XCTAssertEqualObjects(mockClient, [kitInstance appboyInstance]); + + // Should succeed since opted_in is a valid value + MPKitExecStatus *execStatus1 = [kitInstance setUserAttribute:@"push_subscribe" value:@"opted_in"]; + XCTAssertEqual(execStatus1.returnCode, MPKitReturnCodeSuccess); + // Should fail since testValue is an invalid value + MPKitExecStatus *execStatus2 = [kitInstance setUserAttribute:@"push_subscribe" value:@"testValue"]; + XCTAssertEqual(execStatus2.returnCode, MPKitReturnCodeFail); + + [mockClient verify]; + + [mockClient stopMocking]; +} + +- (void)testSubscriptionGroupIdsMappedUserAttributes { + NSDictionary *kitConfiguration = @{@"apiKey":@"BrazeID", + @"id":@42, + @"ABKCollectIDFA":@"true", + @"ABKRequestProcessingPolicyOptionKey": @"1", + @"ABKFlushIntervalOptionKey":@"2", + @"ABKSessionTimeoutKey":@"3", + @"ABKMinimumTriggerTimeIntervalKey":@"4", + @"userIdentificationType":@"MPID", + @"subscriptionGroupMapping" : @"[{\"jsmap\":null,\"map\":\"testAttribute1\",\"maptype\":\"UserAttributeClass.Name\",\"value\":\"00000000-0000-0000-0000-00000000000\"},{\"jsmap\":null,\"map\":\"testAttribute2\",\"maptype\":\"UserAttributeClass.Name\",\"value\":\"00000000-0000-0000-0000-00000000001\"}]" + }; + + MPKitAppboy *kitInstance = [[MPKitAppboy alloc] init]; + [kitInstance didFinishLaunchingWithConfiguration:kitConfiguration]; + + BRZConfiguration *configuration = [[BRZConfiguration alloc] init]; + Braze *testClient = [[Braze alloc] initWithConfiguration:configuration]; + id mockClient = OCMPartialMock(testClient); + [kitInstance setAppboyInstance:mockClient]; + XCTAssertEqualObjects(mockClient, [kitInstance appboyInstance]); + + // Should succeed since Bool false is a valid value + MPKitExecStatus *execStatus1 = [kitInstance setUserAttribute:@"testAttribute1" value:@NO]; + XCTAssertEqual(execStatus1.returnCode, MPKitReturnCodeSuccess); + // Should succeed since Bool true is a valid value + MPKitExecStatus *execStatus2 = [kitInstance setUserAttribute:@"testAttribute2" value:@YES]; + XCTAssertEqual(execStatus2.returnCode, MPKitReturnCodeSuccess); + // Should fail since testValue is not type BOOL + MPKitExecStatus *execStatus3 = [kitInstance setUserAttribute:@"testAttribute2" value:@"testValue"]; + XCTAssertEqual(execStatus3.returnCode, MPKitReturnCodeFail); + + [mockClient verify]; + + [mockClient stopMocking]; +} + + +//- (void)testEndpointOverride { +// MPKitAppboy *appBoy = [[MPKitAppboy alloc] init]; +// +// NSDictionary *kitConfiguration = @{@"apiKey":@"BrazeID", +// @"host":@"https://foo.bar.com", +// @"id":@42, +// @"ABKCollectIDFA":@"true", +// @"ABKRequestProcessingPolicyOptionKey": @"1", +// @"ABKFlushIntervalOptionKey":@"2", +// @"ABKSessionTimeoutKey":@"3", +// @"ABKMinimumTriggerTimeIntervalKey":@"4", +// @"ABKCollectIDFA":@"true" +// }; +// +// [appBoy didFinishLaunchingWithConfiguration:kitConfiguration]; +// +// XCTAssertEqualObjects(@"https://foo.bar.com", [appBoy getApiEndpoint:@"https://original.com"]); +// XCTAssertEqualObjects(@"https://foo.bar.com/param1", [appBoy getApiEndpoint:@"https://original.com/param1"]); +// XCTAssertEqualObjects(@"https://foo.bar.com/param1/param2", [appBoy getApiEndpoint:@"https://original.com/param1/param2"]); +// +// NSString *testEndpoint; +// XCTAssertNil([appBoy getApiEndpoint:testEndpoint]); +// XCTAssertEqualObjects(@"https://moo.far.com", [appBoy getApiEndpoint:@"moo.far.com"]); +// XCTAssertEqualObjects(@"http://moo.far.com", [appBoy getApiEndpoint:@"http://moo.far.com"]); +//} +// +//- (void)testEndpointOverride2 { +// MPKitAppboy *appBoy = [[MPKitAppboy alloc] init]; +// +// NSDictionary *kitConfiguration = @{@"apiKey":@"BrazeID", +// @"host":@"http://foo.bar.com", +// @"id":@42, +// @"ABKCollectIDFA":@"true", +// @"ABKRequestProcessingPolicyOptionKey": @"1", +// @"ABKFlushIntervalOptionKey":@"2", +// @"ABKSessionTimeoutKey":@"3", +// @"ABKMinimumTriggerTimeIntervalKey":@"4", +// @"ABKCollectIDFA":@"true" +// }; +// +// [appBoy didFinishLaunchingWithConfiguration:kitConfiguration]; +// +// XCTAssertEqualObjects(@"http://foo.bar.com", [appBoy getApiEndpoint:@"https://original.com"]); +// XCTAssertEqualObjects(@"http://foo.bar.com/param1", [appBoy getApiEndpoint:@"https://original.com/param1"]); +// XCTAssertEqualObjects(@"http://foo.bar.com/param1/param2", [appBoy getApiEndpoint:@"https://original.com/param1/param2"]); +// +// NSString *testEndpoint; +// XCTAssertNil([appBoy getApiEndpoint:testEndpoint]); +// XCTAssertEqualObjects(@"https://moo.far.com", [appBoy getApiEndpoint:@"moo.far.com"]); +// XCTAssertEqualObjects(@"http://moo.far.com", [appBoy getApiEndpoint:@"http://moo.far.com"]); +//} +// +//- (void)testEndpointOverride3 { +// MPKitAppboy *appBoy = [[MPKitAppboy alloc] init]; +// +// NSDictionary *kitConfiguration = @{@"apiKey":@"BrazeID", +// @"host":@"foo.bar.com", +// @"id":@42, +// @"ABKCollectIDFA":@"true", +// @"ABKRequestProcessingPolicyOptionKey": @"1", +// @"ABKFlushIntervalOptionKey":@"2", +// @"ABKSessionTimeoutKey":@"3", +// @"ABKMinimumTriggerTimeIntervalKey":@"4", +// @"ABKCollectIDFA":@"true" +// }; +// +// [appBoy didFinishLaunchingWithConfiguration:kitConfiguration]; +// +// XCTAssertEqualObjects(@"https://foo.bar.com", [appBoy getApiEndpoint:@"https://original.com"]); +// XCTAssertEqualObjects(@"https://foo.bar.com/param1", [appBoy getApiEndpoint:@"https://original.com/param1"]); +// XCTAssertEqualObjects(@"https://foo.bar.com/param1/param2", [appBoy getApiEndpoint:@"https://original.com/param1/param2"]); +// +// +// NSString *testEndpoint; +// XCTAssertNil([appBoy getApiEndpoint:testEndpoint]); +// XCTAssertEqualObjects(@"https://moo.far.com", [appBoy getApiEndpoint:@"moo.far.com"]); +// XCTAssertEqualObjects(@"http://moo.far.com", [appBoy getApiEndpoint:@"http://moo.far.com"]); +//} +// +//- (void)testEndpointOverride4 { +// MPKitAppboy *appBoy = [[MPKitAppboy alloc] init]; +// +// NSDictionary *kitConfiguration = @{@"apiKey":@"BrazeID", +// @"host":@"https://foo.bar.com/baz", +// @"id":@42, +// @"ABKCollectIDFA":@"true", +// @"ABKRequestProcessingPolicyOptionKey": @"1", +// @"ABKFlushIntervalOptionKey":@"2", +// @"ABKSessionTimeoutKey":@"3", +// @"ABKMinimumTriggerTimeIntervalKey":@"4", +// @"ABKCollectIDFA":@"true" +// }; +// +// [appBoy didFinishLaunchingWithConfiguration:kitConfiguration]; +// +// XCTAssertEqualObjects(@"https://foo.bar.com/baz", [appBoy getApiEndpoint:@"https://original.com"]); +// XCTAssertEqualObjects(@"https://foo.bar.com/baz/param1", [appBoy getApiEndpoint:@"https://original.com/param1"]); +// XCTAssertEqualObjects(@"https://foo.bar.com/baz/param1/param2", [appBoy getApiEndpoint:@"https://original.com/param1/param2"]); +// +// +// NSString *testEndpoint; +// XCTAssertNil([appBoy getApiEndpoint:testEndpoint]); +// XCTAssertEqualObjects(@"https://moo.far.com", [appBoy getApiEndpoint:@"moo.far.com"]); +// XCTAssertEqualObjects(@"http://moo.far.com", [appBoy getApiEndpoint:@"http://moo.far.com"]); +//} +// +//- (void)testEndpointOverride5 { +// MPKitAppboy *appBoy = [[MPKitAppboy alloc] init]; +// +// NSDictionary *kitConfiguration = @{@"apiKey":@"BrazeID", +// @"host":@"https://foo.bar.com/baz/baz", +// @"id":@42, +// @"ABKCollectIDFA":@"true", +// @"ABKRequestProcessingPolicyOptionKey": @"1", +// @"ABKFlushIntervalOptionKey":@"2", +// @"ABKSessionTimeoutKey":@"3", +// @"ABKMinimumTriggerTimeIntervalKey":@"4", +// @"ABKCollectIDFA":@"true" +// }; +// +// [appBoy didFinishLaunchingWithConfiguration:kitConfiguration]; +// +// XCTAssertEqualObjects(@"https://foo.bar.com/baz/baz", [appBoy getApiEndpoint:@"https://original.com"]); +// XCTAssertEqualObjects(@"https://foo.bar.com/baz/baz/param1", [appBoy getApiEndpoint:@"https://original.com/param1"]); +// XCTAssertEqualObjects(@"https://foo.bar.com/baz/baz/param1/param2", [appBoy getApiEndpoint:@"https://original.com/param1/param2"]); +// +// +// NSString *testEndpoint; +// XCTAssertNil([appBoy getApiEndpoint:testEndpoint]); +// XCTAssertEqualObjects(@"https://moo.far.com", [appBoy getApiEndpoint:@"moo.far.com"]); +// XCTAssertEqualObjects(@"http://moo.far.com", [appBoy getApiEndpoint:@"http://moo.far.com"]); +//} +// +//- (void)testEndpointOverrideNilHost { +// MPKitAppboy *appBoy = [[MPKitAppboy alloc] init]; +// +// NSDictionary *kitConfiguration = @{@"apiKey":@"BrazeID", +// @"id":@42, +// @"ABKCollectIDFA":@"true", +// @"ABKRequestProcessingPolicyOptionKey": @"1", +// @"ABKFlushIntervalOptionKey":@"2", +// @"ABKSessionTimeoutKey":@"3", +// @"ABKMinimumTriggerTimeIntervalKey":@"4", +// @"ABKCollectIDFA":@"true" +// }; +// +// [appBoy didFinishLaunchingWithConfiguration:kitConfiguration]; +// +// XCTAssertEqualObjects(@"https://original.com", [appBoy getApiEndpoint:@"https://original.com"]); +// XCTAssertEqualObjects(@"https://original.com/param1", [appBoy getApiEndpoint:@"https://original.com/param1"]); +// XCTAssertEqualObjects(@"https://original.com/param1/param2", [appBoy getApiEndpoint:@"https://original.com/param1/param2"]); +// +// +// NSString *testEndpoint; +// XCTAssertNil([appBoy getApiEndpoint:testEndpoint]); +// XCTAssertEqualObjects(@"moo.far.com", [appBoy getApiEndpoint:@"moo.far.com"]); +// XCTAssertEqualObjects(@"http://moo.far.com", [appBoy getApiEndpoint:@"http://moo.far.com"]); +//} + +- (void)testSetMessageDelegate { + id delegate = (id)[NSObject new]; + + XCTAssertNil([MPKitAppboy inAppMessageControllerDelegate]); + + [MPKitAppboy setInAppMessageControllerDelegate:delegate]; + + XCTAssertEqualObjects([MPKitAppboy inAppMessageControllerDelegate], delegate); + + XCTestExpectation *expectation = [self expectationWithDescription:@"async work"]; + + dispatch_async(dispatch_get_main_queue(), ^{ + XCTAssertEqualObjects([MPKitAppboy inAppMessageControllerDelegate], delegate); + [expectation fulfill]; + }); + + [self waitForExpectationsWithTimeout:1 handler:nil]; +} + +- (void)testStrongMessageDelegate { + id delegate = (id)[NSObject new]; + + [MPKitAppboy setInAppMessageControllerDelegate:delegate]; + + delegate = nil; + + XCTestExpectation *expectation = [self expectationWithDescription:@"async work"]; + + dispatch_async(dispatch_get_main_queue(), ^{ + XCTAssertNotNil([MPKitAppboy inAppMessageControllerDelegate]); + [expectation fulfill]; + }); + + [self waitForExpectationsWithTimeout:1 handler:nil]; +} + +- (void)testSetDisableNotificationHandling { + XCTAssertEqual([MPKitAppboy shouldDisableNotificationHandling], NO); + + [MPKitAppboy setShouldDisableNotificationHandling:YES]; + + XCTAssertEqual([MPKitAppboy shouldDisableNotificationHandling], YES); + + [MPKitAppboy setShouldDisableNotificationHandling:NO]; + + XCTAssertEqual([MPKitAppboy shouldDisableNotificationHandling], NO); +} + +- (void)testSetBrazeInstance { + BRZConfiguration *configuration = [[BRZConfiguration alloc] init]; + Braze *testClient = [[Braze alloc] initWithConfiguration:configuration]; + + XCTAssertEqualObjects([MPKitAppboy brazeInstance], nil); + + [MPKitAppboy setBrazeInstance:testClient]; + + MPKitAppboy *appBoy = [[MPKitAppboy alloc] init]; + + XCTAssertEqualObjects(appBoy.appboyInstance, nil); + XCTAssertEqualObjects(appBoy.providerKitInstance, nil); + XCTAssertEqualObjects([MPKitAppboy brazeInstance], testClient); + + NSDictionary *kitConfiguration = @{@"apiKey":@"BrazeID", + @"id":@42, + @"ABKCollectIDFA":@"true", + @"ABKRequestProcessingPolicyOptionKey": @"1", + @"ABKFlushIntervalOptionKey":@"2", + @"ABKSessionTimeoutKey":@"3", + @"ABKMinimumTriggerTimeIntervalKey":@"4", + @"userIdentificationType":@"CustomerId" + }; + + [appBoy didFinishLaunchingWithConfiguration:kitConfiguration]; + + XCTAssertEqualObjects(appBoy.appboyInstance, testClient); + XCTAssertEqualObjects(appBoy.providerKitInstance, testClient); + XCTAssertEqualObjects([MPKitAppboy brazeInstance], testClient); +} + +- (void)testUserIdCustomerId { + MPKitAppboy *appBoy = [[MPKitAppboy alloc] init]; + + NSDictionary *kitConfiguration = @{@"apiKey":@"BrazeID", + @"id":@42, + @"ABKCollectIDFA":@"true", + @"ABKRequestProcessingPolicyOptionKey": @"1", + @"ABKFlushIntervalOptionKey":@"2", + @"ABKSessionTimeoutKey":@"3", + @"ABKMinimumTriggerTimeIntervalKey":@"4", + @"userIdentificationType":@"CustomerId" + }; + + [appBoy didFinishLaunchingWithConfiguration:kitConfiguration]; + + XCTAssertEqual(appBoy.configuration[@"userIdentificationType"], @"CustomerId"); +} + +- (void)testUserIdMPID { + MPKitAppboy *appBoy = [[MPKitAppboy alloc] init]; + + NSDictionary *kitConfiguration = @{@"apiKey":@"BrazeID", + @"id":@42, + @"ABKCollectIDFA":@"true", + @"ABKRequestProcessingPolicyOptionKey": @"1", + @"ABKFlushIntervalOptionKey":@"2", + @"ABKSessionTimeoutKey":@"3", + @"ABKMinimumTriggerTimeIntervalKey":@"4", + @"userIdentificationType":@"MPID" + }; + + [appBoy didFinishLaunchingWithConfiguration:kitConfiguration]; + + XCTAssertEqual(appBoy.configuration[@"userIdentificationType"], @"MPID"); +} + +- (void)testlogCommerceEvent { + MPKitAppboy *kit = [[MPKitAppboy alloc] init]; + kit.configuration = @{@"bundleCommerceEventData" : @0}; + + BRZConfiguration *configuration = [[BRZConfiguration alloc] init]; + Braze *testClient = [[Braze alloc] initWithConfiguration:configuration]; + id mockClient = OCMPartialMock(testClient); + [kit setAppboyInstance:mockClient]; + + XCTAssertEqualObjects(mockClient, [kit appboyInstance]); + + MPProduct *product = [[MPProduct alloc] initWithName:@"product1" sku:@"1131331343" quantity:@1 price:@13]; + + MPCommerceEvent *event = [[MPCommerceEvent alloc] initWithAction:MPCommerceEventActionClick product:product]; + event.customAttributes = @{@"testKey" : @"testCustomAttValue"}; + + MPTransactionAttributes *attributes = [[MPTransactionAttributes alloc] init]; + attributes.transactionId = @"foo-transaction-id"; + attributes.revenue = @13.00; + attributes.tax = @3; + attributes.shipping = @3; + + event.transactionAttributes = attributes; + + [[mockClient expect] logCustomEvent:@"eCommerce - click - Item" + properties:@{@"Id" : @"1131331343", + @"Item Price" : @"13", + @"Name" : @"product1", + @"Quantity" : @"1", + @"Total Product Amount" : @"13", + @"testKey" : @"testCustomAttValue" + }]; + + MPKitExecStatus *execStatus = [kit logBaseEvent:event]; + + XCTAssertEqual(execStatus.returnCode, MPKitReturnCodeSuccess); + + [mockClient verify]; + + [mockClient stopMocking]; +} + +- (void)testlogCommerceEventWithBundledProducts { + MPKitAppboy *kit = [[MPKitAppboy alloc] init]; + kit.configuration = @{@"bundleCommerceEventData" : @1}; + + BRZConfiguration *configuration = [[BRZConfiguration alloc] init]; + Braze *testClient = [[Braze alloc] initWithConfiguration:configuration]; + id mockClient = OCMPartialMock(testClient); + [kit setAppboyInstance:mockClient]; + + XCTAssertEqualObjects(mockClient, [kit appboyInstance]); + + MPProduct *product = [[MPProduct alloc] initWithName:@"product1" sku:@"1131331343" quantity:@1 price:@13]; + + MPCommerceEvent *event = [[MPCommerceEvent alloc] initWithAction:MPCommerceEventActionClick product:product]; + event.customAttributes = @{@"testKey" : @"testCustomAttValue"}; + + MPTransactionAttributes *attributes = [[MPTransactionAttributes alloc] init]; + attributes.transactionId = @"foo-transaction-id"; + attributes.revenue = @13.00; + attributes.tax = @3; + attributes.shipping = @3; + + event.transactionAttributes = attributes; + + [[mockClient expect] logCustomEvent:@"eCommerce - click" + properties:@{@"Attributes" : @{@"testKey" : @"testCustomAttValue"}, + @"products" : @[@{ + @"Id" : @"1131331343", + @"Item Price" : @"13", + @"Name" : @"product1", + @"Quantity" : @"1", + @"Total Product Amount" : @"13" + } + ] + }]; + + MPKitExecStatus *execStatus = [kit logBaseEvent:event]; + + XCTAssertEqual(execStatus.returnCode, MPKitReturnCodeSuccess); + + [mockClient verify]; + + [mockClient stopMocking]; +} + +- (void)testlogPurchaseCommerceEvent { + MPKitAppboy *kit = [[MPKitAppboy alloc] init]; + kit.configuration = @{@"bundleCommerceEventData" : @0}; + + BRZConfiguration *configuration = [[BRZConfiguration alloc] init]; + Braze *testClient = [[Braze alloc] initWithConfiguration:configuration]; + id mockClient = OCMPartialMock(testClient); + [kit setAppboyInstance:mockClient]; + + XCTAssertEqualObjects(mockClient, [kit appboyInstance]); + + MPProduct *product = [[MPProduct alloc] initWithName:@"product1" sku:@"1131331343" quantity:@1 price:@13]; + product.category = @"category1"; + + MPCommerceEvent *event = [[MPCommerceEvent alloc] initWithAction:MPCommerceEventActionPurchase product:product]; + event.customAttributes = @{@"testKey" : @"testCustomAttValue"}; + + MPTransactionAttributes *attributes = [[MPTransactionAttributes alloc] init]; + attributes.transactionId = @"foo-transaction-id"; + attributes.revenue = @13.00; + attributes.tax = @3; + attributes.shipping = @3; + + event.transactionAttributes = attributes; + + [[mockClient expect] logPurchase:@"1131331343" + currency:@"USD" + price:[@"13" doubleValue] + quantity:1 + properties:@{@"Shipping Amount" : @3, + @"Total Amount" : @13.00, + @"Total Product Amount" : @"13", + @"Tax Amount" : @3, + @"Transaction Id" : @"foo-transaction-id", + @"Name" : @"product1", + @"Category" : @"category1", + @"testKey" : @"testCustomAttValue" + }]; + + MPKitExecStatus *execStatus = [kit logBaseEvent:event]; + + XCTAssertEqual(execStatus.returnCode, MPKitReturnCodeSuccess); + + [mockClient verify]; + + [mockClient stopMocking]; +} + +- (void)testlogPurchaseCommerceEventSendingProductName { + MPKitAppboy *kit = [[MPKitAppboy alloc] init]; + kit.configuration = @{@"bundleCommerceEventData" : @0, + @"replaceSkuWithProductName": @"True"}; + + BRZConfiguration *configuration = [[BRZConfiguration alloc] init]; + Braze *testClient = [[Braze alloc] initWithConfiguration:configuration]; + id mockClient = OCMPartialMock(testClient); + [kit setAppboyInstance:mockClient]; + + XCTAssertEqualObjects(mockClient, [kit appboyInstance]); + + MPProduct *product = [[MPProduct alloc] initWithName:@"product1" sku:@"1131331343" quantity:@1 price:@13]; + product.category = @"category1"; + + MPCommerceEvent *event = [[MPCommerceEvent alloc] initWithAction:MPCommerceEventActionPurchase product:product]; + event.customAttributes = @{@"testKey" : @"testCustomAttValue"}; + + MPTransactionAttributes *attributes = [[MPTransactionAttributes alloc] init]; + attributes.transactionId = @"foo-transaction-id"; + attributes.revenue = @13.00; + attributes.tax = @3; + attributes.shipping = @3; + + event.transactionAttributes = attributes; + + [[mockClient expect] logPurchase:@"product1" + currency:@"USD" + price:[@"13" doubleValue] + quantity:1 + properties:@{@"Shipping Amount" : @3, + @"Total Amount" : @13.00, + @"Total Product Amount" : @"13", + @"Tax Amount" : @3, + @"Transaction Id" : @"foo-transaction-id", + @"Name" : @"product1", + @"Category" : @"category1", + @"testKey" : @"testCustomAttValue" + }]; + + MPKitExecStatus *execStatus = [kit logBaseEvent:event]; + + XCTAssertEqual(execStatus.returnCode, MPKitReturnCodeSuccess); + + [mockClient verify]; + + [mockClient stopMocking]; +} + +- (void)testlogPurchaseCommerceEventWithBundledProducts { + MPKitAppboy *kit = [[MPKitAppboy alloc] init]; + kit.configuration = @{@"bundleCommerceEventData" : @1}; + + BRZConfiguration *configuration = [[BRZConfiguration alloc] init]; + Braze *testClient = [[Braze alloc] initWithConfiguration:configuration]; + id mockClient = OCMPartialMock(testClient); + [kit setAppboyInstance:mockClient]; + + XCTAssertEqualObjects(mockClient, [kit appboyInstance]); + + MPProduct *product = [[MPProduct alloc] initWithName:@"product1" sku:@"1131331343" quantity:@1 price:@13]; + + MPCommerceEvent *event = [[MPCommerceEvent alloc] initWithAction:MPCommerceEventActionPurchase product:product]; + event.customAttributes = @{@"testKey" : @"testCustomAttValue"}; + + MPTransactionAttributes *attributes = [[MPTransactionAttributes alloc] init]; + attributes.transactionId = @"foo-transaction-id"; + attributes.revenue = @13.00; + attributes.tax = @3; + attributes.shipping = @3; + + event.transactionAttributes = attributes; + + NSDictionary *testResultDict = @{@"Attributes" : @{@"testKey" : @"testCustomAttValue"}, + @"Shipping Amount" : @3, + @"Total Amount" : @13.00, + @"Tax Amount" : @3, + @"Transaction Id" : @"foo-transaction-id", + @"products" : @[@{ + @"Id" : @"1131331343", + @"Item Price" : @"13", + @"Name" : @"product1", + @"Quantity" : @"1", + @"Total Product Amount" : @"13" + } + ] + }; + BOOL (^testBlock)(id value) = ^BOOL(id value) { + if ([value isKindOfClass:[NSDictionary class]]) { + for (NSString *key in [(NSDictionary *)value allKeys]) { + if ([key isEqualToString: @"products"]) { + NSArray *productArray = (NSArray *)((NSDictionary *)value[key]); + for (int i = 0; i < productArray.count; i++) { + NSDictionary *productDict = productArray[i]; + for (NSString *productDictKey in [productDict allKeys]) { + if (![productDict[productDictKey] isEqual:testResultDict[key][i][productDictKey]]) { + NSLog(@"Invalid Object in Product: %@ Key: %@", productDict, productDictKey); + return false; + } + } + } + } + if (![(NSDictionary *)value[key] isEqual:testResultDict[key]]) { + NSLog(@"Invalid Object in Key: %@", key); + return false; + } + } + return true; + } + return false; + }; + + OCMExpect(([mockClient logPurchase:@"eCommerce - purchase" + currency:@"USD" + price:[@"13" doubleValue] + properties:[OCMArg checkWithBlock:testBlock] + ])); + + MPKitExecStatus *execStatus = [kit logBaseEvent:event]; + + XCTAssertEqual(execStatus.returnCode, MPKitReturnCodeSuccess); + + OCMVerifyAll(mockClient); + + [mockClient stopMocking]; +} + +- (void)testlogCommerceEventWithMultipleBundledProducts { + MPKitAppboy *kit = [[MPKitAppboy alloc] init]; + kit.configuration = @{@"bundleCommerceEventData" : @1}; + + BRZConfiguration *configuration = [[BRZConfiguration alloc] init]; + Braze *testClient = [[Braze alloc] initWithConfiguration:configuration]; + id mockClient = OCMPartialMock(testClient); + [kit setAppboyInstance:mockClient]; + + XCTAssertEqualObjects(mockClient, [kit appboyInstance]); + + MPProduct *product1 = [[MPProduct alloc] initWithName:@"product1" sku:@"1131331343" quantity:@1 price:@13]; + MPProduct *product2 = [[MPProduct alloc] initWithName:@"product2" sku:@"1131331888" quantity:@1 price:@13]; + product2.userDefinedAttributes[@"testKey"] = @"testCustomAttValue"; + + MPCommerceEvent *event = [[MPCommerceEvent alloc] initWithAction:MPCommerceEventActionPurchase]; + [event addProducts:@[product1, product2]]; + event.customAttributes = @{@"testKey" : @"testCustomAttValue"}; + + MPTransactionAttributes *attributes = [[MPTransactionAttributes alloc] init]; + attributes.transactionId = @"foo-transaction-id"; + attributes.revenue = @26.00; + attributes.tax = @3; + attributes.shipping = @3; + + event.transactionAttributes = attributes; + + NSDictionary *testResultDict = @{@"Attributes" : @{@"testKey" : @"testCustomAttValue"}, + @"Shipping Amount" : @3, + @"Total Amount" : @26.00, + @"Tax Amount" : @3, + @"Transaction Id" : @"foo-transaction-id", + @"products" : @[@{ + @"Id" : @"1131331343", + @"Item Price" : @"13", + @"Name" : @"product1", + @"Quantity" : @"1", + @"Total Product Amount" : @"13" + }, + @{ + @"Id" : @"1131331888", + @"Item Price" : @"13", + @"Name" : @"product2", + @"Quantity" : @"1", + @"Total Product Amount" : @"13", + @"Attributes" : @{@"testKey" : @"testCustomAttValue"} + } + ] + }; + BOOL (^testBlock)(id value) = ^BOOL(id value) { + if ([value isKindOfClass:[NSDictionary class]]) { + for (NSString *key in [(NSDictionary *)value allKeys]) { + if ([key isEqualToString: @"products"]) { + NSArray *productArray = (NSArray *)((NSDictionary *)value[key]); + for (int i = 0; i < productArray.count; i++) { + NSDictionary *productDict = productArray[i]; + for (NSString *productDictKey in [productDict allKeys]) { + if (![productDict[productDictKey] isEqual:testResultDict[key][i][productDictKey]]) { + NSLog(@"Invalid Object in Product: %@ Key: %@", productDict, productDictKey); + return false; + } + } + } + } + if (![(NSDictionary *)value[key] isEqual:testResultDict[key]]) { + NSLog(@"Invalid Object in Key: %@", key); + return false; + } + } + return true; + } + return false; + }; + + OCMExpect(([mockClient logPurchase:@"eCommerce - purchase" + currency:@"USD" + price:[@"26" doubleValue] + properties:[OCMArg checkWithBlock:testBlock] + ])); + + MPKitExecStatus *execStatus = [kit logBaseEvent:event]; + + XCTAssertEqual(execStatus.returnCode, MPKitReturnCodeSuccess); + + OCMVerifyAll(mockClient); + + [mockClient stopMocking]; +} + +- (void)testlogPromotionCommerceEventWithBundledProducts { + MPKitAppboy *kit = [[MPKitAppboy alloc] init]; + kit.configuration = @{@"bundleCommerceEventData" : @1}; + + BRZConfiguration *configuration = [[BRZConfiguration alloc] init]; + Braze *testClient = [[Braze alloc] initWithConfiguration:configuration]; + id mockClient = OCMPartialMock(testClient); + [kit setAppboyInstance:mockClient]; + + XCTAssertEqualObjects(mockClient, [kit appboyInstance]); + + MPPromotion *promotion = [[MPPromotion alloc] init]; + promotion.promotionId = @"my_promo_1"; + promotion.creative = @"sale_banner_1"; + promotion.name = @"App-wide 50% off sale"; + promotion.position = @"dashboard_bottom"; + + MPPromotionContainer *container = + [[MPPromotionContainer alloc] initWithAction:MPPromotionActionView + promotion:promotion]; + + MPCommerceEvent *event = [[MPCommerceEvent alloc] initWithPromotionContainer:container]; + event.customAttributes = @{@"testKey" : @"testCustomAttValue"}; + + [[mockClient expect] logCustomEvent:@"eCommerce - view" + properties:@{@"Attributes" : @{@"testKey" : @"testCustomAttValue"}, + @"promotions" : @[@{ + @"Creative" : @"sale_banner_1", + @"Name" : @"App-wide 50% off sale", + @"Position" : @"dashboard_bottom", + @"Id" : @"my_promo_1" + } + ] + }]; + + MPKitExecStatus *execStatus = [kit logBaseEvent:event]; + + XCTAssertEqual(execStatus.returnCode, MPKitReturnCodeSuccess); + + [mockClient verify]; + + [mockClient stopMocking]; +} + +- (void)testlogImpressionCommerceEventWithBundledProducts { + MPKitAppboy *kit = [[MPKitAppboy alloc] init]; + kit.configuration = @{@"bundleCommerceEventData" : @1}; + + BRZConfiguration *configuration = [[BRZConfiguration alloc] init]; + Braze *testClient = [[Braze alloc] initWithConfiguration:configuration]; + id mockClient = OCMPartialMock(testClient); + [kit setAppboyInstance:mockClient]; + + XCTAssertEqualObjects(mockClient, [kit appboyInstance]); + + MPProduct *product = [[MPProduct alloc] initWithName:@"product1" sku:@"1131331343" quantity:@1 price:@13]; + product.userDefinedAttributes = [@{@"productTestKey" : @"productTestCustomAttValue"} mutableCopy]; + + MPCommerceEvent *event = [[MPCommerceEvent alloc] initWithImpressionName:@"Suggested Products List" product:product]; + event.customAttributes = @{@"testKey" : @"testCustomAttValue"}; + + [[mockClient expect] logCustomEvent:@"eCommerce - impression" + properties:@{@"Attributes" : @{@"testKey" : @"testCustomAttValue"}, + @"impressions" : @[@{ + @"Product Impression List" : @"Suggested Products List", + @"products" : @[@{ + @"Id" : @"1131331343", + @"Item Price" : @"13", + @"Name" : @"product1", + @"Quantity" : @"1", + @"Total Product Amount" : @"13", + @"Attributes" : @{@"productTestKey" : @"productTestCustomAttValue"} + } + ] + } + ] + }]; + + MPKitExecStatus *execStatus = [kit logBaseEvent:event]; + + XCTAssertEqual(execStatus.returnCode, MPKitReturnCodeSuccess); + + [mockClient verify]; + + [mockClient stopMocking]; +} + +//- (void)testTypeDetection { +// MPKitAppboy *kit = [[MPKitAppboy alloc] init]; +// +// BRZConfiguration *configuration = [[BRZConfiguration alloc] init]; +// Braze *testClient = [[Braze alloc] initWithConfiguration:configuration]; +// id mockClient = OCMPartialMock(testClient); +// [kit setAppboyInstance:mockClient]; +// +// XCTAssertEqualObjects(mockClient, [kit appboyInstance]); +// +// +// MPEvent *event = [[MPEvent alloc] initWithName:@"test event" type:MPEventTypeNavigation]; +// event.customAttributes = @{@"foo":@"5.0", @"bar": @"true", @"baz": @"abc", @"qux": @"-3", @"quux": @"1970-01-01T00:00:00Z"}; +// +// [kit setEnableTypeDetection:YES]; +// [[mockClient expect] logCustomEvent:event.name withProperties:@{@"foo":@5.0, @"bar": @YES, @"baz":@"abc", @"qux": @-3, @"quux": [NSDate dateWithTimeIntervalSince1970:0]}]; +// +// MPKitExecStatus *execStatus = [kit logBaseEvent:event]; +// +// XCTAssertEqual(execStatus.returnCode, MPKitReturnCodeSuccess); +// +// [mockClient verify]; +// +// [mockClient stopMocking]; +//} +// +// +//- (void)testTypeDetectionDisable { +// MPKitAppboy *kit = [[MPKitAppboy alloc] init]; +// +// BRZConfiguration *configuration = [[BRZConfiguration alloc] init]; +// Braze *testClient = [[Braze alloc] initWithConfiguration:configuration]; +// id mockClient = OCMPartialMock(testClient); +// [kit setAppboyInstance:mockClient]; +// +// XCTAssertEqualObjects(mockClient, [kit appboyInstance]); +// +// +// MPEvent *event = [[MPEvent alloc] initWithName:@"test event" type:MPEventTypeNavigation]; +// event.customAttributes = @{@"foo":@"5.0", @"bar": @"true", @"baz": @"abc", @"quz": @"-3", @"qux": @"1970-01-01T00:00:00Z"}; +// +// [kit setEnableTypeDetection:NO]; +// [[mockClient expect] logCustomEvent:event.name withProperties:event.customAttributes]; +// +// MPKitExecStatus *execStatus = [kit logBaseEvent:event]; +// +// XCTAssertEqual(execStatus.returnCode, MPKitReturnCodeSuccess); +// +// [mockClient verify]; +// +// [mockClient stopMocking]; +//} + +- (void)testEventWithEmptyProperties { + MPKitAppboy *kit = [[MPKitAppboy alloc] init]; + + BRZConfiguration *configuration = [[BRZConfiguration alloc] init]; + Braze *testClient = [[Braze alloc] initWithConfiguration:configuration]; + id mockClient = OCMPartialMock(testClient); + [kit setAppboyInstance:mockClient]; + + XCTAssertEqualObjects(mockClient, [kit appboyInstance]); + + + MPEvent *event = [[MPEvent alloc] initWithName:@"test event" type:MPEventTypeNavigation]; + event.customAttributes = @{}; + + [kit setEnableTypeDetection:NO]; + [[mockClient expect] logCustomEvent:event.name]; + + MPKitExecStatus *execStatus = [kit logBaseEvent:event]; + + XCTAssertEqual(execStatus.returnCode, MPKitReturnCodeSuccess); + + [mockClient verify]; + + [mockClient stopMocking]; +} + +@end diff --git a/kits/braze/braze-12/release.config.js b/kits/braze/braze-12/release.config.js new file mode 100644 index 000000000..683a77a99 --- /dev/null +++ b/kits/braze/braze-12/release.config.js @@ -0,0 +1,37 @@ +module.exports = { + branches: ["main"], + tagFormat: "v${version}", + plugins: [ + [ + "@semantic-release/commit-analyzer", + { + preset: "angular", + }, + ], + [ + "@semantic-release/release-notes-generator", + { + preset: "angular", + }, + ], + [ + "@semantic-release/changelog", + { + changelogFile: "CHANGELOG.md", + }, + ], + [ + "@semantic-release/exec", + { + prepareCmd: + 'sh ./Scripts/release.sh ${nextRelease.version} "${nextRelease.notes}"', + }, + ], + [ + "@semantic-release/github", + { + assets: [], + }, + ], + ], +};