Swift 1.2: <unknown>:0: error: '[Set<T>]' is not convertible to 'Hashable' - swift

I have used xCode 6.3's convertor to convert my project to swift 1.2,
After that i was still left with many errors, but i fixed them all manually.
Now when i compile i get:
<unknown>:0: error: '[Set<T>]' is not convertible to 'Hashable'.
The only place i use Set is:
var productID:Set<NSObject> = [subscriptionId]
var productsRequest:SKProductsRequest = SKProductsRequest(productIdentifiers: productID )
I have tried cleaning the project and also tried deleting the DerivedData folder, but that didn't help.
I have searched but i couldn't find anyone with the same problem.
Anyone know how to solve this?

This won’t be a problem with derived data. It looks like where previously you had an NSArray (probably of NSSet), you now have an Array of Set. Presumably you’re then trying to do something like use that value to key a dictionary type. In 6.3, several API calls that previously returned NSSomething now return native Swift types.
Swift Arrays aren’t hashable (because they might contain something that isn’t hashable). NSArrays are (though not always in a helpful way, depending on what they contain, so be wary).
Bear in mind, with type inference, that your explicit use of Set or Array won’t be the only places you might have a set. If you call a function that returns an array of sets, and you assign that value like so: let thing = funcThatReturnsArrayOfSets() then you will have a [Set<whatever>] even without explicitly writing that type in your code.
To fix this, you need to find the line where you’re getting the error, look at the types involved, then trace back to where those variables were declared. Option-click all the things to see what types they are.

Related

Why bother casting the return value since the type has been specified when calling the function?

I am learning Editor Script of Unity recently, and I come across a piece of code in Unity Manual like this:
EditorWindowTest window = (EditorWindowTest)EditorWindow.GetWindow(typeof(EditorWindowTest), true, "My Empty Window");
I don't know why bother casting the result with (EditorWindowTest) again since the type has been specified in the parameter field of GetWindow().
Thanks in advance :)
There are multiple overloads of the EditorWindow.GetWindow method.
The one used in your code snippet is one of the non-generic ones. It accepts a Type argument which it can use at runtime to create the right type of window. However, since it doesn't use generics, it's not possible to know the type of the window at compile time, so the method just returns an EditorWindow, as that's the best it can do.
You can hover over a method in your IDE to see the return type of any method for yourself.
When using one of the generic overloads of the GetWindow method, you don't need to do any manual casting, since the method already knows at compile time the exact type of the window and returns an instance of that type directly.
The generic variants should be used when possible, because it makes the code safer by removing the need for casting at runtime, which could cause exceptions.
If you closely look, GetWindow's return type is EditorWindow. Not the EditorWindowTest, so typecasting makes sense.
https://docs.unity3d.com/ScriptReference/EditorWindow.GetWindow.html

Does Safety in Swift affect Performance?

