Closed ca13ra1 closed 3 years ago
Since you're using SwiftUI, you may want to try storing the paged results in an Array
, then querying the next page when you reach the end. This should give you an infinite-scroll style. Let me know if that works for you.
struct ContentView : View {
@State private var responses: [(page: Int, element: RickAndMorty)] = []
var body: some View {
NavigationView {
List {
// Loop over each page of results
ForEach(responses, id: \.page) { response in
// Loop over each character. Enumerate the characters so we can identify the last one.
ForEach(Array(response.element.results.enumerated()), id: \.element.id) { character in
Text(character.element.name)
.onAppear {
// When the last item appears, load the next results.
guard character.offset == response.element.results.count - 1,
let next = response.element.info.next,
let pageString = next.components(separatedBy: "?page=").last,
let nextPage = Int(pageString)
else { return }
loadPage(nextPage)
}
}
}
}
.navigationTitle("Characters")
}
.onAppear{ loadPage(1) }
}
func loadPage(_ page: Int) {
// Don't re-fetch any data.
guard !responses.contains(where: { $0.page == page }) else { return }
// Get the next page of characters
AnyRequest<RickAndMorty> {
Url("https://rickandmortyapi.com/api/character")
Query(page == 1 ? [:] : ["page": "\(page)"])
}
.onObject { response in
DispatchQueue.main.async {
// Add the results in the correct spot if they came in late for some reason.
responses.insert((page, response), at: page - 1)
}
}
.onError {
print("Failed with: \($0.localizedDescription)")
}
.call()
}
}
Getting Task <192B2F72-4623-44D4-8485-D206EF287E44>.<1> finished with error [-1007] Error Domain=NSURLErrorDomain Code=-1007 "too many HTTP redirects" UserInfo={NSLocalizedDescription=too many HTTP redirects, NSErrorFailingURLStringKey=https://rickandmortyapi.com/api/character, NSErrorFailingURLKey=https://rickandmortyapi.com/api/character, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask <192B2F72-4623-44D4-8485-D206EF287E44>.<1>" ), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <192B2F72-4623-44D4-8485-D206EF287E44>.<1>, NSUnderlyingError=0x6000034d7ae0 {Error Domain=kCFErrorDomainCFNetwork Code=-1007 "(null)"}} Failed with: too many HTTP redirects
I actually think that's an issue with their API. I would often get the same error in Safari and Postman
Thank you for helping though, much appreciated.
Adding UserAgent fixed the too many HTTP redirects. But no other data is loaded when it reaches the last indexed value
Method(.get)
Header.UserAgent(.firefoxMac)
Is it not running loadPage
at all, or is it throwing an error?
It does actually call loadPage
but nothing happens. It seems the Query
string isn't accepted by the API. I modified the Url to Url("https://rickandmortyapi.com/api/character/?page=\(page == 1 ? 1 : page)")
but can't get the next url to load.
Finally working, thank you for the help! Closing 😁
I'm using the
RickAndMorty API
alongsideRequest
just fine here. The API is limited to 20 items per request. The data includes the page count, next url and previous url. I attempted to useRequestChain
but I can't seem to figure out the correct way to handle the Data type. The end goal is to load all characters from the API usingRequest
in a simpleList
. I've only usedRequestView
andAnyRequest
and not sure if I can do what I'm trying usingAnyRequest
or evenRequestChain/RequestGroup
, been stuck on this for days now.data struct
Failed chain request