GithubHelp home page GithubHelp logo

thomvis / brightfutures Goto Github PK

View Code? Open in Web Editor NEW
1.9K 1.9K 184.0 960 KB

Write great asynchronous code in Swift using futures and promises

License: MIT License

Swift 99.44% Ruby 0.56%
asynchronous-programming concurrency futures promises swift

brightfutures's People

Contributors

andrewsb avatar bkase avatar chunkerchunker avatar danj-stripe avatar e-marchand avatar gitter-badger avatar jeroenb-triple avatar jgh- avatar kennytm avatar kimdv avatar mathebox avatar mattfenwick avatar mickeyreiss avatar noobish1reviewer avatar nvh avatar paiv avatar peyton avatar phimage avatar possen avatar robertoaceves avatar romanpodymov avatar sajjon avatar slessans avatar thomvis avatar tmu avatar tonyarnold avatar wiruzx avatar wvteijlingen avatar yonaskolb avatar zenkimoto avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

brightfutures's Issues

Add "isCompleted" property to Future

From the Scala docs:

"Returns whether the future has already been completed with a value or an exception."

This would be really helpful to have.

Safe to naïvely use 'self' methods?

Probably best explained with a code example. I have a UIViewController which fetches data wrapped in BrightFutures, and on completion fills in that data in its views - simple enough:

class SomeViewController: UIViewController {

    override func viewDidAppear() {
        super.viewDidAppear()
        // loadUser returns a Future
        User.loadUser().onSuccess(callback: displayUser)
    }

    func displayUser(user: User) {
        println("displaying user \(user)")
    }
}

What happens if SomeViewController was deallocated before the loadUser future resolves? Does BrightFutures retain the callback method and the relevant object associated with it, or do I need to always wrap it in a 'weak self' wrapper like so:

    User.loadUser().onSuccess { [weak self] user in
      self?.displayUser(user)
   }

I much prefer the first form - and preferably an even simpler one (currently the callback argument name is required). It's already a huge improvement over the existing success/failure block or delegate method approaches used, IMO.

(note: Swift 1.2, BrightFutures 2.x)

Adding dispatch_after to Queue

Hi @Thomvis,

In my current project, I need to use the dispatch_after() GCD function. I do like your Queue wrapper very much and I think it would be a great fit. Let me know if something like this would fit the philosophy behind this project. I've added a pull request for your review.

Bring consistency between `error` and `failure`.

The completion callbacks and Result use failure, while Promise uses the word error. Is there any reason for this? It seems to me it would be more clear that one leads to another if they were both called either error or failure.

Push newer versions to CocoaPods

I could be wrong, but it looks like you have newer versions that are not in CocoaPods.

# pod search BrightFutures

-> BrightFutures (1.0.0-beta.3)
   A simple Futures & Promises library for iOS and OS X written in Swift
   pod 'BrightFutures', '~> 1.0.0-beta.3'
   - Homepage: https://github.com/Thomvis/BrightFutures
   - Source:   https://github.com/Thomvis/BrightFutures.git
   - Versions: 1.0.0-beta.3, 1.0.0-beta.2 [master repo]

ErrorType does not conform ErrorType :/

I'll throw this one out there, no clue what's going on.

let foo: Future<String, ErrorType>

error: protocol type ErrorType does not conform to protocol ErrorType because ErrorType is not declared @objc

// Custom protocols don't work either
protocol MyError: ErrorType {}

// and trying to make it @objc backfires
@objc public protocol MyObjCError: ErrorType {}

error: @objc protocol MyObjCError cannot refine non-@objc protocol ErrorType

Any wizard has a magic spell to fix this one?

// this is ugly
enum FutureError : ErrorType {
    case Error(ErrorType)
}
// and this is not kosher
class FutureError : ErrorType { }

Swift 2.0
XCode Version 7.0 beta 5 (7A176x)

Map function does not work on Futures

Applying the map function on a future seems to never finish. The map block never gets executed. I tried debugging the map myself, even looking at the BrightFutures code by setting breakpoints there, but that has only caused xcode to seg fault (a lovely feature I keep seeing with swift). So I am stuck.

Here is the source of me using the map, the 'dummyAbbrDictF' function is the culprit.

