LR-1403 Add example of SHR query in swift and kotlin#163
Conversation
There was a problem hiding this comment.
Pull request overview
Adds end-to-end sample app examples (Swift + Kotlin) for the new searchHealthResources API, exposing additional filters and response fields to support QA verification.
Changes:
- iOS: expands
ProviderSearchViewModelfilter state (gender, patient acceptance, specialty, radius, filter-values toggles) and surfaces more result details in the provider list row. - Android: introduces a new “Health Resources” category and a new Health Resources search screen (fragment + adapter + MVVM wiring) with filter controls and debug logging.
- Adds required Android resources/layouts and application wiring for the new screen.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| bwell-swift-ios/bwell-swift-ios/ProviderSearch/ProviderSearchViewModel.swift | Adds SHR filters, location radius/filter-values support, and response debug logging. |
| bwell-swift-ios/bwell-swift-ios/ProviderSearch/ProviderSearchView.swift | Displays specialties in result rows. |
| bwell-swift-ios/bwell-swift-ios/ProviderSearch/ProviderFilterView.swift | Restores/adds filter UI controls and triggers refresh on apply. |
| bwell-swift-ios/bwell-swift-ios/ProviderSearch/ProviderDetailView.swift | Minor formatting-only change. |
| bwell-kotlin-android/app/src/main/res/values/strings.xml | Adds “Health Resources” category string. |
| bwell-kotlin-android/app/src/main/res/layout/health_resource_item_view.xml | Adds list item layout for SHR results. |
| bwell-kotlin-android/app/src/main/res/layout/fragment_health_resources_search.xml | Adds SHR search screen layout and filter controls. |
| bwell-kotlin-android/app/src/main/java/com/bwell/sampleapp/viewmodel/HealthResourcesViewModelFactory.kt | Adds ViewModel factory for SHR screen. |
| bwell-kotlin-android/app/src/main/java/com/bwell/sampleapp/viewmodel/HealthResourcesViewModel.kt | Adds SHR search + client-side filtering state. |
| bwell-kotlin-android/app/src/main/java/com/bwell/sampleapp/repository/HealthResourcesRepository.kt | Adds repository wrapper for SHR API call. |
| bwell-kotlin-android/app/src/main/java/com/bwell/sampleapp/repository/DataConnectionsRepository.kt | Adds “Health Resources” to category suggestions. |
| bwell-kotlin-android/app/src/main/java/com/bwell/sampleapp/activities/ui/data_connections/healthresources/HealthResourcesSearchFragment.kt | Implements SHR screen behavior, request building, and logging. |
| bwell-kotlin-android/app/src/main/java/com/bwell/sampleapp/activities/ui/data_connections/healthresources/HealthResourcesListAdapter.kt | Binds SHR result fields into the list UI. |
| bwell-kotlin-android/app/src/main/java/com/bwell/sampleapp/activities/ui/data_connections/DataConnectionsFragment.kt | Routes category selection to the new SHR fragment. |
| bwell-kotlin-android/app/src/main/java/com/bwell/sampleapp/BWellSampleApplication.kt | Wires HealthResourcesRepository into the app singleton. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
aanchalrakhejaa
left a comment
There was a problem hiding this comment.
- Error state leaves UI stuck on "Searching..."
The progressBar is set to visible and statusText to "Searching..." before the request, but the collector only hides progress when result != null. Since HealthResourcesRepository emits null on failure, a failed API call will leave the user stuck with a spinner forever.
For reference, LabsSearchFragment handles the null case to show an empty state.
aanchalrakhejaa
left a comment
There was a problem hiding this comment.
Review of error handling and code quality in the Android example.
|
Screen.Recording.2026-05-14.at.15.28.06.movScreen.Recording.2026-05-14.at.16.08.00.mov |
colevoss
left a comment
There was a problem hiding this comment.
Code Review — Additional Findings
Reviewed the latest state of the diff. The issues previously raised by @aanchalrakhejaa and Copilot (stuck spinner on null, multiple collectors, adapter re-creation, debug logging not gated) are excluded below. These are new findings not covered in prior reviews.
1. iOS hardcodes "Aetna HMO Gold" and appointment filters into every search request
In ProviderSearchViewModel.fetchProviders(), insurance plan and next-available-slot filters are declared as constants and always applied — there's no UI to control or disable them:
let insurancePlanFilter: [BWell.SearchHealthResourcesRequest.InsurancePlanFilterInput] = [
.init(owner: "Aetna", plan: "HMO Gold")
]
let nextAvailableSlotFilter: [BWell.SearchHealthResourcesRequest.NextAvailableSlotFilterInput] = [
.init(appointmentType: ["new-patient"], start: "2026-05-14T00:00:00Z")
]The same hardcoded values appear in SearchConnectionsViewModel.swift. The Android version correctly reads these from UI input fields. This silently narrows every iOS search to Aetna-accepting providers with new-patient slots after May 14, with no user indication.
Suggested fix: Either make these conditional, add matching UI fields like Android, or add a visible indicator that demo filters are active.
Files: ProviderSearchViewModel.swift ~L214-221, SearchConnectionsViewModel.swift ~L20-30
2. Catching CancellationException breaks Kotlin structured concurrency
Both HealthResourcesRepository.kt and HealthResourcesViewModel.kt catch Exception broadly. In Kotlin coroutines, CancellationException extends Exception — catching it prevents proper coroutine cancellation when the user navigates away or the ViewModel scope is cleared. This can produce misleading "Search failed: Job was cancelled" errors on normal navigation.
Since this is a sample app that developers will copy, it's worth demonstrating the correct pattern:
} catch (e: CancellationException) {
throw e
} catch (e: Exception) {
Log.e("HealthResourcesVM", "Search failed", e)
_searchError.emit("Search failed: ${e.message}")
}Files: HealthResourcesViewModel.kt ~L35, HealthResourcesRepository.kt ~L15
3. Invalid latitude/longitude input silently falls back to hardcoded Baltimore coordinates
val lat = binding.etLatitude.text.toString().toDoubleOrNull() ?: 39.2848102
val lon = binding.etLongitude.text.toString().toDoubleOrNull() ?: -76.702898If a user types invalid coordinates, the search silently uses Baltimore, MD (39.28, -76.70) with no feedback. A brief Toast or validation message would help developers understand what happened.
File: HealthResourcesSearchFragment.kt ~L186-187
Automated review — 3 issues found (1 bug, 1 correctness, 1 UX)

