Why doesn't throw work in Swift? - swift

Any ideas why the following doesn't work?
func someFunction() throws {
print ("this is a test")
}

I believe that throws was introduced in swift 2.0, if you are using an earlier version then you will not be able to use it.
https://developer.apple.com/swift/blog/?id=29

Related

Swift generic sequence observable ambiguity

I've got following code
protocol NamedOption {
var optionTitle: String { get }
}
struct DebugOption: NamedOption {
let optionTitle: String
let debugViewControllerType = UIViewController.self
}
func testFunk<T: Sequence>(d: Observable<T>) where T.Element == NamedOption {
}
func bindFullResultsRx() {
let dd: Observable<[DebugOption]> = self.dataModel.debugOptions // this is defined and properly assigned earlier
testFunk(d: dd)
}
and at the line where I call testFunk Xcode gives me following error:
Expression type '()' is ambiguous without more context
I have no idea why this is happening :( So far I was able to make it working by changing constraints on testFunk into this:
func funk<T: NamedOption>(d: Observable<[T]>) {
}
which seems to me more restrictive then version at the top. Does any one knows how to make it working with T: Sequence ?
Xcode version is 9.4, Swift version is 4.1.
After some digging and help from work colleagues I was able to make it working by simply changing == into : so it looks like this
func testFunk<T: Sequence>(d: Observable<T>) where T.Element: NamedOption {
}
It's just a matter of swift syntax
https://docs.swift.org/swift-book/ReferenceManual/GenericParametersAndArguments.html
conformance-requirement → type-identifier : protocol-composition-type
OO and generics don't play too well together. In order to do what you want, you have to manually cast up as in:
testFunk(d: dd.map { $0.map { $0 as NamedOption } })

Generic typealias with Void gives error missing argument in Swift 4

When I tried to migrate to Swift 4 an error occurred with my generic typealias for closures if you give it Void as an input. This worked fine in Swift 3 but not so much now, anybody know why, and is this a bug or a feature?
There is a workaround by defying another closure that explicit handles this case. But would be nice to not have to use this workaround and to understand why this error arose in Swift 4.
typealias Handler<T> = (T) -> Void
func foo(completion: Handler<String>) {
completion("fooing")
}
// This worked in Swift 3, but not in Swift 4
func bar(completion: Handler<Void>) {
completion() // Missing argument for parameter #1 in call
}
It seems that this is not a bug but how Swift works now. You cannot omit an associated value of type Void anymore.
I have found two passable workarounds:
The first one just explicitly just pass the value.
func bar(completion: Handler<Void>) {
completion(())
}
The second solution is to declare another typealias for void cases.
typealias VoidHandler = () -> Void
func barbar(completion: VoidHandler) {
completion()
}

Ambiguous use of DispatchQueue on trying to use main thread

This is a weird issue and I can't seem to find any help. On Swift 3, trying to make a call on the main thread I try to use DispatchQueue.main.async, but it doesn't compile.
Any ideas would be helpful.
Try this code instead, this is the Swift 3.0 syntax:
DispatchQueue.main.async(execute: { () -> Void in
})
For Swift 4.x you can also use:
DispatchQueue.main.async {
}

Swift 2 : Try/Catch a non-throwing function

I'm refactoring a Obj-c class where there was a #try/#catch block around removeObserver:.
Doing the same thing in swift triggers a warning since removeObserver might fail (when there is no observer) but it doesn't throw any errors.
Any idea how I could achieve the same behaviour ?
edit : My code :
try {
self.removeObserver(self, forKeyPath: "LineDisplayChanged")
}
The func removeObserver(_ anObserver: NSObject,forKeyPath keyPath: String) you are calling is from the NSKeyValueObserving protocol and does not throws any exceptions.
Also, note that in Swift 2 the syntax for exception(that are actually ErrorType enum subclasses) has changed and is now something like this:
do{
try functionThrowingExceptions()
}catch ErrorTypeSubclassEnum.Value {
// Do something
}catch ErrorType {
// Do something, catches everything else
}
See this post for more info.
Note: I'm using KVO with the latest beta of XCode7, doing a self.removeObserver(self, forKeyPath: "path") does not trigger any error/warning.
To remove warning just remove try { }. removeObserver:forKeyPath: is throwing an exception and not an error. And you cannot catch exceptions in Swift so make sure you call this method only if you observing it otherwise it will crash and there is no way around it in Swift.
You could write a category in Objective-C that wraps this call and capture the exception and returns an error instead.

Catching Exceptions In Swift?

From what I understand, it is not possible to catch exceptions in Swift without building integrating a throw into your functions.
In other words, the following doesn't work, where myArr only has 5 items:
do {
var someItem = try myArr[10]
}
catch {
print("something went wrong")
}
Can anyone confirm the above simple try/catch is not possible in Swift? In other words, one where you don't have to build some elaborate, meta exception function to handle exceptions?
Correct, but you have other options. You could simply check 10 < myArr.count first.
Or, check out Erica Sadun's post on Safe array indexing:
// Erica Sadun / Mike Ash
// http://ericasadun.com/2015/06/01/swift-safe-array-indexing-my-favorite-thing-of-the-new-week/
extension Array {
subscript (safe index: UInt) -> Element? {
return Int(index) < count ? self[Int(index)] : nil
}
}