func dummyStationsF() -> Future<[Station]> {
    return future {
      let expected12StSt = Station(name: "12th St. Oakland City Center", abbreviation: "12th", city: "Oakland", latitude: 37.803664, longitude: -122.271604)
      let expected16StSt = Station(name: "16th St. Mission", abbreviation: "16th", city: "San Francisco", latitude: 37.765062, longitude: -122.419694)
      let expectedMontSt = Station(name: "Montgomery St.", abbreviation: "mont", city: "San Francisco", latitude: 37.789256, longitude: -122.401407)
      let expectedRockSt = Station(name: "Rockridge", abbreviation: "rock", city: "Oakland", latitude: 37.844601, longitude: -122.251793)
      let expectedSFOSt = Station(name: "San Francisco Int'l Airport", abbreviation: "sfia", city: "San Francisco Int'l Airport", latitude: 37.616035, longitude: -122.392612)
      let expectedSSFSt = Station(name: "South San Francisco", abbreviation: "ssan", city: "South San Francisco", latitude: 37.664174, longitude: -122.444116)

      let stns = [expected12StSt,expected16StSt,expectedMontSt,expectedRockSt,expectedSFOSt,expectedSSFSt]
      return Result.Success(Box(stns))
    }
  }

  func dummyAbbrDictF() -> Future<Dictionary<String, Station>> {
    return self.dummyStationsF().map { stations -> Dictionary<String, Station> in
      var dict: Dictionary<String, Station> = [:]
      for station in stations {
        dict[station.abbreviation] = station
      }
      return dict
    }
  }

I also put all the code into a branch https://github.com/firemuzzy/BartApp, the 'testAbbrs' test in StationStoreTests is failing due the issue of the map function getting stuck.

I can't install BrightFutures in my project

I wanted to add BrightFutures to my OSX project using cocoapods. But for some reason it won't let me install it.

My Podfile

platform :osx, '10.8'

use_frameworks!

pod 'BrightFutures', '~> 2.0.1'
$ pod install --verbose
  Preparing

Updating local specs repositories

Updating spec repo `master`
  $ /usr/local/bin/git pull --ff-only
  Already up-to-date.

Analyzing dependencies

Inspecting targets to integrate
  Using `ARCHS` setting to build architectures of target `Pods`: (``)

Resolving dependencies of `Podfile`
[!] Unable to satisfy the following requirements:

- `BrightFutures (~> 2.0.1)` required by `Podfile`

/usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/cocoapods-0.38.1/lib/cocoapods/resolver.rb:388:in `handle_resolver_error'
/usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/cocoapods-0.38.1/lib/cocoapods/resolver.rb:69:in `rescue in resolve'
/usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/cocoapods-0.38.1/lib/cocoapods/resolver.rb:56:in `resolve'
/usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/cocoapods-0.38.1/lib/cocoapods/installer/analyzer.rb:535:in `block in resolve_dependencies'
/usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/cocoapods-0.38.1/lib/cocoapods/user_interface.rb:59:in `section'
/usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/cocoapods-0.38.1/lib/cocoapods/installer/analyzer.rb:533:in `resolve_dependencies'
/usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/cocoapods-0.38.1/lib/cocoapods/installer/analyzer.rb:70:in `analyze'
/usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/cocoapods-0.38.1/lib/cocoapods/installer.rb:209:in `analyze'
/usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/cocoapods-0.38.1/lib/cocoapods/installer.rb:131:in `block in resolve_dependencies'
/usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/cocoapods-0.38.1/lib/cocoapods/user_interface.rb:59:in `section'
/usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/cocoapods-0.38.1/lib/cocoapods/installer.rb:130:in `resolve_dependencies'
/usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/cocoapods-0.38.1/lib/cocoapods/installer.rb:103:in `install!'
/usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/cocoapods-0.38.1/lib/cocoapods/command/project.rb:71:in `run_install_with_update'
/usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/cocoapods-0.38.1/lib/cocoapods/command/project.rb:101:in `run'
/usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/claide-0.9.1/lib/claide/command.rb:312:in `run'
/usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/cocoapods-0.38.1/lib/cocoapods/command.rb:48:in `run'
/usr/local/var/rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/cocoapods-0.38.1/bin/pod:44:in `<top (required)>'
/usr/local/var/rbenv/versions/2.1.2/bin/pod:23:in `load'
/usr/local/var/rbenv/versions/2.1.2/bin/pod:23:in `<main>'

Playgrounds

Hi @Thomvis

I created a playground and a pull request. Let me know if that's something you'd be interested in. More info in the pull request itself.

Possible to send multiple values over time to a Future?

This is probably straying a bit into RAC's territory, but is there a way to send multiple values over time to a Future? My use case is the CLLocationManager's delegate API, where things like authorisation can return indeterminate states before returning a proper value.

I'd prefer not to have to use some kind of "retry" mechanism, but I get this might not be the point of BF.

function signature specialization?

I'm having trouble deciphoering an error, and it's listed in my code (rather than a BrightFutures file) so probably it's my own bug, but in case it's meaningful I wanted to post here (and perhaps you'll have seen something like this before?)

function signature specialization <Arg[0] = Owned To Guaranteed, Arg[1] = Owned To Guaranteed, Arg[2] = Owned To Guaranteed> of MyPackage.MyFile.myFunction (MyFile.myFunction)(ObjectiveC.NSMutableDictionary, then : () -> ()) -> () (MyFile.swift:1562)

Compile error: `direct generic type metadata pattern for Result.Result`

I use BrightFutures with Alamofire

I write extension for Alamofire.Request.

request.responseJSONPromise() run with no error.

However, when I chain Future using flatMap, Xcode7 shows a compile error message.

screen shot 2558-09-19 at 15 54 40

Here's my code

public func getToken(username username: String, password: String) -> Future<String, DRCloudServerError> {

    let request = Alamofire.request( .POST, url, parameters: params)

    return request.responseJSONPromise().flatMap{ json -> Future<String, DRCloudServerError> in

        let promise = Promise<String, DRCloudServerError>()
        if let accessToken = json["access_token"].string{
            promise.trySuccess(accessToken)
        }else{
            promise.tryFailure(DRCloudServerError.JSONParseError)
        }
        return promise.future
    }
}

and my Alamofire.Request extension

extension Alamofire.Request{

    func responseJSONPromise() -> Future<JSON,DRCloudServerError>{

        let promise = Promise<JSON, DRCloudServerError>()
        responseJSON{ request, response, result in

            if let error = self.handleStatusCodeError(response, data: result.data){
                promise.tryFailure(error)
            }

            switch(result){
            case let .Failure(_, error):
                let errorDescription = "\(error)"
                promise.tryFailure(DRCloudServerError.RequestError(errorDescription))
            case let .Success(value):
                let json = JSON(value)
                promise.trySuccess(json)
            }
        }
        return promise.future
    }
}

How to cancel future?

Say I have a long-running background calculation, that the user should be able to cancel. The current implementation does not include some communication mechanism for signalling this event. How could such a feature be implemented? I think the following concerns should be addressed:

  • Signal the background calculation of the cancellation; it would be up to the future to check for this flag and stop further processing.
  • Signal the promise of some "cancel" or "failure" state; so that any subsequent callbacks also recognize the cancellation of the promise/future.

Complete a future multiple times?

So far I'm seeing this is not possible. I'm looking for a way to replace callback logic where the callback is executed 2 times.

The reason I have this is a webservice call with a local-database cache. I always return to the caller the result of the local database and do webservice call in the background. If the result of the webservice call is different from the result which I returned from the local db, I return this result (again) to the caller. So my callback can be executed 1 or 2 times. The idea is to show the cached result to the client as soon as possible, and if there's a change in the remote data to refresh the UI immediately with it.

Previously I had (roughly) something like:

func myCall(handler: (MyResult) -> ()) {
    getFromLocalDB {localDBResult in
         handler(localDBResult)
    }

    getFromRemote {remoteResult
         //...
         if remoteResult != localDBResult {
             handler(remoteResult)
         }
    }

This is what I came up as replacement using futures (I have little experience with futures, maybe there's a better way):

func myCall() -> Future<MyResult, NSError> {

    let promise = Promise<MyResult, NSError>()

    getFromLocalDB.onComplete {result in
         // ...
         promise.success(localDBResult)
    }

    getFromRemote.onComplete {result
         // ...
         if remoteResult != localDBResult {
             promise.success(remoteResult)
         }

    return promise.future
}

But this causes an assertion error on the second success call because the future is already completed.

I came up with a solution in which I return 2 futures, like this:

func myCall() -> (cached: Future<MyResult, NSError>, remote:  Future<MyResult, NSError>) {

    let promiseCached = Promise<MyResult, NSError>()
    let promiseRemote = Promise<MyResult, NSError>()

    getFromLocalDB.onComplete {result in
         // ...
         promiseCached.success(localDBResult)
    }

    getFromRemote.onComplete {result
         // ...
         if remoteResult != localDBResult {
             promiseRemote.success(remoteResult)
         }

    return (cached: promiseCached.future, remote: promiseRemote.future)
}

And handle with a common closure:

let completion: Result<[MyResult], NSError> -> () = {result in
    // ...  
}

let (cached: Future<[MyResult], NSError>, remote: Future<[MyResult], NSError>) = getMyResults()

cached.onComplete { // this additional closure is necessary - somehow it was not possible to pass the completion closure directly 
    completion($0)
}
remote.onComplete {
    completion($0)
}

And that works, but I wonder if there's a better way. Having the handler callback called twice is maybe not the cleanest way to implement this, but there may be other scenarios with a callback-similar setup which has to be called multiple times.

symbol(s) not found for architecture x86_64

Hey there, I'm using BrightFutures as a dependency in Spine and I'm getting the following when compiling:

Ld /Users/kurko/Library/Developer/Xcode/DerivedData/Dinero-frfqupqfiefqgtevsufnmfrmbtcl/Build/Products/Debug-iphonesimulator/Spine.framework/Spine normal x86_64
    cd /Users/kurko/www/ios/Dinero/Pods
    export IPHONEOS_DEPLOYMENT_TARGET=8.0
    export PATH="/Applications/Xcode7.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode7.app/Contents/Developer/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
    /Applications/Xcode7.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch x86_64 -dynamiclib -isysroot /Applications/Xcode7.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator9.0.sdk -L/Users/kurko/Library/Developer/Xcode/DerivedData/Dinero-frfqupqfiefqgtevsufnmfrmbtcl/Build/Products/Debug-iphonesimulator -F/Users/kurko/Library/Developer/Xcode/DerivedData/Dinero-frfqupqfiefqgtevsufnmfrmbtcl/Build/Products/Debug-iphonesimulator -filelist /Users/kurko/Library/Developer/Xcode/DerivedData/Dinero-frfqupqfiefqgtevsufnmfrmbtcl/Build/Intermediates/Pods.build/Debug-iphonesimulator/Spine.build/Objects-normal/x86_64/Spine.LinkFileList -install_name @rpath/Spine.framework/Spine -Xlinker -rpath -Xlinker @executable_path/Frameworks -Xlinker -rpath -Xlinker @loader_path/Frameworks -mios-simulator-version-min=8.0 -Xlinker -objc_abi_version -Xlinker 2 -fobjc-arc -fobjc-link-runtime -L/Applications/Xcode7.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator -Xlinker -add_ast_path -Xlinker /Users/kurko/Library/Developer/Xcode/DerivedData/Dinero-frfqupqfiefqgtevsufnmfrmbtcl/Build/Intermediates/Pods.build/Debug-iphonesimulator/Spine.build/Objects-normal/x86_64/Spine.swiftmodule -framework BrightFutures -framework Foundation -framework SwiftyJSON -single_module -current_version 1 -Xlinker -dependency_info -Xlinker /Users/kurko/Library/Developer/Xcode/DerivedData/Dinero-frfqupqfiefqgtevsufnmfrmbtcl/Build/Intermediates/Pods.build/Debug-iphonesimulator/Spine.build/Objects-normal/x86_64/Spine_dependency_info.dat -o /Users/kurko/Library/Developer/Xcode/DerivedData/Dinero-frfqupqfiefqgtevsufnmfrmbtcl/Build/Products/Debug-iphonesimulator/Spine.framework/Spine

Undefined symbols for architecture x86_64:
  "direct generic type metadata pattern for Result.Result", referenced from:
      ext.Spine.BrightFutures.Future<A, B where B: Swift.ErrorType>.onServerFailure <A, B where B: Swift.ErrorType> (BrightFutures.Future<A, B>)((B) -> ()) -> BrightFutures.Future<A, B> in FutureExtensions.o
      ext.Spine.BrightFutures.Future<A, B where B: Swift.ErrorType>.onNetworkFailure <A, B where B: Swift.ErrorType> (BrightFutures.Future<A, B>)((B) -> ()) -> BrightFutures.Future<A, B> in FutureExtensions.o
      ext.Spine.BrightFutures.Future<A, B where B: Swift.ErrorType>.onClientFailure <A, B where B: Swift.ErrorType> (BrightFutures.Future<A, B>)((B) -> ()) -> BrightFutures.Future<A, B> in FutureExtensions.o
  "protocol witness table for <A, B where B: Swift.ErrorType> Result.Result<A, B> : Result.ResultType in Result", referenced from:
      ext.Spine.BrightFutures.Future<A, B where B: Swift.ErrorType>.onServerFailure <A, B where B: Swift.ErrorType> (BrightFutures.Future<A, B>)((B) -> ()) -> BrightFutures.Future<A, B> in FutureExtensions.o
      ext.Spine.BrightFutures.Future<A, B where B: Swift.ErrorType>.onNetworkFailure <A, B where B: Swift.ErrorType> (BrightFutures.Future<A, B>)((B) -> ()) -> BrightFutures.Future<A, B> in FutureExtensions.o
      ext.Spine.BrightFutures.Future<A, B where B: Swift.ErrorType>.onClientFailure <A, B where B: Swift.ErrorType> (BrightFutures.Future<A, B>)((B) -> ()) -> BrightFutures.Future<A, B> in FutureExtensions.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I saw other issues here with the same problem and it seems like setting Result explicitly in the Podfile would solve it, but it doesn't for me. Here's my Podfile.lock:

PODS:
  - Alamofire (3.0.1)
  - BrightFutures (3.0.0):
    - Result (= 0.6.0-beta.4)
  - Realm (0.96.1):
    - Realm/Headers (= 0.96.1)
  - Realm/Headers (0.96.1)
  - RealmSwift (0.96.1):
    - Realm (= 0.96.1)
  - Result (0.6.0-beta.4)
  - Spine (0.2):
    - BrightFutures (~> 3.0)
    - SwiftyJSON (~> 2.3.0)
  - SwiftyJSON (2.3.0)

DEPENDENCIES:
  - Alamofire (~> 3.0)
  - RealmSwift
  - Spine (from `https://github.com/kurko/Spine.git`, tag `swift-2.0`)

