In this article, we will learn how to use websocket to develop a Swift application that can receive and display Bitcoin / Bitcoin prices in real time.
Let's take a look at our final results:
Bitcoin development links:
- Java bitcoin docking tutorial
- C-bitcoin docking tutorial
- PHP bitcoin docking tutorial
- Bitcoin data analysis ETL tool
- Bitcoin PHP offline transaction package
- Bitcoin UTXO scan PHP development package
1. Creating WebSocket with URLSession
With the help of URLSession WebSocket task, it is very easy to create WebSockets with URLSession. The following describes the five core operations of a WebSocket connection.
First, open connection:
let urlSession = URLSession(configuration: .default) let webSocketTask = urlSession.webSocketTask(with: "wss://ws.finnhub.io?token=XYZ") webSocketTask.resume()
Second, send string or data
webSocketTask.send(.string("Hello")){error in ...}
Third, receive the response result message
webSocketTask.receive{result in ...}
4th, disconnect
webSocketTask.cancel(with: .goingAway, reason: nil)
Fifth, we can use the ping/pong mechanism to ensure that the connection remains active:
webSocketTask?.sendPing { (error) in ... }
2. Implementation of bitcoin real-time market interface based on SwiftUI + WebSocket
First to this website Generate an API KEY that can access bitcoin quotes:
The following SwiftUI view contains an SF symbol image and a text box that shows the real-time price of bitcoin:
import SwiftUI import Combine import Foundation struct ContentView: View { @ObservedObject var service = WebSocketService() var body: some View { VStack{ Image(systemName: "bitcoinsign.circle.fill") .font(.system(size: 150)) .foregroundColor(Color(red: 247 / 255, green: 142 / 255, blue: 26 / 255)) .padding() Text("USD") .font(.largeTitle) .padding() Text(service.priceResult) .font(.system(size: 60)) }.onAppear { self.service.connect() } } }
priceResult needs to be published from the ObservableObject class -- it can be found in WebSocketService.swift below See:
class WebSocketService : ObservableObject { private let urlSession = URLSession(configuration: .default) private var webSocketTask: URLSessionWebSocketTask? private let baseURL = URL(string: "wss://ws.finnhub.io?token=XYZ")! let didChange = PassthroughSubject<Void, Never>() @Published var price: String = "" private var cancellable: AnyCancellable? = nil var priceResult: String = "" { didSet { didChange.send() } } init() { cancellable = AnyCancellable($price .debounce(for: 0.5, scheduler: DispatchQueue.main) .removeDuplicates() .assign(to: \.priceResult, on: self)) } }
In the above code, we defined some properties and established the subscription in the init method. You need to replace XYZ with your own API KEY.
It is important to use operators on Publisher. We used Debounce to reduce the frequency of real-time updates and removedupdates to eliminate duplicate values.
To manually send changes to the SwiftUI view, you can trigger the didChange.send() method when the priceResult property is updated.
Other codes for constructing WebSocketService class of WebSocket URLSession are as follows:
class WebSocketService : ObservableObject { func connect() { stop() webSocketTask = urlSession.webSocketTask(with: baseURL) webSocketTask?.resume() sendMessage() receiveMessage() } func stop() { webSocketTask?.cancel(with: .goingAway, reason: nil) } private func sendMessage() { let string = "{\"type\":\"subscribe\",\"symbol\":\"BINANCE:BTCUSDT\"}" let message = URLSessionWebSocketTask.Message.string(string) webSocketTask?.send(message) { error in if let error = error { print("WebSocket couldn't send message because: \(error)") } } } private func receiveMessage() { webSocketTask?.receive {[weak self] result in switch result { case .failure(let error): print("Error in receiving message: \(error)") case .success(.string(let str)): do { let decoder = JSONDecoder() let result = try decoder.decode(APIResponse.self, from: Data(str.utf8)) DispatchQueue.main.async{ self?.price = "\(result.data[0].p)" } } catch { print("error is \(error.localizedDescription)") } self?.receiveMessage() default: print("default") } } } }
The following structure model is used to decode the response results of the API:
struct APIResponse: Codable { var data: [PriceData] var type : String private enum CodingKeys: String, CodingKey { case data, type } } struct PriceData: Codable{ public var p: Float private enum CodingKeys: String, CodingKey { case p } }
Now run the app using the WatchOS emulator, which looks like this:
Original link: Using Swift to develop bitcoin real-time market application huizhi.com