following this tutorial... here
for (index, labelText) in stringData.enumerate() {
let row = myTable.rowControllerAtIndex(index)
as! MyRowController
row.myLabel.setText(labelText)
getting an error message that says:
Value of type '[String]' has no member 'enumerate'
is there a Swift code update change?
That's a really old tutorial, the function you're looking for is called enumerated now.
for (index, labelText) in stringData.enumerated() {
...
}
Related
I'm trying to create a set of random exercises. I have made my struct Hashable and Equatable following the tutorial here https://medium.com/#JoyceMatos/hashable-protocols-in-swift-baf0cabeaebd and that is working fine so it's ready to be put in a Set<>.
When I use an Array to collect the workout exercises, as per below, it works fine. But when I switch to a Set<> I get an error "cannot convert value of type [_] to specified type 'Set'. What is it about 'Sets' that mean you can't map in the same way as an Array?
func generateWorkout() {
let allPossibleExercises = masterExerciseArray
let numberOfExercisesKey = Int(arc4random_uniform(4)+3)
//error triggers on the line below if I switch [WorkoutExercise]
//for Set<WorkoutExercise> (which conforms to Hashable/Equatable
let workoutSet : [WorkoutExercise] = (1...numberOfExercisesKey).map { _ in
let randomKey = Int(arc4random_uniform(UInt32(allPossibleExercises.count)))
return WorkoutExerciseGenerator( name: allPossibleExercises[randomKey].name,
maxReps: allPossibleExercises[randomKey].maxReps).generate()
}
print (workoutSet)
}
There is an answer here with a similar error message Cannot convert value of type '[_]' to specified type 'Array' but my array wouldn't be empty as in this example so I don't think this is the same root cause?
UPDATE : for anyone having the same problem, you can use Array but then simply convert the Array to a Set afterwards if the correct elements are Hashable/Equatable
If creating the array works create the array and then make the Set from the array. If all involved objects conform to Hashable this is supposed to work.
func generateWorkout() {
let allPossibleExercises = masterExerciseArray
let numberOfExercisesKey = Int(arc4random_uniform(4)+3)
let workoutArray : [WorkoutExercise] = (1...numberOfExercisesKey).map { _ in
let randomKey = Int(arc4random_uniform(UInt32(allPossibleExercises.count)))
return WorkoutExerciseGenerator( name: allPossibleExercises[randomKey].name,
maxReps: allPossibleExercises[randomKey].maxReps).generate()
}
let workoutSet = Set(workoutArray)
print (workoutSet)
}
Confused as to why getting error "Cannot subscript a value of type 'inout [[String]]' (aka 'inout Array>'). Within a working table view class
(Originally followed Jared Davidson tutorial https://www.youtube.com/watch?v=pR6dR-vVZeY)
var secondArray = [SecondTable]()
let latest = ViewController().getArrayListLast()
var latestClass = latest.getFullClasses()
print(latestClass[0])
for i in 0...(latest.getAssetClasses().count)
{
if SecondTable(secondTitle: latestClass[i]) != nil
{
secondArray = secondArray.append(SecondTable(secondTitle: latestClass[i]))
}
}
append(_:) is mutating function and it doesn't return anything.
Now your code making 3 more mistakes.
As #vadian mentioned in comment ViewController() will never work when using storyboard.
It will give you run time crash index out of bounds because you have provide for loop till the array count but it should be till the less one of the array count, so it should like for i in 0..<(latest.getAssetClasses().count)
You are creating two times object with init of SecondTable to just check for the nil instead of that you can use if let.
if let secondTable = SecondTable(secondTitle: latestClass[i]) {
secondArray.append(secondTable)
}
I am trying to attach data to a UITableView. I have download the project form here and am using the code where data is attached to the tableView: http://yannickloriot.com/2016/01/make-uitableview-reactive-with-rxswift/:
Firstly I have created the following variable:
let currentQuestion: Variable<Taxi?> = Variable(nil)
I then try to do the following:
currentQuestion
.asObservable()
.bindTo(tableView.rx_itemsWithCellIdentifier("ChoiceCell", cellType: ChoiceCell.self)) { (row, element, cell) in
cell.choiceModel = element
}
.addDisposableTo(disposeBag)
But I am getting the following warning: 'Extra argument in call' on the line .bindTo. I have tried adding a new cell and get the same result. Not sure if it is relevant, but I have registered the cell.
I have read here that you can get this warning if the types of the arguments don't match: Swift - Extra Argument in call . However it looks like the arguments match fine.
I am new to Rx and was hope someone could help me understand what might be going wrong here. Thanks.
======
Edit
Here is my new code. I have tried rx_itemsWithCellIdentifier("ChoiceCell") alone and rx_itemsWithCellIdentifier("ChoiceCell", cellType: ChoiceCell.self):
let currentQuestion = Variable<[Taxi]>(taxis)
currentQuestion.asObservable()
.bindTo(tableView.rx_itemsWithCellIdentifier("ChoiceCell")) {(row, element, cell) in
cell.choiceModel = element
}.addDisposableTo(disposeBag)
Where I have used (taxis), it is an array of taxi items. See picture below:
Also once I have called .asObservable(), I have the following:
I managed to print these out by removing the line .bindTo. If I add that line back I get the same error as before.
IMPORTANT: I played around with code base from article I linked to earlier. If I remove from ChoiceCell I can replicate the same error:
// var choiceModel: ChoiceModel? {
// didSet {
// layoutCell()
// }
// }
From experience the extra argument in call message is most often given when you are trying to bind a variable with the wrong expected data type. The first issue is that you are trying to bind a single instance of Taxi to the tableview which is expecting a sequence of observables.
/**
Binds sequences of elements to table view rows.
- parameter cellIdentifier: Identifier used to dequeue cells.
- parameter source: Observable sequence of items.
- parameter configureCell: Transform between sequence elements and view cells.
- parameter cellType: Type of table view cell.
- returns: Disposable object that can be used to unbind.
*/
public func rx_itemsWithCellIdentifier<S : SequenceType, Cell : UITableViewCell, O : ObservableType where O.E == S>(cellIdentifier: String, cellType: Cell.Type = default) -> (source: O) -> (configureCell: (Int, S.Generator.Element, Cell) -> Void) -> Disposable
It doesn't seem like the issue is caused by the optional object but I don't see why you would want to bind optional objects to the tableview, so I would advice you to avoid that too. Here is an example which would work.
let currentQuestion = Variable<[Taxi]>([Taxi()])
currentQuestion.asObservable().bindTo(tableView.rx_itemsWithCellIdentifier("ChoiceCell")) {(row, element, cell) in
cell.choiceModel = element
}.addDisposableTo(disposeBag)
Thanks to Philip Laine answer above: https://stackoverflow.com/a/36536320/2126233
That helped me see that I was making a mistake in regards to what I was observing. It helped me to see the problem I was having in my code.
If you just want to bind to a normal tableViewCell then you need to use tableView.rx_itemsWithCellFactory:
currentQuestion.asObservable()
.bindTo(tableView.rx_itemsWithCellFactory) {(tableView, row, item) in
let cell = UITableViewCell()
cell.textLabel?.text = item.distance
return cell
}.addDisposableTo(disposeBag)
If you are using a custom cell then you can use tableView.rx_itemsWithCellIdentifier("ChoiceCell", cellType: ChoiceCell.self). Here is an example:
currentQuestion
.asObservable()
.filter { $0 != nil }
.map { $0!.choices }
.bindTo(tableView.rx_itemsWithCellIdentifier("ChoiceCell", cellType: ChoiceCell.self)) { (row, element, cell) in
cell.choiceModel = element
}
.addDisposableTo(disposeBag)
For me I was still getting this same error unless I had a property inside the tableView cell that matched the element that was coming out of the array I was binding the tableView to.
So if you have an array of [Taxis] like so then inside the tableViewCell I required a variable that stored a Taxis. Then I was able to compile my project.
So in ChoiceCell I have a var like so:
var taxi: Taxi? {
didSet {
layoutCell()
}
}
I hope this helps anyone else having issues binding a tableViewCell to an array.
Well, this is a late answer but here is your problem. If this can help others to understand it.
You have an array of Taxi elements
when rx_itemsWithCellIdentifier() is called, element is a Taxi (of course, it is an element of the array)
But in your code you do:
cell.choiceModel = element
// Where
var choiceModel: ChoiceModel? {
didSet {
layoutCell()
}
}
So, you are trying to assign a Taxi to a ChoiceModel. This is why your are getting this error. Swift type inference determines that the types mismatch. You can try to comment the line inside the block and the error should disappear.
Several SO posts like this deal with the same error message, but none of those solutions work. It appears like this could be a case of a misleading error message.
The code below generates an "Ambiguous reference to member map" error for the map call.
Anyone know why?
func saveUser(user: User) {
var userDicts = masterDict["users"] as! [[String:AnyObject]]
let newDict = user.getDict()
// Replace matching element with <newDict>
let replaced = false
masterDict["users"] = userDicts.map {
if ($0["id"] as String! == user.getId()) {
replaced = true
return newDict
} else {
return $0 as [String:AnyObject]
}
}
// If no match found, means must add new user
if (!replaced) {
userDicts.append(newDict)
}
}
Unfortunately, swift is not perfect and can not infer types at all times, this is why you are getting the ambiguous reference. Try userDicts.map {val -> [String:AnyObject] in and swap out $0 for val This will explicitly tell the map that the values coming in are [String:AnyObject], and should be able to return said type
Never isolated the cause of the error so switched to using a for loop, creating a new array inside the loop, and calling masterDict["users"] = newArray after the loop. Not the cleanest, but it fixes the error.
I am trying to create an OSX Swift app with Firebase. I can write to Firebase following the examples, but is not able to read the data back correctly. I have tried using the .Value listener and println(snapshot.value), it appears that the value returned is not correct.
let userRoot = "https://inkcloud.firebaseio.com/users/" + user
ref = Firebase(url:userRoot)
ref!.observeEventType(.ChildChanged, withBlock: { snapshot in
let result = snapshot.value.objectForKey("test") as? String
println("the result is \(result)")
}, withCancelBlock: { error in
println(error.description)
})
I get compiler error: '() -> AnyObject!' does not have a member named 'objectForKey'
Any help would be appreciated.
Ben
Found the soluiton, need to use functions calls instead of property.