EXTERNAL SOURCES:
  Spine:
    :git: https://github.com/kurko/Spine.git
    :tag: swift-2.0

CHECKOUT OPTIONS:
  Spine:
    :git: https://github.com/kurko/Spine.git
    :tag: swift-2.0

SPEC CHECKSUMS:
  Alamofire: 2457e1b2e6c46bb05c3a598c542b7bfd08893775
  BrightFutures: 4a3f46747e5633562bdcef55c9e291bfb7288c34
  Realm: d05e4621f67fb1c36acd4e573ac5b52a407fc2cc
  RealmSwift: 6c96a72b385027d9593b69f6821c697fe843eb68
  Result: f7927152cbaec0c043abb06ba0bc432678818418
  Spine: f3414766a0e500dc150b838af6663288890495ce
  SwiftyJSON: 8d6b61a70277ef2a5d710d372e06e7e2d87fb9e4

COCOAPODS: 0.39.0

Any idea what it could be? Seems like it's either BrightFutures or Result.

Closure passed to flatMap needs return type specified?

Maybe I'm missing something here, but it seems like I must specify the return type of the closure passed to flatMap. When I use just the parameters, it fails to build with error: "Missing argument for parameter 'f' in call".

Doesn't work:

Artist.findOne("1").flatMap { resource, meta in
    return resource.findRelated("albums")
}

