PromiseKit segmentation fault: 11 - xcode

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
}
}

Related

correct use of retryWhen operator with RxSwift 4.0.0

with RxSwift 3.6.1 I made this extension to ObservableType to get a new token after an error request:
public extension ObservableType where E == Response {
public func retryWithToken() -> Observable<E> {
return retryWhen { error -> Observable<Response> in
return error.flatMap({ (error) -> Observable<Response> in
if let myApiError: MyApiError = error as? MyApiError {
if (myApiError == MyApiError.tokenError) {
return Session.shared.myProvider.request(.generateToken)
} else {
return Observable.error(myApiError)
}
}
return Observable.error(error)
})
}
}
}
and then I can use it:
Session.shared.myProvider.rx
.request(.mySampleRequest)
.filterSuccessfulStatusCodes()
.retryWithToken()
.subscribe { event in
....
}.disposed(by: self.disposeBag)
but with RxSwift 4.0.0 now the sequence expect a
PrimitiveSequence<SingleTrait, Response>
someone can explain to me how to do the same with RxSwift 4.0.0? I try with an extension to PrimitiveSequence but I've some compilation errors.
I believe that has nothing to do with RxSwift but is a Moya change. MoyaProvider.rx.request returns Single which is a typealias for PrimitiveSequence which is not an ObservableType.
You declare your function upon the ObservableType.
So just do asObservable() before retryWithToken()

PromiseKit branching promise

Suppose you have a branch in your promise chain that could either return nothing or an AnyObject promise. What would you specify as the return type of the 'then' closure? For example:
func sample() -> Promise<AnyObject> {
return Promise { fulfill, reject in
fulfill(1)
}
.then { _ -> Void in
if false {
return Promise { fulfill, reject in
fulfill(0)
}
}
}
}
If I put Void as the return type for the 'then' closure I get a seg fault; if I put Promise as return type then I get an error:
missing return in a closure expected to return Promise<AnyObject>
Any suggestions?
Thanks
Based on the code sample, I see no reason to return an AnyObject. If you want to optionally return Void or an Object, then make a promise that contains an optional.
func sample() -> Promise<AnyObject?> {
return Promise { fulfill, reject in
functionForGettingObjectWithCallback() { result: AnyObject? in
fulfill(result)
}
}
}

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
}
}
}
}

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

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)
}

Can't get SequenceType to work in Swift Beta 6

In beta 5 this code works perfectly, but it doesn't compile in Beta 6. Any ideas why?
struct GenericGenerator<T>: GeneratorType {
var items: [T]
mutating func next() -> T? {
return items.isEmpty ? .None : items.removeAtIndex(0)
}
}
class ExerciseContainer : SequenceType {
var exercises: [Exercise] = []
func generate() -> GenericGenerator<Exercise> {
return GenericGenerator(items: self.exercises)
}
}

Resources