[2026-07-resubmission] Add guest browsing flow with App Attest session for App Review resubmission

Adds a pre-login public store locator (guest session via DeviceCheck/App
Attest, keychain-backed token storage) so the app no longer forces sign-in
before showing any content, plus updated support URL metadata.
This commit is contained in:
Daniel Arantes Loverde
2026-07-30 11:35:25 -03:00
parent 3e93196b92
commit 017bd7168f
21 changed files with 1140 additions and 136 deletions

View File

@@ -123,17 +123,7 @@ struct HomeView: View {
HStack(spacing: 16) {
ForEach(featuredStoresCards) { store in
NavigationLink {
StoreDetailView(
storeId: store.id,
storeName: store.name,
storeCoverURL: store.coverURL,
storeLogoURL: store.logoURL,
storeCategory: store.category,
storeRating: store.rating,
storeDistance: store.distance,
storeDeliveryFee: store.deliveryFee,
appState: $appState
)
storeDestination(for: store)
} label: {
FeaturedStoreCard(
store: store,
@@ -210,22 +200,27 @@ struct HomeView: View {
}
}
@ViewBuilder
private func storeDestination(for store: FeaturedStoreCardModel) -> some View {
StoreDetailView(
storeId: store.id,
storeName: store.name,
storeCoverURL: store.coverURL,
storeLogoURL: store.logoURL,
storeCategory: store.category,
storeRating: store.rating,
storeDistance: store.distance,
storeDeliveryFee: store.deliveryFee,
appState: $appState
)
}
@ViewBuilder
private var storeCardsList: some View {
VStack(spacing: 16) {
ForEach(filteredStoreCards) { store in
NavigationLink {
StoreDetailView(
storeId: store.id,
storeName: store.name,
storeCoverURL: store.coverURL,
storeLogoURL: store.logoURL,
storeCategory: store.category,
storeRating: store.rating,
storeDistance: store.distance,
storeDeliveryFee: store.deliveryFee,
appState: $appState
)
storeDestination(for: store)
} label: {
FeaturedStoreCard(
store: store,
@@ -407,6 +402,14 @@ struct HomeView: View {
storesError = nil
}
// Anonymous browsing has no account address/coordinates the public
// locator uses a manually-picked state/city instead (geolocation is
// out of scope for that flow, see public-store-locator-sdd.md).
guard appState.session.isAuthenticated else {
await loadGuestStores(hadExistingStores: hadExistingStores, category: category, refreshCategories: refreshCategories)
return
}
let coordinate = await resolveCoordinates(forceRefresh: forceLocationRefresh)
let hasAddress = hasConfiguredAddress()
@@ -498,7 +501,7 @@ struct HomeView: View {
}
}
private func reportStoresLoadFailure(_ message: String, hadExistingStores: Bool) {
func reportStoresLoadFailure(_ message: String, hadExistingStores: Bool) {
if hadExistingStores {
SnackbarCenter.shared.show(title: message, style: .warning, icon: "exclamationmark.triangle.fill", duration: 3.0)
} else {
@@ -548,7 +551,7 @@ struct HomeView: View {
return selected.title
}
private func isCancelledRequest(_ error: Error) -> Bool {
func isCancelledRequest(_ error: Error) -> Bool {
if error is CancellationError {
return true
}