Swift 5.6은 동시성과 네트워크 프로그래밍을 결합한 분산 액터(Distributed Actor) 기능을 공식 지원합니다.
이 기능은 서버-클라이언트 모델, 멀티플레이어 게임, 분산 처리 시스템에 혁신적인 해법을 제시합니다.
기존 Swift 액터로는 네트워크 경계 넘는 작업이 어려움
→ 분산 액터로 네트워크 및 동시성 문제를 한 번에 해결
현대 앱 개발에서 단일 디바이스의 한계를 넘어서는 것은 필수가 되었습니다. 실시간 멀티플레이어 게임, 협업 도구, 클라우드 컴퓨팅, 마이크로서비스 아키텍처 등 모든 곳에서 분산 시스템이 요구됩니다.
하지만 분산 시스템 개발은 전통적으로 매우 복잡했습니다:
네트워크 프로그래밍의 복잡성
직렬화/역직렬화 처리
에러 처리와 재시도 로직
네트워크 지연과 실패 관리
동기화 문제
Distributed Actors는 이런 복잡성을 Swift의 강력한 타입 시스템과 컴파일러 지원으로 해결합니다.
Actor 관련 세션들을 보면 "동시성의 바다"라는 표현이 자주 사용된다.

액터는 데이터 무결성과 안전성을 위한 ‘동시성 보호 컨테이너’입니다.
public actor OfflinePlayer: Identifiable {
nonisolated public let id: ActorIdentity = .random
let team: CharacterTeam
let model: GameViewModel
var movesMade: Int = 0
public init(team: CharacterTeam, model: GameViewModel) {
self.team = team
self.model = model
}
public func makeMove(at position: Int) async throws -> GameMove {
let move = GameMove(playerID: id, position: position, team: team, teamCharacterID: team.characterID(for: movesMade))
await model.userMadeMove(move: move)
movesMade += 1
return move
}
public func opponentMoved(_ move: GameMove) async throws {
do {
try await model.markOpponentMove(move)
} catch {
log("player", "Opponent made illegal move! \(move)")
}
}
}
분산 액터는 distributed 키워드로 선언하며,
원격 호출(distributed func)이 가능해집니다.
import Distributed
public distributed actor BotPlayer: Identifiable {
typealias ActorSystem = LocalTestingDistributedActorSystem
var ai: RandomPlayerBotAI
var gameState: GameState
public init(team: CharacterTeam, actorSystem: ActorSystem) {
self.actorSystem = actorSystem
self.gameState = .init()
self.ai = RandomPlayerBotAI(playerID: self.id, team: team)
}
public distributed func makeMove() throws -> GameMove {
return try ai.decideNextMove(given: &gameState)
}
public distributed func opponentMoved(_ move: GameMove) async throws {
try gameState.mark(move)
}
}
ActorSystem은 네트워크 연결, 액터 인스턴스 관리, ID 발급 및 직렬화까지 담당합니다.
let sampleSystem = SampleWebSocketActorSystem()
let opponentID = BotPlayer.ID.randomID(opponentFor: self.id)
let bot = try BotPlayer.resolve(id: opponentID, using: sampleSystem)
@main
struct Boot {
static func main() {
let system = try! SampleWebSocketActorSystem(mode: .serverOnly(host: "localhost", port: 8888))
system.registerOnDemandResolveHandler { id in
if system.isBotID(id) {
return system.makeActorWithID(id) { OnlineBotPlayer(team: .rodents, actorSystem: system) }
}
return nil
}
print("=== TicTacFish Server Running on: ws://\(system.host):\(system.port) ===")
try await server.terminated
}
}
네트워크상에서 액터의 ID로 해당 객체를 찾아냅니다.
let opponentID = BotPlayer.ID.randomID(opponentFor: currentPlayerID)
let remoteActor = try BotPlayer.resolve(id: opponentID, using: actorSystem)
서버, 클라이언트 모두 ActorSystem을 통해
분산 액터 기반의 서버/클라이언트 구조를 쉽게 구축할 수 있습니다.
서버는 필요한 순간 액터 생성, 클라이언트의 분산 호출에 대응
클라이언트에서 서버의 RemotePlayer 등 resolve 후 직접 분산 함수 사용
직렬화/역직렬화:
보안:
에러 처리:
| 장점 | 한계점 |
|---|---|
| 동시성 & 네트워크 합친 구조 | 복잡한 ActorSystem 직접 설계 필요 |
| 안전성 & 오류 방지 | 직렬화/보안 등 네트워크 코딩 추가 필요 |
| Swift 자체 기술 | 성능 튜닝, 장애복구 직접 구현해야 함 |
| 동적 매칭, 확장성 | 실서비스 환경 배포/운영 난이도 있음 |
분산 액터는 동시성과 네트워크 분산을 Swift에서 직접 해결하는 최신 패턴입니다.
실제 코딩 시, ActorSystem 설계, 직렬화/복구 패턴, 서버-클라이언트 구조 등
아래 예시처럼 전체 구조/코드/동작 원리를 이해하고 사용하면 성공적인 대규모 Swift 프로젝트가 가능합니다.
// 분산 액터 선언 예시
public distributed actor GamePlayer {
// 분산 함수
public distributed func makeMove() -> GameMove { ... }
public distributed func opponentMoved(move: GameMove) async throws { ... }
}
// ActorSystem을 통한 네트워크 연결
let system = MyActorSystem()
let remotePlayer = try GamePlayer.resolve(id: GamePlayer.ID("player2"), using: system)
// 네트워크를 통해 remotePlayer 분산 함수 호출 가능!