This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Optimizely Flutter SDK - Cross-platform plugin wrapping native Optimizely SDKs (iOS, Android) for A/B testing, feature flags, CMAB, and ODP integration.
Main Branch: master
# Setup
flutter pub get
cd ios && pod install # iOS dependencies
# Testing
flutter test # All tests
flutter test test/cmab_test.dart # Specific test
flutter test --coverage # With coverage
# Linting
flutter analyze
# Run example app
cd example && flutter runDart API (OptimizelyFlutterSdk)
↓
Wrapper (OptimizelyClientWrapper) + MethodChannel
↓
Native Plugins (Swift/Java)
↓
Native Optimizely SDKs (5.2.1 iOS / 5.1.1 Android)
1. Response Object Pattern
- ALL methods return
BaseResponsederivatives (never throw exceptions) - Check
successboolean andreasonstring for errors
2. Multi-Instance State Management
- SDK instances tracked by
sdkKey - User contexts:
sdkKey → userContextId → context - Notification listeners:
sdkKey → listenerId → callback - Call
close()for cleanup
3. Platform-Specific Type Encoding (CRITICAL)
- iOS: Attributes need type metadata:
{"value": 123, "type": "int"} - Android: Direct primitives:
{"attribute": 123} - Conversion in
Utils.convertToTypedMap()(lib/src/utils/utils.dart) - Test override:
forceIOSFormatparameter
4. Dual MethodChannel Architecture
optimizely_flutter_sdk- Main API operationsoptimizely_flutter_sdk_logger- Native → Dart log forwarding
- Add data models in
lib/src/data_objects/if needed - Update
lib/src/optimizely_client_wrapper.dartwith MethodChannel call - Android: Add case in
OptimizelyFlutterClient.java, parse args, call native SDK - iOS: Add case in
SwiftOptimizelyFlutterSdkPlugin.swift, parse args, call native SDK - Handle type conversions (iOS requires metadata wrapping)
- Write tests in
test/ - Update public API in
lib/optimizely_flutter_sdk.dart
Three locations must stay synchronized:
pubspec.yaml→version: X.Y.Zlib/package_info.dart→version = 'X.Y.Z'README.md→ Installation example^X.Y.Z
Simply ask Claude to create a release:
"Create release 3.4.2 with ticket FSSDK-12345"
"Bump patch version with ticket FSSDK-12345"
Claude will execute the full workflow:
- ✅ Pre-flight checks (master branch, clean working tree)
- ✅ Create release branch (prepare-X.Y.Z)
- ✅ Update all 3 version files (pubspec.yaml, package_info.dart, README.md)
- ✅ Generate CHANGELOG.md template
- ✅ Commit and push
- ✅ Create PR
# 1. Create release branch
git checkout -b prepare-X.Y.Z
# 2. Update versions (pubspec.yaml, package_info.dart, README.md)
# 3. Update CHANGELOG.md (add release notes at top)
# 4. Commit with standard format
git commit -m "chore: prepare for release X.Y.Z
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
# 5. Push and create PR
git push -u origin prepare-X.Y.Z
gh pr create --title "[FSSDK-XXXXX] prepare for release X.Y.Z"
# 6. After merge, create GitHub release
gh release create vX.Y.Z --title "Release X.Y.Z" --draft --target master
# 7. Publish to pub.dev
flutter pub publish## X.Y.Z
Month Day, Year
### New Features / Enhancements / Bug Fixes
* Description ([#PR](link))Follow Angular guidelines:
feat:- New featuresfix:- Bug fixeschore:- Maintenancedocs:- Documentationrefactor:- Code restructuringtest:- Test additions
- Never commit directly to
master - Feature branches:
feature/name,prepare-X.Y.Z,fix/name - All PRs target
masterbranch
- Tests required for all code changes
- All CI checks must pass (4 parallel workflows)
- Apache 2.0 license header on new files
- Sign CLA (Contributor License Agreement)
unit_test_coverage(macOS) - Dart tests + Coveralls uploadbuild_test_android(Ubuntu) - Android build validationbuild_test_ios(macOS) - iOS build validationintegration_android_tests(Ubuntu) - Triggersoptimizely-flutter-testapprepointegration_ios_tests(Ubuntu) - Triggersoptimizely-flutter-testapprepo
Flutter/Dart:
- Dart: >=2.16.2 <4.0.0
- Flutter: >=2.5.0
Android:
- minSdk: 21 (Android 5.0)
- compileSdk: 35 (Android 15)
- Kotlin: 2.1.0
- Native SDK: android-sdk 5.1.1
iOS:
- Minimum: iOS 10.0
- Swift: 5.0
- Native SDK: OptimizelySwiftSDK 5.2.1
Dart Layer:
lib/optimizely_flutter_sdk.dart- Public API (initialize, decide, track)lib/src/optimizely_client_wrapper.dart- Platform bridge (545 LOC)lib/src/user_context/optimizely_user_context.dart- User context operationslib/src/data_objects/- 21 response/request models
Android Layer:
android/src/.../OptimizelyFlutterSdkPlugin.java- MethodChannel handlerandroid/src/.../OptimizelyFlutterClient.java- Core client wrapper (921 LOC)android/build.gradle- Dependencies & SDK versions
iOS Layer:
ios/Classes/SwiftOptimizelyFlutterSdkPlugin.swift- Plugin implementation (786 LOC)ios/Classes/OptimizelyFlutterLogger.swift- Logger bridge with task queueios/optimizely_flutter_sdk.podspec- CocoaPods dependencies