Does work:

Artist.findOne("1").flatMap { resource, meta -> Future<([Resource], Meta?)> in
    return resource.findRelated("albums")
}

Support Carthage

It would be nice to have Carthage support. Since Carthage doesn't support semver with extra labels added, we need an intermediate release for that. Also, the scheme must be marked as shared.

Cannot build using Swift 2.0 xcode 7

I keep seeing this compile crashes:

    Undefined symbols for architecture x86_64:
      "direct generic type metadata pattern for Result.Result", referenced from:
          type metadata accessor for Result.Result<Swift.String, BrightFutures.NoError> in Track.o
      "protocol witness table for <A, B where B: Swift.ErrorType> Result.Result<A, B> : Result.ResultType in Result", referenced from:
          static UpshotCore.Track.(demographicData in _355BED5052E6A82D51CFE2CBBD95410A) (UpshotCore.Track.Type)(Swift.String) -> () in Track.o
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

Even when I'm just using test code:

func doStuff() -> Future<String, NoError> {
    let promise = Promise<String, NoError>()

    promise.success("hi")

    return promise.future
}

Is it possible to use 1.0 with Swift 2 until 2.0 is ready?

I'm currently updating my app for Swift 2.0, but can't get my app to run with any of the Swift 2.0 branches using Carthage.

I was able to (after some hacking) get the "swiftier-2.0" branch to build with Carthage, but I kept getting a fatal error whenever I would call onSuccess

"when" promise?

Is there a way to run a set of promises simultaneously with this library?

Conditional Future chaining

Hi,

Just start using BrightFutures and it's really fun! Thanks for the work done :)

I have a question, recently hit this patter two times:

future {
    //Do some computation
    return Result(value: successValue)
}.flatMap { goodValue in
    if goodValue.holdSomeCondition() {
        return doSomethingElse()
    } else {
        return Future(value: goodValue)
    }
}

The question is, how can I avoid the flatMap when the condition isn't true? I found filter but if the condition is false the operation fail. I could do the filter and handle the error but I don't like it much.

Thanks

Use of unresolved identifier 'FutureUtils'

var allFutures = [future1, future2]
FutureUtils.sequence(allFutures).onSuccess { result in
    println("complete")
}

When attempting to use FutureUtils class like above, I get the following error:

Use of unresolved identifier 'FutureUtils'

