Description
Palm trees, coral reefs and breaking waves. Welcome to the surf club Malibu,
a networking library built on promises. It's more than just a wrapper
around URLSession
, but a powerful framework that helps to chain your
requests, validations and request processing.
Using When under the hood, Malibu
adds a lot of sugar helpers and moves your code up to the next level:
- No more "callback hell".
- Your requests are described in one place.
- Response processing could be easily broken down into multiple logical tasks.
- Data and errors are handled separately.
- Your networking code is much cleaner, readable and follows
DRY
principle.
Equip yourself with the necessary gears of Malibu, become a big wave surfer
and let the days of shark infested asynchronous networking be a thing of the
past. Enjoy the ride!
Features
- [x] Multiple network stacks
- [x] Declarative requests
- [x] Chainable response callbacks built on promises
- [x] All needed content types and parameter encodings
- [x] HTTP response validation
- [x] Response data serialization
- [x] Response mocking
- [x] Request, response and error logging
- [x] Synchronous and asynchronous modes
- [x] Request pre-processing and middleware
- [x] Request offline storage
- [x] Extensive unit test coverage
Table of Contents
- Catching the wave
- RequestConvertible
- Request
- Networking
- Response
- Logging
- Installation
- Author
- Credits
- Contributing
- License
Catching the wave
You can start your ride straight away, not thinking about configurations:
If you still don't see any benefits, keep scrolling down and be ready for even
more magic ?...
RequestConvertible
Most of the time we need separate network stacks to work with multiple API
services. It's super easy to archive with Malibu. Create an
enum
that conforms to RequestConvertible protocol and describe your
requests with all the properties:
Note that Accept-Language
, Accept-Encoding
and User-Agent
headers are
included automatically.
Request
Request is described with a struct in Malibu:
There are also multiple helper methods with default values for every HTTP method:
URLSessionDataTask
is default for executing requests. For uploading there
are two additional options that use URLSessionUploadTask
instead of
URLSessionDataTask
.
Content types
query
- creates a query string to be appended to any existing url.formURLEncoded
- usesapplication/x-www-form-urlencoded
as a
Content-Type
and formats your parameters with percent-encoding.json
- sets theContent-Type
toapplication/json
and sends a JSON
representation of the parameters as the body of the request.multipartFormData
- sends parameters encoded asmultipart/form-data
.custom(String)
- uses givenContent-Type
string as a header.
Encoding
Malibu comes with 3 parameter encoding implementations:
FormURLEncoder
- a percent-escaped encoding following RFC 3986.JsonEncoder
-JSONSerialization
based encoding.MultipartFormEncoder
- multipart data builder.
You can extend default functionality by adding a custom parameter encoder
that conforms to ParameterEncoding
protocol:
Cache policy
URLSession
handles cache based on the URLRequest.CachePolicy
property:
URLRequest.CachePolicy.useProtocolCachePolicy
is the default policy for URL
load requests. URLSession
will automatically add the If-None-Match
header
in the request before sending it to the backend. When URLSession
gets the
304 Not Modified
response status it will call the URLSessionDataTask
completion block with the 200
status code and data loaded from the cached
response.
You can set cachePolicy
property to .reloadIgnoringLocalCacheData
if you
want to prevent this automatic cache management. Then URLSession
will not
add the If-None-Match
header to the client requests, and the server will
always return a full response.
Networking
Networking
class is a core component of Malibu that executes actual HTTP
requests on a specified API service.
Initialization
It's pretty straightforward to create a new Networking
instance:
Mode
Malibu uses OperationQueue
to execute/cancel requests. It makes it
easier to manage request lifetime and concurrency.
When you create a new networking instance there is an optional argument to
specify mode which will be used:
sync
async
limited(maxConcurrentOperationCount)
Mocks
Mocking is great when it comes to writing your tests. But it also could speed
up your development while the backend developers are working really hardly
on API implementation.
In order to start mocking you have to do the following:
Create a mock provider
Create a networking instance with your mock provider
Both real and fake requests can be used in a mix:
Session configuration
SessionConfiguration
is a wrapper around URLSessionConfiguration
and could
represent 3 standard session types + 1 custom type:
default
- configuration that uses the global singleton credential, cache and
cookie storage objects.ephemeral
- configuration with no persistent disk storage for cookies, cache
or credentials.background
- session configuration that can be used to perform networking
operations on behalf of a suspended application, within certain constraints.custom(URLSessionConfiguration)
- if you're not satisfied with standard
types, your customURLSessionConfiguration
goes here.
Pre-processing
Middleware
Middleware is the function which works as the first promise in the chain,
before the actual request. It could be used to prepare networking, do some
kind of pre-processing task, cancel request under particular conditions, etc.
For example, in the combination with https://github.com/hyperoslo/OhMyAuth
Authentication
Making a request
Networking
is set up and ready, so it's time to fire some requests.
Response and NetworkPromise
Response
object consists of Data
, URLRequest
and HTTPURLResponse
properties.
NetworkPromise
is just a typealias
to Promise<Response>
, which is returned
by every request method. You may use NetworkPromise
object to add different
callbacks and build chains of tasks. It has a range of useful helpers, such as
validations and serialization.
Offline storage
Want to store request when there is no network connection?
Want to replay cached requests?
Request storage is networking-specific, and while it replays cached requests
it will be set to Sync
mode. Cached request will go through normal request
lifecycle, with applied middleware and pre-process operations. Request will be
automatically removed from the storage when it's completed.
Backfoot surfer
Malibu has a shared networking object with default configurations for the
case when you need just something simple to catch the wave. It's not necessary
to create a custom RequestConvertible
type, just call the same request
method right
on Malibu
:
Response
Serialization
Malibu gives you a bunch of methods to serialize response data:
Validation
Malibu comes with 4 validation methods:
Decoding
Malibu is able to convert the response body into models that conform to Decodable
:
Logging
If you want to see some request, response and error info in the console, you
get this for free. Just choose one of the available log levels:
none
- logging is disabled, so your console is not littered with networking
stuff.error
- prints only errors that occur during the request execution.info
- prints incoming request method + url, response status code and errors.verbose
- prints incoming request headers and parameters in addition to
everything printed in theinfo
level.
Optionally you can set your own loggers and adjust the logging to your needs:
Author
Hyper Interaktiv AS, ios@hyper.no
Installation
Malibu is available through CocoaPods. To install
it, simply add the following line to your Podfile:
Malibu is also available through Carthage.
To install just write into your Cartfile:
Malibu can also be installed manually.
Just Download and drop /Sources
folder in your project.
Author
Vadym Markov, markov.vadym@gmail.com
Credits
This library was originally done at Hyper, a digital
communications agency with a passion for good code
and delightful user experiences.
Credits go to Alamofire for
inspiration and to When for promises.
Contributing
Check the CONTRIBUTING file for more info.
License
Malibu is available under the MIT license. See the LICENSE file for more info.