🔥 AsyncParsableCommand
386자
4분
강의 목차
AsyncParsableCommand
는 비동기로 실행할 수 있는 명령 타입입니다. 중첩된 명령 트리 일부로 작동해요. 아래 코드는 AsyncParsableCommand
프로토콜을 정의하고 있습니다.
protocol AsyncParsableCommand : ParsableCommand
swift
명령 run()
메서드 구현에서 async
/await
코드를 사용하려면 다음 단계를 따르세요:
- 커맨드 라인 도구 루트 명령에
AsyncParsableCommand
를 따르도록 선언하세요. 해당 명령이 비동기 코드를 사용하는지 여부는 상관없습니다. - 루트 명령에
@main
속성을 적용하세요. (참고: 루트 명령이main.swift
파일에 있다면 파일 이름을 명령 이름으로 바꾸세요.) - 비동기 코드를 사용해야 하는 모든 명령에
AsyncParsableCommand
를 따르도록 선언하고run()
메서드를async
로 표시하세요. 비동기 코드를 사용하지 않는 하위 명령은 변경이 필요 없습니다.
다음 예제는 Foundation 비동기 FileHandle.AsyncBytes
를 사용해 파일에서 줄 수를 세는 CountLines
명령을 선언합니다. 여기서 CountLines
는 커맨드 라인 도구 루트 명령입니다:
import Foundation import ArgumentParser struct CountLines: AsyncParsableCommand { @Argument(transform: URL.init(fileURLWithPath:)) var inputFile: URL mutating func run() async throws { let fileHandle = try FileHandle(forReadingFrom: inputFile) let lineCount = try await fileHandle.bytes.lines.reduce(into: 0) { count, _ in count += 1 } print(lineCount) } }
swift
코드 설명:
import Foundation
: Foundation 프레임워크를 가져옵니다.struct CountLines: AsyncParsableCommand
:CountLines
구조체를 선언하고AsyncParsableCommand
프로토콜을 따릅니다.@Argument(transform: URL.init(fileURLWithPath:))
: 명령줄 인수로 받은 파일 경로를URL
로 변환합니다.var inputFile: URL
: 입력 파일URL
을 저장할 프로퍼티입니다.mutating func run() async throws
: 비동기로 실행되는run()
메서드를 선언합니다.let fileHandle = try FileHandle(forReadingFrom: inputFile)
: 입력 파일을 읽기 위한FileHandle
을 생성합니다.let lineCount = try await fileHandle.bytes.lines.reduce(into: 0) { count, _ in count += 1 }
: 파일 각 줄을 비동기로 읽어 줄 수를 계산합니다.print(lineCount)
: 줄 수를 출력합니다.
Swift 5.5에서 사용
Swift 5.5에서는 비동기 @main
진입점으로 별도 독립형 타입을 선언해야 합니다. 아래 코드 스니펫처럼 AsyncMainProtocol
을 따르는 구조체를 선언하고 typealias Command
를 루트 명령으로 지정하세요.
@main struct AsyncMain: AsyncMainProtocol { typealias Command = <#RootCommand#> }
swift
여기서 <#RootCommand#>
를 실제 루트 명령 이름으로 변경합니다. 위 예제에서는 CountLines
가 루트 명령이므로 다음과 같이 작성할 수 있습니다:
@main struct AsyncMain: AsyncMainProtocol { typealias Command = CountLines }
swift
그리고 CountLines
명령을 구현합니다:
import Foundation struct CountLines: AsyncParsableCommand { @Argument(transform: URL.init(fileURLWithPath:)) var inputFile: URL mutating func run() async throws { let fileHandle = try FileHandle(forReadingFrom: inputFile) let lineCount = try await fileHandle.bytes.lines.reduce(into: 0) { count, _ in count += 1 } print(lineCount) } }
swift
이렇게 하면 AsyncParsableCommand
를 사용해 커맨드 라인 도구에 비동기 코드를 쉽게 통합할 수 있습니다. 그리고 명령 run()
메서드에서 async
/await
을 활용하면 다양한 비동기 작업을 수행할 수 있습니다.