Migrate from iOS 17 Observation to iOS 16-compatible Combine architecture.

Lower deployment target to iOS 16, replace @Observable with ObservableObject, add navigation and UI compatibility shims, and include login smoke UI tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-26 10:16:35 +08:00
parent c32a610ee0
commit 26f4d0e671
127 changed files with 2320 additions and 1465 deletions

View File

@ -6,21 +6,20 @@
//
import Foundation
import Observation
import Combine
/// ViewModel
@MainActor
@Observable
final class PunchPointListViewModel {
var selectedFilter: PunchPointFilter = .all
var items: [PunchPointItem] = []
var selectedDetail: PunchPointItem?
var errorMessage: String?
var isLoading = false
var isLoadingMore = false
var total = 0
final class PunchPointListViewModel: ObservableObject {
@Published var selectedFilter: PunchPointFilter = .all
@Published var items: [PunchPointItem] = []
@Published var selectedDetail: PunchPointItem?
@Published var errorMessage: String?
@Published var isLoading = false
@Published var isLoadingMore = false
@Published var total = 0
private var page = 1
@Published private var page = 1
private let pageSize = 20
///
@ -121,35 +120,41 @@ final class PunchPointListViewModel {
/// ViewModel OSS
@MainActor
@Observable
final class PunchPointEditorViewModel {
var name = ""
var description = ""
var address = ""
var latitudeText = ""
var longitudeText = ""
var scenicSpotText = ""
var remoteImages: [String] = []
var localImages: [PunchPointLocalImage] = []
var errorMessage: String?
var isSubmitting = false
final class PunchPointEditorViewModel: ObservableObject {
@Published var name = ""
@Published var description = ""
@Published var address = ""
@Published var latitudeText = ""
@Published var longitudeText = ""
@Published var scenicSpotText = ""
@Published var remoteImages: [String] = []
@Published var localImages: [PunchPointLocalImage] = []
@Published var errorMessage: String?
@Published var isSubmitting = false
let editingItem: PunchPointItem?
private(set) var editingItem: PunchPointItem?
/// ViewModel
init(item: PunchPointItem? = nil) {
editingItem = item
if let item {
name = item.name
description = item.description
address = item.region?.address ?? ""
latitudeText = item.region.map { String($0.lat) } ?? ""
longitudeText = item.region.map { String($0.lot) } ?? ""
scenicSpotText = item.scenicSpotStr
remoteImages = item.guideImages
apply(item)
}
}
/// ObservableObject
func apply(_ item: PunchPointItem) {
editingItem = item
name = item.name
description = item.description
address = item.region?.address ?? ""
latitudeText = item.region.map { String($0.lat) } ?? ""
longitudeText = item.region.map { String($0.lot) } ?? ""
scenicSpotText = item.scenicSpotStr
remoteImages = item.guideImages
localImages = []
}
///
func applyLocation(latitude: Double, longitude: Double, address: String) {
latitudeText = String(format: "%.6f", latitude)