Как в Swift отправлять сетевые запросы при нажатии, чтобы каждый запрос имел задержку в несколько секунд?IOS

Программируем под IOS
Ответить
Anonymous
 Как в Swift отправлять сетевые запросы при нажатии, чтобы каждый запрос имел задержку в несколько секунд?

Сообщение Anonymous »

Я создал этот простой пример, чтобы продемонстрировать проблему.
У меня есть 4 кнопки для голосования «за», добавления в избранное, пометки и скрытия. Пользователь может нажимать любую кнопку в любое время и столько раз, сколько захочет. Однако сетевой запрос, отправляемый после касания, всегда должен иметь минимальную задержку в 2 секунды между ними. Кроме того, все запросы должны отправляться по порядку.
Например, предположим, что пользователь нажимает «голосовать за» через 0,1 секунды после нажатия «флажка». Запрос на пометку должен быть отправлен сразу после нажатия «флаг», и через 2 секунды после получения ответа на запрос на пометку должен быть отправлен запрос на голосование.
Следующее, кажется, работает, но иногда , он не подчиняется 2-секундной задержке и отправляет несколько запросов одновременно без какой-либо задержки между ними. Мне трудно понять, что является причиной этого. Есть лучший способ сделать это? Или в чем тут проблема?
import UIKit
import SnapKit

extension UIControl {
func addAction(for controlEvents: UIControl.Event = .touchUpInside, _ closure: @escaping()->()) {
addAction(UIAction { (action: UIAction) in closure() }, for: controlEvents)
}
}

let networkDelay = TimeInterval(2)
var requestWorkItems = [DispatchWorkItem]()
var lastRequestCompletionTime: Date?

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

let stack = UIStackView()
stack.axis = .vertical
view.addSubview(stack)
stack.snp.makeConstraints { make in
make.center.equalToSuperview()
}

["UPVOTE","FAVORITE","FLAG","HIDE"].forEach { title in
let button = UIButton()
button.setTitle(title, for: .normal)
button.addAction { [weak self] in

let urlString = "https://example.com/api?action=\(title)"

self?.scheduleNetworkRequest(urlString: urlString)
}
button.titleLabel?.font = UIFont.systemFont(ofSize: 30, weight: .bold)
button.snp.makeConstraints { make in
make.height.equalTo(100)
}
stack.addArrangedSubview(button)
}

}

func scheduleNetworkRequest(urlString : String) {
let workItem = DispatchWorkItem { [weak self] in
self?.sendNetworkRequest(urlString: urlString)
}

requestWorkItems.append(workItem)

if Date().timeIntervalSince(lastRequestCompletionTime ?? .distantPast) > networkDelay {
scheduleNextWork(delay: 0)
}
}

func scheduleNextWork(delay : TimeInterval) {
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
if let workItem = requestWorkItems.first {
requestWorkItems.removeFirst()
print("Tasks remaining: \(requestWorkItems.count)")
workItem.perform()
}
}
}

func sendNetworkRequest(urlString : String) {
guard let url = URL(string: urlString) else { return }

let task = URLSession.shared.dataTask(with: url) { [weak self] data, response, error in
if let error = error {
print("Error: \(error)")
} else if let _ = data {
print("Completed: \(urlString) at: \(Date())")
}
lastRequestCompletionTime = Date()
self?.scheduleNextWork(delay: networkDelay)
}
task.resume()
}

}


Подробнее здесь: https://stackoverflow.com/questions/785 ... -has-a-few
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»