Code Monkey home page Code Monkey logo

then's Introduction

Try it!

Download our starter iOS Project and see how our tools fit together in a typical iOS App:
Download Starter Project

Our mission

FreshOS is on a mission to provide iOS developers with simple tools to solve problems that 99% of us have. We believe developers should focus on valuable things like app logic, rather than casting the values of a JSON Parsing \o/. We thrive to make apis as simple as possible, yet flexible enough to handle 99% of use-cases. We believe in Unix-style libraries, that do one thing and do it well. Since we have control over those tools, they fit together nicely.

Solutions

AutoLayout - Stevia 🍃 Star

Write expressive autolayout code, readable and maintainable

Networking - ws ☁️ Star

Write concise networking code that leverages the power of Alamofire, promises and JSON Parsing

Async - then 🎬 Star

Make Async code delightful with Promises

Write minimalist JSON Parsing that infers type and doest get in the way of your models

Reduce Stress & Errors

Emit warnings and errors when Localizations are missing or unused

Emit warnings and errors when assets are missing or unused

Integrate Faster

Generate Swift code from Sketch designs

Who we are

<script src="//cdn.jsdelivr.net/github-cards/latest/widget.js"></script>
<script src="//cdn.jsdelivr.net/github-cards/latest/widget.js"></script> Let's not forget the 100+ people that contributed via pull requests, issues or even just talking to them :) This wouldn't be possible without them <3

Production ready

Our libraries have been Downloaded 175k+ times and already more than 3700+ Apps use freshOS tools!

Source : Cocoapods

Testimonials <3

Sketch to Swift is an amazing way to build quick prototypes. Always using to build small samples for my freelancing clients. Also using AssetChecker so I'm never messing up and breaking my code because I deleted or changed the name of an asset. I appreciate the work they put in freshOS and I'm glad AwesomeiOS has all of them
Lucas Farah - Admin @Awesome-iOS

Just want to say I love your different solutions. It's smart clean and easy to use.
Florent Douine - iOS Developer

Man I just wanted to tell you that Stevia, then, Arrow and ws is the most beautiful thing ever made! Really! This is beautiful!
Mauran Muthiah - Developer

This kind of libraries really is perfect. Very focused, obviously simple and useful, no magic, and small. They make development easier one step at a time.
Anonymous - HackerNews

Support/Contact

You can raise a github issue on the project you need support with or contact us at [email protected]

Hosting sponsored with 💚 by Muxu.Muxu

<script async defer src="https://buttons.github.io/buttons.js"></script>

then's People

Contributors

crarau avatar ezisazis avatar florianbuerger avatar gitter-badger avatar ksmandersen avatar laixyf avatar luizfelipeairesoares avatar maxkonovalov avatar mdcarter1 avatar michalsrutek avatar neoneye avatar qhua948 avatar roczhang9673 avatar s4cha avatar tmcw avatar ykyouhei 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

then's Issues

Library name

Thank you for providing such a great library.

Nevertheless the name shall be update in CamelCase

import Then

looks better than

import then

Xcode 11.2.1: fatal error: Unexpected Swift version

I seem unable to compile the current master with the latest release of Xcode. I have a log if that's helpful - but am not sure if 11.2.1 is officially supported yet or not?

Any advice would be appreciated. Thx

export variant=normal
/bin/sh -c /Users/jenkins/Library/Caches/org.carthage.CarthageKit/DerivedData/11.2.1_11B500/then/5.1.1/Build/Intermediates.noindex/ArchiveIntermediates/then/IntermediateBuildFilesPath/Then.build/Release-iphoneos/Then.build/Script-9962ADBE1D58534D005769CD.sh
fatal error: Unexpected Swift version: file /tmp/swiftlint-20170407-4750-thxk9c/Source/SwiftLintFramework/Models/SwiftVersion.swift, line 38
/Users/jenkins/Library/Caches/org.carthage.CarthageKit/DerivedData/11.2.1_11B500/then/5.1.1/Build/Intermediates.noindex/ArchiveIntermediates/then/IntermediateBuildFilesPath/Then.build/Release-iphoneos/Then.build/Script-9962ADBE1D58534D005769CD.sh: line 6: 42465 Illegal instruction: 4 swiftlint
Command PhaseScriptExecution failed with a nonzero exit code

