@@ -160,8 +160,12 @@ enum HomeResponseParser {
160160
161161 guard !items. isEmpty else { return nil }
162162
163+ // Generate stable ID from title and first item to avoid SwiftUI identity churn
164+ let firstItemId = items. first. map { Self . extractItemId ( $0) } ?? " "
165+ let stableId = ParsingHelpers . stableId ( title: title, components: firstItemId)
166+
163167 return HomeSection (
164- id: UUID ( ) . uuidString ,
168+ id: stableId ,
165169 title: title,
166170 items: items,
167171 isChart: ParsingHelpers . isChartSection ( title)
@@ -184,8 +188,12 @@ enum HomeResponseParser {
184188
185189 guard !items. isEmpty else { return nil }
186190
191+ // Generate stable ID from title and first item to avoid SwiftUI identity churn
192+ let firstItemId = items. first. map { Self . extractItemId ( $0) } ?? " "
193+ let stableId = ParsingHelpers . stableId ( title: title, components: firstItemId)
194+
187195 return HomeSection (
188- id: UUID ( ) . uuidString ,
196+ id: stableId ,
189197 title: title,
190198 items: items,
191199 isChart: ParsingHelpers . isChartSection ( title)
@@ -215,8 +223,12 @@ enum HomeResponseParser {
215223
216224 guard !items. isEmpty else { return nil }
217225
226+ // Generate stable ID from title and first item to avoid SwiftUI identity churn
227+ let firstItemId = items. first. map { Self . extractItemId ( $0) } ?? " "
228+ let stableId = ParsingHelpers . stableId ( title: title, components: firstItemId)
229+
218230 return HomeSection (
219- id: UUID ( ) . uuidString ,
231+ id: stableId ,
220232 title: title,
221233 items: items,
222234 isChart: ParsingHelpers . isChartSection ( title)
@@ -239,8 +251,12 @@ enum HomeResponseParser {
239251
240252 guard !items. isEmpty else { return nil }
241253
254+ // Generate stable ID from title and first item to avoid SwiftUI identity churn
255+ let firstItemId = items. first. map { Self . extractItemId ( $0) } ?? " "
256+ let stableId = ParsingHelpers . stableId ( title: title, components: firstItemId)
257+
242258 return HomeSection (
243- id: UUID ( ) . uuidString ,
259+ id: stableId ,
244260 title: title,
245261 items: items,
246262 isChart: ParsingHelpers . isChartSection ( title)
@@ -270,8 +286,12 @@ enum HomeResponseParser {
270286
271287 guard !sectionItems. isEmpty else { return nil }
272288
289+ // Generate stable ID from title and first item to avoid SwiftUI identity churn
290+ let firstItemId = sectionItems. first. map { Self . extractItemId ( $0) } ?? " "
291+ let stableId = ParsingHelpers . stableId ( title: title, components: firstItemId)
292+
273293 // Check if this is a chart section based on title, not renderer type
274- return HomeSection ( id: UUID ( ) . uuidString , title: title, items: sectionItems, isChart: ParsingHelpers . isChartSection ( title) )
294+ return HomeSection ( id: stableId , title: title, items: sectionItems, isChart: ParsingHelpers . isChartSection ( title) )
275295 }
276296
277297 // MARK: - Item Parsing
@@ -464,6 +484,16 @@ enum HomeResponseParser {
464484
465485 // MARK: - Helpers
466486
487+ /// Extracts a stable ID from a HomeSectionItem for identity purposes.
488+ private static func extractItemId( _ item: HomeSectionItem ) -> String {
489+ switch item {
490+ case let . song( song) : song. id
491+ case let . album( album) : album. id
492+ case let . playlist( playlist) : playlist. id
493+ case let . artist( artist) : artist. id
494+ }
495+ }
496+
467497 private static func extractCarouselTitle( from data: [ String : Any ] ) -> String ? {
468498 if let header = data [ " header " ] as? [ String : Any ] ,
469499 let headerRenderer = header [ " musicCarouselShelfBasicHeaderRenderer " ] as? [ String : Any ]
0 commit comments