Android Spike Ticket

1. Ticket 1 [iOS] Address Field Ordering - RFC

Key Alignment with Android:
Centralized Configuration: Both platforms now define field order per market in a single place (iOS: Market enum extension; Android: MarketExtensions.kt).
Remote Config Readiness: Your RFC should explicitly call out how Android’s AddressFieldConfig and iOS’s Market enum extensions can be replaced with remote JSON configurations later (e.g., fetching order/labels from a server).
Recommendations:
Reference Android’s AddressFieldConfig pattern in the RFC to emphasize cross-platform parity.
Propose a shared schema for remote configurations (e.g., JSON structure with order, labels, validators).

2. Ticket 2 [iOS] Define Address Field Ordering

Key Alignment with Android:
Enum-Driven Logic: iOS’s Market enum mirrors Android’s MarketExtensions.kt for defining field order.
Testing: Both platforms need unit tests to validate field order for each market (e.g., USA fields ordered as [.secondLine, .firstLine, ...]).
Recommendations:
Use the same market codes (e.g., "USA", "GBR") to simplify future remote config mapping.
Ensure AddressField enums match across platforms (e.g., LINE_ONE vs .firstLine).

Tickets 3 & 4 [iOS] Dynamic Address Input Forms

Key Alignment with Android:
View Builders: iOS’s ViewBuilder pattern aligns with Android’s HomeAddressFields composable. Both iterate over Market-defined fields.
Code Simplification: Removing if statements in favor of loops improves maintainability on both platforms.
Recommendations:
Share code snippets between teams to highlight similarities:
ForEach(market.fields) { field in
switch field {
case .firstLine: FirstLineView()
case .secondLine: SecondLineView()
// ...
}
}
config.order.forEach { field ->
when (field) {
AddressField.LINE_ONE -> TextInput(...)
// ...
}
}

Ticket 5 [iOS] Remove AddressViewConfigurationProtocol

Key Alignment with Android:
Trimming Boilerplate: Both platforms eliminated redundant layers (iOS: AddressViewConfigurationProtocol; Android: AddressUIState).
Validation Consistency: Keep regex/validation logic in core modules (e.g., Address.kt’s validate()).
Recommendations:
Use Android’s AddressFieldConfig as inspiration for iOS’s simplified protocol.

Cross-Platform Risks & Mitigations

Table 4
Risk
Mitigation
Divergent Field Orders
Sync market configurations during sprint planning (e.g., USA order for iOS/Android).
Inconsistent Labels
Share localization keys (e.g., us_street_address"street_address" in iOS).
Validation Mismatches
Align regex rules for fields like ZIP Code/Postcode in core modules.
There are no rows in this table

Proposed Next Steps

Joint RFC Review:
Present Android’s MarketExtensions and iOS’s Market enum extensions as complementary patterns.
Agree on remote config schema for future-proofing.
Shared Testing Strategy:
Define mutual test cases (e.g., USA field order, fallback to GBR).
Cross-validate SEIT results for iOS and Android screens.
Documentation Sync:
Add a "Cross-Platform Alignment" section to both iOS and Android ADRs.

RFC: Dynamic Address Field Ordering for Android

Author: Muhamad Ega ​Date: dd/mm/yyyy

1. Problem Statement

The current address input forms in Android (e.g., Edit Home Address, Registration) use hardcoded field ordering and scattered logic for different markets (e.g., USA, UK). This leads to:
Maintenance challenges: Adding/updating markets requires modifying multiple UI components.
Code duplication: Similar logic exists across screens (Account, Registration).
Scalability issues: Introducing new markets (e.g., China) will exacerbate complexity.

2. Proposed Solution

Adopt a market-driven configuration pattern to dynamically order address fields, aligning with iOS’s approach while respecting Android’s modular constraints.
Key Components:
AddressField Enum: Standardize address components.
enum class AddressField { LINE_ONE, LINE_TWO, CITY, POSTCODE, COUNTY }
Market Configuration: Define field order and labels per market using Kotlin extensions.
Dynamic UI Rendering: Build address forms by iterating over the configured fields.

