├── .cm
└── gitstream.cm
├── .github
├── dependabot.yml
└── workflows
│ ├── dart.yml
│ ├── pr-format.yml
│ ├── release.yaml
│ ├── test.yaml
│ ├── update-android-sdk-version.yaml
│ ├── update-ios-sdk-version.yaml
│ └── update-sdk-versions.yaml
├── .gitignore
├── .metadata
├── .pubignore
├── CHANGELOG.md
├── DEVELOPMENT.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── android
├── .gitignore
├── build.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── settings.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── kotlin
│ └── com
│ └── devcycle
│ └── devcycle_flutter_client_sdk
│ └── DevCycleFlutterClientSdkPlugin.kt
├── example
├── .gitignore
├── README.md
├── analysis_options.yaml
├── android
│ ├── .gitignore
│ ├── app
│ │ ├── build.gradle
│ │ └── src
│ │ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── kotlin
│ │ │ │ └── com
│ │ │ │ │ └── example
│ │ │ │ │ └── devcycle_flutter_client_sdk_example
│ │ │ │ │ └── MainActivity.kt
│ │ │ └── res
│ │ │ │ ├── drawable-v21
│ │ │ │ └── launch_background.xml
│ │ │ │ ├── drawable
│ │ │ │ └── launch_background.xml
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── values-night
│ │ │ │ └── styles.xml
│ │ │ │ └── values
│ │ │ │ └── styles.xml
│ │ │ └── profile
│ │ │ └── AndroidManifest.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.properties
│ └── settings.gradle
├── ios
│ ├── .gitignore
│ ├── Flutter
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Podfile
│ ├── Podfile.lock
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ └── WorkspaceSettings.xcsettings
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── Runner
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ └── Icon-App-83.5x83.5@2x.png
│ │ └── LaunchImage.imageset
│ │ │ ├── Contents.json
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ └── README.md
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── Runner-Bridging-Header.h
├── lib
│ └── main.dart
├── pubspec.yaml
└── test
│ └── widget_test.dart
├── ios
├── .gitignore
├── Assets
│ └── .gitkeep
├── Classes
│ ├── DevCycleFlutterClientSdkPlugin.h
│ ├── DevCycleFlutterClientSdkPlugin.m
│ └── SwiftDevCycleFlutterClientSdkPlugin.swift
└── devcycle_flutter_client_sdk.podspec
├── lib
├── devcycle_event.dart
├── devcycle_flutter_client_sdk.dart
├── devcycle_flutter_client_sdk_method_channel.dart
├── devcycle_flutter_client_sdk_platform_interface.dart
├── devcycle_options.dart
├── devcycle_user.dart
├── dvc_feature.dart
└── dvc_variable.dart
├── pubspec.yaml
├── scripts
└── deploy.sh
└── test
├── devcycle_flutter_client_sdk_method_channel_test.dart
├── devcycle_flutter_client_sdk_test.dart
├── dvc_event_test.dart
├── dvc_options_test.dart
├── dvc_user_test.dart
├── feature_test.dart
└── variable_test.dart
/.cm/gitstream.cm:
--------------------------------------------------------------------------------
1 | # -*- mode: yaml -*-
2 |
3 | manifest:
4 | version: 1.0
5 |
6 | # The `automations` section includes a list of automation that applies
7 | # to the repository in which gitStream is installed. Each automation has an
8 | # `if` key with a list of the necessary assertions, as well as a `run` key with a
9 | # list of all actions. All the listed assertions need to pass in order
10 | # for the following actions to be executed (there is AND relation between conditions).
11 |
12 | # Each automation under the `automations` section is independent of the others.
13 | # Every time a PR is opened or changed, the automation's conditions are evaluated (the `if`).
14 | # The actions under `run` are executed one by one if all the conditions pass.
15 |
16 | # Conditions consists of an expression, which are wrapped with double curly braces, and
17 | # includes a context variable like `files` and filter functions like `length`. Filters
18 | # functions are essentially functions that can be applied to context variables. They are
19 | # called with a pipe operator (|) and can take arguments. Read more on https://docs.gitstream.cm
20 |
21 | automations:
22 | # This is the name of the review automation. You can use whatever name, a meaningful name
23 | # will help to identify it in the future. Each automation name in this file should be unique.
24 | estimated_time_to_review:
25 | if:
26 | - true
27 | run:
28 | - action: add-label@v1
29 | args:
30 | label: "{{ calc.etr }} min review"
31 | color: {{ 'E94637' if (calc.etr >= 20) else ('FBBD10' if (calc.etr >= 5) else '36A853') }}
32 |
33 | safe_changes:
34 | # The `if` key has a list of conditions, each condition is specified as a Jinja expression
35 | # in a double curly braces. Expressions are evaluated by gitStream on a PR when triggered.
36 | if:
37 | # Given the PR code changes, check that only formatting changes were made
38 | - {{ is.formatting or is.docs or is.tests or is.dependabot }}
39 | # `run` key has a list of actions, which are executed one by one whenever the automation
40 | # conditions are met.
41 | run:
42 | # When the changes are validated as formatting only, you can help to speed up the review
43 | # by adding a label that marks it accordingly.
44 | - action: add-label@v1
45 | args:
46 | label: 'safe-changes'
47 | - action: approve@v1
48 | - action: merge@v1
49 | args:
50 | rebase_on_merge: true
51 | wait_for_all_checks: true
52 |
53 |
54 | calc:
55 | etr: {{ branch | estimatedReviewTime }}
56 | is:
57 | formatting: {{ source.diff.files | isFormattingChange }}
58 | docs: {{ files | allDocs }}
59 | tests: {{ files | allTests }}
60 | dependabot: {{ pr.author | includes(term='dependabot') }}
61 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "github-actions"
4 | directory: "/"
5 | schedule:
6 | interval: "weekly"
7 | - package-ecosystem: gradle
8 | directory: "/android"
9 | schedule:
10 | interval: "weekly"
11 | reviewers:
12 | - "devcyclehq/engineering"
13 |
--------------------------------------------------------------------------------
/.github/workflows/dart.yml:
--------------------------------------------------------------------------------
1 | name: Publish to pub.dev
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'v[0-9]+.[0-9]+.[0-9]+*'
7 |
8 | jobs:
9 | publish:
10 | permissions:
11 | id-token: write
12 | uses: dart-lang/setup-dart/.github/workflows/publish.yml@v1
--------------------------------------------------------------------------------
/.github/workflows/pr-format.yml:
--------------------------------------------------------------------------------
1 | name: 'Semantic PR'
2 |
3 | on:
4 | pull_request_target:
5 | types:
6 | - opened
7 | - edited
8 | - synchronize
9 |
10 | permissions:
11 | pull-requests: read
12 |
13 | jobs:
14 | main:
15 | name: Semantic PR title
16 | runs-on: ubuntu-latest
17 | steps:
18 | - uses: amannn/action-semantic-pull-request@v5
19 | env:
20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
--------------------------------------------------------------------------------
/.github/workflows/release.yaml:
--------------------------------------------------------------------------------
1 | name: Release
2 |
3 | permissions:
4 | contents: write
5 |
6 | on:
7 | workflow_dispatch:
8 | inputs:
9 | prerelease:
10 | description: "Prerelease"
11 | required: true
12 | type: boolean
13 | draft:
14 | description: "Draft"
15 | required: true
16 | type: boolean
17 | version-increment-type:
18 | description: "Which part of the version to increment:"
19 | required: true
20 | type: choice
21 | options:
22 | - major
23 | - minor
24 | - patch
25 | default: "patch"
26 |
27 | jobs:
28 | build:
29 | name: Release Flutter SDK
30 | runs-on: ubuntu-latest
31 | steps:
32 | - uses: actions/checkout@v4
33 | with:
34 | token: ${{ secrets.AUTOMATION_USER_TOKEN }}
35 | fetch-depth: 0
36 |
37 | - name: Install Flutter
38 | uses: subosito/flutter-action@e938fdf56512cc96ef2f93601a5a40bde3801046 # v2.19.0
39 | with:
40 | flutter-version: "3.x"
41 | channel: "stable"
42 |
43 | - uses: DevCycleHQ/release-action/prepare-release@v2.3.0
44 | id: prepare-release
45 | with:
46 | github-token: ${{ secrets.AUTOMATION_USER_TOKEN }}
47 | prerelease: ${{ github.event.inputs.prerelease }}
48 | draft: ${{ github.event.inputs.draft }}
49 | version-increment-type: ${{ github.event.inputs.version-increment-type }}
50 |
51 | - name: Update version in code
52 | run: |
53 | sed -i -E "s/version:.*/version: \"${{steps.prepare-release.outputs.next-release-tag}}\"/" ./pubspec.yaml
54 | sed -i -E "s/s.version = '.*'/s.version = '${{steps.prepare-release.outputs.next-release-tag}}'/g" ios/devcycle_flutter_client_sdk.podspec
55 | sed -i -E "s/version '.*'/version '${{steps.prepare-release.outputs.next-release-tag}}'/g" android/build.gradle
56 | sed -i -E "s/# Change Log//g" CHANGELOG.md
57 | echo -e "# Change Log\n## [${{steps.prepare-release.outputs.next-release-tag}}] - "$(date "+%Y-%m-%d")"\n${{ steps.prepare-release.outputs.changelog }}" > update.md
58 | cat update.md CHANGELOG.md > CHANGELOG.md.tmp
59 | mv CHANGELOG.md.tmp CHANGELOG.md
60 | rm update.md
61 |
62 | - name: Commit and push
63 | if: inputs.draft != true
64 | run: |
65 | git config --global user.email "foundation-admin@devcycle.com"
66 | git config --global user.name "DevCycle Automation"
67 | git add .
68 | git commit -m "Release ${{steps.prepare-release.outputs.next-release-tag}}"
69 | git push origin HEAD:main
70 |
71 | - name: Install dependencies
72 | run: flutter pub get
73 |
74 | - name: Analyze
75 | run: flutter analyze
76 |
77 | - name: Run tests
78 | run: flutter test
79 |
80 | - uses: DevCycleHQ/release-action/create-release@v2.3.0
81 | id: create-release
82 | with:
83 | github-token: ${{ secrets.AUTOMATION_USER_TOKEN }}
84 | tag: ${{ steps.prepare-release.outputs.next-release-tag }}
85 | target: main
86 | prerelease: ${{ github.event.inputs.prerelease }}
87 | draft: ${{ github.event.inputs.draft }}
88 | changelog: ${{ steps.prepare-release.outputs.changelog }}
89 |
90 | - name: Display link to release
91 | run: |
92 | echo "::notice title=Release ID::${{ steps.create-release.outputs.release-id }}"
93 | echo "::notice title=Release URL::${{ steps.create-release.outputs.release-url }}"
94 |
--------------------------------------------------------------------------------
/.github/workflows/test.yaml:
--------------------------------------------------------------------------------
1 | name: Flutter SDK Unit Tests
2 | permissions:
3 | contents: read
4 |
5 | # Leverages the Flutter GH Action at https://github.com/marketplace/actions/flutter-action
6 |
7 | on:
8 | pull_request:
9 | branches: [main]
10 |
11 | jobs:
12 | build:
13 | name: Unit Test
14 | runs-on: ubuntu-latest
15 | steps:
16 | - name: Checkout Project
17 | uses: actions/checkout@v4
18 | - name: Install and set Flutter version
19 | uses: subosito/flutter-action@e938fdf56512cc96ef2f93601a5a40bde3801046 # v2.19.0
20 | with:
21 | flutter-version: "3.x"
22 | channel: "stable"
23 | - name: Install Flutter packages
24 | run: flutter pub get
25 | - name: Analyze
26 | run: flutter analyze
27 | - name: Run Unit Tests
28 | run: flutter test
29 | - name: Run Publish Dry Run
30 | run: flutter pub publish --dry-run
31 |
--------------------------------------------------------------------------------
/.github/workflows/update-android-sdk-version.yaml:
--------------------------------------------------------------------------------
1 | name: Update Android SDK Version
2 |
3 | on:
4 | schedule:
5 | - cron: "0 9 * * MON"
6 | workflow_dispatch:
7 | workflow_call:
8 | inputs:
9 | target-version:
10 | description: "Specific Android SDK version to update to (optional)"
11 | required: false
12 | type: string
13 |
14 | permissions:
15 | contents: write
16 | pull-requests: write
17 |
18 | jobs:
19 | update-android-sdk:
20 | name: Update Android SDK Version
21 | runs-on: ubuntu-latest
22 | steps:
23 | - name: Checkout repository
24 | uses: actions/checkout@v4
25 | with:
26 | token: ${{ secrets.AUTOMATION_USER_TOKEN }}
27 | fetch-depth: 0
28 |
29 | - name: Fetch latest Android SDK version
30 | id: android-version
31 | run: |
32 | if [ -n "${{ inputs.target-version }}" ]; then
33 | TARGET_VERSION=$(echo "${{ inputs.target-version }}" | sed 's/^v//')
34 | echo "version=$TARGET_VERSION" >> $GITHUB_OUTPUT
35 | echo "Using specified Android SDK version: $TARGET_VERSION"
36 | else
37 | LATEST_ANDROID_VERSION=$(curl -s https://api.github.com/repos/DevCycleHQ/android-client-sdk/releases/latest | jq -r '.tag_name' | sed 's/^v//')
38 | echo "version=$LATEST_ANDROID_VERSION" >> $GITHUB_OUTPUT
39 | echo "Latest Android SDK version: $LATEST_ANDROID_VERSION"
40 | fi
41 |
42 | - name: Get current Android SDK version
43 | id: current-android
44 | run: |
45 | CURRENT_ANDROID=$(grep "android-client-sdk" android/build.gradle | sed -E 's/.*:([^"]+)".*/\1/')
46 | echo "version=$CURRENT_ANDROID" >> $GITHUB_OUTPUT
47 | echo "Current Android SDK version: $CURRENT_ANDROID"
48 |
49 | - name: Check if Android update is needed
50 | id: check-update
51 | run: |
52 | if [ "${{ steps.android-version.outputs.version }}" != "${{ steps.current-android.outputs.version }}" ]; then
53 | echo "update-needed=true" >> $GITHUB_OUTPUT
54 | echo "Android SDK update needed: ${{ steps.current-android.outputs.version }} -> ${{ steps.android-version.outputs.version }}"
55 | else
56 | echo "update-needed=false" >> $GITHUB_OUTPUT
57 | echo "Android SDK is already up to date"
58 | fi
59 |
60 | - name: Update Android SDK version
61 | if: steps.check-update.outputs.update-needed == 'true'
62 | run: |
63 | sed -i -E 's/(implementation\("com\.devcycle:android-client-sdk:)[^"]+("\))/\1${{ steps.android-version.outputs.version }}\2/' android/build.gradle
64 | echo "Updated Android SDK version to ${{ steps.android-version.outputs.version }}"
65 |
66 | - name: Setup Flutter
67 | if: steps.check-update.outputs.update-needed == 'true'
68 | uses: subosito/flutter-action@e938fdf56512cc96ef2f93601a5a40bde3801046 # v2.19.0
69 | with:
70 | flutter-version: "3.x"
71 | channel: "stable"
72 |
73 | - name: Prepare Flutter
74 | if: steps.check-update.outputs.update-needed == 'true'
75 | run: |
76 | cd example
77 | flutter pub get
78 |
79 | - name: Setup Java for Gradle
80 | if: steps.check-update.outputs.update-needed == 'true'
81 | uses: actions/setup-java@v4
82 | with:
83 | distribution: "temurin"
84 | java-version: "17"
85 |
86 | - name: Update Android dependency resolution
87 | if: steps.check-update.outputs.update-needed == 'true'
88 | run: |
89 | cd example/android
90 | ./gradlew dependencies --configuration implementation > /dev/null 2>&1 || true
91 | echo "✅ Updated Android dependency resolution for version ${{ steps.android-version.outputs.version }}"
92 |
93 | - name: Create Pull Request
94 | if: steps.check-update.outputs.update-needed == 'true'
95 | uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
96 | with:
97 | token: ${{ secrets.AUTOMATION_USER_TOKEN }}
98 | commit-message: |
99 | chore: update Android SDK version to ${{ steps.android-version.outputs.version }}
100 |
101 | - Android SDK: ${{ steps.current-android.outputs.version }} -> ${{ steps.android-version.outputs.version }}
102 | title: "chore: update Android SDK to v${{ steps.android-version.outputs.version }}"
103 | body: |
104 | ## Summary
105 | This PR updates the DevCycle Android SDK to the latest version.
106 |
107 | ## Changes
108 | - **Android SDK**: `${{ steps.current-android.outputs.version }}` → `${{ steps.android-version.outputs.version }}`
109 |
110 | ## Files Modified
111 | - `android/build.gradle` - Updated Android SDK dependency version
112 | - Android dependency resolution updated for example app
113 |
114 | ## Testing
115 | This PR will be automatically tested by the Flutter SDK Unit Tests workflow which validates:
116 | - Flutter package dependencies
117 | - Code analysis with `flutter analyze`
118 | - Unit tests with `flutter test`
119 | - Package publishing validation with `flutter pub publish --dry-run`
120 |
121 | ## Release Notes
122 | See the [Android SDK release notes](https://github.com/DevCycleHQ/android-client-sdk/releases/tag/v${{ steps.android-version.outputs.version }}) for details on what's new in this version.
123 |
124 | ---
125 | This PR was automatically generated by the Update Android SDK Version workflow.
126 | branch: update-android-sdk-${{ steps.android-version.outputs.version }}
127 | delete-branch: true
128 | base: main
129 | labels: |
130 | dependencies
131 | android
132 | automated-pr
133 |
134 | - name: Output results
135 | run: |
136 | if [ "${{ steps.check-update.outputs.update-needed }}" = "true" ]; then
137 | echo "::notice title=Android SDK Updated::Created PR to update Android SDK to v${{ steps.android-version.outputs.version }}"
138 | else
139 | echo "::notice title=No Updates::Android SDK is already up to date (v${{ steps.current-android.outputs.version }})"
140 | fi
141 |
--------------------------------------------------------------------------------
/.github/workflows/update-ios-sdk-version.yaml:
--------------------------------------------------------------------------------
1 | name: Update iOS SDK Version
2 |
3 | on:
4 | schedule:
5 | - cron: "0 9 * * MON"
6 | workflow_dispatch:
7 | workflow_call:
8 | inputs:
9 | target-version:
10 | description: "Specific iOS SDK version to update to (optional)"
11 | required: false
12 | type: string
13 |
14 | permissions:
15 | contents: write
16 | pull-requests: write
17 |
18 | jobs:
19 | update-ios-sdk:
20 | name: Update iOS SDK Version
21 | runs-on: macos-latest
22 | steps:
23 | - name: Checkout repository
24 | uses: actions/checkout@v4
25 | with:
26 | token: ${{ secrets.AUTOMATION_USER_TOKEN }}
27 | fetch-depth: 0
28 |
29 | - name: Fetch latest iOS SDK version
30 | id: ios-version
31 | run: |
32 | if [ -n "${{ inputs.target-version }}" ]; then
33 | TARGET_VERSION=$(echo "${{ inputs.target-version }}" | sed 's/^v//')
34 | echo "version=$TARGET_VERSION" >> $GITHUB_OUTPUT
35 | echo "Using specified iOS SDK version: $TARGET_VERSION"
36 | else
37 | LATEST_IOS_VERSION=$(curl -s https://api.github.com/repos/DevCycleHQ/ios-client-sdk/releases/latest | jq -r '.tag_name' | sed 's/^v//')
38 | echo "version=$LATEST_IOS_VERSION" >> $GITHUB_OUTPUT
39 | echo "Latest iOS SDK version: $LATEST_IOS_VERSION"
40 | fi
41 |
42 | - name: Get current iOS SDK version
43 | id: current-ios
44 | run: |
45 | CURRENT_IOS=$(grep "s.dependency 'DevCycle'" ios/devcycle_flutter_client_sdk.podspec | sed -E "s/.*'DevCycle', '([^']+)'.*/\1/")
46 | echo "version=$CURRENT_IOS" >> $GITHUB_OUTPUT
47 | echo "Current iOS SDK version: $CURRENT_IOS"
48 |
49 | - name: Check if iOS update is needed
50 | id: check-update
51 | run: |
52 | if [ "${{ steps.ios-version.outputs.version }}" != "${{ steps.current-ios.outputs.version }}" ]; then
53 | echo "update-needed=true" >> $GITHUB_OUTPUT
54 | echo "iOS SDK update needed: ${{ steps.current-ios.outputs.version }} -> ${{ steps.ios-version.outputs.version }}"
55 | else
56 | echo "update-needed=false" >> $GITHUB_OUTPUT
57 | echo "iOS SDK is already up to date"
58 | fi
59 |
60 | - name: Update iOS SDK version
61 | if: steps.check-update.outputs.update-needed == 'true'
62 | run: |
63 | sed -i '' -E "s/(s\.dependency 'DevCycle', ')([^']+)(')/\1${{ steps.ios-version.outputs.version }}\3/" ios/devcycle_flutter_client_sdk.podspec
64 | echo "Updated iOS SDK version to ${{ steps.ios-version.outputs.version }}"
65 |
66 | - name: Setup Flutter
67 | if: steps.check-update.outputs.update-needed == 'true'
68 | uses: subosito/flutter-action@e938fdf56512cc96ef2f93601a5a40bde3801046 # v2.19.0
69 | with:
70 | flutter-version: "3.x"
71 | channel: "stable"
72 |
73 | - name: Prepare Flutter
74 | if: steps.check-update.outputs.update-needed == 'true'
75 | run: |
76 | cd example
77 | flutter pub get
78 |
79 | - name: Update iOS dependency lock file
80 | if: steps.check-update.outputs.update-needed == 'true'
81 | run: |
82 | cd example/ios
83 | pod update DevCycle --repo-update
84 | echo "✅ Updated iOS Podfile.lock for DevCycle ${{ steps.ios-version.outputs.version }}"
85 |
86 | - name: Create Pull Request
87 | if: steps.check-update.outputs.update-needed == 'true'
88 | uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
89 | with:
90 | token: ${{ secrets.AUTOMATION_USER_TOKEN }}
91 | commit-message: |
92 | chore: update iOS SDK version to ${{ steps.ios-version.outputs.version }}
93 |
94 | - iOS SDK: ${{ steps.current-ios.outputs.version }} -> ${{ steps.ios-version.outputs.version }}
95 | title: "chore: update iOS SDK to v${{ steps.ios-version.outputs.version }}"
96 | body: |
97 | ## Summary
98 | This PR updates the DevCycle iOS SDK to the latest version.
99 |
100 | ## Changes
101 | - **iOS SDK**: `${{ steps.current-ios.outputs.version }}` → `${{ steps.ios-version.outputs.version }}`
102 |
103 | ## Files Modified
104 | - `ios/devcycle_flutter_client_sdk.podspec` - Updated iOS SDK dependency version
105 | - `example/ios/Podfile.lock` - Updated iOS dependency lock file
106 |
107 | ## Testing
108 | This PR will be automatically tested by the Flutter SDK Unit Tests workflow which validates:
109 | - Flutter package dependencies
110 | - Code analysis with `flutter analyze`
111 | - Unit tests with `flutter test`
112 | - Package publishing validation with `flutter pub publish --dry-run`
113 |
114 | ## Release Notes
115 | See the [iOS SDK release notes](https://github.com/DevCycleHQ/ios-client-sdk/releases/tag/v${{ steps.ios-version.outputs.version }}) for details on what's new in this version.
116 |
117 | ---
118 | This PR was automatically generated by the Update iOS SDK Version workflow.
119 | branch: update-ios-sdk-${{ steps.ios-version.outputs.version }}
120 | delete-branch: true
121 | base: main
122 | labels: |
123 | dependencies
124 | ios
125 | automated-pr
126 |
127 | - name: Output results
128 | run: |
129 | if [ "${{ steps.check-update.outputs.update-needed }}" = "true" ]; then
130 | echo "::notice title=iOS SDK Updated::Created PR to update iOS SDK to v${{ steps.ios-version.outputs.version }}"
131 | else
132 | echo "::notice title=No Updates::iOS SDK is already up to date (v${{ steps.current-ios.outputs.version }})"
133 | fi
134 |
--------------------------------------------------------------------------------
/.github/workflows/update-sdk-versions.yaml:
--------------------------------------------------------------------------------
1 | name: Update DevCycle SDK Versions
2 |
3 | on:
4 | schedule:
5 | - cron: "0 9 * * MON"
6 | workflow_dispatch:
7 | repository_dispatch:
8 | types: [update-dvc-sdks]
9 |
10 | permissions:
11 | contents: write
12 | pull-requests: write
13 |
14 | jobs:
15 | trigger-ios-update:
16 | name: Update iOS SDK
17 | uses: ./.github/workflows/update-ios-sdk-version.yaml
18 | secrets: inherit
19 |
20 | trigger-android-update:
21 | name: Update Android SDK
22 | uses: ./.github/workflows/update-android-sdk-version.yaml
23 | secrets: inherit
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 | migrate_working_dir/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 |
19 | # The .vscode folder contains launch configuration and tasks you configure in
20 | # VS Code which you may wish to be included in version control, so this line
21 | # is commented out by default.
22 | #.vscode/
23 |
24 | # Flutter/Dart/Pub related
25 | # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
26 | pubspec.lock
27 | **/doc/api/
28 | .dart_tool/
29 | .packages
30 | build/
31 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled.
5 |
6 | version:
7 | revision: 135454af32477f815a7525073027a3ff9eff1bfd
8 | channel: stable
9 |
10 | project_type: plugin
11 |
12 | # Tracks metadata for the flutter migrate command
13 | migration:
14 | platforms:
15 | - platform: root
16 | create_revision: 135454af32477f815a7525073027a3ff9eff1bfd
17 | base_revision: 135454af32477f815a7525073027a3ff9eff1bfd
18 | - platform: ios
19 | create_revision: 135454af32477f815a7525073027a3ff9eff1bfd
20 | base_revision: 135454af32477f815a7525073027a3ff9eff1bfd
21 |
22 | # User provided section
23 |
24 | # List of Local paths (relative to this file) that should be
25 | # ignored by the migrate tool.
26 | #
27 | # Files that are not part of the templates will be ignored by default.
28 | unmanaged_files:
29 | - 'lib/main.dart'
30 | - 'ios/Runner.xcodeproj/project.pbxproj'
31 |
--------------------------------------------------------------------------------
/.pubignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 | migrate_working_dir/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 |
19 | # The .vscode folder contains launch configuration and tasks you configure in
20 | # VS Code which you may wish to be included in version control, so this line
21 | # is commented out by default.
22 | #.vscode/
23 |
24 | # Flutter/Dart/Pub related
25 | # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
26 | pubspec.lock
27 | **/doc/api/
28 | .dart_tool/
29 | .packages
30 | build/
31 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 | ## [1.10.0] - 2025-06-05
3 | ## Bug Fixes
4 |
5 | - fix: update DevCycle SDKs action by @jonathannorris in #169
6 | - fix: pod update command by @jonathannorris in #171
7 | - fix: actions permissions by @jonathannorris in #173
8 | - fix: update iOS SDK action by @jonathannorris in #175
9 |
10 | ## Other Changes
11 |
12 | - chore: add GH action script to update DevCycle iOS / Android SDKs by @jonathannorris in #168
13 | - chore: remove 'v' from version check by @jonathannorris in #170
14 | - chore: split DevCycle SDK Update workflows into two, run iOS workflow on mac by @jonathannorris in #172
15 | - chore: update Android SDK to v2.3.1 by @DevCycle-Automation in #174
16 | - chore: update iOS SDK to v1.20.0 by @DevCycle-Automation in #176
17 |
18 |
19 |
20 | ## Uncategorized
21 |
22 |
23 |
24 | ## [1.9.2] - 2025-06-04
25 | ## Bug Fixes
26 |
27 | - fix: add namespace to build gradle for newer versions of gradle by @jsalaber in #167
28 |
29 | ## Other Changes
30 |
31 | - chore: Use flutter/dart native OIDC by @JamieSinn in #163
32 | - chore: Potential fix for code scanning alert no. 1: Workflow does not contain permissions by @JamieSinn in #165
33 | - chore: Potential fix for code scanning alert no. 2: Workflow does not contain permissions by @JamieSinn in #164
34 |
35 |
36 |
37 | ## Uncategorized
38 |
39 |
40 |
41 | ## [1.9.1] - 2024-10-03
42 | ## Other Changes
43 |
44 | - chore: update logger, plugin_platform_interface, uuid and flutter_lints dependencies by @kaushalkapasi in #162
45 |
46 |
47 |
48 | ## Uncategorized
49 |
50 |
51 |
52 | ## [1.9.0] - 2024-09-20
53 | ## Bug Fixes
54 |
55 | - fix: onInitialization to wait for initialization to the complete and config received by @suthar26 in #160
56 |
57 |
58 |
59 | ## Uncategorized
60 |
61 |
62 |
63 | ## [1.8.4] - 2024-07-09
64 | ## Bug Fixes
65 |
66 | - fix: pass in type for swift to use the correct variable types by @jsalaber in #158
67 |
68 |
69 |
70 | ## Uncategorized
71 |
72 |
73 |
74 | ## [1.8.3] - 2024-04-30
75 | ## Bug Fixes
76 |
77 | - fix: Revert to previous release code by @JamieSinn in #149
78 |
79 | ## Other Changes
80 |
81 | - chore: release v2 - move all into one file again by @JamieSinn in #148
82 | - chore: update DevCycle iOS Client SDK to 1.17.1 by @kaushalkapasi in #150
83 |
84 |
85 |
86 | ## Uncategorized
87 |
88 |
89 |
90 | ## [1.8.3] - 2024-04-26
91 | ## Other Changes
92 |
93 | - chore: release v2 - move all into one file again by @JamieSinn in #148
94 |
95 |
96 |
97 | ## Uncategorized
98 |
99 |
100 |
101 | ## [1.8.2] - 2024-04-26
102 | ## Other Changes
103 |
104 | - chore: Enable flutter's native auto publishing based on github tags. by @JamieSinn in #147
105 |
106 |
107 |
108 | ## Uncategorized
109 |
110 |
111 |
112 | ## [1.8.1] - 2024-04-26
113 | ## Bug Fixes
114 |
115 | - fix: use raw value instead of returning internal enum class by @jsalaber in #146
116 |
117 |
118 |
119 | ## Uncategorized
120 |
121 | - Change dependabot to weekly by @JamieSinn in #144
122 |
123 |
124 | ## [1.8.1] - 2024-04-26
125 | ## Bug Fixes
126 |
127 | - fix: use raw value instead of returning internal enum class by @jsalaber in #146
128 |
129 |
130 |
131 | ## Uncategorized
132 |
133 | - Change dependabot to weekly by @JamieSinn in #144
134 |
135 |
136 | ## [1.8.0] - 2024-04-24
137 | ## Features
138 |
139 | - feat: add apiProxyUrl and eventsApiProxyUrl options to the DevCycle Options Builder by @kaushalkapasi in #139
140 |
141 | ## Bug Fixes
142 |
143 | - fix: update iOS options builder to use the right proxyURL builder options by @kaushalkapasi in #140
144 | - fix: update Android minSdkVeresion to 23 (Android 6.0 - Marshmallow) by @kaushalkapasi in #142
145 |
146 | ## Other Changes
147 |
148 | - chore: Update android example app by @kaushalkapasi in #141
149 | - chore: Fix release action by @kaushalkapasi in #143
150 |
151 |
152 |
153 | ## Uncategorized
154 |
155 |
156 |
157 | ## [1.7.5] - 2024-04-19
158 | ## Features
159 |
160 | - feat: add apiProxyUrl and eventsApiProxyUrl options to the DevCycle Options Builder by @kaushalkapasi in #139
161 |
162 |
163 |
164 | ## Uncategorized
165 |
166 |
167 |
168 | ## [1.7.4] - 2024-04-18
169 |
170 |
171 | ## Uncategorized
172 |
173 | - chore: Update DevCycle Deps by @kaushalkapasi in #137
174 | - chore: Bump com.android.tools.build:gradle from 8.3.1 to 8.3.2 in /android by @dependabot[bot] in #138
175 |
176 |
177 | ## [1.7.3] - 2023-12-19
178 |
179 |
180 | ## Uncategorized
181 |
182 | - Bump com.devcycle:android-client-sdk from 2.0.2 to 2.0.5 in /android by @dependabot[bot] in #129
183 |
184 |
185 | ## [1.7.2] - 2023-10-24
186 |
187 |
188 | ## Uncategorized
189 |
190 | - chore: dependabot by @JamieSinn in #116
191 | - chore(deps): actions/checkout from 2 to 4 by @dependabot[bot] in #120
192 | - chore(deps): subosito/flutter-action from 1 to 2 by @dependabot[bot] in #118
193 | - chore(deps): com.devcycle:android-client-sdk from 2.0.0 to 2.0.2 in /android by @dependabot[bot] in #119
194 | - chore(deps): com.android.tools.build:gradle from 7.1.2 to 8.1.2 in /android by @dependabot[bot] in #117
195 | - chore(deps): org.jetbrains.kotlin:kotlin-gradle-plugin from 1.6.10 to 1.9.10 in /android by @dependabot[bot] in #121
196 |
197 |
198 | ## [1.7.1] - 2023-08-09
199 | ## Bug Fixes
200 |
201 | - fix: release action name change by @JamieSinn in #107
202 | - fix: rename model files from dvc to devcycle by @jonathannorris in #110
203 | - fix: Update versions for all sub-projects and add the changelog script by @JamieSinn in #111
204 |
205 | ## Build System / CI
206 |
207 | - ci: revised how the changelog updates in the github action by @chris-hoefgen in #113
208 | - ci: fixed incorrect changelog filename in release action by @chris-hoefgen in #114
209 | - ci: another release action fix by @chris-hoefgen in #115
210 |
211 |
212 |
213 | ## Uncategorized
214 |
215 | - chore: update to use the tagged version of the release action instead of main by @chris-hoefgen in #112
216 |
217 |
218 |
219 | ## [1.7.0] - 2023-07-27
220 |
221 | - update Android to 2.0.0
222 | - update iOS to 1.14.0
223 | - External interfaces changed to use `DevCycle` over `DVC`. For example: `DVCClient` -> `DevCycleClient`, `DVCUser` -> `DevCycleUser`.
224 | Old interfaces are marked as deprecated.
225 |
226 | ## [1.6.10] - 2023-06-19
227 |
228 | - add logging disabling methods `disableCustomEventLogging()` and `disableAutomaticEventLogging()`
229 |
230 | ## [1.5.1] - 2023-05-26
231 |
232 | - bump Android version to 1.6.1
233 |
234 | ## [1.5.0] - 2023-05-25
235 |
236 | - bump Android version to 1.6.0
237 |
238 | ## [1.4.0] - 2023-05-16
239 |
240 | - Add `variableValue()` method to `DVCClient` to get the value of a variable for a user.
241 | - Update `variable()` method to return non-optional value, will use default value if variable is not found.
242 |
243 | ## [1.3.3] - 2023-05-09
244 |
245 | - Fix error handling, and update callbacks to pass errors as strings
246 |
247 | ## [1.3.2] - 2023-05-03
248 |
249 | - bump Android version to 1.4.4
250 |
251 | ## [1.3.1] - 2023-04-11
252 |
253 | - add builder method for disabling realtime updates using `.disableRealtimeUpdates()`
254 |
255 | ## [1.3.0] - 2023-03-24
256 |
257 | - update ios and android version to latest release
258 | - update support for flutter versions
259 |
260 | ## [1.2.0] - 2023-03-21
261 |
262 | - catchup with androids new function definitions
263 |
264 | ## [1.1.2] - 2023-03-17
265 |
266 | - bump iOS version to 1.10.0
267 |
268 | ## [1.1.1] - 2023-02-22
269 |
270 | - ignore deprecated usage in test
271 |
272 | ## [1.1.0] - 2023-02-22
273 |
274 | - rename `environmentKey` to `sdkKey` for consistency across SDKs
275 | - bump iOS version to 1.9.1
276 | - bump Android version to 1.4.0
277 |
278 | ## [1.0.2] - 2023-02-3
279 |
280 | - bump iOS version to 1.9.0
281 |
282 | ## [1.0.1] - 2023-02-1
283 |
284 | - bump Android version to 1.2.4
285 |
286 | ## [1.0.0] - 2023-01-16
287 |
288 | - First supported release of DevCycle Flutter Client SDK. Supports Android and iOS.
289 |
290 | ## [0.0.2] - 2023-01-16
291 |
292 | - bump iOS version
293 |
294 | ## [0.0.1] - 2023-01-13
295 |
296 | - Initial Publish
297 |
--------------------------------------------------------------------------------
/DEVELOPMENT.md:
--------------------------------------------------------------------------------
1 | ## Development
2 |
3 | Build instructions
4 | ------------------
5 |
6 | ## Prerequisites
7 |
8 | See the [Flutter install](https://flutter.dev/docs/get-started/install) page for setting up Flutter for building Android and iOS plugins.
9 |
10 | ### Android
11 |
12 | Open `example/android` in Android Studio. From there you can run the example app or develop the Android host by modifying `devcycle_flutter_client_sdk > java > com.devcycle.devcycle_flutter_client_sdk > DevCycleFlutterClientSdkPlugin.kt`
13 |
14 | ### iOS
15 |
16 | To run the example app, open `example/ios/Runner.xcworkspace` in xCode or use the `flutter` command line tool and run `flutter run` in the `/example` directory. Develop the iOS host by modifying `ios > Classes > SwiftDevCycleFlutterClientSdkPlugin.swift`.
17 |
18 | ## Testing
19 |
20 | To run the unit tests for the SDK, run `flutter test` in the SDK repo.
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 DevCycle.com
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DevCycle Flutter Client SDK
2 |
3 | The Flutter Client SDK for DevCycle! This SDK uses our Client SDK APIs to perform all user segmentation and bucketing for the SDK, providing fast response times using our globally distributed edge workers all around the world.
4 | The SDK is available as a package on Pub. It is also open source and can be viewed on GitHub.
5 |
6 | ## Supported Platforms
7 |
8 | This version of the DevCycle Flutter Client SDK supports a minimum of Flutter 2.5.0, iOS 13.7 and Android API Version 26.
9 |
10 | Other Flutter platforms are not currently supported by this SDK.
11 |
12 | ## Installation
13 |
14 | ### Flutter CLI
15 |
16 | The SDK can be installed into your Flutter project by running `flutter pub add devcycle_flutter_client_sdk`.
17 |
18 | ### Pub Spec
19 |
20 | The SDK can be installed into your Flutter project by adding the following to your `pubspec.yaml`:
21 |
22 | ```dart
23 | devcycle_flutter_client_sdk: ^1.7.0
24 | ```
25 |
26 | Then, run `flutter pub get`.
27 |
28 | ## Usage
29 |
30 | To find usage documentation, check out our [docs](https://docs.devcycle.com/docs/sdk/client-side-sdks/flutter).
31 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:flutter_lints/flutter.yaml
2 | analyzer:
3 | exclude: [test/**]
4 | # Additional information about this file can be found at
5 | # https://dart.dev/guides/language/analysis-options
6 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle/
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .cxx
10 |
11 | gradlew
12 | gradlew.bat
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | group 'com.devcycle.devcycle_flutter_client_sdk'
2 | version '1.10.0'
3 |
4 | buildscript {
5 | ext.kotlin_version = '1.9.23'
6 | repositories {
7 | google()
8 | mavenCentral()
9 | }
10 |
11 | dependencies {
12 | classpath 'com.android.tools.build:gradle:8.3.2'
13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14 | }
15 | }
16 |
17 | allprojects {
18 | repositories {
19 | google()
20 | mavenCentral()
21 | }
22 | }
23 |
24 | apply plugin: 'com.android.library'
25 | apply plugin: 'kotlin-android'
26 |
27 | android {
28 | namespace "com.devcycle.devcycle_flutter_client_sdk"
29 | compileSdkVersion 31
30 |
31 | compileOptions {
32 | sourceCompatibility JavaVersion.VERSION_1_8
33 | targetCompatibility JavaVersion.VERSION_1_8
34 | }
35 |
36 | kotlinOptions {
37 | jvmTarget = '1.8'
38 | }
39 |
40 | sourceSets {
41 | main.java.srcDirs += 'src/main/kotlin'
42 | }
43 |
44 | defaultConfig {
45 | minSdkVersion 23
46 | }
47 |
48 | dependencies {
49 | implementation("com.devcycle:android-client-sdk:2.3.1")
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DevCycleHQ/flutter-client-sdk/aa2a4366da774db6bd354f4c09076cceabecba83/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
4 | networkTimeout=10000
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'devcycle_flutter_client_sdk'
2 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/android/src/main/kotlin/com/devcycle/devcycle_flutter_client_sdk/DevCycleFlutterClientSdkPlugin.kt:
--------------------------------------------------------------------------------
1 | package com.devcycle.devcycle_flutter_client_sdk
2 |
3 | import android.content.Context
4 | import android.os.Handler
5 | import android.os.Looper
6 | import androidx.annotation.NonNull
7 | import com.devcycle.sdk.android.api.*
8 | import com.devcycle.sdk.android.model.*
9 | import com.devcycle.sdk.android.util.LogLevel
10 |
11 | import kotlin.collections.*
12 | import io.flutter.embedding.engine.plugins.FlutterPlugin
13 | import io.flutter.plugin.common.MethodCall
14 | import io.flutter.plugin.common.MethodChannel
15 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler
16 | import io.flutter.plugin.common.MethodChannel.Result
17 | import org.json.JSONArray
18 | import org.json.JSONObject
19 | import java.math.BigDecimal
20 | import java.text.SimpleDateFormat
21 |
22 | /** DevCycleFlutterClientSdkPlugin */
23 | class DevCycleFlutterClientSdkPlugin: FlutterPlugin, MethodCallHandler {
24 | /// The MethodChannel that will the communication between Flutter and native Android
25 | ///
26 | /// This local reference serves to register the plugin with the Flutter Engine and unregister it
27 | /// when the Flutter Engine is detached from the Activity
28 | private lateinit var channel : MethodChannel
29 | private lateinit var context: Context
30 | private lateinit var client: DevCycleClient
31 | private var stringVariableUpdates = mutableMapOf>()
32 | private var numberVariableUpdates = mutableMapOf>()
33 | private var booleanVariableUpdates = mutableMapOf>()
34 | private var jsonArrayVariableUpdates = mutableMapOf>()
35 | private var jsonObjectVariableUpdates = mutableMapOf>()
36 |
37 |
38 | override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
39 | context = flutterPluginBinding.applicationContext
40 | channel = MethodChannel(flutterPluginBinding.binaryMessenger, "devcycle_flutter_client_sdk")
41 | channel.setMethodCallHandler(this)
42 | }
43 |
44 | private fun callFlutter(method: String, arguments: Any?) {
45 | // invokeMethod must be called on main thread
46 | if (Looper.myLooper() == Looper.getMainLooper()) {
47 | channel.invokeMethod(method, arguments)
48 | } else {
49 | // Call ourselves on the main thread
50 | Handler(Looper.getMainLooper()).post { callFlutter(method, arguments) }
51 | }
52 | }
53 |
54 | override fun onMethodCall(@NonNull call: MethodCall, @NonNull res: Result) {
55 | val args = mutableMapOf()
56 | when (call.method) {
57 | "initializeDevCycle" -> {
58 | val codecOptions: Map? = call.argument("options")
59 | val logLevel = getLogLevelFromMap(codecOptions)
60 | val clientBuilder = DevCycleClient
61 | .builder()
62 | .withContext(context)
63 | .withSDKKey(call.argument("sdkKey")!!)
64 | .withUser(getUserFromMap(call.argument("user")!!))
65 | .withOptions(getOptionsFromMap(codecOptions))
66 | if (logLevel is LogLevel) {
67 | clientBuilder.withLogLevel(logLevel)
68 | }
69 |
70 | client = clientBuilder.build()
71 |
72 | client.onInitialized(object : DevCycleCallback {
73 | override fun onSuccess(result: String) {
74 | args["isInitialized"] = true
75 | callFlutter("clientInitialized", args)
76 | res.success(null)
77 | }
78 |
79 | override fun onError(t: Throwable) {
80 | args["error"] = t.message
81 | args["isInitialized"] = false
82 | callFlutter("clientInitialized", args)
83 | res.error("error", t.message, null)
84 | }
85 | })
86 | }
87 | "identifyUser" -> {
88 | val user = getUserFromMap(call.argument("user")!!)
89 | args["callbackId"] = call.argument("callbackId") as String?
90 | val callback = object: DevCycleCallback