** ARCHIVE FAILED **

The following build commands failed:
PhaseScriptExecution Run\ Script /Users/jenkins/Library/Caches/org.carthage.CarthageKit/DerivedData/11.2.1_11B500/then/5.1.1/Build/Intermediates.noindex/ArchiveIntermediates/then/IntermediateBuildFilesPath/Then.build/Release-iphoneos/Then.build/Script-9962ADBE1D58534D005769CD.sh
(1 failure)

"Incompatible Swift version - framework was built with 4.2 (swiftlang-1000.11.37.1 clang-1000.11.45.1) and the local version is 4.2.1 (swiftlang-1000.11.42 clang-1000.11.45.1)."

carthage install method: [ ] .pkg, [ x] homebrew, [ ] source
which carthage:/usr/local/bin/carthage
carthage version: 0.31.2
xcodebuild -version: Xcode 10.1\Build version 10B61
Are you using --no-buildno
Are you using --no-use-binariesno
Are you using --use-submodulesno
Are you using --cache-buildsno
Are you using --new-resolverno

cartfile

github "freshOS/then" "4.2.0"

*** Downloading then.framework binary at "Xcode10 & Swift 4.2"
***  Skipped installing then.framework binary due to the error:
	"Incompatible Swift version - framework was built with 4.2 (swiftlang-1000.11.37.1 clang-1000.11.45.1) and the local version is 4.2.1 (swiftlang-1000.11.42 clang-1000.11.45.1)."

Cocoapods support

Hi!

I saw that Cocoapods is deprecated now, I would like to suggest adding support again since it doesn't change the way to develop for SPM as well.

The library is a very useful library and Cocoapods still in use for a huge number of projects out there, would be nice to keep using this the way it is.

Thanks.

.progress should be able to return Progress, not Float

Currently, this library can only return Float value when using .progress directive.
However, Alamofire and other network libraries return Progress instance instead of Float.

I think thenPromise should be able to return Progress instance on .progress directive.
For example:

return Promise<URL> { resolve, reject, progress in
    Alamofire.download(escapedUrl, to: destination)
        .downloadProgress { downloadProgress in // downloadProgress is Progress class
            // let currentProgress = Float(downloadProgress.completedUnitCount) / Float(downloadProgress.totalUnitCount)
            // progress(currentProgress)
            progress(downloadProgress) // <- should be able to write like this
        }
        .response { response in
            ...
        }
}

Cloning the library takes a long while

Cloning the library takes a long while. Receiving objects downloads 359MB and Resolving deltas is very long.

git clone https://github.com/freshOS/then.git
Cloning into 'then'...
remote: Counting objects: 897792, done.
remote: Total 897792 (delta 0), reused 0 (delta 0), pack-reused 897792
Receiving objects: 100% (897792/897792), `359.35 MiB` | 32.12 MiB/s, done.
Resolving deltas:  59% (234493/391788)  

Ambiguous use of 'init(callback:)'

I'm trying to use Stevia and ws and am getting the following error in this included pod:

.../Pods/thenPromise/Source/Promise+Delay.swift:30:16: Ambiguous use of 'init(callback:)'

I've tried the usual update/install of pods but no joy. Any advise would be appreciated as I've not used these libraries before and was just starting to like it, but couldn't compile.

When I tried to use the freshOS starter project I got: Module compiled with Swift 4.0 cannot be imported in Swift 4.1

Thanks

Data race

Thread sanitizer is often complains about data race in "_synchronize" function:

private let lockQueueSpecificKey = DispatchSpecificKey<Void>()
private lazy var lockQueue: DispatchQueue = {
	let queue = DispatchQueue(label: "com.freshOS.then.lockQueue", qos: .userInitiated)
	queue.setSpecific(key: self.lockQueueSpecificKey, value: ())
	return queue
}()

private func _synchronize<U>(_ action: () -> U) -> U {
	if DispatchQueue.getSpecific(key: lockQueueSpecificKey) != nil {
		return action()
	} else {
		return lockQueue.sync(execute: action) // <- Data race detected here
	}
}

That's probably due to using lockQueue from many threads simultaneously. And lockQueue is a lazily computed variable, which is not thread safe.

Memory Leaks

