SwiftUI 실시간 데이터 업데이트: WebSocket과 서버리스 연동

작성일 :

SwiftUI 실시간 데이터 업데이트: WebSocket과 서버리스 연동

서론

모바일 애플리케이션에서 실시간 데이터 업데이트는 사용자 경험을 크게 향상시킬 수 있는 중요한 기능입니다. 주가 정보, 채팅 어플리케이션, 스포츠 경기 업데이트 등 다양한 분야에서 이러한 기능은 매우 유용합니다. 이번 글에서는 SwiftUIWebSocket을 활용하여 실시간으로 데이터를 업데이트하는 방법을 살펴보겠습니다. 이를 위해 서버리스(back-end) 솔루션도 함께 이용합니다.

WebSocket 개요

WebSocket은 클라이언트와 서버 간의 양방향 통신을 가능하게 하는 프로토콜입니다. 일반적인 HTTP 요청과 응답 방식과 달리, WebSocket은 연결이 유지되는 동안 양쪽에서 자유롭게 데이터를 주고받을 수 있습니다. 이는 실시간 데이터 업데이트에 매우 적합합니다.

준비사항

  • 최신 버전의 Xcode
  • AWS Lambda 또는 Firebase Functions 같은 서버리스 플랫폼
  • 기본적인 SwiftUI 및 Swift 언어에 대한 이해

프로젝트 설정

SwiftUI 프로젝트 생성

먼저, Xcode에서 SwiftUI 프로젝트를 생성합니다. 이는 일반적인 iOS 앱 만들기와 동일합니다. 프로젝트 이름을 예를 들어 'RealTimeDataApp'으로 설정합니다.

WebSocket 클라이언트 구현

Swift는 URLSessionWebSocketTask를 활용해 WebSocket을 쉽게 구현할 수 있는 도구를 제공합니다. URLSessionWebSocketTask를 사용해 WebSocket 연결을 설정하고 데이터를 주고받는 방법을 살펴보겠습니다.

swift
import Foundation
import Combine

class WebSocketManager: ObservableObject {
    private var webSocketTask: URLSessionWebSocketTask?
    private var cancellables: Set<AnyCancellable> = []
    
    @Published var receivedMessage: String?
    
    func connect() {
        let url = URL(string: "wss://your-websocket-endpoint")!
        let webSocketTask = URLSession.shared.webSocketTask(with: url)
        self.webSocketTask = webSocketTask
        webSocketTask.resume()
        receiveMessage()
    }
    
    func receiveMessage() {
        webSocketTask?.receive { [weak self] result in
            switch result {
            case .failure(let error):
                print("Error receiving message: \(error)")
            case .success(.string(let message)):
                DispatchQueue.main.async {
                    self?.receivedMessage = message
                }
                self?.receiveMessage() // continue listening for new messages
            case .success:
                break // handle other message types
            }
        }
    }
    
    func sendMessage(_ message: String) {
        let message = URLSessionWebSocketTask.Message.string(message)
        webSocketTask?.send(message) { error in
            if let error = error {
                print("Error sending message: \(error)")
            }
        }
    }
    
    func disconnect() {
        webSocketTask?.cancel(with: .goingAway, reason: nil)
    }
}

이제 WebSocket을 통해 데이터를 주고받을 수 있는 커넥션을 만들었습니다. 이를 SwiftUI 뷰와 연결해보겠습니다.

SwiftUI와 WebSocket 연동

이제 SwiftUI 뷰에서 WebSocket을 통해 실시간 데이터를 업데이트할 수 있도록 작업하겠습니다.

swift
import SwiftUI

struct ContentView: View {
    @ObservedObject var webSocketManager = WebSocketManager()
    
    var body: some View {
        VStack {
            if let message = webSocketManager.receivedMessage {
                Text("Received: \(message)")
                    .padding()
            }
            Button("Connect") {
                webSocketManager.connect()
            }
            Button("Disconnect") {
                webSocketManager.disconnect()
            }
        }
    }
}

이제 ContentViewWebSocketManager의 상태를 관찰하고 실시간으로 메시지를 표시합니다. 버튼을 통해 WebSocket 연결 및 해제를 제어할 수 있습니다.

서버리스 백엔드 설정

실시간 데이터를 제공하기 위해 서버리스 백엔드를 설정할 수 있습니다. 여기에서는 AWS Lambda와 API Gateway를 예로 들어 설명하겠습니다.

AWS Lambda 함수 작성

AWS Lambda는 서버를 관리하지 않고도 코드를 실행할 수 있는 서버리스 컴퓨팅 서비스입니다. 다음은 간단한 Lambda 함수 예시입니다.

python
import json
import boto3
import os

apigatewaymanagementapi = boto3.client('apigatewaymanagementapi', endpoint_url=os.environ['ENDPOINT_URL'])


def lambda_handler(event, context):
    message = json.dumps({"message": "Hello from Lambda!"})
    connection_id = event['requestContext']['connectionId']

    try:
        apigatewaymanagementapi.post_to_connection(ConnectionId=connection_id, Data=message)
        return {
            'statusCode': 200,
            'body': 'Message sent'
        }
    except Exception as e:
        return {
            'statusCode': 500,
            'body': str(e)
        }

이 Lambda 함수는 WebSocket 연결을 통해 클라이언트로 메시지를 보냅니다. 이를 AWS API Gateway와 연동하여 WebSocket API를 생성할 수 있습니다.

결론

SwiftUI와 WebSocket을 활용해 실시간 데이터 업데이트를 구현하는 방법을 배웠습니다. 또한, 서버리스 백엔드를 사용해 더욱 확장 가능하고 관리하기 쉬운 시스템을 구축할 수 있었습니다. 이런 기술을 통해 다양한 실시간 애플리케이션을 개발하는데 도움이 되길 바랍니다.