Swift #autoclosure broke compatibility in v1.2 for enum cases - xcode

I just update Xcode to 6.3 and the Swift code that used to compile in Xcode 6.2 is not compiling now.
import Foundation
public enum Result<T> {
case Success(#autoclosure() -> T)
case Failure(NSError)
case Cancelled
public init(_ value: T) {
self = .Success(value)
}
public init(_ error: NSError) {
self = .Failure(error)
}
public init() {
self = .Cancelled
}
public var failed: Bool {
switch self {
case .Failure(let error):
return true
default:
return false
}
}
public var error: NSError? {
switch self {
case .Failure(let error):
return error
default:
return nil
}
}
public var value: T? {
switch self {
case .Success(let value):
return value()
default:
return nil
}
}
}
This line:
case Success(#autoclosure() -> T)
yields an error: 'autoclosure' attribute is only allowed on parameters, not on enum cases
Just removing #autoclosure doesn't solve the problem.

Correct. This has been removed, explicitly to prevent the case you provide. Autoclosures were not intended to be used this way, and the Swift team intentionally removed the ability to do so. In a Result type, this is dangerous because the closure will be re-evalated every time it is accessed. If there are side-effects in the closure, this can have quite surprising impacts. Even if it's just non-trivial, it can have surprising performance impacts.
The correct tool here is Box. See Rob Rix's Result for a good implementation of this type.

I think that I have found the solution. You only need to change 2 lines in your original implementation to make it work:
case Success(() -> T)
And
public init(#autoclosure(escaping) _ value: () -> T) {

For those who only want a simply solution without having to import external frameworks:
public enum Result<T> {
case Success(Box<T>)
case Failure(String)
public init(_ value: T) {
self = .Success(Box(value))
}
public init(_ error: String) {
self = .Failure(error)
}
}
// Due to current swift limitations, we have to include this Box in Result.
final public class Box<T> {
public let unbox: T
public init(_ value: T) { self.unbox = value }
}
public func success<T>(value: T) -> Result<T> {
return .Success(Box(value))
}
public func failure<T>(error: String) -> Result<T> {
return .Failure(error)
}

Related

RxSwift Delegate Binding isn't Generated?

I am trying to bind a delegate this is what was done
/** Delegate Proxy **/
func castOrThrow<T>(_ resultType: T.Type, _ object:Any) throws -> T {
guard let returnValue = object as? T else {
throw RxCocoaError.castingError(object: object, targetType: resultType)
}
return returnValue
}
#objc
public protocol TestEventGeneratorDelegate:class {
#objc optional func asyncEventResult(int:Int)
}
open class TestEventGenerator {
public var delegate: TestEventGeneratorDelegate?
func asyncCall() {
DispatchQueue.global().asyncAfter(deadline: .now() + .seconds(1)) { [weak self] in
guard let self = self else { return }
self.delegate?.asyncEventResult!(int: 0)
}
}
}
extension TestEventGenerator: HasDelegate {
public typealias Delegate = TestEventGeneratorDelegate
}
open class RxTestDelegateProxy : DelegateProxy<TestEventGenerator,TestEventGeneratorDelegate>,
DelegateProxyType,
TestEventGeneratorDelegate {
public weak private(set) var testGenerator: TestEventGenerator?
public init(testEventGenerator: ParentObject) {
self.testGenerator = testEventGenerator
super.init(parentObject: testEventGenerator, delegateProxy: RxTestDelegateProxy.self)
}
public static func registerKnownImplementations() {
self.register { RxTestDelegateProxy(testEventGenerator: $0) }
}
}
extension Reactive where Base: TestEventGenerator {
public var delegate: DelegateProxy<TestEventGenerator, TestEventGeneratorDelegate> {
return RxTestDelegateProxy.proxy(for: base)
}
public var asyncEventResult: Observable<Int> {
let source = delegate.methodInvoked(#selector(TestEventGeneratorDelegate.asyncEventResult(int:)))
.map { (a) in
return try castOrThrow(Int.self,a[0])
}
return source
}
}
/** Delegate Proxy **/
Then when I use it
let testEventGenerator = TestEventGenerator()
textEventGenerator.rx.asyncEventResult.subscribe.... // subscribe here no rx found?
testEventGenerator.asyncCall() // call and wait for the observable to return to the delegate
It doesn't compile and says there is no such rx
I have to bind it because the person who wrote the API didn't use a callback to return the value but rather a delegate.
This is example of how he wrote the code and how I want to wrap it.
Is there a way to bind a delegate that requires a kick off from asyncCall()?
so I can chain it using flatmapLatest in a promiseLike way?
Thanks let me know!
I followed these tutorial:
How to convert Delegate to Observable RxSwift?
and
https://blog.ippon.fr/2018/11/13/rxswift-how-to-make-your-favorite-delegate-based-apis-reactive/
have conform to TestEventGenerator:ReactiveCompatible and that will fix it.

Crash fetching row value for custom type

I've defined an enum and made it conform to Value like so:
enum Name: Int {
//cases
}
extension Name: Value {
static var declaredDatatype: String {
return Int.declaredDatatype
}
static func fromDatatypeValue(_ intValue: Int) -> Name {
return Name(rawValue: intValue)!
}
var datatypeValue: Int {
return self.rawValue
}
}
Unfortunately I get the follow exception:
fatal error: unexpectedly found nil while unwrapping an Optional value
It happens in this function:
public func get<V: Value>(_ column: Expression<V>) -> V {
return get(Expression<V?>(column))!
}
The function in my enum extension is not called so I think this is a more general bug in SQLite.swift, but it only happens with my custom type.
Im using Xcode 8.3.3 and SQLite.swift ec7b589.

PromiseKit segmentation fault: 11

I'm trying to get a basic promise working with PromiseKit. However the following code wont compile:
import Foundation
import PromiseKit
class MyClass {
var myInt: Int?
func sample() -> Promise<AnyObject> {
return Promise { fulfill, reject in
fulfill(1)
}.then { data -> Int in
return 3
}
}
init() {
sample().then { data -> Void in
debugPrint("got data: \(data)")
}
}
}
This is the error I get:
command failed due to signal: segmentation fault: 11
This is pretty frustrating. Has anyone encountered this?
This is because Int is not AnyObject
func sample() -> Promise<AnyObject> {
return Promise { fulfill, reject in
fulfill(1)
}.then { data -> Int in
return 3
}
}
This is most likely fixed in Swift 3, however either of these will fix the compile:
func sample() -> Promise<Int> {
return Promise { fulfill, reject in
fulfill(1)
}.then { data -> Int in
return 3
}
}
Or:
func sample() -> Promise<AnyObject> {
return Promise { fulfill, reject in
fulfill(1)
}.then { data -> NSNumber in
return 3
}
}

How to write a factory function in swift?

There are a number of other questions floating around with various complicated answers for this question, but as far as I can see, none of them answer the basic question being posed:
How do you write a factory function that takes a type and returns an instance when the return type is known?
That is:
func factory<T>(T) -> Fooish { ... }
// Usage:
class Something : Fooish { ... }
let x:Fooish = factory(Something)
For example, this code:
public class Fooish {
var x:String = ""
public func foo() -> String {
return x
}
}
public class FooA : Fooish {
public override init() {
super.init()
x = "Hello"
}
}
public class FooB : Fooish {
public override init() {
super.init()
x = "World"
}
}
// This works
print(FooA().foo())
print(FooB().foo())
// This does not work
func factory<U>(type:U) -> Fooish {
return U()
}
print(factory(FooA).foo())
print(factory(FooB).foo())
Results in this error:
Sources/main.swift:32:10: error: 'U' cannot be constructed because it has no accessible initializers
return U()
^
<unknown>:0: error: build had 1 command failures
So what is the bound to place on T, such that we can call T() and know that the returned instance is a some Fooish?
Some answers suggest using a protocol for it, such as:
protocol IsFoo {
init()
}
factory<T: IsFoo>(t:T) -> Fooish { .. }
However, this doesn't seem to work:
error: cannot invoke 'factory' with an argument list of type '((FooA).Type)'
expected an argument list of type '(U)'
Every answer to this question seems to have multiple conflicting and updated answers; please, just simply post the snippet above, with a working implementation of the function factory, for swift 2.2.
Make a protocol which defines a common initializer to be called by the factory method:
protocol FactoryInitializable {
init ()
}
func factory<T: FactoryInitializable>(type: T.Type) -> T {
return T()
}
public class Fooish {
var x = ""
public func foo() -> String {
return x
}
}
public class FooA : Fooish, FactoryInitializable {
required public override init() {
super.init()
x = "This is FooA"
}
}
public class FooB : Fooish, FactoryInitializable {
required public override init() {
super.init()
x = "This is FooB"
}
}
let a = factory(FooA)
let b = factory(FooB)
print(a.x) // print: This is FooA
print(b.x) // print: This is FooB

Class declaration cannot close over value 'fulfill' defined in outer scope - Swift 2.0

I'm trying to convert my app from Swift 1.2 to Swift 2.0 and I'm encountering the following error:
class B {
func test() -> Promise<A> {
return Promise<A> { (fulfill, reject) -> Void in
anotherPromise.then { _ -> Void in
return fulfill(A()) // Class declaration cannot close over value 'fulfill' defined in outer scope
}
}
}
}
How can I make B (or the then closure) capture fulfill properly?
PS: Promise comes from PromiseKit, and I'm running Xcode 7 beta 1.
You should be able to workaround this by assigning fulfill to a local that you capture instead.
class B {
func test() -> Promise<A> {
return Promise<A> { (fulfill, reject) -> Void in
let innerFulfill = fulfill // close on this instead
anotherPromise.then { _ -> Void in
return innerFulfill(A()) // Class declaration cannot close over value 'fulfill' defined in outer scope
}
}
}
}

Resources