Introduction to Combine | How to connect to the Web Server with the Combine

This article explains that how to connect to the web server with the Combine.

スポンサーリンク

Create the Publisher of the DataTask

Create the publisher of the data task to connect to the web server. Two methods are available to create it:

func dataTaskPublisher(for: URL) -> URLSession.DataTaskPublisher

func dataTaskPublisher(for: URLRequest) -> URLSession.DataTaskPublisher

The first method has an argument “URL”. If you want to simply connect to the URL and GET the contents, you can use this method.

The second method has an argument “URLRequest”. With “URLRequest”, you can set the method of the HTTP, the body data, the header value and so on.

You can handle most cases, but if wan to download the large file, you should use the download task of URLSession directly.

Receiving Result

To receive the result, use sink method.

func sink(receiveCompletion: @escaping ((Subscrivers.Completion<URLError>) -> Void),
receiveValue: @escaping (((data: Data, response: URLResponse)) -> Void)) -> AnyCancellable

Returned value need to be keep in anywhere.

You can write the code in following form:

cancellable = urlSession.dataTaskPublisher(for: url)
.sink(receiveCompletion: { (failure) in
	switch failure {
		case .finished:
			// Finished without error
			break

		case .failure(let error: URLError):
			// Finished with error
			break
	}
}, receiveValue: { (data: Data, response: URLResponse) in 
	// Process the received data and the response.
})

Keep in mind the thread

Closures are executed on the sub-thread. Updating the GUI need to be executed on the main thread only.

Sample Code

Following code is a sample code. Enter the URL and tap the “GET” button, the application get the content from the URL with Combine.

This code uses SwiftUI, you can copy & paste to the ContentView.swift and can try it.

import SwiftUI
import Combine

struct ContentView: View {
    class ContentViewContext {
        public var cancellable: AnyCancellable?
        
        init() {
            self.cancellable = nil
        }
    }
    
    @State private var urlString: String = "https://example.com/"
    @State private var logText: String = ""
    
    private var urlSession: URLSession = URLSession(configuration: .default)
    private var context: ContentViewContext = ContentViewContext()
    
    var body: some View {
        VStack {
            TextField("URL", text: $urlString)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .keyboardType(.URL)
            Button(action: {
                self.getFromServer()
            }) {
                Text("GET")
            }
            
            ScrollView(.vertical, showsIndicators: true) {
                Text("(self.logText)")
                .frame(width: 400)
            }
            .frame(width: 400, height: 400, alignment: .top)
        }.padding()
    }
    
    func getFromServer() {
        guard let url = URL(string: self.urlString) else {
            return
        }
        
        self.logText = ""

        self.context.cancellable = self.urlSession.dataTaskPublisher(for: url)
            .sink(receiveCompletion: { (failure) in
                DispatchQueue.main.async {
                    switch failure {
                    case .finished:
                        self.logText += "Finishedn"
                        
                    case .failure(let error):
                        self.logText += "Failure: (error.localizedDescription)n"
                    }
                }
                 
            }, receiveValue: { (data: Data, response: URLResponse) in
                DispatchQueue.main.async {
                    if let httpURLResponse = response as? HTTPURLResponse {
                        self.logText += "HTTP STATUS: (httpURLResponse.statusCode)nn"
                    }
                    
                    if let text = String(data: data, encoding: .utf8) {
                        self.logText += "(text)n"
                    }

                }
            })
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

スポンサーリンク
最新情報をチェックしよう!
>現役のプログラマーが書くプログラミング情報

現役のプログラマーが書くプログラミング情報

日々の開発の中での学びや分かったこと、調べたことなどを書いていくブログです。

CTR IMG