While learning Swift, I have seen many cases of safe code vs. unsafe code. A perfect example of this is
as? and as!
as?, from my understanding tries to type cast, but if it doesn't cast, returns nil.
as!, from my understanding, tries to type cast, and crashes if it fails.
My question, is why does as!, (and other unsafe syntax with safe counterparts, for that matter) exist? Obviously as? is the better choice. The only answer I could come up with is that maybe using as! is faster for the compiler to compile, and therefore is mainly an optimization piece of syntax.
I'm just curious to know I'm right about safe syntax being a bit slower to compile, since performance matters to me a great deal.
Thank you for your time.
This question is based upon a false premise: The primary choice of as? vs as! is not generally one of performance. Sure, as! potentially might be a bit more efficient, but in an optimized build, the difference is generally negligible.
One chooses as! vs as? based upon the context:
If the cast can possibly fail at runtime, then you'd use as?. Of course you add code to check to see whether the cast succeeded or not.
A common example of a cast that could fail would be whenever the source of the data is some external source (e.g. user input or a network request). A user could paste text values into a field in which you were expecting only numeric values. An external web server could be unavailable or it could even return data in an unexpected format. You'd want to use as? to detect these situations and handle it gracefully.
But if the cast can not possibly fail at runtime, you use as!. But you do so less for performance reasons than for reasons of clarity and writing concise code.
A common example of a cast that cannot fail would be when retrieving a cell prototype from a storyboard, where you know the base type was set in Interface Builder, though the Cocoa API cannot know this. It would be ineffiencient to add a lot of code checking to see if the base type was set correctly (especially since this would be a fatal programming error, anyway) and leads to code with a lot of syntactic noise with no benefit. And if you don't do it correctly, you could easily accidentally suppress an error that you really would want to flush out during the testing process, making it harder to find the problem. This is a good use case for as! syntax.
as! is not unsafe unless your code before it has failed to ensure the cast can't fail. Imagine a situation where your code has already verified the object can indeed be cast to a particular protocol. If for whatever reason you find it convenient to not create a new local variable of that type and cast the first variable to it, then using as! can be appropriate.
The same logic goes for implicitly unwrapped optionals. Since when your view controller is instantiated, an IBOutlet property can't be assigned yet (storyboard hasn't loaded yet), the property has to be optional. But it's irksome to have to use the property as an optional throughout the class when you know the storyboard has loaded. In fact, if there is a problem with locating the storyboard element and assigning it, a 100% guaranteed crash is desired so that the developer can always spot and fix the problem.
So returning to as!, this raises a second case of when it's appropriate to use: whenever a crash is the most desirable outcome of the failed cast.
So it's not about compiler speed. It's about code logic convenience. There are appropriate times to use it, and for those times, it's a more compact and easier to read way of representing your logic goals.
As you say, as! should hardly ever be used. There are a few cases, though, where due to legacy issues, the compiler doesn't know what type something should be, even though the developer does. One example of this is the NSCopying protocol. Because Objective-C was not as strict about type safety as Swift, copy() returns an id, which is bridged to Any in Swift. However, when you use copy(), mutableCopy(), and friends, you usually know exactly what type you will get out of it, so as! is typically used to force a cast to the correct type.
let aString: NSAttributedString = ...
let mutableAString = aString.mutableCopy() as! NSMutableAttributedString
You can investigate this question for yourself by compiling something like
func f(a: Any) -> Int {
(a as! Int) + 5
}
vs.
func f(a: Any) -> Int {
((a as? Int) ?? 3) + 5
}
With the Swift 4 compiler, running swiftc -O -emit-assembly on this Swift code produces extremely similar output, which should square with your understanding of how as! works and how we would implement it if it wasn't part of the language:
func forceCast<T>(_ subject: Any) -> T {
return subject as? T ?? fatalError("Could not cast \(subject) to \(T)")
}
It's worth noting, as SmartCat already alluded to, that as! isn't actually "unsafe" in the sense that the Swift compiler authors define that word; because it, like as?, actually specifically checks the type of subject. There is a unsafe-in-the-swift-sense force cast in swift; it's called, unsurprisingly, unsafeBitCast; and is equivalent to a C/Objective-C cast; it doesn't check types and just assumes you knew what you were doing. Will it be faster than as? Without a doubt.
So, to answer your title's question: yes, safety has a cost in Swift. The flip side of the coin is that if you write code that avoids casts and optionality, Swift can (in theory) optimize your code far more aggressively than languages that make less strong safety guarantees.
To answer your actual question; there's no difference between as? and as! in terms of performance.
Other's have already covered why as! exists; it's so you can tell the compiler "I can't explain why to you, but this will always work; trust me".

Swift 2: How to parse a time signature from MIDIMetaEvent?

