我目前正在努力寻找一种易于使用的编程方法/设计模式,它解决了以下问题:
我有一个 REST API,iOS 应用程序可以在其中请求所需的数据。不同的 ViewController 中需要数据。但问题是,数据应该“始终”是最新的。所以我需要设置一个计时器,每 5-20 秒或类似的时间触发一次请求。每次数据更改时,都需要更新 View (在显示的当前 View Controller 中)。 我尝试了一些委托(delegate)和 MVC 模式,但有点乱。如何以正确的方式完成?
在我当前的实现中,我只能更新整个 UICollectionView,而不是某些特定的单元格,因为我不知道数据是如何变化的。我的 Controller 跟踪来自 api 的数据,并且仅在散列更改时(如果服务器上的数据更改)才更新。我的模型总是保存最后获取的数据。 在我看来,这不是完美的解决方案..
我还考虑了让自己保持最新状态的模型,以抽象或虚拟化我的 Rest-API。在这种情况下,我的 Controller 甚至不知道它不是可直接访问的数据。
也许有人可以帮我解决某种编程模型、设计模式或其他问题。我对任何事都感到高兴!
更新:当前实现
Controller,处理所有数据
import Foundation
import SwiftyJSON
import SwiftyTimer
class OverviewController {
static let sharedInstance = OverviewController()
let interval = 5.seconds
var delegate : OverviewControllerUpdateable?
var model : OverviewModel?
var timer : NSTimer!
func startFetching() -> Void {
self.fetchData()
timer = NSTimer.new(every: interval) {
self.fetchData()
}
timer.start(modes: NSRunLoopCommonModes)
}
func stopFetching() -> Void {
timer.invalidate()
}
func getConnections() -> [Connection]? {
return model?.getConnections()
}
func getConnectionsSlave() -> [Connection]? {
return model?.getConnectionsSlave()
}
func getUser() -> User? {
return model?.getUser()
}
func countConnections() -> Int {
if let count = model?.getConnections().count {
return count
}
return 0
}
func countConnectionsSlave() -> Int {
if let count = model?.getConnectionsSlave().count {
return count
}
return 0
}
func fetchData() {
ApiCaller.doCall(OverviewRoute(), completionHandler: { (data, hash) in
if let actModel = self.model {
if (actModel.getHash() == hash) {
//no update required
return
}
}
var connections : [Connection] = []
var connectionsSlave : [Connection] = []
for (_,connection):(String, JSON) in data["connections"] {
let connectionObj = Connection(json: connection)
if (connectionObj.isMaster == true) {
connections.append(connectionObj)
} else {
connectionsSlave.append(connectionObj)
}
}
let user = User(json: data["user"])
//model needs update
let model = OverviewModel()
model.setUser(user)
model.setConnections(connections)
model.setConnectionsSlave(connectionsSlave)
model.setHash(hash)
self.model = model
//prevent unexpectedly found nil exception
if (self.delegate != nil) {
self.delegate!.reloadView()
}
}, errorHandler: { (errors) in
}) { (progress) in
}
}
}
protocol OverviewControllerUpdateable {
func reloadView()
}
保存数据的模型:
class OverviewModel {
var user : User!
var connections : [Connection]!
var connectionsSlave : [Connection]!
var connectionRequests : [ConnectionRequest]!
var hash : String!
...
}
在 ViewController 中,我这样使用它:
class OverviewVC: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, OverviewControllerUpdateable {
let controller = OverviewController.sharedInstance
override func viewDidLoad() {
super.viewDidLoad()
self.controller.delegate = self
self.controller.startFetching()
}
//INSIDE THE UICOLLECTIONVIEW DELEGATE METHODS
...
if let user : User = controller.getUser() {
cell.intervalTime = interval
cell.nameLabel.text = "Ihr Profil"
}
...
func reloadView() {
self.userCollectionView.reloadData()
}
}
最佳答案
您可以使用 Singleton
对象定期获取数据,然后在数据更新时发布通知(使用 NSNotificationCenter
)。每个依赖于数据的 View Controller 都会监听这些通知,然后根据更新的数据重新加载 UI。
关于ios - REST API、Swift、自动更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40251070/