I need some help with NSMutableDictionary inside NSArray in Swift 3.0. The structure is an Array of Dictionaries
This is my code
class abc{
var myTempArr : NSArray!
}
// I need objC variables as I need to pass them as reference
someMethod(){
myTempArr = [["title":"abc","id":"1"]] // creating a dictionary inside the array
// I have changed the value like this also, but the crash remains
// [["title":"abc","id":"1"] as! NSMutableDictionary]
}
// This method is called in every key stroke in keyboard. Lets say we replace the "title", with the letter in the keyboard it is tapped
func someotherMethod(){
let firstDictionary = myTempArr[0] as! NSMutableDictionary
// Its crashing here!!!!
// Again i need nsmutabledictionary as i need to change the value
// inside the dictionary so that the value inside the main array
// that is myTempArr also changes. I need a pass by reference
// method, hence i choosed NSMutableDictionary instead of swift dictionary
firstDictionary["title"] = "New Title"
// After this line, the original dictionary inside myTempArr
// should change as well. But its crashing in the mentioned line
}
I dont want to use class instances as I know they are also pass by reference but I need to apply Predicate to finding the correct dictionary inside the array, instead of searching by index. This is also a concept I cannot understand. Please help me figure this out.
The crash says :
Could not cast value of type 'Swift._SwiftDeferredNSDictionary' (0x7facdb71e6c0) to 'NSMutableDictionary' (0x102bfa350).
[EDIT]
As many people are suggesting the option of getting the Dictionary in a variable, changing the variable and then replacing the dictionary in the array. Well this approach I want to avoid, as this would be the same as using value based solution (Swift Dictionary where its passed by value). The reason I want to avoid this is because, the original DS I am using has a huge number of dictionaries and values of dictionary are changing very often. Hence I dont think using the replace Dictionary approach would be sound.
Also I know in swift this is not good, as swift was NOT designed for this. This approach works perfectly fine in Objective C, as we changing variables (cue : Pointers of variables), changes the variable it was originally from. If anyone can suggest an alternate or good approach in Swift, then please It would be awesome.
Also for the sake of simplicity I have used an index of 0. as there is only 1 dictionary. But in the original DS, there are a lot of dictionaries as I mentioned, hence I am using predicate. This is also a reason why I didnt use instance of a class (also pass by reference in swift), as I dont know if instances of class behave like dictionaries when we search them by Predicate.
Any solution or alternative is highly welcome. As always thank you guys for giving time to this, as I am trying to wrap my head around how to go for a new approach
I would suggest that a dictionary is probably the wrong data structure to store in your array. You have indicated that the dictionaries represent some sort of form fields. You can create an object to model these fields and then take advantage of the mutability of objects while still using immutable arrays.
Something like:
class Field {
let id: Int
let name: String
var value: String
init(id: Int, name: String, value: String = "") {
self.id = id
self.name = name
self.value = value
}
}
let firstNameField = Field(id:1, name:"FirstName")
let surnameField = Field(id:2, name:"Surname")
firstNameField.value = "Paul"
var fieldsArray = [firstNameField,surnameField]
firstNameField.value = "Peter"
print(fieldsArray[0].value) // Prints Peter
if let field1 = fieldsArray.first(where:{ $0.id == 1} ) {
print(field1.value) // Prints Peter
field1.value = "John"
}
print(fieldsArray[0].value) // Prints John
Note that since Field
is a class we were able to use reference semantics and never had to mutate the array, so there were no copy on modify operations on the array.