3

Using PromiseKit 2.0 with Swift 1.2, I'm trying to use a PMKPromise that was created in Objective C from Swift.

Objective C code:

@interface FooTest : NSObject
+ (PMKPromise *)promise;
@end

Swift code (I've tried a number of variations, none of which work. This one is closest to the example given at http://promisekit.org/PromiseKit-2.0-Released/):

FooTest.promise().then { (obj: AnyObject?) in
    self.obj = obj
}

Compiler error: Cannot invoke 'then' with an argument list of type '((AnyObject?) -> _)'

This doesn't work either:

FooTest.promise().then { (obj: AnyObject?) -> AnyPromise in
    return AnyPromise()
}

Similar error: "Cannot invoke 'then' with an argument list of type '((AnyObject?) -> AnyPromise)'"

Tim Norman
  • 1,999
  • 1
  • 20
  • 26
  • The code is here: https://github.com/mxcl/PromiseKit/blob/master/Sources/AnyPromise.h – Tim Norman Jul 05 '15 at 16:43
  • Um, well okay but I'm pretty sure it's not as simple as knowing just the declaration, as there are #defines and other bridging magic going on. `- (AnyPromise *(^)(id))then;` – Tim Norman Jul 05 '15 at 16:50
  • Well, I let you down. :( Sorry. – matt Jul 05 '15 at 17:01
  • did you create a bridging header? – Steve Jul 05 '15 at 17:20
  • @Steve yes there's a bridging header – Tim Norman Jul 05 '15 at 19:00
  • From what I can tell it doesn't seem PromiseKit is ready for Swift (this is an opinion, I realize, and before the gauntlets are released hear me out). The `then` call still uses `id` to allow multiple types of blocks to be passed in; in swift this probably should be done by overloading `then` and using the proper type signatures. I will try to look into a solution for a little bit, but this appears to be pretty mucky to work with. – DanZimm Jul 05 '15 at 19:43

1 Answers1

6

There are two different promise classes in PromiseKit, one for Swift (Promise<T>) and one for ObjC (AnyPromise). The Swift ones are generic and Objective-C cannot see generic classes, so this is why there are two.

If Foo.promise() is meant to be used in both ObjC and Swift then you are doing the right thing. If however you only intend to use this promise in Swift then I suggest rewriting it as a Promise<T>.

To use an Objective-C AnyPromise (PMKPromise is a deprecated alias for AnyPromise: prefer AnyPromise) in Swift code you must splice it into a an existing chain.

someSwiftPromise().then { _ -> AnyPromise in
    return someAnyPromise()
}.then { (obj: AnyObject?) -> Void in
    //…
}

There should be a way to start from an AnyPromise, probably I will add this later today:

someAnyPromise().then { (obj: AnyObject?) -> Void in
    //…
}

Expect a 2.1 update. [edit: 2.1 pushed with the above then added]

mxcl
  • 26,392
  • 12
  • 99
  • 98