Swift Dictionary array - swift

I am using Swift 1.2 and trying to get the correct syntax for this declaration that comes from a previous version of Swift:
var dataSource: Dictionary<String, String> [][] = [[],[]]
The error I get is :
Array types are now written with the brackets around the element type.
I just don't know how to correct it.

The syntax has changed since then. As your error reads:
Array types are now written with the brackets around the element type.
So instead of Dictionary<String, String>[][] you wrap the brackets around the type for example [[Dictionary<String, String>]] or using shorthand syntax: [[[String: String]]]:
var dataSource: [[[String: String]]] = [[],[]]

Related

Can't assign value of type Dictionary to LazyMapCollection

I am working on an application and I am relatively new to Swift where I am trying to initialize answerKeys with the keys of answer variable with the following code but it is showing an error.
Cannot assign value of type 'Dictionary<IntPoint, String>.Keys' to type 'LazyMapCollection<Dictionary<IntPoint, String>, IntPoint>' (aka 'LazyMapSequence<Dictionary<IntPoint, String>, IntPoint>')
I have gone through the documentation but couldn't fix this.
var answer:[IntPoint:String] = [:]
var answerKeys:LazyMapCollection<Dictionary<IntPoint,String>,IntPoint>
init() {
answerKeys = answer.keys
}
It may be that Dictionary.keys returned a LazyMapCollection in earlier Swift versions. In Swift 5 it is Dictionary<Key, Value>.Keys as can be seen from the documentation, in your case
var answerKeys: Dictionary<IntPoint, String>.Keys
But note that you can always access answer.keys in your code instead of assigning this to a separate property.

Type "Any" has no subscript members despite casting as AnyObject on Swift 3?

Recently converted code from earlier version of swift to swift 3. Got a lot of errors signifying that type "any" has no subscript members and I thought this could be fixed by casting as AnyObject, but the error persists (and therefore the code I post here does not have this cast in it). Here is the relevant code:
func textfieldTextWasChanged(_ newText: String, parentCell: CustomCell) {
let parentCellIndexPath = tblExpandable.indexPath(for: parentCell)
var address = ""
address = "\(newText)"
// TODO: add a pin to the map from input address
cellDescriptors[0][11].setValue(address, forKey: "primaryTitle")
location = cellDescriptors[0][11]["primaryTitle"]! as! String
tblExpandable.reloadData()
}
Note that cellDescriptors is defined earlier in the code as an NSMutableArray. The error shows up right after cellDescriptors[0] in both lines that it is in. Not sure how to fix this.
It's because you're using more than one subscript operator, because presumably this is something like an array of arrays. But NSMutableArray's subscript operator returns Any. As a result, cellDescriptors[0] is Any. You try to use [11] on the result, but Any doesn't accept subscripts because it's Any, not a collection type.
Casting to AnyObject doesn't help because AnyObject is also not a collection type.
What you should do is cast cellDescriptors[0] to something that accepts subscripts. The right choice depends on what kind of data you're storing in cellDescriptors, but it's presumably some kind of collection, probably an array type.
Another approach would be to change cellDescriptors to be a Swift type instead of NSMutableArray. You could specifically declare the types for each part of your data structure, and then type casting wouldn't be needed.

Cannot convert value of type 'Int' to expected argument type '_?'

Note: I'm a rookie in Swift
I'm using Former.
I'm fetching data from a realm model.
let industries = realm.objects(Industry)
Then I try to define a list of InlinePickerItem from it:
$0.pickerItems = industries.map({ industry in
return InlinePickerItem(title: industry.name, value: industry.id)
})
But XCode keeps saying: Cannot convert value of type 'Int' to expected argument type '_?', pointing to industry.id.
Am I missing something? I don't know if the issue comes from Former or from something that I don't understand in Swift. For example, what kind of type is _??
UPDATE:
After #dfri comment, attempt was unsuccessful. From my small understanding of Swift, I get that Swift gets lost. So I extracted the initialisation of the list of InlinePickerItem from the closure.
let industries = realm.objects(Industry)
let inlinePickerItems = industries.map({ industry in
return InlinePickerItem(title: industry.name, displayTitle: nil, value: industry.id)
})
let catRow = InlinePickerRowFormer<ProfileLabelCell, String>(instantiateType: .Nib(nibName: "ProfileLabelCell")) {
$0.titleLabel.text = "CATEGORY".localized
}.configure {
$0.pickerItems = inlinePickerItems
}
The error is disappeared when calling InlinePickerItem(title: industry.name, displayTitle: nil, value: industry.id) but I get something new when assigning it to $0.pickerItems which now is:
Cannot assign value of type '[InlinePickerItem<Int>]' to type '[InlinePickerItem<String>]'
Hope this will provide you with some helpful hints.
Type mismatch when assigning array to different type array
After the re-factoring of your code (after "update") its now apparent what is the source of error.
Immutable catRow is of type InlinePickerRowFormer<ProfileLabelCell, String>. From the source of [InlinePickerRowFormer] we see the that the class and its property pickerItems is declared as follows
public class InlinePickerRowFormer<T: UITableViewCell, S where T: InlinePickerFormableRow>
: ... {
// ...
public var pickerItems: [InlinePickerItem<S>] = []
// ...
}
The key here is that for an instance InlinePickerRowFormer<T,S> its property pickerItems will be an array with elements of type InlinePickerItem<S>. In your example above S is String
let catRow = InlinePickerRowFormer<ProfileLabelCell, String>
/* |
S = String */
Hence pickerItems is an array of InlinePickerItem<String> instances.
You try, however, to append the immutable inlinePickerItems to pickerItems, which means you're trying to assign an array of InlinePickerItem<Int> instances to an array with elements of type InlinePickerItem<String>; naturally leading to a type mismatch.
You can solve this type mismatch by:
Setting your catRow immutable to be of type InlinePickerRowFormer<ProfileLabelCell, Int>.

Syntax to create Dictionary in Swift

As far as I know there are two ways to create an empty dictionary in swift
var randomDict = [Int:Int]()
or
var randomDict = Dictionary<Int, Int>()
Is there any difference between these? Both versions seems to work just the same.
No, both are same.
From Apple's Book on Swift:
The type of a Swift dictionary is written in full as Dictionary<Key, Value>
You can also write the type of a dictionary in shorthand form as [Key: Value]. Although the two forms are functionally identical, the shorthand form is preferred.
So
var randomDict = [Int:Int]()
and
var randomDict = Dictionary<Int, Int>()
both calls the initializer which creates an empty dictionary and are basically the same in different form.
A third way you could do it is:
var randomDict:[Int:Int] = [:]
They're all equivalent as far as the code goes. I prefer one of the shorthand versions.

Set<NSObject>' does not have a member named 'allObjects'

With the original swift I could turn an NSSet (e.g. of Strings) into a typed array with the following syntax:
var stringArray = exampleSet.allObjects as [String]
With the new update I am getting the above error. What is the best way now to convert the Set into an array?
It looks as if your exampleSet is not an NSSet but a native
Swift Set which was introduced with Swift 1.2 (compare https://stackoverflow.com/a/28426765/1187415).
In that case you can convert it to an array simply with
let array = Array(exampleSet)
Looks like 'set' is a keyword. Try using a different variable name