Waiting for a piece to load before loading more

I am creating an application where I need to load data into pieces, I mean first load 5 elements, and then go to another 5, but I canโ€™t figure out how to do this. At the moment, I am breaking a list of my items, so I get a list of lists of 5 pieces each. For now, for-loop just starts with requests, but I want to wait for an answer and then go into the for loop.

I am using alamofire and my code looks like this.

private func requestItemsForField(items: [Item], completion: @escaping (_ measurements: Array<Measurement>?, _ success: Bool) -> ()) { let userPackageId = UserManager.instance.selectedUserPackage.id let params = ["userPackageId": userPackageId] for field in fields { let url = apiURL + "images/\(field.id)" let queue = DispatchQueue(label: "com.response-queue", qos: .utility, attributes: [.concurrent]) Alamofire.request(url, method: .get, parameters: params, headers: headers()).responseArray(queue: queue, completionHandler: { (response: DataResponse<[Item]>) in if let items = response.result.value as [Item]? { NotificationCenter.default.post(name: NSNotification.Name(rawValue: "itemsLoadedNotification"), object: nil) completion(items, true) } else { print("Request failed with error: \(response.result.error)") completion(nil, false) } }) } } 

Here I break up my list and pass it above.

  private func fetchAllMeasurements(completion: @escaping (_ measurements: [Item]?, _ done: Bool) -> ()) { let fieldSet = FieldStore.instance.data.keys var fieldKeys = [Item]() for field in fieldSet { fieldKeys.append(field) } // Create chunks of fields to load let fieldChunks = fieldKeys.chunkify(by: 5) var measurementsAll = [Measurement]() for fields in fieldChunks { requestItemsForField(fields: fields, completion: { (measurements, success) in if let currentMeasurement = measurements { measurementsAll.append(contentsOf: currentMeasurement) } completion(measurementsAll, true) } }) } } 
+6
source share
3 answers

you need to get the number of dimensions that you will have (for example, the server has 34 dimensions), with your request, and then a code like

 var serverMeasurementsCount = 1 //should be for first request func requestData() { if self.measurements.count < self.serverMeasurementsCount { ...requestdata { data in self.serverMeasurementsCount = data["serverMeasurementsCount"] self.measurements.append(..yourData) self.requestData() } } 

or call requestData not inside the completion handler or anywhere else

edit: fixed bit code ( serverMeasurementsCount = 1 )

+2
source

Instead of using a for loop, it seems that you need to do something like var index = 0 to start and call requestItemsForField() send to fieldChunks[index] as the first parameter. Then, in the completion handler, check if there is another element of the array, and if so, call requestItemsForField() again, this time sending fieldChunks[index+1] as the first parameter.

+1
source

One solution would be to make a new recursive function to populate the elements, add a new Bool parameter to the closure as isComplete. then call the function upon completion of isComplete boolean. to split a recursive function, add the global static variable itemsCountMax if itemCountMax == itemsCount interrupts the recursive function.

0
source

Source: https://habr.com/ru/post/1015668/


All Articles