Super Duper File Downloader!
- DownPeriscopeLib: Primary functional library for downloading a file
- DownPeriscopeTests: Unit tests written against
DownPeriscopeLib
- DownPeriscopeCLI: Command line executable wrapping
DownPeriscopeLib
- DownPeriscopeApp: Preliminary start of a SwiftUI MacOS GUI for
DownPeriscopeLib
- DownPeriscopeUITests: Empty project for writing tests against
DownPeriscopeApp
- From the command line:
- Run
./build
(always verify scripts before running) - The CLI executable will be output to ```pwd``/bin
, which will be appended to
$PATH` - Run
./bin/down --help
to see documentation
- Open in Xcode (
xed .
) - Run tests with the DownPeriscopeTests scheme
- Started out using Alamofire, as I was most familiar with that library for networking. Half way through realized the
Progress
object updated and returned by Alamofire is incomplete. It does not contain information that may be provided by the underlying NSURLSession;throughput
,estimatedTimeRemaining
. Resource URLs need to support HEAD requests, for validating URLs and getting file size. It seemed like the best idea, until I tried a URL that didn't support HEAD requests. So we can put that under improvements
- Alamofire: Chosen for familiarity of using it for networking in Swift
- RxSwift (includes RxRelay): Prefer reactive programming to imperative. Not yet proficient in Combine
- swift-log: Standard logging library for Swift code
- Swift Argument Parser: Standard library for writing CLI applications in Swift
- Nimble: Fantastic library for writing cleaner testing code
- Xcode build output. How do I specify the location of the executable created by DownPeriscopeCLI
- Expected the
DSTROOT
set in Xcode to do what it says it does. - Instead required using
xcodebuild
and passing a value as command input: xcodebuild install -scheme DownPeriscopeCLI -configuration Release DSTROOT=/
- Expected the
Observable.asSingle()
- Doesn't complete until the source observable completes.
- So without something like
take(1)
, orobserver.onCompleted()
it just waits... ๐คฆ
RxSwift
may have been a bad choice. Given the environment of a CLI as a single threaded process, the reactive nature of RxSwift presents a problem. RxSwift is optimal in a multi-threaded environment with a run loop to prevent blocking- This particular issue
- Support resources URLs that don't respond to HEAD requests
- Have
Periscope
andDefaultRepository
better handle their DispatchQueues - Add blocking functions to
Periscope
that abstract away the RxSwift for ease of use from the command line - Show throughput as a human readable string (currently B/s)
- Use
RunLoop
? OrProcess
? Instead ofSemaphore
ArgumentParser
now supports async/await:- https://github.com/rensbreur/SwiftTUI