Before Swift, a MIDIMetaEvent's data was accessed via data[0], data[1], etc.
To get to a time signature I need two values from the data part which is labeled as (UInt8)... with the parens.
But when I try to get the value in this way:
let midiMessage = UnsafePointer<MIDIMetaEvent>(eventData).memory
let data1 = midiMessage.data[0]
This results in an error: "Cannot subscript a value of type 'UInt8' with an index of type 'Int'
Any clue what I've done wrong here? Just getting midiMessage.data only returns the first byte of data.
No snark intended, but file a Radar and ask for an "enhancement" to get rid of using tuples for dynamically sized arrays. They have done this already with some parts of Core MIDI, but not meta events. Or MIDI thru.
It would be nice if they just added the Core MIDI functionality to AVFoundation (they've started) to get rid of the C API altogether.
In the meantime you can go through contortions like this which uses Mirror https://github.com/jverkoey/swift-midi/blob/master/LUMI/CoreMIDI/MIDIPacket%2BSequenceType.swift

Interaction with enum members in swift-based app

I'm beginning to teach myself swift and I'm going through examples of games at the moment. I've run across a line of code that I thought was peculiar
scene.scaleMode = .ResizeFill
In languages I'm used to (C / Java) the "." notation is used to reference some sort of structure/ object but I'm not exactly sure what this line of code does as there is no specified object explicitly before the "."
Information regarding clarification of this non-specified "." reference, or when/ how it can be used, would be great
P.S. I'm using sprite kit in Xcode
In Swift, as in the other languages you mentioned, '.' is a member access operator. The syntax you are referring to is a piece of shorthand that Swift allows because it is a type-safe language.
The compiler recognises that the property you are assigning to is of type SKSceneScaleMode and so the value you are assigning must be one of that type's enumerated values - so the enumeration name can be omitted.
To add to PaulW11's answer, what's happening here is only valid syntax for enums, and won't work with any other type (class, struct, method, function). Swift knows the type of the property that you are assigning to is an enum of type SKSceneScaleMode, so lets you refer to the enum member without having to explicitly give the type of the enum (ie SKSceneScaleMode.ResizeFill).
There are some situations where there will be ambiguity, and you will have to give the full name, this will be dependant on the context. For example, you may have two different enum types in scope, that both have a matching member name.
EDIT
Updating this answers as I incorrectly specified this was only applicable to enums, which is not true. There is a good blog post here which explains in more detail
http://ericasadun.com/2015/04/21/swift-occams-code-razor/

What use does the new as! operator have?

I don't quite understand what new functionality the as! operator is supposed to add.
Apple's documentation says:
The as! operator performs a forced cast of the expression to the specified type. The as! operator returns a value of the specified type, not an optional type. If the cast fails, a runtime error is raised. The behavior of x as! T is the same as the behavior of (x as? T)!.
It seems that using as! only makes sense, when you know that the downcast will be successful, because otherwise a runtime error will be triggered. But when I know that the downcast will be successful I just use the as operator. And since neither as! nor as return an optional they even return the exact same type.
Maybe I'm missing something, but what's the point?
The as (no bang) operator is for casts that are guaranteed by the language to succeed — primarily, that means casts from a subtype to one of its ancestor types.
The as! and as? operators are for casts that the language can't guarantee will succeed. This comes into play when you have a general type and want to treat it as a more specific subtype. The compiler doesn't know which subtype might really be hiding behind the general type — that information can be decided at run time — so as far as the language knows, there's a possibility of the cast failing.
The difference between as? and as! is how that failure is handled. With the former, the result of the cast gets wrapped in an optional, forcing you to yeast for the failure and allowing you to handle it in a way that makes sense to your app. The latter assumes the cast will succeed, so you aren't forced to check for failure—you'll just crash if your assumption turns out to be wrong.
So why use as!? It fills the same role as the Implicitly Unwrapped Optional: you can use it (at your own risk) for situations where some behavior is "guaranteed" by some factor external to the language (even if the language itself can't guarantee it), allowing you to skip having to write code to test for failures you don't expect to happen. One of the most common cases of such is when you're depending on the runtime behavior of another class — the language doesn't say that the subviews array of a UIView must contain other UIViews, but its documentation assures you that it will.
Before Swift 1.2, there was no as! — as included both cases that could crash and cases that couldn't. The new operator requires you to be clear about whether you're doing something that will always succeed, something you expect to always succeed, and something you plan to test for failure.
There are cases where you as a programmer can know that as would succeed, but the compiler can't be sure of it. In such cases, as is a compile-time error, but as! will compile.