Wrapper around URLSession and URLSessionTask to enable seamless integration with Operation / OperationQueue.
Micro-library designed to allow seamless cooperation between URLSession(Data)Task and Operation(Queue) APIs.
URLSession framework is, on its own, incompatible with Operation API. A bit of trickery is required to make them cooperate. (note: do read those blog posts)
I have extended URLSessionTask with additional properties of specific closure types which allows you to overcome this incompatibility.
OperationQueue
and Operation
are great API to use when...
If this is too complex for your needs, take a look at Alley — it’s much simpler but surprisingly capable.
Essentials
folder from here into your projectAvenue
and Alley
, just copy them into your project.ServerTrust
as well.· · ·
If you prefer to use dependency managers, see below. Releases are tagged with Semantic Versioning in mind.
CocoaPods is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate Avenue into your Xcode project using CocoaPods, specify it in your Podfile
:
pod 'Avenue', :git => 'https://github.com/radianttap/Avenue.git'
Carthage is a decentralized dependency manager that automates the process of adding frameworks to your Cocoa application.
You can install Carthage with Homebrew using the following command:
$ brew update
$ brew install carthage
To integrate Avenue into your Xcode project using Carthage, specify it in your Cartfile
:
github "radianttap/Avenue"
(1) Subclass NetworkSession
to create your API wrapper, configure URLSession
for the given service endpoints and make an OperationQueue
instance.
final class WebService: NetworkSession {
private init() {
queue = {
let oq = OperationQueue()
oq.qualityOfService = .userInitiated
return oq
}()
let urlSessionConfiguration: URLSessionConfiguration = {
let c = URLSessionConfiguration.default
c.allowsCellularAccess = true
c.httpCookieAcceptPolicy = .never
c.httpShouldSetCookies = false
c.requestCachePolicy = .reloadIgnoringLocalCacheData
return c
}()
super.init(urlSessionConfiguration: urlSessionConfiguration)
}
// Local stuff
private var queue: OperationQueue
}
(2) Model API endpoints in any way you want. See IvkoService example in the Demo app for one possible way, using enum with associated values.
The end result of that model would be URLRequest
instance.
(3) Create an instance of NetworkOperation
and add it to the queue
let op = NetworkOperation(urlRequest: urlRequest, urlSession: urlSession) {
payload in
// ...process NetworkPayload...
}
queue.addOperation(op)
It will be automatically executed. You can also supply the desired number of automatic retries, among other arguments.
See
AssetManager
andIvkoService
in the Demo project, as examples. Write as many of these as you need.
Avenue handles just the URLSession boilerplate: URLErrors, HTTP Auth challenges, Server Trust Policy etc.
The only assumption Avenue makes is that web service you connect to is HTTP(S) based.
NetworkPayload
is particularly useful struct since it aggregates URLRequest
+ response headers, data and error and gives you simple speed metering capability by recording start and end of each network call.
ServerTrustPolicy
is directly picked up from Alamofire v4; it’s great as it is and there’s no need for me to reinvent the wheel.
Set ServerTrustPolicy.defaultPolicy
in your project configuration file (or wherever is appropriate) to the value you need for each app target you have. For example, if you connect to some self-signed demo API host:
ServerTrustPolicy.defaultPolicy = .disableEvaluation
Note: AsyncOperation
is my own simple subclass which makes sure that Operation
is marked finished
only when the network async callback returns. Atomic.swift
is required by AsyncOperation
.
Platform and Swift compatibility is listed at the top of this document.
MIT License, like all my open source code.
Alamofire community for their invaluable work over the years. I don’t use the library itself, but there are re-usable gems in it (like ServerTrustPolicy handling).
Marcus Zarra for this great talk which got me started to write this library. There’s a blog post on his blog too.
I want re-iterate what Marcus said at the end of his talk:
Write it [network code] yourself. I guarantee code you write yourself will be faster than any generic code, that is the law. Whenever you write something that is very specific, it is going to be faster than generics.
Alley – automatic retries for URLSessionDataTask
TN2232: HTTPS Server Trust Evaluation
WWDC 2017, Session 709: Advances in Networking, Part 2
Security analysis of ATS
Alamofire notes on ATS
Resolving ATS issues
Bad SSL in many ways, fantastic resource to test your code.
nscurl --help
(in your macOS Terminal)