Reputation: 14390
Hello I'm trying to do pagination for array of contacts, some how i the code crashed on paged 2
here is my code :
// Initialize
let limit : Int = 10
var page : Int = self.defaults.integer(forKey: "ConPage") == 0 ? 1 : self.defaults.integer(forKey: "ConPage")
var start : Int = page == 0 || page == 1 ? 0 : limit * ( page-1)
var increment : Int = 1
var data = (contacts)?[start...limit]
print("[CONTACTS SYNC][LoadUpContacts] Success \(success) , Data : \(data?.count) , start : \(start) , Limit : \(limit) , Page : \(page), Total : \(contacts?.count) ")
for contact in data!
{
print("\(increment) : \(contact.name) ")
increment = increment + 1
}
//go Next
self.defaults.set(page+1, forKey: "ConPage")
self.LoadUpContacts()
and here is the crash log :
fatal error: Can't form Range with upperBound < lowerBound
2017-07-10 11:32:01.758790+0300 muzeit[6085:2216770] fatal error: Can't form Range with upperBound < lowerBound
What is the best way to paginate an array in swift 3 ?
Upvotes: 0
Views: 1776
Reputation: 15784
To respond to your question in the comment. In fact, the subArrayWithRange
is only available in Objective-c. So you can create a subarray from an index
, with length
by:
let arr = [1, 3, 4, 5, 10, 2, 100, 40, 1244, 23]
let startIndex = 3
let length = 4
let arr2 = arr[startIndex..<(startIndex + length)] //print [5, 10, 2, 100]
And to get the contents of a page from your items, you have to calculate the right startIndex and the endIndex of your subarray. Be attention that, the subcript returns a ArraySlice, not Array. You may to cast it to Array.
//page start from 0
func getPageItems(page: UInt, allItems: [Int], maxItemsPerPage: UInt) -> [Int] {
let startIndex = Int(page * maxItemsPerPage)
var length = max(0, allItems.count - startIndex)
length = min(Int(maxItemsPerPage), length)
guard length > 0 else { return [] }
return Array(allItems[startIndex..<(startIndex + length)])
}
the call:
let arr3 = getPageItems(page: 3, allItems: arr, maxItemsPerPage: 4)
will return [1244, 23]
Upvotes: 2
Reputation: 14390
the problem was in array range , so i fixed it and i hope it solve someone else issue , below is the correct code for array pagination in Swift 3
let total : Int = (contacts?.count)!
let limit : Int = 20
let page : Int = self.defaults.integer(forKey: "ConPage") == 0 ? 1 : self.defaults.integer(forKey: "ConPage")
let start : Int = page == 0 || page == 1 ? 0 : (limit * page) - limit
var end : Int = start + limit
end = end >= total ? total : end
end = end - 1
let data = start >= total ? [] : (contacts)?[start...(end)]
Upvotes: 3
Reputation: 217
Looking at the error it seems like there is an issue with the array range. If you look at the line:
var data = (contacts)?[start...limit]
of your code, you can see that the limit is always equal to 10. And the range upper...lower represents the start and the end of the range. So you should properly calculate the lower bound also in the way you calculate the upper bound.
Upvotes: 0