I've found an instance where I can produce a memory leak when using a Promise from within a new Promise:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        noleaky().finally {

        }

        leaky().finally {
            
        }
    }

    func leaky() -> Promise<Void> {
        return Promise { [unowned self] resolve, reject in
            self.doSomething(for: 0)
                .then(self.doSomething)
                .onError(reject)
                .finally(resolve)
        }
    }

    func noleaky() -> Promise<Void> {
        return doSomething(for: 0)
            .then(doSomething)
            .then(Promise.resolve())
    }

    func doSomething(for blah: Int) -> Promise<Int> {
        return Promise.resolve(3)
    }

}

I'm not sure if this is expected or not? Sample project is attached.
ThenLeakExample.zip

WhenAll always succeeds

whenAll always calls then block, disregarding its inner promises success or fail:

let promise1 = Promise<Void> { (resolve, reject) in
    print("promise1")
    reject(NSError())
}

let promise2 = Promise<Void> { (resolve, reject) in
    print("promise2")
    reject(NSError())
}

whenAll(promise1, promise2)
    .then { _ in
        print("whenAll success")
    }
    .onError { _ in
        print("whenAll failed")
    }
    .finally { _ in
        print("whenAll finally")
}

Output:

promise1
promise2
whenAll success
whenAll finally

Is this by design? Would be good to get onError called when one of the promises fails.

Package.swift needs upgrade for swift 4.

I tried to use 3.0.0 in a project, compiling with Swift 4.0 from command line ... Got:

.../Source/Promise.swift:204:9: error: 'promiseProgressCallBack' is inaccessible due to 'private' protection level
        promiseProgressCallBack = { resolve, reject, progress in
        ^

.../Promise.swift:39:17: note: 'promiseProgressCallBack' declared here
    private var promiseProgressCallBack: ((_ resolve: @escaping ((T) -> Void),
                ^

.../Promise.swift:218:9: error: 'promiseProgressCallBack' is inaccessible due to 'private' protection level
        promiseProgressCallBack = { resolve, reject, progress in
        ^

.../Promise.swift:39:17: note: 'promiseProgressCallBack' declared here
    private var promiseProgressCallBack: ((_ resolve: @escaping ((T) -> Void),

It seems if you're using swift 4 toolchain, when you build 'then' from command line, it's built using swift 3 mode due to old manifest file format.
Since Swift 4 changed access control rules the errors above appear.

When I changed 'then' Package.swift to:

// swift-tools-version:4.0
import PackageDescription

let package = Package(
   name: "then",
   products: [
      .library(
         name: "then",
         targets: ["then"]),
      ],
   dependencies: [
   ],
   targets: [
      .target(
         name: "then",
         dependencies: [])
      ]
)

Project built with no errors.

I created a new subfolder 'then' inside Sources and moved the source files to the folder to be able to compile the code, since new package manager requires it... (I tried with path property but with no success)

path: This property defines the path to the top-level directory containing the target's sources, relative to the package root. It is not legal for this path to escape the package root, i.e., values like "../Foo", "/Foo" are invalid.

Progress not getting called

Hi, struggling with the semantics for progress block

Here are two scenarios:

getFile()
        .then(uploadFile)
        .progress {
            /// Not getting called
        }
getFile()
        .then {
            self.uploadFile(fileUrl: $0)
                    .progress {
                        /// Called OK
                    }
        }

Is this the expected behavior? Or am I doing something wrong in the first case?

Thanks

whenAll.then issue in then execution

Hello, I have an issue with the whenAll feature.

The promises are executed successfully but the then block is never called.
here is a code sample:

return Promise { resolve, reject  in
    let asyncMatchers = matchers.filter { $0.asyncMatch }
    var promises = [Promise<MatchResult>]()
    for matcher in asyncMatchers {
        promises.append(matcher.matchTermsAsync(from: phraseComponents))
    } 
    Promises.whenAll(promises).then { results in
        resolve(results)
    }
}

As walk arround I managed to make it work like this:

return Promise { resolve, reject  in
    let asyncMatchers = matchers.filter { $0.asyncMatch }
    async {
        for matcher in asyncMatchers {
               let matchResults = try await(matcher.matchTermsAsync(from: phraseComponents))
               results.append(contentsOf: matchResults)
         }
    }.then {
         resolve(results)
    }
}

Can you see any obvious reason why the .then block in never invoked?
Does whenAll support concurrent execution for the promises?

Thank you.

M1 - Apple Silicon with arm64 excluded architecture issue

Hi all

In order to run my project in Apple Silicon I had to exclude the arch arm64.
But I'm getting this error, could you add support to this please?

Could not find module 'Then' for target 'x86_64-apple-ios-simulator'; found: arm64-apple-ios-simulator, at: /Users/.../.../Developer/Xcode/DerivedData/..../Build/Products/Debug-iphonesimulator/Then.swiftmodule

To reproduce it:

In M1 - Apple Silicon Mac:

  1. -Create new project
  2. Instal Swift package Then 6.0.0
  3. In build settings add excluded Architecture for Any iOS simulator SDK = arm64

Screen Shot 2022-05-17 at 18 18 40

4. Import Then in ViewController.swift 5. Try to compile the project

Screen Shot 2022-05-17 at 18 15 06

Swift 5 support

Sorry, I probably should've opened this issue before the PR. I'm mostly pasting the info from #51 here so that we can discuss these better. I've begun working on integrating the changes necessary to allow compilation of the project on Xcode 10.2 using its Swift 5 toolchain.

All tests are currently passing, but I've had to relax the timings on some of them from 0.3 to 0.5 seconds in order to run successfully on simulators. Is that a problem?

Some changes, such as the ones made to Promise will be breaking the current API, as the compiler can't (any longer?) disambiguate the types on its own. I'm open to ideas on these solutions!

Thanks!

Privacy Manifest

Hello,

At WWDC23 Apple announced that apps and SDKs that make use of certain "required reason" APIs etc will need to provide a privacy manifest.
Does Then need to include this manifest?

Here are some useful references:

https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_data_use_in_privacy_manifests
https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api
https://developer.apple.com/videos/play/wwdc2023/10060/

Thanks

whenAll not fulfilled nor rejected

Hello, I have an issue with whenAll

I have a piece of code like this:

func download(from url: URL) -> Promise<Void> { ... }
...
let promises = downloadURLs.map(download(from:))
Promises.whenAll
  .then { ... }
  .onError { _ in ... }

This code randomly fails. I can find out that each of download promises are fulfilled but neither then nor onError are called.

Then I wrote a test:

    private let concurrentQueue = DispatchQueue(
        label: "then.whenAll.test.concurrent",
        qos: .userInitiated,
        attributes: .concurrent)
    func testWhenAllAllAsynchronous() {
        let values = (1...10).map { $0 }
        let promises: [Promise<Int>] = values.map { value in
            return Promise { fulfill, _ in
                self.concurrentQueue.async {
                    fulfill(value)
                }
            }
        }
        let block = expectation(description: "Block called")
        Promises.whenAll(promises).then { array in
            XCTAssertEqual(Set(array), Set(values))
            block.fulfill()
        }
        waitForExpectations(timeout: 3, handler: nil)
    }

and it fails.

Looks like the temporary variable var ts = [T]() has a thread race issue, and registerFinally is not an atomic operation.

Thank you.

Promise callback opportunity

Callback will never be called:
image

Callback will be called if write "then" logic:
image

Compare with javascript (Callback will run at once while creating a promise):
image

Okay, which is better one?

swift 3 with pod file

hello I am using pod in swift 3

pod 'thenPromise', :git => 'https://github.com/freshOS/then.git', :branch => 'swift3' #swift 3

but it doesn't work can you tell me right syntax

Synchronous promises don't chain properly

This is a corner case but could be interesting support it. When we have 3 promises encapsulating synchronous code, if we try to chain all of them, the chaining is not working properly.

func promiseA() -> Promise<Int> { 
    return Promise { resolve, reject in 
        print("Promise A")
        resolve(result: 1) 
    } 
}

func promiseB() -> Promise<Int> {
    return Promise { resolve, reject in
        print("Promise B")
        resolve(result: 2)
    }
}

func promiseC() -> Promise<Int> {
    return Promise { resolve, reject in
        print("Promise C")
        resolve(result: 3)
    }
}

If we chain all of them, A and B are executed but C doesn't it:

promiseA().then(promiseB()).then(promiseC())

I think the problem in this case is in the method:

    public func then<X>(p:Promise<X>) -> Promise<X>{
        p.isFirstPromise = false
        successBlock = { t in p.start() }
        startPromiseIfNeeded()
        return p
    }

When then is executed over promiseA, is defined the successBlock and startPromiseIfNeeded provokes promiseA starts, at the end of promiseA the successBlock is executed and promiseB starts although as all the code is synchronous promiseA and promiseB are executed in the same cycle while promiseB still doesn't have a successBlock assigned to execute promiseC. So when then is executed over promiseB, this is already started and fulfilled, startPromiseIfNeeded never calls start.

I think a possible solution would be the next code although I'm not completely confident about it

    public func then<X>(p:Promise<X>) -> Promise<X>{
        p.isFirstPromise = false
        if state == .Fulfilled {
            p.start()
        } else {
            successBlock = { t in p.start() }
            startPromiseIfNeeded()
        }
        return p
    }

Really this is a corner case, because per definition a Promise encapsulates some asynchronous operation and in this situation we are encapsulating synchronous operations, but could be interesting because some times we need to simulate the results of async operations inside Promises.

Wrapping completion handlers

Awesome lib, I love it. I wondered if anyone had any advice on wrapping completion handlers, so I can convert a standard callback to a promise?

In PromiseKit I'd normally do something like -

func doSomething() -> Promise<Bool> {
   return Promise<Bool> { seal in 
       someLibrary.doSomeTask(handler: { value in
           seal.fullfill(value)

           // we also have seal.reject(error), seal.resolve(value, error)
       })
   }
}

I'd love to be able to migrate and only use Then if possible, sadly I have a couple of legacy services that I must wrap to create promises.

Promise does not deinit

In Promise.swift add debug outputs

    public init(callback: @escaping (_ resolve: @escaping ResolveCallBack,
        _ reject: @escaping RejectCallBack) -> Void) {
        promiseCallBack = callback
        print("+")
    }

    public init(callback: @escaping (_ resolve: @escaping ResolveCallBack,
        _ reject: @escaping RejectCallBack, _ progress: @escaping ProgressCallBack) -> Void) {
        promiseProgressCallBack = callback
        print("+")
    }

    deinit { print("-") }

Then if you run

func foo() {
    let a = Promise { r, _ in r() }
    let b = Promise { r, _ in r() }
    a.then{ print(".") }.then(b).then{ print(".") }
}
foo()

The output will be

+
+
+
.
+
+
+
+
.

After adding [weak self] to all registerThen<X> blocks

let p = Promise<X> { [weak self] resolve, reject in

and changing passAlongFirstPromiseStartFunctionAndStateTo<X> to

        } else {
            promise.initialPromiseStart = { [weak self] self?.start() }
        }

The output:

+
+
+
.
+
+
+
+
.
-
-

There are still strong ref cycles somewhere, any ideas?

Await is working ?

Hi all,

Like PromiseKit wrapping delegates example on CLLocationManager, I try to do the same with freshOS/then.

https://github.com/mxcl/PromiseKit/blob/master/Documentation/CommonPatterns.md#wrapping-delegate-systems

The promise is working with:

LocatorManager.shared.getLocation()
            .timeout(0.5)
            .then { location in
                print("then" + String(data: try! JSONEncoder().encode(location), encoding: .utf8)!)
            }.onError { error in
                print(error)
        }

but not with await, my app is blocked. An idea..?

Thank a lot for helping.

do {
            let location = try await(LocatorManager.shared.getLocation().timeout(0.2))
            print("await" + String(data: try! JSONEncoder().encode(location), encoding: .utf8)!)
            
        } catch {
            print(error)
        }

All LocatorManager singleton class code

import Foundation
import CoreLocation

public class LocatorManager: NSObject, CLLocationManagerDelegate {
    static let shared = LocatorManager()
    private let locationManager = CLLocationManager()
    private var promise = Promise<DeviceLocation>()
    
    override private init() {
        super.init()
        locationManager.delegate = self
        locationManager.requestWhenInUseAuthorization()
    }
    
    func getLocation() -> Promise<DeviceLocation> {
        self.promise = Promise<DeviceLocation> { _, reject, _ in
            if !CLLocationManager.locationServicesEnabled() {
                reject(LocatorError.locationServiceDisabled)
                return
            }
            
            if CLLocationManager.authorizationStatus() == .authorizedWhenInUse ||
                CLLocationManager.authorizationStatus() == .authorizedAlways {
                    self.locationManager.requestLocation()                
            } else {
                reject(LocatorError.noUserAuthorization)
            }
        }
        
        return self.promise
    }
    
    public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let deviceLocation = DeviceLocation(latitude: locations.last!.coordinate.latitude,
                                            longitude: locations.last!.coordinate.longitude)
        self.promise.fulfill(deviceLocation)
    }
    
    public func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        self.promise.reject(error)
    }
}

public enum LocatorError: Error {
    case locationServiceDisabled
    case noUserAuthorization
}

Add watchOS platform support

Would it be possible to add watchOS platform support for this project? If not, what are the limitations in supporting watchOS?

Resolve promise on main thread

👋

Is there a way to resolve a promise on the main thread?

I saw a resolveOnMainThread() on the readme, but couldn't find any reference to it in the source code.

Thanks

Readme code snippet typoed

fetchUserId().then { id in
    print("UserID : \(id)")
}.onError { e in
    print("An error occured : \(e)")
}.finally {M
    print("Everything is Done :)")
}

see }.finally {M

Thread explosion causing a deadlock?

Hi, we are using Then together with Vapor for a swift server side project. While doing some performance tests, we noticed that our current implementation is not able to support more than 64 concurrent requests without collapsing and being stuck in what it seems to be a deadlock.

For each request, we are always creating an async block and inside we'll be calling multiple async methods with await.

I've been able to reproduce the same issue using one of your tests. Our methods for each requests are similar to the testAsyncAwaitChainWorks one in AsyncAwaitTests class. If you modify that method to do the same code 100 times, it will look like this:

func testAsyncAwaitChainWorks() {
  for _ in 0..<100 {
    let exp = expectation(description: "")
    print("starting new task")
    async {
      print("starting async block")
      let userId = try await(fetchUserId())
      XCTAssertEqual(userId, 1234)
      let userName = try await(fetchUserNameFromId(userId))
      XCTAssertEqual(userName, "John Smith")
      let isFollowed = try await(fetchUserFollowStatusFromName(userName))
      XCTAssertFalse(isFollowed)
      exp.fulfill()
      print("finishing async block")
    }
  }
  waitForExpectations(timeout: 1000.0, handler: nil)
}

Executing this will print 100 times starting new task, but it will only print 64 times starting async block and finishing async block will not be printed at all, the execution will never finished.

Is there any way of avoiding this kind of issues and being able to use async/await approach while supporting a lot of concurrent requests?

Mapping a response to `Void`

I was thinking perhaps there may be some benefit to mapping a promise result to Void.

For example, I do not care about the result of a task, only that it has completed.

I use the VIPER pattern quite heavily and a lot of the time I simply want my components to know another task has finished, without needing to give it context of models, or responses etc.

This could be a fairly simple addition -

extension Promise {
    func asVoid() -> Promise<Void> {
        return .resolve(())
    }
}

This would allow me to have chains within the call that had context of the response and made use of it's model, but the original trigger could simply move along to the next promise in it's async block.

Retain Cycle in registerThen

Found this in Promise+then.swift:

 @discardableResult  public func registerThen<X>(_ block: @escaping (T) -> Promise<X>)
        -> Promise<X> {
            let p = Promise<X>()
            switch state {
            case let .fulfilled(value):
                registerNextPromise(block, result: value,
                                    resolve: p.resolvePromise, reject: p.rejectPromise)
            case let .rejected(error):
                p.rejectPromise(error)
            case .pending:
                blocks.success.append({ t in
                   // RETAIN CYCLE HERE
                    self.registerNextPromise(block, result: t, resolve: p.resolvePromise,
                                             reject: p.rejectPromise)
                })
                blocks.fail.append(p.rejectPromise)
            }
            p.start()
            passAlongFirstPromiseStartFunctionAndStateTo(p)
            return p
    }

Notice the retain cycle in the append block. Was this intentional? Looking back in the code history it seems a [weak self] was used at one point but was then removed later.

Can not upload update of app to App Store after name change

First of all: this framework rocks!

Just tried uploading a new version of our app to the app store and was prompted with an error: "Code signing "Then.framework" failed." This happened just after the name change to "Then". All imports has been updated to "Then" so it builds correctly.

Any clues on how to fix this?

Cheers,

Ted

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.