在启动我的应用程序时,我会执行一些 http 请求、一些繁重的 http 请求(下载一些图像)和一些使用 UIGraphics 的繁重任务(例如从两个 UIImages 为 GMSMarker 执行图标以及使用 GraphicsContext 执行其他操作)。这需要一些时间,所以我想同时完成所有这些任务。你能告诉我最好的方法吗? 一开始我必须:
- 下载所有设备并写入本地数据库
- 下载所有地理围栏并写入本地数据库
- 下载所有用户并写入本地数据库
下载所有位置并写入本地数据库
为设备、用户和地理围栏下载图像
为设备、用户和地理围栏设置 GMSMarkers(在该对象的图像可用后 - 用于设置标记图标)
我的登录函数的代码(可以运行,但是太慢了):
func loginPressed(_ sender: UIButton) {
guard
let username = self.usernameTextField.text,
let password = self.passwordTextField.text,
!username.isEmpty,
!password.isEmpty
else {
return
}
self.loginButton.isEnabled = false
self.activityIndicator.startAnimating()
WebService.shared.connect(email: username, password: password) { error, loggedUser in
guard
error == nil,
let loggedUser = loggedUser
else {
self.showAlert(title: "Ошибка подключения", message: error?.localizedDescription ?? "", style: .alert)
self.activityIndicator.stopAnimating()
self.loginButton.isEnabled = true
return
}
DB.users.client.insert(loggedUser)
print("Start loading user photo...")
loggedUser.loadPhoto() { image in
if let image = image {
loggedUser.photo = UIImageJPEGRepresentation(image, 0.0)
}
print("User photo loaded...")
loggedUser.marker = UserMarker(loggedUser, at: CLLocation(latitude: 48.7193900, longitude: 44.50183))
DB.users.client.modify(loggedUser)
}
DB.geofences.server.getAll() { geofences in
DB.devices.server.getAll() { devices in
DB.positions.server.getAll() { positions in
for device in devices {
device.loadPhoto() { image in
if let image = image {
device.photo = UIImageJPEGRepresentation(image, 0.0)
}
if let position = positions.findById(device.positionId) {
device.marker = DeviceMarker(device, at: position)
}
device.attributes.battery = device.lastKnownBattery(in: positions)
}
}
geofences.forEach({$0.marker = GeofenceMarker($0)})
DB.geofences.client.updateAddress(geofences) { geofences in
if DEBUG_LOGS {
print("Geofences with updated addresses: ")
geofences.forEach({print("\($0.name), \($0.address ?? "")")})
}
DB.devices.client.insert(devices)
DB.geofences.client.insert(geofences)
DB.positions.client.insert(positions)
self.activityIndicator.stopAnimating()
WebService.shared.addObserver(DefaultObserver.shared)
self.performSegue(withIdentifier: "toMapController", sender: self)
}
}
}
}
}
}
不确定在此处张贴所有类和对象的代码片段是否是个好主意,希望您能理解。 任何帮助,将不胜感激。
附言如果您想知道什么是 DB,它是数据库,它由两部分组成 - 每组对象的服务器端和客户端,因此第一个任务是从服务器获取所有对象并将它们写入内存(在客户端数据库中)
附言我已将登录时的“下载所有内容”逻辑更改为“立即下载我需要的所有内容,稍后再下载其余内容”。因此,现在在我获得所有设备、地理围栏和位置后,我正在对 MapController 执行 segue,在其上显示所有这些对象。登录后,我将显示带有默认 iconView 的 deviceMarkers (GMSMarker)。所以问题是 - 在显示包含所有对象的 map 之后,我可以开始在后台下载设备照片,然后用这些照片刷新标记(当然是在主线程中)吗?
最佳答案
默认情况下网络请求是异步的,因此您所请求的已经具有预期的行为。
但是,您可以使用 Promises 库(例如 then)让您的生活变得更加简单。 .
示例用法可能如下所示:
login(email: "foo@bar.com", password: "pa$$w0rd")
.whenAll(syncDevices(), syncGeofences(), syncUsers(), syncPositions(), syncImages())
.onError { err in
// process error
}
.finally {
// update UI
}
关于swift - 在 Swift 中同时发出 HTTP 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46162049/