3. Implementation Plan

Step 1: Define AddressField Enum
// AddressField.kt (Core Module)
enum class AddressField {
LINE_ONE, LINE_TWO, CITY, POSTCODE, COUNTY
}
Step 2: Extend Market Class (UI Module)
Use extensions to add field configurations without modifying the read-only Market class:
// MarketExtensions.kt (UI Module)
fun Market.getAddressFieldConfig(): AddressFieldConfig {
return when (alphaThreeMarketCode) {
MarketList.ALPHA_THREE_USA_MARKET_CODE -> usaConfig()
MarketList.ALPHA_THREE_GBR_MARKET_CODE -> ukConfig()
else -> ukConfig() // Fallback to UK
}
}

private fun Market.ukConfig() = AddressFieldConfig(
order = listOf(
AddressField.LINE_ONE,
AddressField.LINE_TWO,
AddressField.CITY,
AddressField.COUNTY,
AddressField.POSTCODE
),
labels = mapOf(
AddressField.LINE_ONE to R.string.uk_address_line_1,
AddressField.POSTCODE to R.string.uk_postcode
)
)

private fun Market.usaConfig() = AddressFieldConfig(...)
Step 3: AddressFieldConfig Data Class
kotlin
Copy
// AddressFieldConfig.kt (UI Module)
data class AddressFieldConfig(
val order: List<AddressField>,
val labels: Map<AddressField, Int>, // String resource IDs
val placeholders: Map<AddressField, Int>
)
Step 4: Dynamic Composable
Refactor HomeAddressFields to use dynamic ordering:
@Composable
fun HomeAddressFields(
address: Address,
visibleFields: Set<AddressField>,
eventHandler: AddressFieldEventHandler
) {
val config = address.market.getAddressFieldConfig()
Column {
config.order.forEach { field ->
if (visibleFields.contains(field)) {
AddressFieldInput(
field = field,
value = getValue(address, field),
onValueChange = getHandler(eventHandler, field),
label = stringResource(config.labels[field] ?: R.string.default_label),
placeholder = stringResource(config.placeholders[field] ?: R.string.default_placeholder)
)
}
}
}
}

4. Alignment with iOS

Table 2
Aspect
iOS
Android
Configuration Source
Market enum extension
Market Kotlin extensions
Dynamic Rendering
SwiftUI ViewBuilder + ForEach
Jetpack Compose Column + loop
Localization
Localized strings in code
Android strings.xml resources
There are no rows in this table

5. Benefits

Centralized Logic: All market configurations in one place (MarketExtensions.kt).
Scalability: Add new markets (e.g., China) by extending MarketExtensions.
Maintainability: Eliminate if/else blocks and reduce UI boilerplate.
Cross-Platform Consistency: Aligns with iOS’s RFC for future remote config parity.

6. Future Work

Remote Configuration:
Define a shared JSON schema for field order/labels (e.g., { "USA": ["LINE_TWO", "LINE_ONE", ...] }).
Fetch configurations from a server to avoid app updates for new markets.
China Market Support: Collaborate with the CN team to integrate their requirements into MarketExtensions.

7. Testing Strategy

Unit Tests: Validate Market.getAddressFieldConfig() returns correct orders.
UI Tests: Ensure fields render in the correct order for USA/UK markets.
Localization Tests: Verify labels/placeholders adapt to device language.

8. Risks & Mitigations

Table 3
Risk
Mitigation
Core module compatibility
Use Kotlin extensions to avoid modifications
Inconsistent field order with iOS
Sync configurations during sprint planning
There are no rows in this table

9. Feedback Request

Android Team: Review the proposed pattern and provide feedback on extensibility.
iOS Team: Collaborate on remote config schema design.
CN Team: Input on China-specific field requirements.
Approval Requested:
Android Team
iOS Team
Product/QA

Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.