Skip to content

4.0.0 Beta 5

Pre-release
Pre-release
Compare
Choose a tag to compare
@danthorpe danthorpe released this 28 Nov 16:48
· 385 commits to development since this release

4.0.0 Beta 5

Beta 5 is primarily about refinements and bug fixes.

Breaking API Changes

  1. #574, #583 Removal of GroupObserverProtocol

    This protocol was to allow observer to be attached to a group, and be informed when children are added to the group. Instead, this functionality has been rolled into ProcedureObserver.

  2. #601, #605 Refactor of ResultInjection.

    The ResultInjection protocol has been overhauled, again. The major changes here, are:

    • Change to a pair of protocols, InputProcedure and OutputProcedure, with associated type Input and Output respectively. This change is to avoid overloading the "result" concept.
    • Renames PendingValue<T> to just Pending. Both protocols have properties which are Pending, which in turn maintains the .pending and .ready cases.
    • ProcedureResult<T> which is an either enum type, which is either .success(value) or .failure(error). The error is not an associated type - so any Error will do.
    • OutputProcedure's output property is Pending<ProcedureResult<Output>> which means that it can now capture the procedure finishing with an error instead of just a value.

    In addition, Procedure subclasses which conform to OutputProcedure can use the following API:

    /// Finish the procedure with a successful result.
    finish(withResult: .success(outputValue))
    
    /// Finish the procedure with an error.
    finish(withResult: .failure(anError))    

    To support OutputProcedure with a Void output value, there is also a public constant called success which represents .success(()).

    All other APIs have been changed to reflect this change, e.g. injectResult(from: dependency) works as before if your receiver is updated to conform to OutputProcedure.

  3. #561 Rename & refactor of ResilientNetworkProcedure

    NetworkProcedure now performs the functionality of network resiliency, in addition to automatic handling of client reachability errors.

New Features

  1. #565 NetworkDownloadProcedure

    Thanks to @yageek for adding support for network file downloads.

  2. #567 NetworkUploadProcedure

    Thanks to @yageek for adding support for network file uploads.

  3. #570 ProcessProcedure

    Thanks to @yageek for adding support for wrapping Process (previously NSTask) to ProcedureKitMac.

  4. #542, #599 CloudKitProcedure

    This is a wrapper class for running Apple's CKOperation subclasses.

  5. #587 Mutual Exclusion categories

    Mutually exclusive conditions now support arbitrary category names, which means that a condition can be used to add mutual exclusion to any number of disparate procedures.

  6. #563 NetworkProcedure (called NetworkReachableProcedure here)

    NetworkProcedure is a wrapper procedure for executing network procedures. It has full support for handling client reachability issues, and resilient handling of client and server errors.

  7. #569 Profiler

    Thanks to @yageek for implementing the Profiler which is a ProcedureObserver and can be used to report timing profiles of procedures.

  8. #593 Supports the merging of collections of Procedure subclasses which all conform to ResultInjection.

    These APIs flatMap, reduce and gathered() each return another procedure which will depend on all other procedures in the collection, and then perform synchronous processing of the results. For example, either just gather the results into a single array, or flat map the resultant array into an array of different types, or reduce the resultant array into a single type.

  9. #606, #607 AsyncResultProcedure etc.

    AsyncResultProcedure, AsyncBlockProcedure and AsyncTransformProcedure support asynchronous blocks. Each procedure's initialiser receives a finishWithResult closure, which must be called to finish the procedure. For example:

    let procedure = AsyncBlockProcedure { finishWithResult in
        asyncTask {
            finishWithResult(success)
        }
    }

Bug Fixes etc

  1. #562 Fixes a typo in LocationServicesRegistrarProtocol
  2. #566 Fixes Condition so that it can support result injection.
  3. #575 Improves the performance of add(observer: ).
  4. #568 Opens up add(operation: Operation) for overriding by subclasses. Thanks to @bizz84.
  5. #579 Adds more test coverage to GroupProcedure.
  6. #586 Fixes HTTPRequirement initializers. Thanks to @yageek for this one.
  7. #588 Fixes bug where using the produce(operation:) from a GroupProcedure subclass was failing. This was actually introduced by other changes since Beta 4.
  8. #591 Adds some missing equality checks in ProcedureKitError.Context.
  9. #600 Minor changes to remove @testable imports.
  10. #602 Adds stress tests for cancelling RepeatProcedure.
  11. #603 Adds more GroupProcedure tests.
  12. #608 Uses the internal queue for the DispatchAfter delayed functionality in NetworkActivityController instead of the main queue.
  13. #611 Restores import Foundation etc where needed in all classes, which makes Xcode 8 a little happier - although not strictly necessary.
  14. #615 Fixes issues where BackgroundObserver was not removing notification observers.
  15. #619 Fixes some issues with location related procedures.

Thread Safety bug fixes

Recently, @swiftlyfalling has been fixing a number of thread safety issues highlighted either from our own stress tests, or from the Thread Sanitizer.

  1. NetworkObserver - #577
  2. StressTestCase - #596
  3. RepeatProcedure - #597
  4. Procedure - #598
  5. NetworkDataProcedure etc - #609
  6. BackgroundObserver - #614
  7. DelayProcedure - #616

Thanks so much to everyone who has contributed thus far, for this release, @swiftlyfalling has been doing loads of fantastic work finding and fixing subtle thread safety issues - amazing stuff 💚. Thanks also to @yageek who helped implement procedure subclasses in ProcedureKitNetwork while I was on holiday!