For iOS developers, AFNetworking is what we all know, but what about Alamofire? The Alamofire framework is actually the AFNetworking brothers, from the same author. If the author is the same, then their use method, the framework structure should also remain the same. AFNetworking, Alamofire

First, network request steps

  1. Set the requesturl
  2. Set up theURLRequestObject that configures request information
  3. Creating a Session ConfigurationURLSessionConfiguration
  4. Create a sessionURLSession
  5. Create the task and set the request callback, and initiate the request

Generally, network requests are completed through the preceding steps. Of course, request attributes need to be configured according to different application scenarios.

Second, the experience

Make a request:

func responseData(a) {
    let url = "http://onapp.yahibo.top/public/? s=api/test/list"
    Alamofire.request(url).responseJSON {
        (response) in
        switch response.result{
        case .success(let json):
            print("json:\(json)")
            let dict = json as! Dictionary<String.Any>
            let list = dict["data"] as! Array<AnyObject>
            guard let result = [UserModel1].deserialize(from: list) else{return}
            self.observable.onNext(result as [Any])
            break
        case .failure(let error):
            print("error:\(error)")
            break}}}Copy the code
  • responseJSONIs the corresponding type, specified asjsonThe data type
  • responseisAlamofireEncapsulation of server response results
  • Get the data using normal unpackingheadimg
  • throughHandyJSONConvert to model data forUIshow

Making a request directly through Alamofire and returning the result of the request through a closure, no secondary wrapping is required. Simple to use. Here we do not specify the request type and request parameters. How does Alamofire encapsulate these request parameters? Click to view the method definition:

public func request(
    _ url: URLConvertible,
    method: HTTPMethod = .get,
    parameters: Parameters? = nil,
    encoding: ParameterEncoding = URLEncoding.default,
    headers: HTTPHeaders? = nil)
    -> DataRequest
{
    return SessionManager.default.request(
        url,
        method: method,
        parameters: parameters,
        encoding: encoding,
        headers: headers
    )
}
Copy the code

The parameters required by the request are provided and default values are set, so the outside world defaults to get when no method is specified. Set response parameters according to actual development requirements:

Alamofire.request(url,method: .post,parameters: ["page":"1"."size":"20"]).responseJSON
Copy the code

This is common in our development to set the request way, request parameters, here url support a variety of data types, can be String, URL, URLRequest type, why so design? Because there may be a String connection or a URL connection in front of us in the project, it can be used directly without conversion, which is convenient, fast and more flexible.

The effect is as follows:

Third, URLSession

It also encapsulates URLSession in Alamofire, NSURLSession in OC, which is the same thing. A general network request consists of three steps:

1. Set the URL request address
let url = URL.init(string: "Protocol :// host address/path/parameter 1& Parameter 2")!
Copy the code
  • Agreement: specifiedhttpAgreement orhttpsagreement
  • Host: indicates the address of the serveripAddress or bindingipThe domain name
  • Path: The location of the project on the server
  • Parameters:getParameters are concatenated to the connection
2. Set the URLRequest attribute
var request  = URLRequest.init(url: url)
request.httpMethod = HTTPMethod.post.rawValue
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let postData = ["username":"hibo"."password":"123456"]
request.httpBody = try?JSONSerialization.data(withJSONObject: postData, options: [])
request.timeoutInterval = 30
request.cachePolicy = .useProtocolCachePolicy
Copy the code
  • httpMethodSetting the request Modepostorget
  • setValueSet the request header information
  • httpBodySets the request parameters, which are packaged in the request body
  • timeoutIntervalThe request timeout period is set
  • cachePolicySet the network request caching policy

Through the above parameter Settings, you can feel how difficult it is to send a request, so network requests must be encapsulated

3. Make a request
URLSession.shared.dataTask(with: request) { (data, response, error) in
    print("******* Web request *******")
    do {
        let list =  try JSONSerialization.jsonObject(with: data! , options: .allowFragments)print(list)
    }catch{
        print(error)
    }
}.resume()
Copy the code
  • URLSession.sharedIs a global shared singleton talk object
  • calldataTaskCreate a network request task
  • resumeThe state is suspended by default, and the restart network request task is invoked
  • data: Indicates that the requested data flow passesJSONSerializationSerialized asjsonFormat to use

Four, URLSessionConfiguration

Urlsession. shared has been configured internally. As a session configuration item, this item is generally configured to apply to different scenarios. View the class as follows:

open class var `default` :URLSessionConfiguration { get }
open class var ephemeral: URLSessionConfiguration { get }
@available(iOS 8.0, *)
open class func background(withIdentifier identifier: String) - >URLSessionConfiguration
Copy the code
  • default: Default mode: common mode. In this mode, the system creates a persistent cache and stores the certificate in the user’s key string
  • ephemeral: Does not support persistent storage, all content will followsessionRelease at the end of the life cycle
  • backgroundAnd:defaultIn this mode, a separate thread is created to transfer network request data, which can be transferred in the background or even when the APP is closed

