Post

Replies

Boosts

Views

Activity

Reply to SwiftData lazy loaded list
Hi magnuti, All, to offer a solution here - I think you could work with a combination of pagination and batching to construct a lazier list. This would allow you to break down data fetches into lazy batches and loading more data only when needed (e.g., when reaching the end of the currently displayed items) To further enhance the pagination approach, you can refer to a detailed example discussed in Thomas Ricouard's post on Medium for a pagination . It outlines best practices for building paginated views in SwiftUI, including strategies for managing state transitions and efficiently fetching data when using List or LazyVStack. To test this idea, I have constructed lazy data supply with a combination of FetchDescriptor, #Predicate (to support dynamic search), and fetch-limit and offset in a view model (that you can both set as properties on the FetchDescriptor). I have abstracted over Thomas's ideas by introducing a 'pageable' protocol. Of course everyone loves a good puzzle, but let me know if you want any more code examples. Curious if anyone has any other thoughts there!
Nov ’24
Reply to SwiftData lazy loaded list
Hi, I would be curious about this as well. I'm not a 100% sure, but I think while the List itself builds lazily, the underlying Query executes fully and loads into memory. My suspicion comes from empirical observation constructing a test case similar to your posts example - using a chunky dataset and displaying that in a List with high debug output (using flag -com.apple.CoreData.SQLDebug 3) the logs would indicate a full load of the underlying entity into memory. In my example I'm dabbling with a dictionary of ~120k entries and .searchable list. I'm creating a dynamic filter through a subview using the @Query macro. W/o debouncing it or anything similar, this freezes the UI on every key stroke, as I believe it does the full load just like below every single time... CoreData: annotation: Connecting to sqlite database file at ... CoreData: sql: SELECT TBL_NAME FROM SQLITE_MASTER WHERE TBL_NAME = 'Z_METADATA' CoreData: sql: pragma recursive_triggers=1 CoreData: sql: pragma journal_mode=wal ... CoreData: annotation: sql connection fetch time: 0.1419s CoreData: annotation: fetch using NSSQLiteStatement <0x600002c5d040> on entity 'DictionaryItem' with sql text 'SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZDEFINITION, t0.ZPINYIN, t0.ZSC, t0.ZTC FROM ZDICTIONARYITEM t0 WHERE (CASE (? = ?) when 1 then (?) else ((CASE (( NSCoreDataStringSearch( t0.ZSC, ?, 417, 1) OR NSCoreDataStringSearch( t0.ZDEFINITION, ?, 417, 1))) when 1 then (?) else (?) end)) end) = ? ORDER BY t0.Z_PK' returned 122780 rows CoreData: annotation: with values: ( "<NSManagedObject: 0x600002c7e0d0> (entity: DictionaryItem; id: 0x90a265083a343fde <x-coredata://F80EEF97-F2E4-46EE-84DC-FB33BFB0AA0B/DictionaryItem/p1>; data: <fault>)", "<NSManagedObject: 0x600002c7df40> (entity: DictionaryItem; id: 0x90a265083a543fde <x-coredata://F80EEF97-F2E4-46EE-84DC-FB33BFB0AA0B/DictionaryItem/p2>; data: <fault>)", "<NSManagedObject: 0x600002c7e3a0> (entity: DictionaryItem; id: 0x90a265083a743fde <x-coredata://F80EEF97-F2E4-46EE-84DC-FB33BFB0AA0B/DictionaryItem/p3>; data: <fault>)”, … 26533c9543fde <x-coredata://F80EEF97-F2E4-46EE-84DC-FB33BFB0AA0B/DictionaryItem/p122778>; data: <fault>)", "<NSManagedObject: 0x60000acbf6b0> (entity: DictionaryItem; id: 0x90a26533c9743fde <x-coredata://F80EEF97-F2E4-46EE-84DC-FB33BFB0AA0B/DictionaryItem/p122779>; data: <fault>)", "<NSManagedObject: 0x60000acbf700> (entity: DictionaryItem; id: 0x90a26533c9943fde <x-coredata://F80EEF97-F2E4-46EE-84DC-FB33BFB0AA0B/DictionaryItem/p122780>; data: <fault>)" ) CoreData: annotation: total fetch execution time: 6.7316s for 122780 rows. … (Repeats for every keystroke, e.g. typing ‘apple’ incrementally narrows down the result set but the first few strokes are large chunks just like the full dictionary)
Nov ’24