My class has a property
var activeSquares = Dictionary <String, SKShapeNode> ()
I try to add and update values in the dictionary using
let squareNode = SKShapeNode(rectOfSize: CGSizeMake(80, 80), cornerRadius: 8)
activeSquares.updateValue(squareNode, forKey: "someUniqueDescription")
I also get the same crash if I use
activeSquares["someUniqueDescription"] = squareNode
But it is causing a crash when compiling
1. While emitting IR SIL function #_TFC14gamename9GameScene11addedSquarefS0_FCS_6SquareT_ for 'addedSquare' at /.../gamename/gamename/GameScene.swift:30:5
<unknown>:0: error: unable to execute command: Segmentation fault: 11
<unknown>:0: error: swift frontend command failed due to signal (use -v to see invocation)
Command /Applications/Xcode6-Beta2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 254
How do I properly use updateValue to add/update key/value pairs to my dictionary?
No sure if my solution fits here, but it could help. Seems there's something weird with subscription for NSDictionary. Not sure why, but it's defined as:
func objectForKeyedSubscript(key: NSCopying!) -> AnyObject!
so, if I'm not wrong it returns implicitly unwrapped optional, but should return optional, as far as there could be no value for a key. If you try to write:
if(dictionary["key"] != nil)
you'll get a compile error "AnyObject is not convertible to UInt8" while if you write:
if(dictionary["key"])
you don't get one.
The way I solved this issue was using optional unwrapping, so:
if(someBool && dictionary["key"]) // fine in beta 2, crash in beta 3-4
// turned to:
var hasValueForKey = false
if dictionary["key"]
{
hasValueForKey = true
}
if(someBool && hasValueForKey) // fine in beta 4
and:
var someArray : NSArray? = dictionary["key"]? as? NSArray // note ? after []
I guess there could be something with optionals and stuff for setting an object via subscript, it's defined as:
func setObject(obj: AnyObject!, forKeyedSubscript key: NSCopying!)
Maybe playing with optional unwrapping could help here as well.
Related
I receive several crash reports:
Bugsnag:
VC.swift:290:34
Swift runtime failure: Unexpectedly found nil while implicitly unwrapping an Optional value
Apple Crash:
Line 290 has following code
func showFolders(path:String, topLevel:Bool = false, absolutePath:String) {
print("đź“‚ Get folder: " + path)
NetworkingService.shared.webdav.contentsOfDirectory(path: path, completionHandler: {
some code
})
}
The function 'showFolders' is called by following code which avoids to send any optional value:
let path = browser_relativePath?.absoluteString.removingPercentEncoding ?? ""
let topLevel = NetworkingService.shared.url_connected.hostOnly.withTrailingSlash == browser_absolutePath?.absoluteString
let absolutePath = browser_absolutePath?.path ?? ""
self.embeddedViewController.showFolders(path:path, topLevel: topLevel, absolutePath: absolutePath)
I don't understand how this might crash by "unwrapping an optional" when there is no optional in that part of the code... But I am probably blind ;-)
Can someone help me out ?
The clue is it says when implicitly unwrapping… so either NetworkingService.shared or NetworkingService.shared.webdav is declared as implicitly unwrapped and is nil when you call it
Swift 5, Xcode 11
I have a bunch of Realm queries in my app that filter based on the presence of an Optional object.
For example:
//Class property
var currentWorkspace: Workspace?
//In viewDidLoad()
let objects = realm.objects(Entry.self).filter("workspace = %#", currentWorkspace)
I see the warning:
Expression implicitly coerced from 'Workspace?' to 'Any'
...with some proposed solutions:
I've tried setting a default value and casting to Any but that's not really what I want. The only way I've found to get rid of the warning is to guard the currentWorkspace variable:
guard let workspace = currentWorkspace else { return }
Why can't I leave currentWorkspace as an Optional? Is this warning only because of the string interpolation that's going on?
Swift 2.1 code which worked without any problem:
let userDetail = response["params"]?["users"]
I updated to Xcode 7.3 which runs Swift 2.2. And it's start to complain on same above line.
It complains like:
Value of optional type AnyObject? not unwrapped; did you mean to use '!' or '?' ?
When I auto corrected xcode suggestion it is giving me following code as a corrected one:
let userDetail = response["params"]?!["users"]
Here response is of type AnyObject?
I dont want to forcefully unwrap an optional here.
Does anybody know what's the problem here? And what has changed about optionals in Swift 2.2 which is giving me this error.
For a dictionary [K: V], the return type of the subscript is V?, and thus in your case the return type of response["params"] is AnyObject?? since V == AnyObject?. To recover an AnyObject to need to unwrap twice:
// swift 2.2 only:
// v
let userDetail = response["params"]??["users"]
// note: the type of userDetail is still `AnyObject??`
I'm not sure what is changed in Swift 2.2, maybe the check becomes stricter.
Update: In Swift 3 the type of userDetail becomes Any?? and you can't chain further subscripts. In fact Swift 3's JSONSerialization is changed to return Any instead of AnyObject, so you can't even write response["params"]. Consider using dedicated JSON packages like SwiftyJSON instead.
Swift 2.2 is more restrictive about key/index subscription of AnyObject returned from a dictionary key.
You could use a chained optional binding checking against the expected type,
if let userDetail = response["params"] as? [String:AnyObject], users = userDetail["users"] as? Whatever {}
I was playing with an idea in the Playground. This idea NSDictionaries used as a way to "keep" data.
I started creating a variable called layer type [String:[String:String]].
So, an error occurred. I'm an hour trying to solve, and could not find the error reason happen. I am new to Swift.
var layers: [String:[String:String]]!
layers["key"] = ["layer":"layer"]
layers["key2"] = ["asd":"12312"]
print(layers)
Could someone help me? Or tell me how can I get the end result of my NSDictionaries?
You've declared the type of the variable layers but you haven't allocated storage for it yet.
Try this instead:
var layers = [String:[String:String]]()
If you insist on layers being an implicitly unwrapped optional, then you could initialize it this way:
var layers: [String:[String:String]]! = [:]
This would allow you to assign nil to it later, but that would be dangerous because it would crash if you try to use it when it is nil. That is the reason for your crash.
If you want it to be optional, you should declare it with ? so that it can be safely unwrapped:
var layers: [String:[String:String]]?
// Sometime later
layers = [:]
// use optional chaining to assign values, this safely does
// nothing if layers is nil
layers?["key"] = ["layer":"layer"]
layers?["key2"] = ["asd":"12312"]
// use optional binding to unwrap layers
if let unwrapped_layers = layers {
print(unwrapped_layers)
}
Try this in a Playground, and then try commenting out the layers = [:] part and you will see that it doesn't crash because all accesses to layers are done in a safe manner that properly handle the case when layers is nil.
All I'm trying to do is to inverse key/values in a dictionary, and I get the following error:
extra argument 'count' in cal
var dictionary = SWIFT_DICTIONARY
var inverseDictionary = NSDictionary.dictionaryWithObjects(dictionary?.keys, forKeys: dictionary?.values, count: dictionary?.count)
Use this instead:
var inverseDictionary = NSDictionary(objects: dictionary.keys.array, forKeys: dictionary.values.array)
I notice that you are unwrapping dictionary in your code, but it is declared as non optional. Code mistake or just copy & paste mistake?
Addendum - if you try the static version without the count parameter:
var inverseDictionary = NSDictionary.dictionaryWithObjects(dictionary.keys.array, forKeys: dictionary.values.array)
the compiler complains with this message:
'dictionaryWithObjects(_:forKeys:) is unavailable: use object construction 'NSDictionary(objects:forKeys:)'
I think the same happens for the other method you want to use, but the compiler doesn't report the proper error message.