
While Swift provides built-in networking capabilities, there are some disadvantages to using them, such as lack of standardisation, limited flexibility and challenges in maintaining and updating the codebase over time, especially as the number of endpoints grows. So, is there a more efficient way to accomplish this task?
Well, great news! You can handle network requests more conveniently by using our GoodNetworking swift package. Let’s begin, shall we?
Preparing API & Endpoints
In this example, we will retrieve Star Wars heroes using the free Star Wars API.
To begin, we must first define the base URL for the ApiServer that conforms to the type String. We will also need to define an endpoint that conforms to the GREndpointManager protocol.
This endpoint will specify the path, method, parameters, headers, encoding, and URL for your network request.
You can define multiple endpoints for different network requests within your application.
import GoodNetworking import Combine import Alamofire // define the base url of the api server enum ApiServer: String { case base = "<https://swapi.dev/api/>" } // define Endpoint for fetching the StarWars heroes // later on you can add edpoints for StarWars Planets or Starships enum Endpoint: GREndpointManager { case hero(id: Int) var path: String { switch self { case .hero(let id): return "people/\\(id)" } } var method: HTTPMethod { .get } var parameters: EndpointParameters? { nil } var headers: HTTPHeaders? {nil} var encoding: ParameterEncoding { JSONEncoding.default } func asURL(baseURL: String) throws -> URL { var url = try baseURL.asURL() url.appendPathComponent(path) return url } }Prepare API response
Next, we have to specify the expected response from the API. According the StarWars API, we expect a response with the name attribute of type String. We can define a struct with this attribute as follows:
// define the request response struct HeroResponse: Decodable { let name: String }Now we have almost everything ready, we can setup our GRSession to make requests.
Making a network request
Once we have endpoint defined, we can create an instance of the GRSession.
**GRSession**is based on Alamofire Session class and ****manages network requests in client apps within its URLSession.
It takes two generic parameters:
- (one conforming to GREndpointManager) - the Endpoint we defined earlier
- (one conforming to RawRepresentable with RawValue of String) - our ApiServer
Here's an example of how you can use the GRSession class to make a network request:
// Create a GRSession object let session: GRSession<Endpoint, ApiServer> = GRSession( baseURL: ApiServer.base configuration: .default ) // fetch a hero with specified ID func fetchHero(heroId: Int) -> AnyPublisher<HeroResponse, Never> { return session.request(endpoint: .hero(id: heroId)) .goodify() .replaceError(with: HeroResponse(name: "unknown")) .eraseToAnyPublisher() }The result of **fetchHero** function is a publisher so you can continue chaining Combine functions.
To show fetched StarWars hero’s name inside a label, simply call the function and use Combine’s sink or assign methods to achieve this goal.
// define heroLabel to show hero Name let heroLabel = UILbel() // define subscriber var cancellable: AnyCancellable? // subcribe to result of network request cancellable = fetchHero(heroId: Int.random(1...66)) .map { response in response.name } .removeDuplicates() .assing(to: \\.text, on: heroLabel, ownership: .weak)Congrats!
You have gone through the process of making Network Request using GoodNetworking package.
Now you may be wondering how it works under the hood inside the app. Luckily, the package comes with a sample that you can explore to gain a deeper understanding of its functionality.
If you found this package useful, be sure to check out our other packages. Who knows, you might just find another gem that can help take your app to the next level!




