SwiftyCurl is an easily usable Swift and Objective-C wrapper for libcurl.
It uses native Darwin multithreading in conjunction with libcurl's "easy" interface,
(Instead of libcurl's own "multi" multithreading, which feels pretty clunky on Apple platforms.)
together with standard Foundation
classes
URLRequest
and
HTTPURLResponse
.
let request = URLRequest(url: .init(string: "http://google.com")!)
let curl = SwiftyCurl()
curl.followLocation = true
curl.queue = .global(qos: .background)
let progress = Progress()
let observation = progress.observe(\.fractionCompleted) { progress, _ in
print("Progress: \(progress.completedUnitCount) of \(progress.totalUnitCount) = \(progress.fractionCompleted)")
}
curl.perform(with: request, progress: progress) { data, response, error in
print(String(data: data ?? .init(), encoding: .ascii) ?? "(nil)")
if let response = response as? HTTPURLResponse {
print("Response: \(response.url?.absoluteString ?? "(nil)") \(response.statusCode)\nheaders: \(response.allHeaderFields)")
}
if let error = error {
print("Error: \(error)")
}
observation.invalidate()
}
When you use SwiftyCurl
in a lot of places, it is recommended, that you create a shared singleton,
instead of constantly creating and destroying SwiftyCurl
objects.
The reason for this is, that SwiftyCurl
calls
curl_global_init
on constructions and
curl_global_cleanup
on destruction.
These calls might interfere, if you repeatedly create and destoy SwiftyCurl
objects.
Do it like this:
extension SwiftyCurl {
static let shared = {
let curl = SwiftyCurl()
// Put your standard configuration here.
return curl
}()
}
}
The main reason why this exists, is, that URLSession
is somewhat limited for specific applications.
Especially when it comes to sending any headers you wish, URLSession
often is in the way.
The notes about this in URLRequest
explicitly don't apply here: E.g. you can send your own
Host
header with SwiftyCurl and it won't get changed by it!
-
When using
SwiftyCurl.followLocation
, the returnedHTTPURLResponse
should return the last location curl ended up with. However,CURLINFO_EFFECTIVE_URL
doesn't seem to work as expected in experiments. -
No support for input/output streams, yet. You'll have to move your huge files into RAM first.
-
Other protocols than HTTP aren't fully supported by SwiftyCurl, esp. when it comes to response processing.
-
curl_easy
handles are thrown away after one use. These could instead get pooled and reused to improve efficiency. -
Lots of libcurl features aren't properly exposed.
If any of these bug you, I am awaiting your merge requests!
To run the example project, clone the repo, and run pod install
from the Example directory first.
SwiftyCurl relies on curl-apple, which is libcurl built for iOS and macOS as an easily ingestible xcframework.
It should be downloaded automaticaly on pod installation, but if this doesn't work,
please just run download-curl.sh
yourself and rerun pod install
!
SwiftyCurl is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod 'SwiftyCurl'
Benjamin Erhart, [email protected]
SwiftyCurl is available under the MIT license. See the LICENSE file for more info.