Create a session:

let configuration = URLSessionConfiguration.background(withIdentifier: "request_id")
let session = URLSession.init(configuration: configuration, delegate: self, delegateQueue: OperationQueue.main)
session.dataTask(with: request) { (data, response, error) in
    print("******* Web request *******")
    do {
        let list =  try JSONSerialization.jsonObject(with: data! , options: .allowFragments)print(list)
    }catch{
        print(error)
    }
}.resume()
Copy the code
  • Set a unique session identifier to distinguish different session tasks
  • followURLSessionDelegateAgent, implement agent method, monitor task progress in this class

Download tasks:

let configuration = URLSessionConfiguration.background(withIdentifier: "request_id")
let session = URLSession.init(configuration: configuration, delegate: self, delegateQueue: OperationQueue.main)
session.downloadTask(with: url).resume()
Copy the code

** Note that the background download permission must be enabled when using background mode, otherwise the background download cannot be completed and the data can be called back. ** Requires the following two steps to complete:

1. Enable background download permission

var backgroundHandler: (()->Void)? = nil
// Set this to enable background download permission
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping (a) -> Void) {
    self.backgroundHandler = completionHandler
}
Copy the code

2, implement the SessionDelegate proxy method, call the closure method, notify the system to update the screen

func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
    print("Background task download back")
    DispatchQueue.main.async {
        guard let appDelegate = UIApplication.shared.delegate as? AppDelegate.let backgroundHandle = appDelegate.backgroundHandler else { return }
        backgroundHandle()
    }
}
Copy the code

Apple officially gave the need to achieve the above two methods to complete the background download, notify the system to update the screen in time. The official documentation

5. Related attributes

The official documentation

1. General attributes

  • Identifier:Configures the background session identifier of the object
  • HttpAdditionalHeaders:A dictionary of additional header files sent with the request
  • NetworkServiceType:Network service type
  • AllowsCellularAccess:A Boolean value for whether a connection should be made over a cellular network
  • TimeoutIntervalForRequest:Timeout time to wait for additional data
  • TimeoutIntervalForResource:Maximum time range allowed for resource requests
  • SharedContainerIdentifier:Identifier of the shared container to which files in the background URL session should be downloaded
  • WaitsForConnectivity:A Boolean value indicating whether the session should wait for the connection to become available or fail immediately

2. Set the Cookie policy

  • HttpCookieAcceptPolicy:A policy constant that determines when to accept cookies
  • HttpShouldSetCookies:A Boolean value that determines whether the request contains data fromcookieThe storage areacookie
  • httpCookieStorage: Used for in-session storagecookiethecookieStorage area
  • HTTPCookie:This object is an immutable object, from containscookieProperty, supports two different versions of cookies,Where v0, v1

3. Set security policies

  • The TLS protocol:Used to provide confidentiality and data integrity between two communication applications
  • TlsMaximumSupportedProtocol:Maximum the client should request when establishing a connection in this sessionThe TLS protocolversion
  • TlsMinimumSupportedProtocol:The minimum amount to be accepted during the agreement negotiationThe TLS protocol
  • UrlCredentialStorage:A credential store that provides credentials for authentication

4. Set the cache policy

  • UrlCache:Used to provide cached responses to requests in the sessionURLThe cache
  • RequestCachePolicy:Predefined constants that determine when a response is returned from the cache

5. Support background transfer

  • SessionSendsLaunchEvents:A Boolean value indicating whether the application should resume or start in the background when the transfer is complete
  • IsDiscretionary:A Boolean value that determines whether background tasks can be scheduled by the system for optimal performance
  • ShouldUseExtendedBackgroundIdleMode:A Boolean value indicating whether the application should be held when it is moved to the backgroundTCPConnection is opened

6. Support custom protocols

  • ProtocolClasses:An array of additional protocol subclasses that process the request in the session
  • URLProtocol:This object is used to handle load protocol specificURLdata

7. Support multipath TCP

  • MultipathServiceType:Designated for use byWi-FiAnd cellular interfaces to transmit data multipathingTCPService type of the connection policy

8. Set HTTP policies and proxy properties

  • HttpMaximumConnectionsPerHost:The maximum number of simultaneous connections to a given host
  • HttpShouldUsePipelining:A Boolean value used to determine whether the session is usedHTTPAssembly line
  • ConnectionProxyDictionary:A dictionary containing information about agents to be used in this session

9. Support connection changes

  • WaitsForConnectivity:A Boolean value indicating whether the session should wait for a connection to become available or fail immediately

A request task has so many configuration attributes, it can be imagined that the integration of a network framework, the workload is also very large. Let’s take a step-by-step look at how Alamofire is integrated.