Reputation: 41
I am trying to get a value from a swift dictionary to display as cell texts. I am getting error:
Type 'Any' has no subscript members
cell.audioLabel.text = audiofiles["filetitle"] <-line producing error
I believe I may have set the variables incorrectly, the value is being passed using segue from another tableview using the didSelectRowAt.
var audios = Array<Any>() <- gets from another controller
This is my current viewcontroller code:
import UIKit
class DetailViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var audioTable: UITableView!
@IBOutlet weak var descText: UITextView!
@IBOutlet weak var clickButton: UIButton!
var practitle = String()
var desc = String()
var hasAudio = Int()
var audios = Array<Any>()
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = practitle
descText.text = desc
if hasAudio != 0 {
clickButton.isHidden = false
}
print(audios)
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return audios.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "audiocell", for: indexPath) as! DetailViewCell
let audiofiles = audios[indexPath.row]
cell.audioLabel.text = audiofiles["filetitle"]
return cell
}
When I use
print(audios)
The result that I get is:
[demoApp.Audiofile(id: 1, filetitle: "Sample file one", filename: "breath5mins", fileformat: "mp3"), demoApp.Audiofile(id: 2, filetitle: "Sample file two", filename: "breath10mins", fileformat: "mp3"), demoApp.Audiofile(id: 3, filetitle: "Sample file three", filename: "breath20mins", fileformat: "mp3")]
How can I use the filetitle as the label texts for my cell?
The goal is to display the title and open another view on cell click and allow the user to click a button on the new view and play the mp3 file.
Upvotes: 0
Views: 941
Reputation: 1475
The reason you get the error is Any
is an object with no definition. You can cast it into an AudioFile
like this:
let audiofiles = audios[indexPath.row] as! AudioFile
If audios
is an array of AudioFile
only then declare it as such and you can use it the way you described.
Upvotes: -1
Reputation: 285180
Apparently the object is not a Swift dictionary, it's a custom class or struct.
You are fighting Swift's strong type system. Don't do that.
Declare audios
with the static type
var audios = Array<AudioFile>()
and use dot notation instead of insecure KVC (which does not work anyway in this case).
cell.audioLabel.text = audiofiles.filetitle
Upvotes: 2
Reputation: 114974
You have declared your array as Array<Any>
- which means that the array can contain anything; the elements of the array don't even all need to be the same type. As a result, the Swift compiler doesn't know what type of thing it is getting from audios[indexPath.row]
; it could be a dictionary, it could be an array or it could be an integer. When you try and use subscripting, the compiler gives you an error because it doesn't know whether the item supports subscripting - i.e. an Int
doesn't, and Any
could be an Int
.
Don't use Any
or AnyObject
in Swift if you know the actual type; Swift's type safety allows it to eliminate a large number of potential runtime issues at compile time by know what types things are.
From the print
statement it appears that your array contains Audiofile
instances (presumably a struct or class you have defined, not a dictionary). You should, therefore, declare audios
correctly:
var audios = Array<Audiofile>()
You can then access the object's properties in your cellForRow
:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "audiocell", for: indexPath) as! DetailViewCell
let audiofiles = audios[indexPath.row]
cell.audioLabel.text = audiofiles.filetitle
return cell
}
Upvotes: 1