@@ -12,83 +12,63 @@ import Foundation
12
12
/// loaded when it's needed.
13
13
extension List {
14
14
15
- /// Represents the data state of the `List`.
16
- internal enum LoadState {
17
- case pending
18
- case loaded
19
- }
20
-
21
15
// MARK: - Asynchronous API
22
16
23
- /// Trigger `DataStore` query to initialize the collection. This function always
24
- /// fetches data from the `DataStore.query`.
17
+ /// Call this to initialize the collection if you have retrieved the list by traversing from your model objects
18
+ /// to its associated children objects. For example, a Post model may contain a list of Comments. By retrieving the
19
+ /// post object and traversing to the comments, the comments are not retrieved from the data source until this
20
+ /// method is called. Data will be retrieved based on the plugin's data source and may have different failure
21
+ /// conditions--for example, a data source that requires network connectivity may fail if the network is
22
+ /// unavailable. Alternately, you can trigger an implicit `load` by invoking the Collection methods (such as using
23
+ /// `map`, or iterating in a `for/in` loop) on the List, which will retrieve data if it hasn't already been
24
+ /// retrieved. In such cases, the time to perform that operation will include the time required to request data
25
+ /// from the underlying data source.
25
26
///
26
- /// - seealso: `load()`
27
- public func load( _ completion: DataStoreCallback < Elements > ) {
28
- lazyLoad ( completion)
29
- }
30
-
31
- internal func lazyLoad( _ completion: DataStoreCallback < Elements > ) {
32
-
33
- // if the collection has no associated field, return the current elements
34
- guard let associatedId = associatedId,
35
- let associatedField = associatedField else {
27
+ /// If you have directly created this list object (for example, by calling `List(elements:)`) then the collection
28
+ /// has already been initialized and calling this method will have no effect.
29
+ public func load( _ completion: DataStoreCallback < [ Element ] > ) {
30
+ if case . loaded( let elements) = loadedState {
36
31
completion ( . success( elements) )
37
32
return
38
33
}
39
-
40
- let predicate : QueryPredicate = field ( associatedField . name ) == associatedId
41
- Amplify . DataStore . query ( Element . self , where : predicate ) {
42
- switch $0 {
43
- case . success( let elements) :
44
- self . elements = elements
45
- self . state = . loaded
46
- completion ( . success ( elements ) )
47
- case . failure ( let error) :
48
- completion ( . failure( causedBy: error) )
34
+ let result = listProvider . load ( )
35
+ switch result {
36
+ case . success ( let elements ) :
37
+ self . elements = elements
38
+ completion ( . success( elements) )
39
+ case . failure ( let coreError ) :
40
+ switch coreError {
41
+ case . listOperation ( _ , _ , let error ) ,
42
+ . clientValidation ( _ , _ , let error) :
43
+ completion ( . failure( causedBy: error ?? coreError ) )
49
44
}
50
45
}
51
46
}
52
47
53
48
// MARK: - Synchronous API
54
49
55
- /// Trigger `DataStore` query to initialize the collection. This function always
56
- /// fetches data from the `DataStore.query`. However, consumers must be aware of
50
+ /// This method has been deprecated, Use load(completion:) instead.
51
+ ///
52
+ /// Load data into the collection from the data source. Consumers must be aware of
57
53
/// the internal behavior which relies on `DispatchSemaphore` and will block the
58
54
/// current `DispatchQueue` until data is ready. When operating on large result
59
55
/// sets, prefer using the asynchronous `load(completion:)` instead.
60
56
///
61
57
/// - Returns: the current instance after data was loaded.
62
58
/// - seealso: `load(completion:)`
59
+ @available ( * , deprecated, message: " Use load(completion:) instead. " )
63
60
public func load( ) -> Self {
64
- lazyLoad ( )
65
- return self
66
- }
67
-
68
- /// Internal function that only calls `lazyLoad()` if the `state` is not `.loaded`.
69
- /// - seealso: `lazyLoad()`
70
- internal func loadIfNeeded( ) {
71
- if state != . loaded {
72
- lazyLoad ( )
61
+ guard case . notLoaded = loadedState else {
62
+ return self
73
63
}
74
- }
75
-
76
- /// The synchronized version of `lazyLoad(completion:)`. This function is useful so
77
- /// instances of `List<ModelType>` behave like any other `Collection`.
78
- internal func lazyLoad( ) {
79
- let semaphore = DispatchSemaphore ( value: 0 )
80
- lazyLoad {
81
- switch $0 {
82
- case . success( let elements) :
83
- self . elements = elements
84
- semaphore. signal ( )
85
- case . failure( let error) :
86
- semaphore. signal ( )
87
- // TODO how to handle this failure? should it crash? just log the error?
88
- fatalError ( error. errorDescription)
89
- }
64
+ let result = listProvider. load ( )
65
+ switch result {
66
+ case . success( let elements) :
67
+ self . elements = elements
68
+ case . failure( let error) :
69
+ Amplify . log. error ( error: error)
70
+ assert ( false , error. errorDescription)
90
71
}
91
- semaphore . wait ( )
72
+ return self
92
73
}
93
-
94
74
}
0 commit comments