Looks like the FutureUtils functions were turned into free functions here: 17d4f21. But when I change my code to a "free function":

var allFutures = [future1, future2]
sequence(allFutures).onSuccess { result in
    println("complete")
}

I get this error:

Cannot invoke 'onSuccess' with an argument list of type '((_) -> _)'

Any ideas of how to use the FutureUtils functions? Also, the documentation needs to be updated regarding the FutureUtils methods.

exploring persistent future as notification alternative

Hello,

We would like to have a more functional notification mechanism due to the following problems in current IOS Notification system:

  • the signature is loose (userInfo), not able to take advantage of swift's powerful compile type checking
  • not possible to declare composition like flatMap
  • only classes can post notifications right now

Both notification and futures let user register future events and handlers, so at least conceptually it seems like a natural extension for futures to handle such use case. The main obstacle for the current BrightFutures implementation is the assumption that future is only executed once, any subsequent completion/callback attempts are treated as illegal state. If this behavior can be configured or allow subclass to override, we should be able to use this persistent future to model the notification use case...

thoughts, concerns or gotcha?

callbackExecutionQueue results in EXC_BAD_ACCESS

I'm trying to perform a background operation using BrightFutures. The result (MKPolyline) should be displayed in a MKMapView; thus the callback should be performed on the main thread. However the callbackExecutionQueue results in an extra dispatch queue on top of the main queue. This results in EXC_BAD_ACCESS when the MKPolyline is added to the MapView. When the highlighted line is removed, everything works as expected.

Simplified usage:

        future(context: Queue.global) { () -> Result<MKPolyline> in
            return Result(polyline)
        }
            .onSuccess(context: Queue.main) { polyline in
                self.mapView.addOverlay(polyline)
            }

How to pass a Promise to a method

I have the following:

func promiseProvider() -> Future<User> {
  let promise = Promise<User>()

  promiseHandler(promise)

  return promise.future
}

func promiseHandler<T>(aPromise: T) {
  // do something with he promise:
  promise.success(User())
}

I'm basically trying to pass the promise I created in PromiseProvider to another method (promiseHandler). But for whatever reason, Swift complains:
Cannot invoke 'promiseHandler' with an argument list of type '(Promise<User>)'

Any help would be appreciated, thanks!

ENABLE_BITCODE

Just updated to v3.0.0-beta.1 and Carthage builds, but emits the following error:

ld: warning: -weak_framework is treated as -framework when used with -bitcode_bundle (Xcode setting ENABLE_BITCODE=YES). Weak linking may still happen based on availability mark-up in headers

Concurrent queues

It looks like Queue only exposes a mechanism for creating queues that are DISPATCH_QUEUE_SERIAL.

Is there a reason you decided not to include a way to create a concurrent (DISPATCH_QUEUE_CONCURRENT) queue directly?

Improve future composition

Hi,
I'm having a lot of issues handling the error type when composing futures.

Typically:

let three: Future<Int, NoError> = future(3)
let fut: Future<Int, NSError> = future { //long computation that can fail }
let composed =fut.flatMap { _ in three)

Produces an compile error. But it all works when both futures have the same Error Type.

I expected composed to be of type Future<Int, NSError> because one of the error type is a Void type, only the other one makes sense.
If both types conform to ErrorType then I would expect a generic ErrorType on which I can patten match or a composed error (like a tuple of optional errors).

Is there a way of achieving this behaviour? Is it intended? Am I doing something wrong?

ERROR ITMS-90060: "This bundle is invalid.

Hello.

When using BrightFutures 3.0.0 I'm unable to upload the .ipa to iTunes Connect. It looks like its because of a dependency to Result<0.6.0-beta.4> which makes the transporter freak out.

[15:39:57]: [Transporter Error Output]: ERROR ITMS-90060: "This bundle is invalid. The value for key CFBundleShortVersionString '0.6.0-beta.4' in the Info.plist file must be a period-separated list of at most three non-negative integers."

Is it possible to use a released version instead? :)

Promises Chaining

Hello @Thomvis! Great project! I love the simplicity and how the code works. However, I didn't notice anything in the documentation that would allow for promises chaining like they have in PromiseKit. I also looked at the code as well. The andThen() function only supports side effects and not the same idea as chaining promises and I didn't see anything else in the code that would support that functionality.

Is there something I missed or is promises chaining not part of the design of BrightFutures? Or maybe it's something that's part of the roadmap? Thanks.

Can't pass Tuple to Promise#success

Trying to pass a tuple to Promise#success and getting hit with a compiler warning stating

Missing argument for parameter #2 in call

Code to re-produce the error:

