Native Adaptive Cards rendering for iOS (SwiftUI) and Android (Jetpack Compose) with strict cross-platform feature parity.
| Asset | Description |
|---|---|
| iOS SDK | SPM sources archive |
| Android SDK | AAR libraries archive |
| iOS Sample App (.ipa) | Simulator build |
| Android Sample App (.apk) | Install via adb install |
SDK+Visualizer.mp4
- Native rendering — SwiftUI on iOS, Jetpack Compose on Android. No web views.
- Adaptive Cards v1.6 — Full schema support including advanced elements: Carousel, Accordion, CodeBlock, TabSet, Rating, Charts, and more.
- Templating engine — Data binding with 60+ expression functions (string, math, date, logic, collection).
- Accessibility — WCAG 2.1 AA compliant with VoiceOver and TalkBack support.
- Responsive layout — Adapts to phone/tablet, portrait/landscape, and Dynamic Type.
- Theming — Host-configurable styles with Fluent UI support and Figma design token alignment.
- Security — URL scheme allowlist prevents XSS and phishing from untrusted card JSON.
The SDK is organized into matching module sets across platforms:
| Module | iOS | Android | Purpose |
|---|---|---|---|
| Core | ACCore | ac-core | Card parsing, models, schema validation |
| Rendering | ACRendering | ac-rendering | UI views and composables |
| Inputs | ACInputs | ac-inputs | Input controls with validation |
| Actions | ACActions | ac-actions | Action handling and delegation |
| Accessibility | ACAccessibility | ac-accessibility | WCAG 2.1 AA helpers |
| Templating | ACTemplating | ac-templating | Template engine (60+ functions) |
| Markdown | ACMarkdown | ac-markdown | CommonMark rendering |
| Charts | ACCharts | ac-charts | Bar, Line, Pie, Donut charts |
| Fluent UI | ACFluentUI | ac-fluent-ui | Fluent UI theming |
| Copilot | ACCopilotExtensions | ac-copilot-extensions | Citations and streaming |
| Teams | ACTeams | ac-teams | Teams integration |
Host Application
└─ Rendering ─┬─ Inputs ──┐
└─ Actions ─┤
└─ Core ── Templating
Cross-platform parity is enforced by CI — the parity gate fails if element type counts diverge by more than 2 between platforms.
Add via Swift Package Manager:
https://github.com/VikrantSingh01/AdaptiveCards-Mobile.git
import AdaptiveCards
// Parse + render
let result = AdaptiveCards.parse(cardJson)
if let card = result.card {
AdaptiveCardView(card: card, configuration: .teams(theme: .dark))
.onCardAction { event in
switch event {
case .submit(_, let inputs): sendToBackend(inputs)
case .openUrl(_, let url): UIApplication.shared.open(url)
case .execute(let action, let inputs): invokeBot(action.verb, inputs)
default: break
}
}
}
// Or 1 line for quick rendering
AdaptiveCardView(json: cardJson)For UIKit, use the bridge: AdaptiveCardUIView(card: card, configuration: .default).
See iOS Integration Guide for full documentation.
Add the dependency via Gradle:
implementation("com.microsoft.adaptivecards:adaptive-cards:<version>")import com.microsoft.adaptivecards.core.AdaptiveCards
import com.microsoft.adaptivecards.rendering.composables.AdaptiveCardView
// Parse + render
val result = AdaptiveCards.parse(cardJson)
result.card?.let { card ->
AdaptiveCardView(
card = card,
configuration = CardConfiguration.teams(TeamsTheme.Dark),
onAction = { event ->
when (event) {
is CardActionEvent.Submit -> sendToBackend(event.inputValues)
is CardActionEvent.OpenUrl -> openBrowser(event.url)
is CardActionEvent.Execute -> invokeBot(event.action.verb, event.inputValues)
else -> {}
}
}
)
}
// Or 1 line for quick rendering
AdaptiveCardView(cardJson = cardJson)For Android Views, use the bridge: AdaptiveCardAndroidView(context).
See Android Integration Guide for full documentation.
Cards support data binding with expressions:
{
"type": "AdaptiveCard",
"body": [
{
"$when": "${showGreeting}",
"type": "TextBlock",
"text": "Hello, ${toUpper(userName)}!"
},
{
"$data": "${items}",
"type": "TextBlock",
"text": "${name} - Item #${$index}"
}
]
}| Platform | Requirements |
|---|---|
| iOS | macOS 12+, Xcode 15+, Swift 5.9+ |
| Android | JDK 17, Android SDK API 34, Gradle 8.5+ (wrapper included) |
iOS
cd ios
swift build # Build all modules
swift test # Run all tests
swift test --filter ACCoreTests # Run specific module testsAndroid
cd android
./gradlew build # Build all modules
./gradlew test # Run all tests
./gradlew :ac-core:test # Run specific module testsBoth platforms include full-featured sample apps with a card gallery, live JSON editor, Teams simulator, performance dashboard, and bookmarks.
| Feature | iOS | Android |
|---|---|---|
| Card Gallery | 333 cards by category | 333 cards by category |
| Live Editor | JSON with real-time preview | JSON with validation |
| Teams Simulator | Teams-style chat UI | Material Design chat UI |
| Deep Links | adaptivecards:// scheme |
adaptivecards:// scheme |
iOS — Open ios/SampleApp.xcodeproj, select the ACVisualizer scheme, and run.
Android — cd android && ./gradlew :sample-app:installDebug
Deep link routes (both platforms):
adaptivecards://card/{category}/{name} — open a specific card
adaptivecards://gallery — card gallery
adaptivecards://editor — JSON editor
adaptivecards://performance — performance dashboard
The SDK includes 333 shared test cards across 7 categories (element samples, official samples, Teams cards, templating, versioning, host configs, and parity tests) plus edge case cards for empty bodies, deep nesting, RTL content, and overflow scenarios.
# Validate all shared test cards
bash shared/scripts/validate-test-cards.sh
# Check cross-platform schema coverage
bash shared/scripts/compare-schema-coverage.shVisual snapshot tests verify rendering consistency:
# iOS visual snapshot tests
cd ios && xcodebuild test \
-scheme AdaptiveCards-Package \
-sdk iphonesimulator \
-destination 'platform=iOS Simulator,name=iPhone 16 Pro' \
-only-testing:VisualTests/CardElementSnapshotTests \
CODE_SIGN_IDENTITY=- CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NOGitHub Actions workflows run on every push and PR:
| Workflow | Purpose |
|---|---|
| Parity Gate | iOS + Android tests, schema validation, parity check |
| iOS Tests | Swift build + test with coverage |
| Android Tests | Gradle test with JUnit 5 |
| Lint | SwiftLint + ktlint |
| Visual Regression | Snapshot baseline comparison |
| Test Card Validation | JSON schema compliance |
| Document | Description |
|---|---|
| CHANGELOG | Version history and release notes |
| CONTRIBUTING | Development setup and guidelines |
| MIGRATION | Migration guide from legacy SDK |
| Implementation Plan | Architecture and phased roadmap |
| Parity Matrix | Cross-platform feature status |
| iOS README | iOS-specific documentation |
| Android README | Android-specific documentation |
| VS Code Guide | VS Code development setup |
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Implement on both platforms (parity is required)
- Write tests and update documentation
- Submit a PR — CI will enforce parity, tests, and lint
See CONTRIBUTING.md for coding standards and detailed guidelines.