Index out of range error even though number of values matches number of rows
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I'm trying to set some images to image views in a tableview, and I have the number of rows set to return keys.count
, which after printing is confirmed to be 5
, which is perfect.
Now in cellForRowAt
I get the images
in an array, then attempt to set the images to my cell's image view.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "stockCell", for: indexPath) as! StockCell
let stock = stockData[keys[indexPath.row]]!
var images = [String]()
stock.news.forEach { images.append($0.image) }
print("nnNumber of Images: (images.count)nnn")
if let companyImageUrl = URL(string: images[indexPath.row]) {
ImageService.getImage(url: companyImageUrl) { (image) in
cell.companyLogoImageView.image = image
}
}
return cell
}
}
I put a print statement in there to print the images.count
(there should be 5), but the console shows 2, then 5 (x3), then 2 again - this is causing the index out of range error presumably, it's seeing 2 when there should be 5:
Why is images.count
showing 2
in the first and last spots, but 5
in the rest?
EDIT: Rest of code
Fetching the data (in viewDidLoad
):
fetchData(url: stockApiUrl) { (result: FetchResult<[String:Stock]>) -> (Void) in
switch result {
case .success(let object):
self.stockData = object
self.keys = Array(object.keys)
print("stockData: nn(self.stockData)")
case .failure(let error):
print("Error decoding JSON: nn(error)")
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
Data is set to a dictionary, with a separate array for the keys:
var stockData = [String:Stock]()
var keys = [String]()
Structs for decoding JSON:
struct Welcome: Decodable {
let aapl, fb, msft, tsla, goog: Stock
enum CodingKeys: String, CodingKey {
case aapl = "AAPL"
case fb = "FB"
case msft = "MSFT"
case tsla = "TSLA"
case goog = "GOOG"
}
}
struct Stock: Decodable {
let quote: Quote
let news: [News]
}
struct Quote: Decodable {
let symbol: String
let companyName: String
let latestPrice: Double
}
struct News: Decodable {
let url: String
let image: String
}
ios swift uitableview
add a comment |
I'm trying to set some images to image views in a tableview, and I have the number of rows set to return keys.count
, which after printing is confirmed to be 5
, which is perfect.
Now in cellForRowAt
I get the images
in an array, then attempt to set the images to my cell's image view.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "stockCell", for: indexPath) as! StockCell
let stock = stockData[keys[indexPath.row]]!
var images = [String]()
stock.news.forEach { images.append($0.image) }
print("nnNumber of Images: (images.count)nnn")
if let companyImageUrl = URL(string: images[indexPath.row]) {
ImageService.getImage(url: companyImageUrl) { (image) in
cell.companyLogoImageView.image = image
}
}
return cell
}
}
I put a print statement in there to print the images.count
(there should be 5), but the console shows 2, then 5 (x3), then 2 again - this is causing the index out of range error presumably, it's seeing 2 when there should be 5:
Why is images.count
showing 2
in the first and last spots, but 5
in the rest?
EDIT: Rest of code
Fetching the data (in viewDidLoad
):
fetchData(url: stockApiUrl) { (result: FetchResult<[String:Stock]>) -> (Void) in
switch result {
case .success(let object):
self.stockData = object
self.keys = Array(object.keys)
print("stockData: nn(self.stockData)")
case .failure(let error):
print("Error decoding JSON: nn(error)")
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
Data is set to a dictionary, with a separate array for the keys:
var stockData = [String:Stock]()
var keys = [String]()
Structs for decoding JSON:
struct Welcome: Decodable {
let aapl, fb, msft, tsla, goog: Stock
enum CodingKeys: String, CodingKey {
case aapl = "AAPL"
case fb = "FB"
case msft = "MSFT"
case tsla = "TSLA"
case goog = "GOOG"
}
}
struct Stock: Decodable {
let quote: Quote
let news: [News]
}
struct Quote: Decodable {
let symbol: String
let companyName: String
let latestPrice: Double
}
struct News: Decodable {
let url: String
let image: String
}
ios swift uitableview
I don't get it, how are we supposed to know whatstock.news
contains?
– Joakim Danielson
Nov 16 '18 at 17:45
Sorry I wasn't sure if that part was necessary, I edited my question to add the rest of the code.
– KingTim
Nov 16 '18 at 17:48
add a comment |
I'm trying to set some images to image views in a tableview, and I have the number of rows set to return keys.count
, which after printing is confirmed to be 5
, which is perfect.
Now in cellForRowAt
I get the images
in an array, then attempt to set the images to my cell's image view.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "stockCell", for: indexPath) as! StockCell
let stock = stockData[keys[indexPath.row]]!
var images = [String]()
stock.news.forEach { images.append($0.image) }
print("nnNumber of Images: (images.count)nnn")
if let companyImageUrl = URL(string: images[indexPath.row]) {
ImageService.getImage(url: companyImageUrl) { (image) in
cell.companyLogoImageView.image = image
}
}
return cell
}
}
I put a print statement in there to print the images.count
(there should be 5), but the console shows 2, then 5 (x3), then 2 again - this is causing the index out of range error presumably, it's seeing 2 when there should be 5:
Why is images.count
showing 2
in the first and last spots, but 5
in the rest?
EDIT: Rest of code
Fetching the data (in viewDidLoad
):
fetchData(url: stockApiUrl) { (result: FetchResult<[String:Stock]>) -> (Void) in
switch result {
case .success(let object):
self.stockData = object
self.keys = Array(object.keys)
print("stockData: nn(self.stockData)")
case .failure(let error):
print("Error decoding JSON: nn(error)")
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
Data is set to a dictionary, with a separate array for the keys:
var stockData = [String:Stock]()
var keys = [String]()
Structs for decoding JSON:
struct Welcome: Decodable {
let aapl, fb, msft, tsla, goog: Stock
enum CodingKeys: String, CodingKey {
case aapl = "AAPL"
case fb = "FB"
case msft = "MSFT"
case tsla = "TSLA"
case goog = "GOOG"
}
}
struct Stock: Decodable {
let quote: Quote
let news: [News]
}
struct Quote: Decodable {
let symbol: String
let companyName: String
let latestPrice: Double
}
struct News: Decodable {
let url: String
let image: String
}
ios swift uitableview
I'm trying to set some images to image views in a tableview, and I have the number of rows set to return keys.count
, which after printing is confirmed to be 5
, which is perfect.
Now in cellForRowAt
I get the images
in an array, then attempt to set the images to my cell's image view.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "stockCell", for: indexPath) as! StockCell
let stock = stockData[keys[indexPath.row]]!
var images = [String]()
stock.news.forEach { images.append($0.image) }
print("nnNumber of Images: (images.count)nnn")
if let companyImageUrl = URL(string: images[indexPath.row]) {
ImageService.getImage(url: companyImageUrl) { (image) in
cell.companyLogoImageView.image = image
}
}
return cell
}
}
I put a print statement in there to print the images.count
(there should be 5), but the console shows 2, then 5 (x3), then 2 again - this is causing the index out of range error presumably, it's seeing 2 when there should be 5:
Why is images.count
showing 2
in the first and last spots, but 5
in the rest?
EDIT: Rest of code
Fetching the data (in viewDidLoad
):
fetchData(url: stockApiUrl) { (result: FetchResult<[String:Stock]>) -> (Void) in
switch result {
case .success(let object):
self.stockData = object
self.keys = Array(object.keys)
print("stockData: nn(self.stockData)")
case .failure(let error):
print("Error decoding JSON: nn(error)")
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
Data is set to a dictionary, with a separate array for the keys:
var stockData = [String:Stock]()
var keys = [String]()
Structs for decoding JSON:
struct Welcome: Decodable {
let aapl, fb, msft, tsla, goog: Stock
enum CodingKeys: String, CodingKey {
case aapl = "AAPL"
case fb = "FB"
case msft = "MSFT"
case tsla = "TSLA"
case goog = "GOOG"
}
}
struct Stock: Decodable {
let quote: Quote
let news: [News]
}
struct Quote: Decodable {
let symbol: String
let companyName: String
let latestPrice: Double
}
struct News: Decodable {
let url: String
let image: String
}
ios swift uitableview
ios swift uitableview
edited Nov 16 '18 at 18:17
rmaddy
247k27328391
247k27328391
asked Nov 16 '18 at 17:39
KingTimKingTim
5261821
5261821
I don't get it, how are we supposed to know whatstock.news
contains?
– Joakim Danielson
Nov 16 '18 at 17:45
Sorry I wasn't sure if that part was necessary, I edited my question to add the rest of the code.
– KingTim
Nov 16 '18 at 17:48
add a comment |
I don't get it, how are we supposed to know whatstock.news
contains?
– Joakim Danielson
Nov 16 '18 at 17:45
Sorry I wasn't sure if that part was necessary, I edited my question to add the rest of the code.
– KingTim
Nov 16 '18 at 17:48
I don't get it, how are we supposed to know what
stock.news
contains?– Joakim Danielson
Nov 16 '18 at 17:45
I don't get it, how are we supposed to know what
stock.news
contains?– Joakim Danielson
Nov 16 '18 at 17:45
Sorry I wasn't sure if that part was necessary, I edited my question to add the rest of the code.
– KingTim
Nov 16 '18 at 17:48
Sorry I wasn't sure if that part was necessary, I edited my question to add the rest of the code.
– KingTim
Nov 16 '18 at 17:48
add a comment |
2 Answers
2
active
oldest
votes
Add another print and make sure that the quantity of news is also different for each row. Then find out why it is different.
stock.news.forEach { images.append($0.image) }
print("nnNumber of Images: (images.count)nnn")
print("nnNumber of stock.news: (stock.news.count)nnn")
Ok, printingstock.news.count
shows the same irregularity asimages.count
, except now both counts are5
,5
,2
,2
,5
.
– KingTim
Nov 16 '18 at 18:11
This isn't an answer, this is a debugging comment. Please wait until you have enough reputation to post comments.
– rmaddy
Nov 16 '18 at 18:17
Ok. But I thought it was. The question: "Why is images.count showing 2 in the first and last spots, but 5 in the rest?" And the answer: "because stock.news is different in each row".
– Sergey
Nov 16 '18 at 18:22
add a comment |
You are assuming that you have 5 images because keys.count
is 5 and this is wrong since keys.count
tells you that you have 5 stocks in the dictionary you created from the json message.
Now each stock has an news array attached to it that I assume contains news articles/messages related to the stock for one day or similar so this array could then contain from 0 up to an infinite (not likely) amount of news articles. (in this case the number of articles ranges between 2 and 5).
Anyway, you can not rely on keys.count
when reading the news array but instead for each array check news.count
.
So this code needs to be changed but I am not sure how
if let companyImageUrl = URL(string: images[indexPath.row]) {
ImageService.getImage(url: companyImageUrl) { (image) in
cell.companyLogoImageView.image = image
}
}
Will you show all images? then you need to surround this with a loop somehow but I get the feeling you only want to show one image so maybe change URL(string: images[indexPath.row])
to URL(string: images[0])
add a comment |
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%2f53342835%2findex-out-of-range-error-even-though-number-of-values-matches-number-of-rows%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Add another print and make sure that the quantity of news is also different for each row. Then find out why it is different.
stock.news.forEach { images.append($0.image) }
print("nnNumber of Images: (images.count)nnn")
print("nnNumber of stock.news: (stock.news.count)nnn")
Ok, printingstock.news.count
shows the same irregularity asimages.count
, except now both counts are5
,5
,2
,2
,5
.
– KingTim
Nov 16 '18 at 18:11
This isn't an answer, this is a debugging comment. Please wait until you have enough reputation to post comments.
– rmaddy
Nov 16 '18 at 18:17
Ok. But I thought it was. The question: "Why is images.count showing 2 in the first and last spots, but 5 in the rest?" And the answer: "because stock.news is different in each row".
– Sergey
Nov 16 '18 at 18:22
add a comment |
Add another print and make sure that the quantity of news is also different for each row. Then find out why it is different.
stock.news.forEach { images.append($0.image) }
print("nnNumber of Images: (images.count)nnn")
print("nnNumber of stock.news: (stock.news.count)nnn")
Ok, printingstock.news.count
shows the same irregularity asimages.count
, except now both counts are5
,5
,2
,2
,5
.
– KingTim
Nov 16 '18 at 18:11
This isn't an answer, this is a debugging comment. Please wait until you have enough reputation to post comments.
– rmaddy
Nov 16 '18 at 18:17
Ok. But I thought it was. The question: "Why is images.count showing 2 in the first and last spots, but 5 in the rest?" And the answer: "because stock.news is different in each row".
– Sergey
Nov 16 '18 at 18:22
add a comment |
Add another print and make sure that the quantity of news is also different for each row. Then find out why it is different.
stock.news.forEach { images.append($0.image) }
print("nnNumber of Images: (images.count)nnn")
print("nnNumber of stock.news: (stock.news.count)nnn")
Add another print and make sure that the quantity of news is also different for each row. Then find out why it is different.
stock.news.forEach { images.append($0.image) }
print("nnNumber of Images: (images.count)nnn")
print("nnNumber of stock.news: (stock.news.count)nnn")
answered Nov 16 '18 at 18:08
SergeySergey
26
26
Ok, printingstock.news.count
shows the same irregularity asimages.count
, except now both counts are5
,5
,2
,2
,5
.
– KingTim
Nov 16 '18 at 18:11
This isn't an answer, this is a debugging comment. Please wait until you have enough reputation to post comments.
– rmaddy
Nov 16 '18 at 18:17
Ok. But I thought it was. The question: "Why is images.count showing 2 in the first and last spots, but 5 in the rest?" And the answer: "because stock.news is different in each row".
– Sergey
Nov 16 '18 at 18:22
add a comment |
Ok, printingstock.news.count
shows the same irregularity asimages.count
, except now both counts are5
,5
,2
,2
,5
.
– KingTim
Nov 16 '18 at 18:11
This isn't an answer, this is a debugging comment. Please wait until you have enough reputation to post comments.
– rmaddy
Nov 16 '18 at 18:17
Ok. But I thought it was. The question: "Why is images.count showing 2 in the first and last spots, but 5 in the rest?" And the answer: "because stock.news is different in each row".
– Sergey
Nov 16 '18 at 18:22
Ok, printing
stock.news.count
shows the same irregularity as images.count
, except now both counts are 5
, 5
, 2
, 2
, 5
.– KingTim
Nov 16 '18 at 18:11
Ok, printing
stock.news.count
shows the same irregularity as images.count
, except now both counts are 5
, 5
, 2
, 2
, 5
.– KingTim
Nov 16 '18 at 18:11
This isn't an answer, this is a debugging comment. Please wait until you have enough reputation to post comments.
– rmaddy
Nov 16 '18 at 18:17
This isn't an answer, this is a debugging comment. Please wait until you have enough reputation to post comments.
– rmaddy
Nov 16 '18 at 18:17
Ok. But I thought it was. The question: "Why is images.count showing 2 in the first and last spots, but 5 in the rest?" And the answer: "because stock.news is different in each row".
– Sergey
Nov 16 '18 at 18:22
Ok. But I thought it was. The question: "Why is images.count showing 2 in the first and last spots, but 5 in the rest?" And the answer: "because stock.news is different in each row".
– Sergey
Nov 16 '18 at 18:22
add a comment |
You are assuming that you have 5 images because keys.count
is 5 and this is wrong since keys.count
tells you that you have 5 stocks in the dictionary you created from the json message.
Now each stock has an news array attached to it that I assume contains news articles/messages related to the stock for one day or similar so this array could then contain from 0 up to an infinite (not likely) amount of news articles. (in this case the number of articles ranges between 2 and 5).
Anyway, you can not rely on keys.count
when reading the news array but instead for each array check news.count
.
So this code needs to be changed but I am not sure how
if let companyImageUrl = URL(string: images[indexPath.row]) {
ImageService.getImage(url: companyImageUrl) { (image) in
cell.companyLogoImageView.image = image
}
}
Will you show all images? then you need to surround this with a loop somehow but I get the feeling you only want to show one image so maybe change URL(string: images[indexPath.row])
to URL(string: images[0])
add a comment |
You are assuming that you have 5 images because keys.count
is 5 and this is wrong since keys.count
tells you that you have 5 stocks in the dictionary you created from the json message.
Now each stock has an news array attached to it that I assume contains news articles/messages related to the stock for one day or similar so this array could then contain from 0 up to an infinite (not likely) amount of news articles. (in this case the number of articles ranges between 2 and 5).
Anyway, you can not rely on keys.count
when reading the news array but instead for each array check news.count
.
So this code needs to be changed but I am not sure how
if let companyImageUrl = URL(string: images[indexPath.row]) {
ImageService.getImage(url: companyImageUrl) { (image) in
cell.companyLogoImageView.image = image
}
}
Will you show all images? then you need to surround this with a loop somehow but I get the feeling you only want to show one image so maybe change URL(string: images[indexPath.row])
to URL(string: images[0])
add a comment |
You are assuming that you have 5 images because keys.count
is 5 and this is wrong since keys.count
tells you that you have 5 stocks in the dictionary you created from the json message.
Now each stock has an news array attached to it that I assume contains news articles/messages related to the stock for one day or similar so this array could then contain from 0 up to an infinite (not likely) amount of news articles. (in this case the number of articles ranges between 2 and 5).
Anyway, you can not rely on keys.count
when reading the news array but instead for each array check news.count
.
So this code needs to be changed but I am not sure how
if let companyImageUrl = URL(string: images[indexPath.row]) {
ImageService.getImage(url: companyImageUrl) { (image) in
cell.companyLogoImageView.image = image
}
}
Will you show all images? then you need to surround this with a loop somehow but I get the feeling you only want to show one image so maybe change URL(string: images[indexPath.row])
to URL(string: images[0])
You are assuming that you have 5 images because keys.count
is 5 and this is wrong since keys.count
tells you that you have 5 stocks in the dictionary you created from the json message.
Now each stock has an news array attached to it that I assume contains news articles/messages related to the stock for one day or similar so this array could then contain from 0 up to an infinite (not likely) amount of news articles. (in this case the number of articles ranges between 2 and 5).
Anyway, you can not rely on keys.count
when reading the news array but instead for each array check news.count
.
So this code needs to be changed but I am not sure how
if let companyImageUrl = URL(string: images[indexPath.row]) {
ImageService.getImage(url: companyImageUrl) { (image) in
cell.companyLogoImageView.image = image
}
}
Will you show all images? then you need to surround this with a loop somehow but I get the feeling you only want to show one image so maybe change URL(string: images[indexPath.row])
to URL(string: images[0])
answered Nov 16 '18 at 18:56
Joakim DanielsonJoakim Danielson
10.8k3725
10.8k3725
add a comment |
add a comment |
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%2f53342835%2findex-out-of-range-error-even-though-number-of-values-matches-number-of-rows%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
I don't get it, how are we supposed to know what
stock.news
contains?– Joakim Danielson
Nov 16 '18 at 17:45
Sorry I wasn't sure if that part was necessary, I edited my question to add the rest of the code.
– KingTim
Nov 16 '18 at 17:48