var promise = Promise<(Int, String)>()
promise.success( (1, "hello") )

I'm sure its a problem with the compiler. Tried in Xcode 6.0.1 and 6.1. Thought I would let you know though.

Use robrix/Box instead of own Box type

When using BrightFutures together with other libraries that implement a Box to work around the enum limitations, it can be confusing to have multiple Box types in your codebase. I would suggest using robrix/Box, since that seems to become the standard micro-framework to use for solving this problem.

best way to implement retry

while there are flatMap to chain futures for successful results, what is the best way to do retry kind of logic when there is failure? i.e. how do we chain futures for failure path?

Add new Future extension 'chain'

In my project find useful to chain multiple futures:

  let f = service.create(user, password: user.password).chain { user in
            return self.service.login(user.email, user.password) 
  }

Both the service request returns a Future type.

I created this extension that might be useful to others:

extension Future {
    func chain<U> (f: (T)-> Future<U> ) -> Future<U> {
        let p = Promise<U>()
        self.onComplete { result in
            switch result{
            case .Success(let boxedFuture):
                let future = f(boxedFuture.value)
                future.onSuccess { value in
                    p.success(value)
                }
                future.onFailure{ err in
                    p.failure(err)
                }
                break
            case .Failure(let e):
                p.failure(e)
                break
            }
        }
        return p.future
    }
}

New workaround needed for the "non-fixed multi-payload" bug

In Xcode Beta 6, compiling BrightFutures gives the following error:

'__conversion' functions are no longer allowed

It looks like there is not another way to do an implicit type conversion to workaround the .Success value in the TaskResult enum. Unfortunately, writing the code as it should be written:

public enum TaskResult<T> {
  case Success(T)
  case Failure(NSError)
  ...
}

still results in an "unimplemented IR generation feature non-fixed multi-payload enum" error.

I think it is necessary to expose the unboxing of the generic value to users of the API, but I didn't want to make a pull-request in case you had a good solution.

Dependency 'Result', '0.6-beta.1' causing newer frameworks to break

Your podspec includes:

  s.dependency 'Result', '0.6-beta.1'

Unfortunately this is causing newer frameworks (such as ReactiveCocoa, Swift 2 branch), Moya, and others to break:

dyld: Library not loaded: @rpath/Result.framework/Result
  Referenced from: /Users/zbeckman/Library/Developer/CoreSimulator/Devices/FCFAAFBF-1AB4-4223-9BCC-CA91CBDE96DC/data/Containers/Bundle/Application/9E7272D7-5C66-48F9-9E37-892E41662655/Glimpulse.app/Frameworks/ReactiveCocoa.framework/ReactiveCocoa
  Reason: Incompatible library version: ReactiveCocoa requires version 1.0.0 or later, but Result provides version 0.6.0
(lldb) 

Doesn't work with xCode plugin template

Cocoapods doesn't work at all.

Carthage works but I can't add it to my project properly - it simply doesn't have "General tab" for binaries and etc. And so I can't simply include your library.

Could you advice another solution?

Master doesn't compile on XCode 6.1.1 / Swift 1.1 due to default context parameters

I get following 4 errors when compiling the latest master (6e4ca98) on XCode 6.1.1 / Swift 1.1

