Swift Spritekit setvalue - swift

In swift with spritekit I want to set a variable of a sprite so I tried to say
p.setValue(value: (String(c)), forKey: "co")
But this gives an error.
So the main question is:
How can i set a key value pair in a sprite to a string
as a key and an int/string as a value?

setValue(_:forKey:) and related methods aren't for associating arbitrary key/value data with an object. They're part of Key-Value Coding, a Cocoa feature that does all sorts of handy things — but unless a class does something special with KVC, all setValue(_:forKey:) does is let you set one of that class's declared properties using a string instead of by directly accessing a property. In other words, the two lines below are equivalent:
node.name = "foo"
node.setValue("foo", forKey: "name")
If you want to associate arbitrary key-value pairs with your sprites—which can be a great way to keep track of entities in your game—use the userData property.

To use setValue:forKey: you need to have (a) a valid key, and (b) a value of the correct type for that key. For example:
mySprite.setValue(UIColor.redColor(), forKey: "co") // error, "co" isn't a valid key
mySprite.setValue("red", forKey: "color") // error, "color" needs a UIColor value
mySprite.setValue(UIColor.redColor(), forKey: "color") // works!
What value and key are you actually using?

Related

How do put multiple values into a single key in Swift?

Is there a way to put multiple values in one key in Swift's dictionary, such as 'multimap' in Java?
var multiDic = [String:UserData]()
This is the dictionary I declared. it has this structure.
struct UserData{
var name: String
var id: String
var nickname: String
}
And when I put the value in one key in the dictionary, the value is updated without being stacked.
for key in 1...10 {
multiDic.updateValue(UserData(name:"name+\(key)", id:"id+\(key)", nickname:"nick+\(key)"), forKey: "A")
}
print(multiDic.count)
reults
1
How can I accumulate multiple values on a single key? I looked up a library called 'Buckets'
(https://github.com/mauriciosantos/Buckets-Swift#buckets), but there has been no update since swift 3.0.
Swift dictionary doesn't support this. One work around is to declare the dictionary to hold an array of values, like this:
var multiDic = [String:[UserData]]()
You would have to modify your code for adding values to work with the array instead of updating the value in place.
I haven't tried the "Buckets" project you mention, but for what it's worth, it probably still works either as-is or with minor changes.

Add New Key/Value to Dictionary

I have a dictionary of type [String: [String]] and is loaded as blank [ : ].
Is there a way I can append a value to the array associated to a new string key? (i.e. exampleDict["test"].append("test"))
When I print out the dictionary after attempting this, I am returned [ : ], which I believe is because the key does not exist and returns as nil.
Swift has a neat "default" feature for doing things exactly like this.
exampleDict["test", default: []].append("test")
If exampleDict["test"] is nil, the default is returned instead. If you modify the returned default object, that modification goes into the dictionary.
Unfortunately this only works properly for value types, since classes aren't reassigned when they're mutated. Fortunately, Array is a value type, so this will work perfectly here.
You have to use Dictionary.subscript(_:default:).
exampleDict["test", default: []].append("test")

How to directly add a key-value pair to a dictionary with "Cannot assign to immutable expression of type" error?

I have a dictionary that contains a JSON object. I'm trying to directly manipulate that dictionary to add a key-value pair. However, I am getting the Cannot assign to immutable expression of type Any error.
I know that the value of Any is immutable, it cannot be changed. I managed to obtain a reference to it to store it in a different dictionary and applied a key-value pair there, but I like to change the original dictionary to reduce code repetition.
Currently this is the output of the dictionary:
dict = ["Object":
[ ["number_1": -117.13,
"number_2": 32.91,
"link": http://www.google.com]
]
]
What I'm trying to do is the following:
( (dict["Object"] as! [Dictionary<String, Any>])[0] as! Dictionary<String, Any>)["image"] = UIImage(named: "")
I'm trying to add "image" as another key with a UIImage as the value, but I can't due to Any being an immutable type.
How can I directly manipulate dict to add a key-value pair?
FYI: dict is declared as a var, not let

NSUserDefault critical coding in ios9 swift?

I am following a tutorial in which I am saving data in a NSUserDefault type having the following code. It has comments but I can't get what's happening over here-
var todoDictionary = NSUserDefaults.standardUserDefaults().dictionaryForKey(ITEMS_KEY) ?? Dictionary() // if todoItems hasn't been set in user defaults, initialize todoDictionary to an empty dictionary using nil-coalescing operator (??)
todoDictionary[item.UUID] = ["deadline": item.deadline, "title": item.title, "UUID": item.UUID] // store NSData representation of todo item in dictionary with UUID as key
NSUserDefaults.standardUserDefaults().setObject(todoDictionary, forKey: ITEMS_KEY)
NSUserDefaults.standardUserDefaults().setObject(todoDictionary, forKey: ITEMS_KEY)
So what's actually happening here can anyone please explain a bit.
What is the ITEMS_KEY doing here ?
Line 1 is retrieving a dictionary from the UserDefaults with key ITEMS_KEY, when that fails, it instantiates an empty Dictionary(). That is what the null-coalescing operator means. ITEMS_KEY is a property you might have set somewhere (a constant).
Line 2 is setting a key-value to the dictionary.
Line 3 is writing the dictionary back to the NSUserDefaults.
Line 4 is double? Not sure if that is right.

Setter for dictionary property - OR: get last added item from dictionary

I have a custom class with different computed properties. One of them is a Dictionary of [String: String]. The getter is no problem, but I don't know how to use the setter: How can I figure out, what was the last value added to the dictionary? Obviously newValue.last doesn't exists (.first does!).
EDIT:
This seems to work:
var myProp: [String: String] {
get { ... }
set {
let lastVal = newValue[newValue.startIndex.advancedBy(newValue.count-1)]
...
}
BUT: will this always return the last added value?
EDIT 2
The first edit is wrong. A dictionary is unordered and with this way it's not sure, if it really returns the last added key and value. See my answer below.
As you point out, a Dictionary is an unorderd collection of key-value pairs, so there is no last getter (first is just a convenience for what in Objective-C was more appropriately called anyObject) . The Dictionary also does not keep track of the order items were added.
To get the last item, there are two possibilities. You could refactor to use an array, e.g. of tuples (key, value); or you could keep track of the last item added in a separate variable.
But maybe there is a misunderstanding about the "setter". A setter sets the entire object.
set { myProp = newValue }
So if you have a myProp = ["foo": "bar"], the entire dictionary in myProp is overwritten with this data.
What you want is to add a key to the property. In Swift, this is done by subscripting.
myProp["foo"] = "bar"
You do not have to implement anything special in the get closure.
Note that you have to remember two things, though: first, the dictionary has to be properly initialized; second, any existing item will be overwritten if the new value uses the identical key.
I understand now... the dictionary is unordered. To really get the last added value, I have to compare the value itself with the newValue. The working code:
var myProp: [String: String] {
get { // doing things to read the things and add them to a dictionary }
set {
var new = newValue
for (key, value) in myProp {
if new[key] == value {
new.removeValueForKey(key)
}
}
// now 'new' should only have one key and one value, that one, that just was added
}
}