🔥 AsyncParsableCommand
386자
4분
강의 목차
AsyncParsableCommand는 비동기로 실행할 수 있는 명령 타입입니다. 중첩된 명령 트리 일부로 작동해요. 아래 코드는 AsyncParsableCommand 프로토콜을 정의하고 있습니다.
protocol AsyncParsableCommand : ParsableCommandswift
명령 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을 활용하면 다양한 비동기 작업을 수행할 수 있습니다.