Latest Xcode upgrade 7.3 broke the following block of code in a tableview:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("GameCell", forIndexPath: indexPath) as! GameViewCell
if PFUser.currentUser()!.objectId == self.user1.objectId{
let user = gameResults[indexPath.row]["user2"] as! PFUser
cell.userName.text = user["first_name"] as! String
self.viewUser = user
}
The line let user = gameResults[indexPath.row]["user2"] as! PFUser returns error ambiguous subscript. I looked at other answers here about this issue so I tried to change it to let user = )(gameResults[indexPath.row]["user2"] as NSArray) as! PFUser but that didn't work.
How can I get this to work? Thanks!!
UPDATE:
I added an exclamation mark after the subscript and it seemed to get rid of the error. Like this:
let user = gameResults[indexPath.row]["user2"]! as! PFUser
Is this an acceptable way of fixing this?
Related
I'm not that much of a pro in using swift..but i've been trying to create an social media app using firebase as backend. But I am stuck in this one part where the data gets stored in an Array..but when . i call the array I keep getting the "Ambiguous reference to member 'count' " error and I have tried many ways to fix this but end up unsuccessful every time
var posts = [AnyObject?]()
override func viewDidLoad() {
super.viewDidLoad()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: HomeViewTableViewCell = tableView.dequeueReusableCell(withIdentifier: "HomeViewTableViewCell", for: indexPath) as! HomeViewTableViewCell
let post = (posts[(self.posts.count - 1) - indexPath.row] as AnyObject).value["text"] as! String //**Ambiguous reference to member 'count'
cell.configure(nil,NameText:self.loggedInUserData!.value["NameText"] as! String, TitleText:self.loggedInUserData!.value["TitleText"] as! String, post:post)
return cell
}
Please help!
Actually trying this tutorial out in Youtube...So if full code required, This is the YouTube link:
https://www.youtube.com/watch?v=BeZ3i7-gaok&list=PLy9JCsy2u97kro0jXbXrPFmT-DQVAmNW0&index=4
you might want to use value(forKey:) here
let post = (posts[(self.posts.count - 1) - indexPath.row] as AnyObject).value(forKey: "text")
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("nameCell", forIndexPath: indexPath)
let pancakeHouse = pancakeHouses[indexPath.row]
if let cell = cell as? FAQsViewCell {
cell.pancakeHouse = pancakeHouse
} else {
cell.textLabel?.text = pancakeHouse.que
}
return cell
}
I got error in this function of UITableViewController when I run my project at that time I got it I can't understand why it came or what is its meaning.
The "definition conflicts with previous value" occurred also when you forgot to set the Cell Identifier
Make sure you have set the correct identifier to your custom cell (in your case "nameCell") :
I'm developing a UIViewController with 2 TableView, following Swift specification I created a class with UITableViewDelegate and UITableViewDataSource interfaces for managing TableViews.
class CurrencyController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var valute = [NSManagedObject]()
var categoria = [NSManagedObject]()
//....
}
I wrote the func to support rearranging TableView:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if tableView == self.tabCurrency{
//
let cell = tableView.dequeueReusableCellWithIdentifier("currencyRow", forIndexPath: indexPath) as! CurrencyCell
let thisElem = valute[indexPath.row]
cell.curName.text = thisElem.valueForKey("valuta") as! String? //This code generates the exception
let elem = thisElem.valueForKey("cambio") as! Double? //This code generates the exception
cell.rateCur.text = "\(elem!)"
return cell
}else{
//
let cell = tableView.dequeueReusableCellWithIdentifier("categoryRow", forIndexPath: indexPath) as! CategoryCell
let thisElem = categoria[indexPath.row]
cell.catName.text = thisElem.valueForKey("cat_name") as! String? //This code generates the exception
return cell
}
}
This code generates unexepctedly found nil while unwrapping an Optional value but using the PO command I saw that variable didn't contain nil values...
Any idea? Thank you in advance
UPDATE:
I wrote the declaration of "valute" and "categoria" objects.
It seems:
this.valueForKey("cambio")
should be:
thisElem.valueForKey("cambio").
this -> thisElem
Ok I saw what I did wrong: I didn't link my CategoryCell and CurrencyCell classes with the Prototype Cell in the Storyboard.
CategoryCell and CurrencyCell are my classes that extend UITableViewCell in order to manage all cells of tho TableView.
Now I link these classes with storyboard properly and now it works fine!
I get this error when the ViewController loads.
I don't know, what I can do
The loadDataFromDb function is this
func loadDataFromDb() {
let fetchRequest = NSFetchRequest(entityName: "Chats")
daten = self.context!.executeFetchRequest(fetchRequest, error: nil) as! [Model]
tableView.reloadData()
}
I googled that error but nothing helped me
dequeueReusableCellWithIdentifier returns an optional that might be nil.
Your force casting to UITableViewCell, by using as! makes it so that the nil gets casted to UITableViewCell and you end up calling a method on nil, which leads to the exception.
Try unwrapping the cell, by using if let before using it or better yet use dequeueReusableCellWithIdentifier(_ identifier: String,
forIndexPath indexPath: NSIndexPath) -> AnyObject , which doesn't return an optional.
Also as a whole, try staying away from ! and refrain from using it, unless you absolutely have to.
Edit:
Here's one way to do it
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as? UITableViewCell {
cell.textLabel?.text = "Text"
return cell
}
return UITableViewCell()
}
I'm trying to use Realm in my UITableViewController and I'm running into issues whenever I try to find the object at a row index if I cast the object to its class (forgive me if I'm using the wrong terminology, I'm still pretty new to Swift, Realm ans iOS dev!)...
I have a Site class which looks like this, and the database has a few thousand entries:
class Site: RLMObject {
var id: String = ""
var name: String = ""
}
In my table view controller, when I try to fetch a Site based on its index in the result set to load into a cell, if I try to cast it to a Site object it's always nil! If I let it be set using AnyObject, then I can see that the correct site at that index has indeed been found.
I'm guessing the .name call on AnyObject is only working because AnyObject responds to .name, but it helps me to see that the index is correct and that the site does exist...
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
let allSites = Site.allObjects()
var any: AnyObject = allSites.objectAtIndex(UInt(indexPath.row))
var site = allSites.objectAtIndex(UInt(indexPath.row)) as? Site
println("With AnyObject: \(any.name)")
println("With casting: \(site?.name)")
return cell
}
The result of the print statements above look like this (for example on a site which is named 'Addeboda'):
With AnyObject: Addeboda
With casting: Optional("")
Am I doing something wrong? I've googled around a bit, and all the tutorials and answers I can find along similar lines suggest that results.objectAtIndex(index) as Class should be the right approach.
No cast needed
It seems that casting to Site is not needed. This works fine:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
let allSites = Site.allObjects()
let site: AnyObject! = allSites[UInt(indexPath.row)]
cell.textLabel!.text = site.name
println("Site is: \(site.id)")
return cell
}
Seems to be a bug with either Swift or Realm. I'm guessing one of them gets confused when downcasting AnyObject! to something.
Initializing a new instance with correct type
However, if you really need to use the Site model class you can initialize a new RLMObject from the result:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
let allSites = Site.allObjects()
let site = Site(object: allSites[UInt(indexPath.row)])
cell.textLabel!.text = site.name
println("Site is: \(site.id)")
return cell
}
First try
It is unfortunate to hear that you are having issues with Realm and Swift. I am by no means a Swift pro, but it looks like you are casting site to an optional, and the result of using the optional cast operator site?.name is also an optional. Hence getting Optional("").
Can you try to see if you have any better luck with the following?
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
let allSites = Site.allObjects()
if var site = allSites[UInt(indexPath.row)] as? Site {
println("Site is: \(site.name)")
} else {
println("it not castable to Site. It is: \(toString(allSites[UInt(indexPath.row)].dynamicType))")
}
return cell
}
Also, you can use yourObject.dynamicType to get a reference to the objects real class type.
Best of luck
Here is some code from the tableview sample project:
class TableViewController: UITableViewController {
var array = DemoObject.allObjects().sortedResultsUsingProperty("date", ascending: true)
...
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as Cell
let object = array[UInt(indexPath.row)] as DemoObject
cell.textLabel?.text = object.title
cell.detailTextLabel?.text = object.date.description
return cell
}
}
You should be able to cast on the line you are storing that indexPath.row object