Kodr.F
Kodr.F

Reputation: 14390

Swift 3 Array pagination?

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

Answers (3)

Duyen-Hoa
Duyen-Hoa

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

Kodr.F
Kodr.F

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

Akshay Agrawal
Akshay Agrawal

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

Related Questions