'Swift pagination method from Medium tutorial throws errors
I need to learn how pagination works for the project I am doing right now. My friend suggested me this tutorial: https://medium.com/swlh/easy-pagination-in-swiftui-da9e1fe3e25e and @loremipsum helped solved several problems I had with it. Still the URL in the tutorial:
"https://testURL.com"
Needs an account and doesn't really allow account creation (even if I wanted to create one). So I have used the URL for which I know API keys.
The code:
ContentView file:
import SwiftUI
struct Members: View {
@ObservedObject var memberData = MemberData()
var body: some View {
NavigationView {
List {
// 1. Members
ForEach(memberData.members) { item in
Text(items.Item) /* No exact matches in call to initializer */
}
// 2. Activity Indicator. Last element of list.
// Show activity spinner if backend has more data.
// Its onAppear method is used to load new members. Pagination done.
if memberData.membersListFull == false {
ProgressView()
.onAppear {
memberData.fetchMembers()
}
}
}
.navigationBarTitle("Members")
}
}
}
Member data file:
import Foundation
import Combine
class MemberData: ObservableObject {
@Published var members = [Item]()
// Tells if all records have been loaded. (Used to hide/show activity spinner)
var membersListFull = false
// Tracks last page loaded. Used to load next page (current + 1)
var currentPage = 0
// Limit of records per page. (Only if backend supports, it usually does)
let perPage = 20
let url = URL(string:"https://api.github.com/search/repositories?q=Core-Data&per_page=\(currentPage+1)&perPage=\(perPage)")! /* 1) Cannot use instance member 'currentPage' within property initializer; property initializers run before 'self' is available; 2) Cannot use instance member 'perPage' within property initializer; property initializers run before 'self' is available */
private var cancellable: AnyCancellable?
func fetchMembers() {
cancellable = URLSession.shared.dataTaskPublisher(for: url)
.tryMap { $0.data }
.decode(type: [Item].self, decoder: JSONDecoder())
.receive(on: RunLoop.main)
.catch { _ in Just(self.members) }
.sink { [weak self] in
self?.currentPage += 1
self?.members.append(contentsOf: $0)
// If count of data received is less than perPage value then it is last page.
if $0.count < perPage { /* Reference to property 'perPage' in closure requires explicit use of 'self' to make capture semantics explicit */
self?.membersListFull = true
}
}
}
}
API caller file:
import SwiftUI
struct Root: Codable {
let items: [Item]
enum CodingKeys: String, CodingKey {
case items
}
}
struct Item: Identifiable, Codable {
let id: Int
let htmlUrl: String
let fullName: String
enum CodingKeys: String, CodingKey {
case id
case htmlUrl = "html_url"
case fullName = "full_name"
}
}
I get 4 errors. One in ContentView, 3 in Member data file. I have added all of them as comments in the corresponding files.
Please help if you can :)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
