Swift 4 tableView API Pagination
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I have successfully parsed and decoded the JSON data and it displays in the console. I don't know how I would set up pagination with the api and display all of the data when I scroll down on the tableView. The API I'm using is https://rickandmortyapi.com/api/character/. Thank you for all your help in advance!
This is the code in my main ViewController
import UIKit
struct PagedCharacters: Codable {
struct Info: Codable {
let count: Int
let pages: Int
let next: String
let prev: String
}
struct Results: Codable {
let name: String
let status: String
let species: String
}
let info: Info
let results: [Results]
}
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet var uiTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
getRickAndMortyData()
self.uiTableView.dataSource = self
self.uiTableView.delegate = self
// Do any additional setup after loading the view.
}
func getRickAndMortyData() {
//create instance of the url
let url = "https://rickandmortyapi.com/api/character/"
//construct the url, use guard to avoid nonoptional
guard let urlObj = URL(string: url) else
{ return }
//fetch data
URLSession.shared.dataTask(with: urlObj) {(data, response, error) in
//to avoid non optional in JSONDecoder
guard let data = data else { return }
do {
//decode object
let downloadedRickAndMorty = try JSONDecoder().decode(PagedCharacters.self, from: data)
DispatchQueue.main.async {
self.uiTableView.reloadData()
}
print(downloadedRickAndMorty)
} catch {
print(error)
}
}.resume()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "rickandmortyCell") as? CharacterTableViewCell else { return UITableViewCell() }
cell.nameLabel.text = "Name: " + PagedCharacters.Results[indexPath.row].name
return cell
}
}
This is my tableviewcell class
import UIKit
class CharacterTableViewCell: UITableViewCell {
@IBOutlet weak var nameLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
This is the data I'm getting in my console when the parsed data is printed. I'm still not getting all the data from the different pages.
PagedCharacters(info: API_Practice.PagedCharacters.Info(count: 493,
pages: 25, next: "https://rickandmortyapi.com/api/character/?page=2",
prev: ""), results: [API_Practice.PagedCharacters.Results(name: "Rick
Sanchez", status: "Alive", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Morty Smith", status:
"Alive", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Summer Smith", status: "Alive", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Beth Smith", status:
"Alive", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Jerry Smith", status: "Alive", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Abadango Cluster
Princess", status: "Alive", species: "Alien"),
API_Practice.PagedCharacters.Results(name: "Abradolf Lincler", status:
"unknown", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Adjudicator Rick", status:
"Dead", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Agency Director", status: "Dead", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Alan Rails", status:
"Dead", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Albert Einstein", status: "Dead", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Alexander", status:
"Dead", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Alien Googah", status: "unknown", species: "Alien"),
API_Practice.PagedCharacters.Results(name: "Alien Morty", status:
"unknown", species: "Alien"),
API_Practice.PagedCharacters.Results(name: "Alien Rick", status:
"unknown", species: "Alien"),
API_Practice.PagedCharacters.Results(name: "Amish Cyborg", status:
"Dead", species: "Alien"), API_Practice.PagedCharacters.Results(name:
"Annie", status: "Alive", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Antenna Morty", status:
"Alive", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Antenna Rick", status: "unknown", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Ants in my Eyes Johnson",
status: "unknown", species: "Human")])
If you need anything else please let me know. Thank you!
api uitableview pagination swift4
add a comment |
I have successfully parsed and decoded the JSON data and it displays in the console. I don't know how I would set up pagination with the api and display all of the data when I scroll down on the tableView. The API I'm using is https://rickandmortyapi.com/api/character/. Thank you for all your help in advance!
This is the code in my main ViewController
import UIKit
struct PagedCharacters: Codable {
struct Info: Codable {
let count: Int
let pages: Int
let next: String
let prev: String
}
struct Results: Codable {
let name: String
let status: String
let species: String
}
let info: Info
let results: [Results]
}
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet var uiTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
getRickAndMortyData()
self.uiTableView.dataSource = self
self.uiTableView.delegate = self
// Do any additional setup after loading the view.
}
func getRickAndMortyData() {
//create instance of the url
let url = "https://rickandmortyapi.com/api/character/"
//construct the url, use guard to avoid nonoptional
guard let urlObj = URL(string: url) else
{ return }
//fetch data
URLSession.shared.dataTask(with: urlObj) {(data, response, error) in
//to avoid non optional in JSONDecoder
guard let data = data else { return }
do {
//decode object
let downloadedRickAndMorty = try JSONDecoder().decode(PagedCharacters.self, from: data)
DispatchQueue.main.async {
self.uiTableView.reloadData()
}
print(downloadedRickAndMorty)
} catch {
print(error)
}
}.resume()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "rickandmortyCell") as? CharacterTableViewCell else { return UITableViewCell() }
cell.nameLabel.text = "Name: " + PagedCharacters.Results[indexPath.row].name
return cell
}
}
This is my tableviewcell class
import UIKit
class CharacterTableViewCell: UITableViewCell {
@IBOutlet weak var nameLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
This is the data I'm getting in my console when the parsed data is printed. I'm still not getting all the data from the different pages.
PagedCharacters(info: API_Practice.PagedCharacters.Info(count: 493,
pages: 25, next: "https://rickandmortyapi.com/api/character/?page=2",
prev: ""), results: [API_Practice.PagedCharacters.Results(name: "Rick
Sanchez", status: "Alive", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Morty Smith", status:
"Alive", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Summer Smith", status: "Alive", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Beth Smith", status:
"Alive", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Jerry Smith", status: "Alive", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Abadango Cluster
Princess", status: "Alive", species: "Alien"),
API_Practice.PagedCharacters.Results(name: "Abradolf Lincler", status:
"unknown", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Adjudicator Rick", status:
"Dead", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Agency Director", status: "Dead", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Alan Rails", status:
"Dead", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Albert Einstein", status: "Dead", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Alexander", status:
"Dead", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Alien Googah", status: "unknown", species: "Alien"),
API_Practice.PagedCharacters.Results(name: "Alien Morty", status:
"unknown", species: "Alien"),
API_Practice.PagedCharacters.Results(name: "Alien Rick", status:
"unknown", species: "Alien"),
API_Practice.PagedCharacters.Results(name: "Amish Cyborg", status:
"Dead", species: "Alien"), API_Practice.PagedCharacters.Results(name:
"Annie", status: "Alive", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Antenna Morty", status:
"Alive", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Antenna Rick", status: "unknown", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Ants in my Eyes Johnson",
status: "unknown", species: "Human")])
If you need anything else please let me know. Thank you!
api uitableview pagination swift4
stackoverflow.com/questions/34588837/…
– Abdulaziz.Musaileekh
Nov 28 '18 at 4:38
add a comment |
I have successfully parsed and decoded the JSON data and it displays in the console. I don't know how I would set up pagination with the api and display all of the data when I scroll down on the tableView. The API I'm using is https://rickandmortyapi.com/api/character/. Thank you for all your help in advance!
This is the code in my main ViewController
import UIKit
struct PagedCharacters: Codable {
struct Info: Codable {
let count: Int
let pages: Int
let next: String
let prev: String
}
struct Results: Codable {
let name: String
let status: String
let species: String
}
let info: Info
let results: [Results]
}
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet var uiTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
getRickAndMortyData()
self.uiTableView.dataSource = self
self.uiTableView.delegate = self
// Do any additional setup after loading the view.
}
func getRickAndMortyData() {
//create instance of the url
let url = "https://rickandmortyapi.com/api/character/"
//construct the url, use guard to avoid nonoptional
guard let urlObj = URL(string: url) else
{ return }
//fetch data
URLSession.shared.dataTask(with: urlObj) {(data, response, error) in
//to avoid non optional in JSONDecoder
guard let data = data else { return }
do {
//decode object
let downloadedRickAndMorty = try JSONDecoder().decode(PagedCharacters.self, from: data)
DispatchQueue.main.async {
self.uiTableView.reloadData()
}
print(downloadedRickAndMorty)
} catch {
print(error)
}
}.resume()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "rickandmortyCell") as? CharacterTableViewCell else { return UITableViewCell() }
cell.nameLabel.text = "Name: " + PagedCharacters.Results[indexPath.row].name
return cell
}
}
This is my tableviewcell class
import UIKit
class CharacterTableViewCell: UITableViewCell {
@IBOutlet weak var nameLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
This is the data I'm getting in my console when the parsed data is printed. I'm still not getting all the data from the different pages.
PagedCharacters(info: API_Practice.PagedCharacters.Info(count: 493,
pages: 25, next: "https://rickandmortyapi.com/api/character/?page=2",
prev: ""), results: [API_Practice.PagedCharacters.Results(name: "Rick
Sanchez", status: "Alive", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Morty Smith", status:
"Alive", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Summer Smith", status: "Alive", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Beth Smith", status:
"Alive", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Jerry Smith", status: "Alive", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Abadango Cluster
Princess", status: "Alive", species: "Alien"),
API_Practice.PagedCharacters.Results(name: "Abradolf Lincler", status:
"unknown", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Adjudicator Rick", status:
"Dead", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Agency Director", status: "Dead", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Alan Rails", status:
"Dead", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Albert Einstein", status: "Dead", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Alexander", status:
"Dead", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Alien Googah", status: "unknown", species: "Alien"),
API_Practice.PagedCharacters.Results(name: "Alien Morty", status:
"unknown", species: "Alien"),
API_Practice.PagedCharacters.Results(name: "Alien Rick", status:
"unknown", species: "Alien"),
API_Practice.PagedCharacters.Results(name: "Amish Cyborg", status:
"Dead", species: "Alien"), API_Practice.PagedCharacters.Results(name:
"Annie", status: "Alive", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Antenna Morty", status:
"Alive", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Antenna Rick", status: "unknown", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Ants in my Eyes Johnson",
status: "unknown", species: "Human")])
If you need anything else please let me know. Thank you!
api uitableview pagination swift4
I have successfully parsed and decoded the JSON data and it displays in the console. I don't know how I would set up pagination with the api and display all of the data when I scroll down on the tableView. The API I'm using is https://rickandmortyapi.com/api/character/. Thank you for all your help in advance!
This is the code in my main ViewController
import UIKit
struct PagedCharacters: Codable {
struct Info: Codable {
let count: Int
let pages: Int
let next: String
let prev: String
}
struct Results: Codable {
let name: String
let status: String
let species: String
}
let info: Info
let results: [Results]
}
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet var uiTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
getRickAndMortyData()
self.uiTableView.dataSource = self
self.uiTableView.delegate = self
// Do any additional setup after loading the view.
}
func getRickAndMortyData() {
//create instance of the url
let url = "https://rickandmortyapi.com/api/character/"
//construct the url, use guard to avoid nonoptional
guard let urlObj = URL(string: url) else
{ return }
//fetch data
URLSession.shared.dataTask(with: urlObj) {(data, response, error) in
//to avoid non optional in JSONDecoder
guard let data = data else { return }
do {
//decode object
let downloadedRickAndMorty = try JSONDecoder().decode(PagedCharacters.self, from: data)
DispatchQueue.main.async {
self.uiTableView.reloadData()
}
print(downloadedRickAndMorty)
} catch {
print(error)
}
}.resume()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "rickandmortyCell") as? CharacterTableViewCell else { return UITableViewCell() }
cell.nameLabel.text = "Name: " + PagedCharacters.Results[indexPath.row].name
return cell
}
}
This is my tableviewcell class
import UIKit
class CharacterTableViewCell: UITableViewCell {
@IBOutlet weak var nameLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
This is the data I'm getting in my console when the parsed data is printed. I'm still not getting all the data from the different pages.
PagedCharacters(info: API_Practice.PagedCharacters.Info(count: 493,
pages: 25, next: "https://rickandmortyapi.com/api/character/?page=2",
prev: ""), results: [API_Practice.PagedCharacters.Results(name: "Rick
Sanchez", status: "Alive", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Morty Smith", status:
"Alive", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Summer Smith", status: "Alive", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Beth Smith", status:
"Alive", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Jerry Smith", status: "Alive", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Abadango Cluster
Princess", status: "Alive", species: "Alien"),
API_Practice.PagedCharacters.Results(name: "Abradolf Lincler", status:
"unknown", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Adjudicator Rick", status:
"Dead", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Agency Director", status: "Dead", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Alan Rails", status:
"Dead", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Albert Einstein", status: "Dead", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Alexander", status:
"Dead", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Alien Googah", status: "unknown", species: "Alien"),
API_Practice.PagedCharacters.Results(name: "Alien Morty", status:
"unknown", species: "Alien"),
API_Practice.PagedCharacters.Results(name: "Alien Rick", status:
"unknown", species: "Alien"),
API_Practice.PagedCharacters.Results(name: "Amish Cyborg", status:
"Dead", species: "Alien"), API_Practice.PagedCharacters.Results(name:
"Annie", status: "Alive", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Antenna Morty", status:
"Alive", species: "Human"), API_Practice.PagedCharacters.Results(name:
"Antenna Rick", status: "unknown", species: "Human"),
API_Practice.PagedCharacters.Results(name: "Ants in my Eyes Johnson",
status: "unknown", species: "Human")])
If you need anything else please let me know. Thank you!
api uitableview pagination swift4
api uitableview pagination swift4
edited Nov 23 '18 at 2:04
newToIosProgramming
asked Nov 22 '18 at 21:37
newToIosProgrammingnewToIosProgramming
32
32
stackoverflow.com/questions/34588837/…
– Abdulaziz.Musaileekh
Nov 28 '18 at 4:38
add a comment |
stackoverflow.com/questions/34588837/…
– Abdulaziz.Musaileekh
Nov 28 '18 at 4:38
stackoverflow.com/questions/34588837/…
– Abdulaziz.Musaileekh
Nov 28 '18 at 4:38
stackoverflow.com/questions/34588837/…
– Abdulaziz.Musaileekh
Nov 28 '18 at 4:38
add a comment |
1 Answer
1
active
oldest
votes
There were many flaws in your logic, so I have rewritten it with minimal changes. Now it will serve your purpose.
import UIKit
struct PagedCharacters: Codable {
let info: Info
let results: [Results]
}
struct Info: Codable {
let count: Int
let pages: Int
let next: String
let prev: String
}
struct Results: Codable {
let name: String
let status: String
let species: String
}
And here is the code for view controller class:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet var uiTableView: UITableView!
var aryDownloadedData:[Results]?
var nextPageUrl:String!
override func viewDidLoad() {
super.viewDidLoad()
getIntitalRickAndMortyData()
self.uiTableView.dataSource = self
self.uiTableView.delegate = self
// Do any additional setup after loading the view.
}
func getIntitalRickAndMortyData(){
aryDownloadedData =
//here first page is next page
nextPageUrl = "https://rickandmortyapi.com/api/character/"
getRickAndMortyData()
}
func getRickAndMortyData() {
//construct the url, use guard to avoid nonoptional
guard let urlObj = URL(string: nextPageUrl) else
{ return }
//fetch data
URLSession.shared.dataTask(with: urlObj) {[weak self](data, response, error) in
//to avoid non optional in JSONDecoder
guard let data = data else { return }
do {
//decode object
let downloadedRickAndMorty = try JSONDecoder().decode(PagedCharacters.self, from: data)
self?.aryDownloadedData?.append(contentsOf: downloadedRickAndMorty.results)
self?.nextPageUrl = downloadedRickAndMorty.info.next
DispatchQueue.main.async {
self?.uiTableView.reloadData()
}
print(self?.aryDownloadedData as Any)
} catch {
print(error)
}
}.resume()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.aryDownloadedData?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let count = aryDownloadedData?.count, count>1{
let lastElement = count - 1
if indexPath.row == lastElement {
//call get api for next page
getRickAndMortyData()
}
}
guard let cell = tableView.dequeueReusableCell(withIdentifier: "rickandmortyCell") as? CharacterTableViewCell else { return UITableViewCell() }
cell.nameLabel.text = "Name: " + (self.aryDownloadedData?[indexPath.row].name ?? "default")
return cell
}
}
@AaronTreinish : if this is the solution you are looking for, please up vote and accept the answer. Thanks 😊
– nikksindia
Dec 11 '18 at 3:00
The code still only gets the data from the first page and not the other pages. Is there something else I have to do to get the data from the other pages?
– newToIosProgramming
Dec 12 '18 at 3:35
tableView(tableView: willDisplayCell:) does this for you. As soon as you reach the end of list, it will trigger api call with next page url.
– nikksindia
Dec 12 '18 at 5:38
I ran the code as you have it and when I scroll to the bottom it doesn't trigger the api call with the next page url. It just has the initial page on the tableview.
– newToIosProgramming
Dec 12 '18 at 15:27
@AaronTreinish: I have updated the code. Check now
– nikksindia
Dec 13 '18 at 6:07
|
show 2 more comments
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53438239%2fswift-4-tableview-api-pagination%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
There were many flaws in your logic, so I have rewritten it with minimal changes. Now it will serve your purpose.
import UIKit
struct PagedCharacters: Codable {
let info: Info
let results: [Results]
}
struct Info: Codable {
let count: Int
let pages: Int
let next: String
let prev: String
}
struct Results: Codable {
let name: String
let status: String
let species: String
}
And here is the code for view controller class:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet var uiTableView: UITableView!
var aryDownloadedData:[Results]?
var nextPageUrl:String!
override func viewDidLoad() {
super.viewDidLoad()
getIntitalRickAndMortyData()
self.uiTableView.dataSource = self
self.uiTableView.delegate = self
// Do any additional setup after loading the view.
}
func getIntitalRickAndMortyData(){
aryDownloadedData =
//here first page is next page
nextPageUrl = "https://rickandmortyapi.com/api/character/"
getRickAndMortyData()
}
func getRickAndMortyData() {
//construct the url, use guard to avoid nonoptional
guard let urlObj = URL(string: nextPageUrl) else
{ return }
//fetch data
URLSession.shared.dataTask(with: urlObj) {[weak self](data, response, error) in
//to avoid non optional in JSONDecoder
guard let data = data else { return }
do {
//decode object
let downloadedRickAndMorty = try JSONDecoder().decode(PagedCharacters.self, from: data)
self?.aryDownloadedData?.append(contentsOf: downloadedRickAndMorty.results)
self?.nextPageUrl = downloadedRickAndMorty.info.next
DispatchQueue.main.async {
self?.uiTableView.reloadData()
}
print(self?.aryDownloadedData as Any)
} catch {
print(error)
}
}.resume()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.aryDownloadedData?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let count = aryDownloadedData?.count, count>1{
let lastElement = count - 1
if indexPath.row == lastElement {
//call get api for next page
getRickAndMortyData()
}
}
guard let cell = tableView.dequeueReusableCell(withIdentifier: "rickandmortyCell") as? CharacterTableViewCell else { return UITableViewCell() }
cell.nameLabel.text = "Name: " + (self.aryDownloadedData?[indexPath.row].name ?? "default")
return cell
}
}
@AaronTreinish : if this is the solution you are looking for, please up vote and accept the answer. Thanks 😊
– nikksindia
Dec 11 '18 at 3:00
The code still only gets the data from the first page and not the other pages. Is there something else I have to do to get the data from the other pages?
– newToIosProgramming
Dec 12 '18 at 3:35
tableView(tableView: willDisplayCell:) does this for you. As soon as you reach the end of list, it will trigger api call with next page url.
– nikksindia
Dec 12 '18 at 5:38
I ran the code as you have it and when I scroll to the bottom it doesn't trigger the api call with the next page url. It just has the initial page on the tableview.
– newToIosProgramming
Dec 12 '18 at 15:27
@AaronTreinish: I have updated the code. Check now
– nikksindia
Dec 13 '18 at 6:07
|
show 2 more comments
There were many flaws in your logic, so I have rewritten it with minimal changes. Now it will serve your purpose.
import UIKit
struct PagedCharacters: Codable {
let info: Info
let results: [Results]
}
struct Info: Codable {
let count: Int
let pages: Int
let next: String
let prev: String
}
struct Results: Codable {
let name: String
let status: String
let species: String
}
And here is the code for view controller class:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet var uiTableView: UITableView!
var aryDownloadedData:[Results]?
var nextPageUrl:String!
override func viewDidLoad() {
super.viewDidLoad()
getIntitalRickAndMortyData()
self.uiTableView.dataSource = self
self.uiTableView.delegate = self
// Do any additional setup after loading the view.
}
func getIntitalRickAndMortyData(){
aryDownloadedData =
//here first page is next page
nextPageUrl = "https://rickandmortyapi.com/api/character/"
getRickAndMortyData()
}
func getRickAndMortyData() {
//construct the url, use guard to avoid nonoptional
guard let urlObj = URL(string: nextPageUrl) else
{ return }
//fetch data
URLSession.shared.dataTask(with: urlObj) {[weak self](data, response, error) in
//to avoid non optional in JSONDecoder
guard let data = data else { return }
do {
//decode object
let downloadedRickAndMorty = try JSONDecoder().decode(PagedCharacters.self, from: data)
self?.aryDownloadedData?.append(contentsOf: downloadedRickAndMorty.results)
self?.nextPageUrl = downloadedRickAndMorty.info.next
DispatchQueue.main.async {
self?.uiTableView.reloadData()
}
print(self?.aryDownloadedData as Any)
} catch {
print(error)
}
}.resume()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.aryDownloadedData?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let count = aryDownloadedData?.count, count>1{
let lastElement = count - 1
if indexPath.row == lastElement {
//call get api for next page
getRickAndMortyData()
}
}
guard let cell = tableView.dequeueReusableCell(withIdentifier: "rickandmortyCell") as? CharacterTableViewCell else { return UITableViewCell() }
cell.nameLabel.text = "Name: " + (self.aryDownloadedData?[indexPath.row].name ?? "default")
return cell
}
}
@AaronTreinish : if this is the solution you are looking for, please up vote and accept the answer. Thanks 😊
– nikksindia
Dec 11 '18 at 3:00
The code still only gets the data from the first page and not the other pages. Is there something else I have to do to get the data from the other pages?
– newToIosProgramming
Dec 12 '18 at 3:35
tableView(tableView: willDisplayCell:) does this for you. As soon as you reach the end of list, it will trigger api call with next page url.
– nikksindia
Dec 12 '18 at 5:38
I ran the code as you have it and when I scroll to the bottom it doesn't trigger the api call with the next page url. It just has the initial page on the tableview.
– newToIosProgramming
Dec 12 '18 at 15:27
@AaronTreinish: I have updated the code. Check now
– nikksindia
Dec 13 '18 at 6:07
|
show 2 more comments
There were many flaws in your logic, so I have rewritten it with minimal changes. Now it will serve your purpose.
import UIKit
struct PagedCharacters: Codable {
let info: Info
let results: [Results]
}
struct Info: Codable {
let count: Int
let pages: Int
let next: String
let prev: String
}
struct Results: Codable {
let name: String
let status: String
let species: String
}
And here is the code for view controller class:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet var uiTableView: UITableView!
var aryDownloadedData:[Results]?
var nextPageUrl:String!
override func viewDidLoad() {
super.viewDidLoad()
getIntitalRickAndMortyData()
self.uiTableView.dataSource = self
self.uiTableView.delegate = self
// Do any additional setup after loading the view.
}
func getIntitalRickAndMortyData(){
aryDownloadedData =
//here first page is next page
nextPageUrl = "https://rickandmortyapi.com/api/character/"
getRickAndMortyData()
}
func getRickAndMortyData() {
//construct the url, use guard to avoid nonoptional
guard let urlObj = URL(string: nextPageUrl) else
{ return }
//fetch data
URLSession.shared.dataTask(with: urlObj) {[weak self](data, response, error) in
//to avoid non optional in JSONDecoder
guard let data = data else { return }
do {
//decode object
let downloadedRickAndMorty = try JSONDecoder().decode(PagedCharacters.self, from: data)
self?.aryDownloadedData?.append(contentsOf: downloadedRickAndMorty.results)
self?.nextPageUrl = downloadedRickAndMorty.info.next
DispatchQueue.main.async {
self?.uiTableView.reloadData()
}
print(self?.aryDownloadedData as Any)
} catch {
print(error)
}
}.resume()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.aryDownloadedData?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let count = aryDownloadedData?.count, count>1{
let lastElement = count - 1
if indexPath.row == lastElement {
//call get api for next page
getRickAndMortyData()
}
}
guard let cell = tableView.dequeueReusableCell(withIdentifier: "rickandmortyCell") as? CharacterTableViewCell else { return UITableViewCell() }
cell.nameLabel.text = "Name: " + (self.aryDownloadedData?[indexPath.row].name ?? "default")
return cell
}
}
There were many flaws in your logic, so I have rewritten it with minimal changes. Now it will serve your purpose.
import UIKit
struct PagedCharacters: Codable {
let info: Info
let results: [Results]
}
struct Info: Codable {
let count: Int
let pages: Int
let next: String
let prev: String
}
struct Results: Codable {
let name: String
let status: String
let species: String
}
And here is the code for view controller class:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet var uiTableView: UITableView!
var aryDownloadedData:[Results]?
var nextPageUrl:String!
override func viewDidLoad() {
super.viewDidLoad()
getIntitalRickAndMortyData()
self.uiTableView.dataSource = self
self.uiTableView.delegate = self
// Do any additional setup after loading the view.
}
func getIntitalRickAndMortyData(){
aryDownloadedData =
//here first page is next page
nextPageUrl = "https://rickandmortyapi.com/api/character/"
getRickAndMortyData()
}
func getRickAndMortyData() {
//construct the url, use guard to avoid nonoptional
guard let urlObj = URL(string: nextPageUrl) else
{ return }
//fetch data
URLSession.shared.dataTask(with: urlObj) {[weak self](data, response, error) in
//to avoid non optional in JSONDecoder
guard let data = data else { return }
do {
//decode object
let downloadedRickAndMorty = try JSONDecoder().decode(PagedCharacters.self, from: data)
self?.aryDownloadedData?.append(contentsOf: downloadedRickAndMorty.results)
self?.nextPageUrl = downloadedRickAndMorty.info.next
DispatchQueue.main.async {
self?.uiTableView.reloadData()
}
print(self?.aryDownloadedData as Any)
} catch {
print(error)
}
}.resume()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.aryDownloadedData?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let count = aryDownloadedData?.count, count>1{
let lastElement = count - 1
if indexPath.row == lastElement {
//call get api for next page
getRickAndMortyData()
}
}
guard let cell = tableView.dequeueReusableCell(withIdentifier: "rickandmortyCell") as? CharacterTableViewCell else { return UITableViewCell() }
cell.nameLabel.text = "Name: " + (self.aryDownloadedData?[indexPath.row].name ?? "default")
return cell
}
}
edited Dec 13 '18 at 6:07
answered Dec 4 '18 at 9:10
nikksindianikksindia
472412
472412
@AaronTreinish : if this is the solution you are looking for, please up vote and accept the answer. Thanks 😊
– nikksindia
Dec 11 '18 at 3:00
The code still only gets the data from the first page and not the other pages. Is there something else I have to do to get the data from the other pages?
– newToIosProgramming
Dec 12 '18 at 3:35
tableView(tableView: willDisplayCell:) does this for you. As soon as you reach the end of list, it will trigger api call with next page url.
– nikksindia
Dec 12 '18 at 5:38
I ran the code as you have it and when I scroll to the bottom it doesn't trigger the api call with the next page url. It just has the initial page on the tableview.
– newToIosProgramming
Dec 12 '18 at 15:27
@AaronTreinish: I have updated the code. Check now
– nikksindia
Dec 13 '18 at 6:07
|
show 2 more comments
@AaronTreinish : if this is the solution you are looking for, please up vote and accept the answer. Thanks 😊
– nikksindia
Dec 11 '18 at 3:00
The code still only gets the data from the first page and not the other pages. Is there something else I have to do to get the data from the other pages?
– newToIosProgramming
Dec 12 '18 at 3:35
tableView(tableView: willDisplayCell:) does this for you. As soon as you reach the end of list, it will trigger api call with next page url.
– nikksindia
Dec 12 '18 at 5:38
I ran the code as you have it and when I scroll to the bottom it doesn't trigger the api call with the next page url. It just has the initial page on the tableview.
– newToIosProgramming
Dec 12 '18 at 15:27
@AaronTreinish: I have updated the code. Check now
– nikksindia
Dec 13 '18 at 6:07
@AaronTreinish : if this is the solution you are looking for, please up vote and accept the answer. Thanks 😊
– nikksindia
Dec 11 '18 at 3:00
@AaronTreinish : if this is the solution you are looking for, please up vote and accept the answer. Thanks 😊
– nikksindia
Dec 11 '18 at 3:00
The code still only gets the data from the first page and not the other pages. Is there something else I have to do to get the data from the other pages?
– newToIosProgramming
Dec 12 '18 at 3:35
The code still only gets the data from the first page and not the other pages. Is there something else I have to do to get the data from the other pages?
– newToIosProgramming
Dec 12 '18 at 3:35
tableView(tableView: willDisplayCell:) does this for you. As soon as you reach the end of list, it will trigger api call with next page url.
– nikksindia
Dec 12 '18 at 5:38
tableView(tableView: willDisplayCell:) does this for you. As soon as you reach the end of list, it will trigger api call with next page url.
– nikksindia
Dec 12 '18 at 5:38
I ran the code as you have it and when I scroll to the bottom it doesn't trigger the api call with the next page url. It just has the initial page on the tableview.
– newToIosProgramming
Dec 12 '18 at 15:27
I ran the code as you have it and when I scroll to the bottom it doesn't trigger the api call with the next page url. It just has the initial page on the tableview.
– newToIosProgramming
Dec 12 '18 at 15:27
@AaronTreinish: I have updated the code. Check now
– nikksindia
Dec 13 '18 at 6:07
@AaronTreinish: I have updated the code. Check now
– nikksindia
Dec 13 '18 at 6:07
|
show 2 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53438239%2fswift-4-tableview-api-pagination%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
stackoverflow.com/questions/34588837/…
– Abdulaziz.Musaileekh
Nov 28 '18 at 4:38