我有以下代码来处理拉动以刷新响应
let copyData = data.reversed() // it is pull to refresh response (load page 1)
for (_,element) in copyData.enumerated() {
let foundElement = allObjects.filter{$0.id == element.id} // Find element in main array
if let firstElement = foundElement.first, let index = allObjects.index(of: firstElement) {
allObjects[index] = element // Replace if found
} else {
allObjects.insert(element, at: 0) // Insert if not found
}
}
self.arrayPosts = allObjects
其中data
是可编码类,它是请求刷新的API响应。 allObjects
是带有分页的预加载数据
问题:假设在allObjects
中我有50个对象(5页,每10个ID为(1至50))
用户拉动刷新,然后我从API(ID 1,2,3,4,5,6,7,10,11)加载第一页,然后如何识别删除哪个对象(8,9)?
我应该将allObjects
的第十个索引与data
的第十个索引对象的ID进行比较吗?
有更好的处理方法吗?请建议
答案 0 :(得分:5)
不比较页面(一次比较10个项目)-如果添加/删除一个项目,页面将不同步,最终会丢失/重复对象。
大概您的对象是按某个键/日期等排序的。
答案 1 :(得分:0)
这是我的处理方式。初次阅读时,代码非常复杂,但添加了注释即可理解
func handleResponse(page:Int,isForRefersh:Bool = false, data:Array<InspirePost>) {
guard data.count != 0 else {
// Check if we are requesting data from pull to referesh and First page is empty then we don't have data to show change state to empty
if self.arrayPosts.count == 0 || (isForRefersh && page == 1) {
self.state = .empty
self.tableView.reloadData()
} else {
self.state = .populated(posts: self.arrayPosts)
}
return
}
// Now we need to check if data called by referesh control then
//1) Replace object in array other wise just append it.
var allObjects = self.state.currentPost
if isForRefersh {
// If both array Has same number of element i.e both has page one loaded
if data.count >= allObjects.count {
allObjects = data
} else {
let copyData = data.reversed()
for (_,element) in copyData.enumerated() {
if let index = allObjects.firstIndex(where: {$0.id == element.id}) {
allObjects[index] = element // Replace if found
} else {
allObjects.insert(element, at: 0) // Insert if not
}
}
let minID = data.min(by: {$0.id ?? 0 < $1.id ?? 0})?.id
// DELETE item
let copyAllObject = allObjects
for (_,element) in copyAllObject.enumerated() {
guard let id = element.id, id >= minID ?? 0 else {
continue
}
if !data.contains(element) {
if let indexInMainArray = allObjects.index(where: {$0.id == id}) {
allObjects.remove(at: indexInMainArray)
}
}
}
}
//When we pull to refersh check the curent state
switch self.state {
case .empty,.populated : // if empty or populated set it as populated (empty if no record was avaiable then pull to refersh )
self.state = .populated(posts: allObjects)
case .error(_, let lastState) : // If there was error before pull to referesh handle this
switch lastState {
case .empty ,.populated: // Before the error tableview was empty or popluated with data
self.state = .populated(posts: allObjects)
case .loading,.error: // Before error there was loading data (There might more pages if it was in loading so we doing paging state ) or error
self.state = .paging(posts: allObjects, nextPage: page + 1)
case .paging(_,let nextPage): // Before error there was paging then we again change it to paging
self.state = .paging(posts: allObjects, nextPage: nextPage)
}
case .loading: // Current state was loading (this might not been true but for safety we are adding this)
self.state = .paging(posts: allObjects, nextPage: page + 1)
case .paging(_,let nextPage): // if there was paging on going don't break anything
self.state = .paging(posts: allObjects, nextPage: nextPage)
}
self.arrayPosts = allObjects
} else {
allObjects.append(contentsOf: data)
self.isMoreDataAvailable = data.count >= self.pageLimit
if self.isMoreDataAvailable {
self.state = .paging(posts: allObjects, nextPage: page + 1)
} else {
self.state = .populated(posts: allObjects)
}
self.arrayPosts = self.state.currentPost
}
self.tableView.reloadData()
}
我在哪里
indirect enum PostListStatus {
case loading
case paging(posts:[InspirePost],nextPage:Int)
case populated(posts:[InspirePost])
case error (error:String,lastState:PostListStatus) // keep last state for future if we need to know about data or state
case empty
var currentPost:[InspirePost] {
switch self {
case .paging(let posts , _):
return posts
case .populated( let posts):
return posts
case .error( _, let oldPost) :
switch oldPost {
case .paging(let posts , _):
return posts
case .populated( let posts):
return posts
default:
return []
}
default:
return []
}
}
var nextPage : Int {
switch self {
case .paging(_, let page):
return page
default:
return 1
}
}
}
答案 2 :(得分:-1)
您可以同时为set
和allObjects
制作data
。然后在subtracting(_:)
中使用set
方法来查找丢失的方法。
从主阵列中删除那些丢失的阵列并使用它。一旦有了正确的主数组元素,就在显示时对其进行分页。