20. Apr 2023iOS

Náš iOS toolbox - Spracovanie sieťových požiadaviek vo Swifte

Hoci Swift poskytuje vstavané funkcie na prácu so sieťou, ich použitie prináša niektoré nevýhody, ako napríklad nedostatočnú štandardizáciu, obmedzenú flexibilitu a problémy s údržbou a aktualizáciou kódu v čase, najmä pri narastajúcom počte endpointov. Existuje teda efektívnejší spôsob, ako riešiť tento problem?

Marek VricaniOS Developer

Máme pre teba skvelú správu! S našim Swift package s názvom GoodNetworking sa môžeš pohodlnejšie vysporiadať so sieťovými požiadavkami. Poďme si ukázať, ako na to.

Príprava API & Endpointov

V tomto príklade si ukážeme, ako môžeme pomocou bezplatného rozhrania Star Wars API získať informácie o postavách zo Star Wars.

Na začiatku potrebujeme definovať base URL pre ApiServer, typu String. Ďalej potrebujeme definovať endpoint, ktorý zodpoveda protokolu GREndpointManager

Tento endpoint nám určí path, method, parametre, headers, encoding a URL pre sieťovú požiadavku. 

V rámci aplikácie môžeme definovať viacero endpointov pre rôzne sieťové požiadavky.

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
    }

}

Príprava API response

Ďalej musíme špecifikovať očakávanú odpoveď z API. Podľa StarWars API očakávame odpoveď s atribútom name typu String. Štruktúru s týmto atribútom môžeme definovať takto:

// define the request response
struct HeroResponse: Decodable {
    
    let name: String
    
}

Teraz máme takmer všetko pripravené, môžeme nastaviť našu GRSession na zadávanie požiadaviek.

Zadanie sieťovej požiadavky

Keď máme zadefinovaný endpoint, môžeme vytvoriť inštanciu GRSession.

GRSession je založená na Alamofire Session triede a umožňuje spravovať sieťové požiadavky v aplikáciách pomocou vlastného URLSession.

Pre správne fungovanie vyžaduje dva generické parametre:

  •  jeden, zodpovedajuci protokolu GREndpointManager - Endpoint, ktorý sme predtým definovali
  • druhy, zodpovedajuci protokolu RawRepresentable s RawValue typu String - náš ApiServer.

Tu je ukážka, ako môžeme využiť triedu GRSession na vytvorenie sieťovej požiadavky:

// 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()
}

Funkcia fetchHero() vracia publisher, ktorý môžeme ďalej reťaziť pomocou funkcií z Combine frameworku.

Ak chceme zobraziť meno postavy zo StarWars, môžeme jednoducho zavolať túto funkciu a použiť metódy sink alebo assign z Combine.

// 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)

Gratulujem!

Po úspešnom vytvorení sieťovej požiadavky pomocou balíka GoodNetworking sa možno zaujímaš o to, ako presne funguje v rámci aplikácie.

Našťastie, balík obsahuje ukážkový kód, ktorý môžeš preskúmať a lepšie porozumieť jeho funkciám.

Ak bol pre teba tento balík užitočný, určite sa pozri aj na naše ďalšie balíky. Kto vie, možno nájdeš ďalší, ktorý ti pomôže posunúť tvoju appku na vyššiu úroveň!

Máš záujem o ďalšiu knižnicu, ktorá ti uľahčí život?

iOS 5 Minút čítania

Náš iOS toolbox - Ako ukladať hodnoty do UserDefaults a KeyChain vo Swifte

Marek Vrican20 Apr 2023
Marek VricaniOS Developer