/Users/teemu/all/flancer/protos/BrightFutures/BrightFutures/FutureUtils.swift:63:33: error: missing argument for parameter 'f' in call
            return zero.flatMap { zeroVal in

/Users/teemu/all/flancer/protos/BrightFutures/BrightFutures/Future.swift:261:24: error: missing argument for parameter 'callback' in call
        self.onFailure { err in
                       ^
/Users/teemu/all/flancer/protos/BrightFutures/BrightFutures/Future.swift:434:29: error: missing argument for parameter 'f' in call
        return self.flatMap { thisVal -> Future<(T,U)> in
                            ^
/Users/teemu/all/flancer/protos/BrightFutures/BrightFutures/Future.swift:442:29: error: missing argument for parameter 'f' in call
        return self.flatMap { value -> Result<T> in

BrightFutures needs a 1.0 release

This issue is created to track the progress towards releasing a 1.0 version. Please chime in if you have any feedback or requests!

TODO:

  • Reconsider the default callback thread. Callbacks are currently scheduled on a background thread (dispatch global queue) unless an execution context is explicitly given. Maybe it is better to make the main thread the default callback thread. This makes a lot of sense in UIKit apps.
  • I don't like that most methods are defined twice: once with an execution context and once without an execution context. I'd think that it is possible to use optional parameters.
  • The naming of Future.succeeded(..) and f.succeeded() (same goes for failed) is confusing.
  • I'm not sure if the switch-case shorthand provided through f.completed({}, {})(and in a lesser way in f.succeeded { } and f.failed { } adds enough value to justify its existence.
  • Both Future and TaskResult have succeeded, failed and completed (/handle) methods, which seems duplicate.
  • I don't like the use of TaskResultValueWrapper. Luckily, it is almost never exposed through public API.
  • Not all FutureUtils functions from Scala have been ported over yet
  • Decide whether Future should be a pure functional future (two states: pending or complete), more like a 'task' (pending, complete, cancelled, succeeded, failed) or somewhere in between
  • Wrap up 1.0 documentation

Postponed until after 1.0:

  • The methods in FutureUtils should work on any SequenceType, not only on Array
  • Move helper classes (Queue, Semaphore, ExecutionContext) to a separate framework
  • A logo?
  • Add Objective-C support

objetive-c support in protocols using BrightFutures

I'm on version 1.0.1

I have a protocol for some couchbase lite utilities

import Foundation
import BrightFutures

@objc protocol CouchUtilsProtocol {
    var manager: CBLManager { get }

    func indexUpdate(
        databaseName: String,
        designDocName: String,
        viewName: String
    ) -> Future<Bool>

}

I have to add @objc because I use dependency injection ('Typhoon', '3.1.7') on compilation I get:

Method cannot be marked @objc because its result type cannot be represented in objective-c

Is this a bug with BrightFutures Objective-C support not added fully etc (#12 confuses me a bit) or simply because Objective-c do not have generics ?

And/Or do I simply declare the protocol wrongly ~ a here and now work around are very welcome!

BrightFutures 5

Now BrightFutures 3 has been released, it's time to think about what BrightFutures 4 could/should look like. I'd like to gather and track feedback from the community and my own idea's in this issue.

Candidate features:

  • Make it possible to use BrightFutures with just the standard library (possibly needed when Swift becomes Open Source without Foundation)

Any other ideas?

Update: I've renamed the issue from "BrightFutures 4" to "BrightFutures 5", because of the near release of 4 that did not have the aforementioned goals.

Pod build fails - unknown option character `X' in: -Xlinker

I installed the pod using:

pod 'BrightFutures', :git => "https://github.com/Thomvis/BrightFutures.git"

when building the project I get:

(null): /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: unknown option character `X' in: -Xlinker

I'm using Xcode 6.1.1 (6A2008a)
For the time being I just embedded BrightFutures in my project, without cocoapods :-/

Anyone?

full error:

Libtool /Users/yelled3/Library/Developer/Xcode/DerivedData/Smore-bikwhdybmwziuicildyctmstzgwd/Build/Products/Debug-iphonesimulator/libPods-Smore-BrightFutures.a normal i386
    cd /Users/yelled3/Development/smore-ios/Smore/Pods
    export IPHONEOS_DEPLOYMENT_TARGET=8.0
    export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static -arch_only i386 -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.1.sdk -L/Users/yelled3/Library/Developer/Xcode/DerivedData/Smore-bikwhdybmwziuicildyctmstzgwd/Build/Products/Debug-iphonesimulator -filelist /Users/yelled3/Library/Developer/Xcode/DerivedData/Smore-bikwhdybmwziuicildyctmstzgwd/Build/Intermediates/Pods.build/Debug-iphonesimulator/Pods-Smore-BrightFutures.build/Objects-normal/i386/Pods-Smore-BrightFutures.LinkFileList -L/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator -Xlinker -add_ast_path -Xlinker /Users/yelled3/Library/Developer/Xcode/DerivedData/Smore-bikwhdybmwziuicildyctmstzgwd/Build/Intermediates/Pods.build/Debug-iphonesimulator/Pods-Smore-BrightFutures.build/Objects-normal/i386/Pods_Smore_BrightFutures.swiftmodule -framework Foundation -o /Users/yelled3/Library/Developer/Xcode/DerivedData/Smore-bikwhdybmwziuicildyctmstzgwd/Build/Products/Debug-iphonesimulator/libPods-Smore-BrightFutures.a

error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: unknown option character `X' in: -Xlinker
Usage: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static [-] file [...] [-filelist listfile[,dirname]] [-arch_only arch] [-sacLT] [-no_warning_for_no_symbols]
Usage: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -dynamic [-] file [...] [-filelist listfile[,dirname]] [-arch_only arch] [-o output] [-install_name name] [-compatibility_version #] [-current_version #] [-seg1addr 0x#] [-segs_read_only_addr 0x#] [-segs_read_write_addr 0x#] [-seg_addr_table <filename>] [-seg_addr_table_filename <file_system_path>] [-all_load] [-noall_load]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.