[swift-evolution] Pitch: Much better-performing, Swift-native Progress replacement

Charles Srstka cocoadev at charlessoft.com
Tue Feb 21 15:22:05 CST 2017

> On Feb 21, 2017, at 2:52 PM, Rod Brown <rodney.brown6 at icloud.com> wrote:
> Ah sorry! To be honest, I didn't see the part about your interoperability with NSProgress trees!
> That said, it does seem to be a hacky solution. A better solution would be a backing NSProgress that is linked and lazily created when casts occur, perhaps? This would map far cleaner to current bridging techniques in the Swift Overlay?
> Sorry, I haven't looked at how your internal implementation is done. I'm just going off the description in your email. I'm curious to get involved in creating a better progress API if we can find a way that is superior and still cleanly interoperates.

Agreed that it’s hacky, which is why I tried to do my best to separate the Objective-C compatibility crud from the rest of the code, so it can be easily yanked and replaced with something better if we think of one.

With that said, the way I’m currently doing it is inspired by the way the Data<->NSData bridging works. My class, CSProgress, has a “backing” property. This property stores an enum with two cases, one for Swift, and one for Objective-C. The Swift backing contains the basic implementation, and the Objective-C one wraps an NSProgress, forwarding all changes to it and registering for KVO notifications on it for the purpose of keeping its own clients notified. Each case contains an associated type that handles all the primitives. There’s also a private NSProgress subclass (unimaginatively named “BridgedNSProgress”) that wraps a CSProgress, and forwards NSProgress changes to it.

What you get if you:

- create a CSProgress from scratch, or from another CSProgress: A CSProgress, with the Swift backing.

- bridge an NSProgress to a CSProgress: If the NSProgress was a BridgedNSProgress, you get the CSProgress it was wrapping. Otherwise, you get a CSProgress with the Objective-C backing.

- bridge a CSProgress to an NSProgress: If the CSProgress uses the Objective-C backing, you get the NSProgress it was wrapping. Otherwise, you get a BridgedNSProgress wrapping the CSProgress.

If no bridging occurs and you’re using CSProgress all the way down, no NSProgress objects get involved.


More information about the swift-evolution mailing list