Замыкания, не обновляющие локальные переменные - PullRequest
0 голосов
/ 23 апреля 2019

Как я могу обновить локальные переменные внутри замыкания Alamofire?

Я пытаюсь обновить количество сообщений, успешно отправленных с использованием запроса Alamofire. Очевидное место для этого - внутри замыкания - в случае .success.

Поэтому я пытаюсь обновить локальную переменную внутри замыкания, но ее область действия ограничена внутри замыкания. Я вижу локальное обновление, когда вступаю в закрытие. Но когда я рассматриваю его ниже замыкания, его значение равно 0. Следовательно, print () отображает «SENT 0 of n RECORDS». Я подозреваю, что это потому, что он проходит через цикл до вызова замыкания.

Вопросы: 1) Что мне не хватает? 2) Я не понимаю, завершение () вызова. Я не могу найти этот метод в моем коде. Это заполнитель, который я заменяю своим обратным вызовом?

func uploadSavedPacketsToServer(completion: @escaping (Int, Int) -> Void) {

var totalNumRecsToSend = recordsToSend.count
for (i, currentRec) in recordsToSend.enumerated() {

   // build request....

    Alamofire.request(request)
             .validate()
             .responseJSON { response in

             switch response.result {

             case .success:
                  // pass the # of recs remaining as well as total # of recs to send
                   completion( (totalNumRecsToSend - i),totalNumRecsToSend)

             case .failure(let error):
                   print("SUBMIT failure: \(error)")

                  // -1, 0 indicates a unique error. Parsed in completion handler
                   completion(-1, 0)   
             }
     }   // end closure
   }   // end for all records to send
}


// Executed AFTER the network call has returned!!
let completionHandler: (Int, Int) -> Void = { (numSent, numTotal) in

error checking ....
    if (numTotal - numSent == 0) {
        // SUCCESS
        // keep a running count of # packets sent to server in this period
        ServerConstants.numPktsUploaded += numSent
    }

    // Build the Notification
    // 1) Create the body content
    let content = UNMutableNotificationContent()
    content.title = NSString.localizedUserNotificationString(forKey: "Data Upload", arguments: nil)
    content.body = NSString.localizedUserNotificationString(forKey: strMsg, arguments: nil)

     // 2) Configure the trigger to appear 10 minutes from now. NOTE: using Calendar will accomodate for DST, TZs etc.
     var calendar = Calendar.current
     let trigger = UNCalendarNotificationTrigger(dateMatching: calendar.dateComponents([.year, .month, .day, .hour, .minute, .second, .timeZone],
                     from: Date(timeIntervalSinceNow: 1)), repeats: false)

     // 3) Create the Local Notification object
     let notify = UNNotificationRequest(identifier: "DataUpload", content: content, trigger: trigger)

     // 4) and queue it up
     UNUserNotificationCenter.current().add(notify, withCompletionHandler: nil)

     // reset our pkt counter
     ServerConstants.numPktsUploaded = 0             

     // and the time of our last upload
     ServerConstants.lastNotifyTime = currentTime    
     return
}

1 Ответ

0 голосов
/ 23 апреля 2019

Вам необходимо использовать DispatchGroup, чтобы получать уведомления о завершении всех асинхронных запросов

let g = DispatchGroup() /// <<<<< 1

for (i, currentRec) in recordsToSend.enumerated() {

    // build request....

    g.enter()  /// <<<<< 2

    Alamofire.request(request)
        .validate()
        .responseJSON { response in

            switch response.result {

            case .success:
                // pass the server's response back in 1st param, & error status in 2nd param
                completion(response.value, nil)

                // keep count of how many records were successfully sent
                self.setNumRecsSent()

            case .failure(let error):
                print("SUBMIT failure: \(error)")
                completion(nil, response.error)

            }

            g.leave()  /// <<<<< 3

    }   // end closure
}   // end for all records to send


g.notify(queue: .main) {  /// <<<<< 4

    print("SENT \(self.getNumRecsSent()) of \(numRecsToSend) RECORDS: ")

}
...