Summary
searchHealthResourcesKotlin SDK APIsearchHealthResourcesSwift SDK filters and response fieldsChanges
Android — New Health Resources Search Screen
HealthResourcesSearchFragmentwith search bar, filters (PROA only, location, gender, patient acceptance, specialty codes, radius), sort options (distance, relevance, name, next available), and filter value toggles (specialty, communication, insurance plan)HealthResourcesListAdapterdisplaying name, type badge, specialties, score, accepting status, locations, languages, and virtual care/bookable badgesHealthResourcesRepository,HealthResourcesViewModel,HealthResourcesViewModelFactoryfollowing existing MVVM patternfragment_health_resources_search.xml,health_resource_item_view.xmlDataConnectionsRepository, navigation case inDataConnectionsFragment, repository inBWellSampleApplicationHealthResourcesSearchtagiOS — Updated Provider Search
patientAcceptance,specialtyFilter,radiusText, filter value toggles (requestSpecialtyFilterValues,requestCommunicationFilterValues,requestInsurancePlanFilterValues),PatientAcceptanceFilterenumfetchProviders()for full SHR response inspectionDepends on: bwell-sdk PR (GR-LR-1403)
Relates to: LR-1403, LR-1518
Screen.Recording.2026-04-28.at.17.36.48.mov
Screen.Recording.2026-04-28.at.20.52.25.mov