Skip to content

Latest commit

 

History

History
120 lines (106 loc) · 3.91 KB

README.md

File metadata and controls

120 lines (106 loc) · 3.91 KB

Networking

Formalized API requests calling by using URLSession.

Swift 5 Platform iOS Platform iPadOS Platform watchOS Platform macOS Platform tvOS Platform macCatalyst License: MIT

Installation

Swift Package Manager

dependencies: [
        .package(
            url: "[email protected]:urjhams/Networking.git",
            from: "1.0.0"
        )
    ]

Usage

Get the Networking instance

let networking = Network.shared

The Request object

With any Http request call, a single request object is used as the input. Create a Request object will automatically prepare the neccessary components for the request to use like header, parameter, etc. We can then later extract an URLRequest from this Request object.

let postRequest = Request(
    from: "https://api.m3o.com/v1/helloworld/Call",
    as: .post,
    authorization: .bearerToken(
      token: "YzhiYmFlNTUtNDE2Mi00MDk5LTg1Y2UtNmNmZDFmMWE1MzY2"
    ),
    parameters: ["name" : "Quan"]
  )

Standard call with callbacks

// send a request with call back
networking.sendRequest(postRequest) { result in
  switch result {
  case .success(let data):
    // do something with the data
  case .failure(let error):
    // do something with the error
  }
}

// get a decoded json object from a request task
networking.get(
  Sample.self,
  from: postRequest
) { result in
  switch result {
  case .success(let sample):
    // do something with the success model with type `Sample`
  case .failure(_):
    break
  }
}

Concurrency with async / await (available from iOS 13+, watchOS 6+, macOS 11+)

get(_:, from:) has a supported version for concurrency. All we need to do is declare the output with the expected Type for the generic requirement and apply try await.

  ...
  let sample = try await networking.get(Sample.self, from: postRequest)
  // do something with the success model with type `Sample`
  ...
  
  // to simply get Data and HttpResponse:
  let (data, response) = try await networking.sendRequest(postRequest)

Combine usage

var subscription = Set<AnyCancellable>()
...
networking
  .publisher(for: Sample.self, from: postRequest)
  .sink { completion in
    switch completion {
    case .finished:
      break
    case .failure(let error):
      print("got an error: \(error.localizedDescription)")
    }
  } receiveValue: { sample in
    // do something with the data received
  }
  .store(in: &subscription)

Connectivity Observing

from iOS 12.0+, macOS 10.14+, the connectivity can be monitor via the monitor object. This object is a static object. All we need to do is append the desired handle via Network.Connectivity.monitorChangeHandlers static property. This stack up a list of handles we want call whenever there is a change of each network availability state, and we can stack a handle from everywhere in the project.

let handler: Networking.Connectivity.Handler  = { state in
  switch state {
  case .available:
    // do something
  case .unavailable:
    // do something
  case .noConnection:
    // do something
  }
}

Network.Connectivity.monitorChangeHandlers.append(handler)