Skip to Content
문서SDKiOS (Swift)API 레퍼런스

API 레퍼런스

Deplite Swift SDK가 공개하는 모든 심볼을 시그니처와 함께 정리해요.
처음 보신다면 개요·Quickstart부터 읽어주세요.

진입 클래스

  • Deplite — External 모드 (Deplite를 호출)
  • DepliteAgent — Embedded 모드 (내 앱이 작업 노드)

이 페이지의 모든 async throws 함수는 4xx/5xx 응답 시 DepliteError.api, 401·403 응답 시 DepliteError.unauthorized를 던질 수 있어요.
처리 방법은 예외 섹션을 참고해주세요.

class Deplite

public final class Deplite: @unchecked Sendable { public static let defaultBaseURL: URL // https://api.deplite.io/v1 public let apiToken: String public let baseURL: URL public let triggers: Triggers public let files: Files public init( apiToken: String, baseURL: URL = Deplite.defaultBaseURL, session: URLSession = .shared ) }

External 모드 클라이언트예요.

속성타입설명
apiTokenStringdpl_... 토큰
baseURLURL기본 https://api.deplite.io/v1
triggersTriggers트리거 호출 매니저
filesFilesExternal 파일 매니저

Deplite.enroll(…)

public static func enroll( installCode: String, name: String, hostname: String? = nil, os: String? = nil, agentVersion: String? = nil, baseURL: URL = Deplite.defaultBaseURL, session: URLSession = .shared ) async throws -> Enrollment

Embedded 모드용 1회 등록.
새 키쌍을 만들고 /agent/enroll을 호출해 Agent ID와 서버 공개키를 받아와요.

옵션타입필수설명
installCodeString대시보드에서 발급한 1회용 설치 코드 (en_...)
nameString에이전트 표시 이름
hostnameString?호스트네임
osString?"ios"·"macos"
agentVersionString?에이전트 버전
baseURLURLAPI 베이스 오버라이드

결과는 Enrollment로 받아오며, 포함된 identityprivateKey는 SDK가 보관하지 않으므로 호출 측이 암호화 후 저장하는 것을 추천드려요.

let enrollment = try await Deplite.enroll( installCode: installCode, name: "kiosk-seoul-01" ) try secureStore.save(enrollment) // identity + privateKey

설치 코드는 1회용이라 enroll 성공 후 폐기돼요.
저장 실패에 대비해 반환값을 먼저 저장한 뒤 후속 로직을 시작하는 게 안전해요.

struct Triggers

triggers.run(…)

public func run( triggerId: String, params: JSONValue? = nil, workflowName: String? = nil, ref: String? = nil, debug: Bool = false, idempotencyKey: String? = nil ) async throws -> TriggerRunResult

POST /triggers/{triggerId}/run을 호출해 트리거를 실행해요.

옵션타입필수설명
triggerIdString트리거 UUID
paramsJSONValue?워크플로우에 전달될 페이로드
workflowNameString?agent-scope 트리거에서는 필수
refString?git ref
debugBoolverbose 실행
idempotencyKeyString?중복 실행 방지 키

호출 결과는 TriggerRunResult로 받아요.

let job = try await deplite.triggers.run( triggerId: triggerId, params: ["ref": "main", "actor": "sehyun"], idempotencyKey: "release-\(UUID().uuidString)" ) print(job.jobId, job.status)

responseMode: sync로 만들어진 트리거여야 응답에 exitCode·output이 와요.
async 트리거는 jobId만 즉시 반환되고, 결과는 알림이나 워크플로우 콜백으로 받아야 해요.

struct Files

External 모드에서 스토리지 파일을 다뤄요.
기본 CleanupRule.ttl(seconds: 86_400)(24시간)이에요.

files.upload(…)

public func upload( fileURL: URL, cleanupRule: CleanupRule = .ttl(seconds: 86_400), filename: String? = nil, contentType: String? = nil, bindingId: String? = nil ) async throws -> FileMeta

presign + PUT + complete를 하나의 호출로 처리해요.

옵션타입필수설명
fileURLURL업로드할 로컬 파일
cleanupRuleCleanupRule기본 24h TTL
filenameString?미지정 시 파일명 자동 추론
contentTypeString?MIME 타입
bindingIdString?토큰이 여러 binding을 허용할 때 필수

업로드가 끝나면 FileMeta 객체로 활성화된 파일 정보를 돌려줘요.

let uploaded = try await deplite.files.upload( fileURL: ipaURL, cleanupRule: .ttl(seconds: 3600), contentType: "application/octet-stream" ) _ = try await deplite.triggers.run( triggerId: triggerId, params: ["ipaFileId": .string(uploaded.id), "ref": .string("main")] )

files.presignUpload(…)

public func presignUpload( cleanupRule: CleanupRule, filename: String? = nil, contentType: String? = nil, bindingId: String? = nil ) async throws -> PresignedUpload

업로드 URL만 발급받아 직접 PUT 한 뒤 completeUpload를 호출하는 저수준 흐름이에요.
응답은 PresignedUpload로 받아오고, 이걸 가지고 직접 PUT 후 completeUpload를 호출하면 끝나요.

External 모드에서는 .onJobEnd를 쓸 수 없어요(잡 컨텍스트가 없으므로).
Agent Files 전용이에요.

files.completeUpload / downloadURL / download / get / list / delete

public func completeUpload(fileId: String) async throws -> FileMeta public func downloadURL(fileId: String) async throws -> URL @discardableResult public func download(fileId: String, to destination: URL) async throws -> URL public func get(fileId: String) async throws -> FileMeta public func list(bindingId: String? = nil, status: String? = nil) async throws -> [FileMeta] public func delete(fileId: String) async throws

completeUpload는 PUT을 마친 뒤 파일을 활성 상태로 만들어요.
downloadURL은 짧은 만료의 다운로드 URL을 발급하므로, 다운로드 직전에 새로 받는 게 안전해요.
downloaddestination에 직접 저장하며 반환은 그 URL 그대로예요.
list는 토큰이 접근 가능한 binding 내 파일만 보여줘요.

class DepliteAgent

public final class DepliteAgent: @unchecked Sendable { public let identity: AgentIdentity public let workflows: AgentWorkflows public let jobs: AgentJobs public let files: AgentFiles public init( identity: AgentIdentity, privateKey: Data, // 정확히 32바이트 session: URLSession = .shared ) throws }

Embedded 모드 클라이언트예요.
enroll() 결과를 별도 저장소에서 꺼내 넘기면 돼요.

속성타입설명
identityAgentIdentity등록 시 받은 비밀이 아닌 신원
workflowsAgentWorkflows워크플로우 인벤토리 보고
jobsAgentJobsJob 로그·결과 보고
filesAgentFilesJob 범위 파일 매니저

생성자에 전달된 privateKey가 32바이트가 아니면 즉시 DepliteError.invalidPrivateKey가 던져져요.

agent.heartbeat()

public func heartbeat() async throws

서명된 heartbeat를 1회 송신해요(추천 주기 30초).

agent.updateIdentity(…)

public func updateIdentity( hostname: String? = nil, os: String? = nil, agentVersion: String? = nil ) async throws

호스트네임·OS·버전 변경 시 PATCH로 알려요.

agent.events()

public func events() -> AsyncThrowingStream<AgentEvent, Error>

SSE 스트림을 AsyncThrowingStream으로 노출해요.
서버 → Agent 명령(deploy 등)의 서명 검증은 SDK가 자동 처리하므로 호출 측은 이벤트 타입만 분기하면 돼요.

이벤트 종류는 AgentEvent를 참고해주세요.

for try await event in agent.events() { switch event { case .deploy(let payload, _): try await handleDeploy(payload) case .syncWorkflows: _ = try await agent.workflows.report(loadLocal()) case .revoke: return case .ping: continue case .unknown(let name, _): print("unknown:", name) } }

전체 시나리오는 예제 페이지에 있어요.

struct AgentJobs

jobs.appendLogs(…)

@discardableResult public func appendLogs(jobId: String, items: [LogItem]) async throws -> Int

LogItem 배열을 한 번에 보내요.
서버가 실제로 수락한 라인 수가 돌아오고, 추천 배치 크기는 64KB 또는 1초 간격 중 빠른 쪽이에요.

jobs.reportResult(…)

public func reportResult(jobId: String, result: JobResult) async throws

잡당 1회만 호출해요.
JobResult는 직접 만들기보다 팩토리(JobResult.success 등)를 추천드려요.

do { let output = try await runWorkflow(payload) try await agent.jobs.reportResult( jobId: payload.jobId, result: .success(output: output) ) } catch { try await agent.jobs.reportResult( jobId: payload.jobId, result: .failed(exitCode: 1, errorMessage: "\(error)") ) }

struct AgentFiles

Job 컨텍스트 안에서 산출물 파일을 다뤄요.
기본 CleanupRule.onJobEnd라 잡 종료 시 자동 정리돼요.
각 메소드의 옵션과 반환값은 External Files와 동일하고, 모든 호출에 jobId가 추가로 필요한 점만 달라요.

public func upload(jobId: String, fileURL: URL, ...) async throws -> FileMeta public func presignUpload(jobId: String, ...) async throws -> PresignedUpload public func complete(fileId: String) async throws -> FileMeta public func downloadURL(fileId: String) async throws -> URL public func download(fileId: String, to: URL) async throws -> URL public func get(fileId: String) async throws -> FileMeta public func delete(fileId: String) async throws

External의 Files와 달리 모든 호출이 서명되고 jobId로 스코프돼요.
list는 노출되지 않아요.

struct AgentWorkflows

workflows.report(…)

@discardableResult public func report(_ workflows: [WorkflowReport]) async throws -> Int

서버에 알려진 워크플로우 인벤토리를 WorkflowReport 배열로 완전히 교체해요.
보고된 워크플로우 수가 돌아와요.

실제 YAML·step run 명령·시크릿 값은 보내지 않는 것을 추천드려요.
이름·메타만 보고하는 게 격리 모델의 핵심이에요.

타입 참조

Enrollment

public struct Enrollment: Sendable, Equatable { public let identity: AgentIdentity public let privateKey: Data // raw 32-byte 개인키 }

Deplite.enroll의 결과. 두 필드 모두 호출 측이 암호화 후 저장하는 것을 추천드려요.

AgentIdentity

public struct AgentIdentity: Codable, Sendable, Equatable { public let agentId: String public let organizationId: String public let baseURL: URL public let serverPublicKeyPEM: String }

비밀이 아니라 일반 저장소에 두어도 무방해요.

AgentEvent

public enum AgentEvent: Sendable { case deploy(payload: DeployPayload, signature: String) case revoke case syncWorkflows case ping case unknown(name: String, data: String) }
케이스의미
.deploy워크플로우 실행 명령 (payloadjobId·workflowName·params 등)
.revokeAgent 자격 회수
.syncWorkflows워크플로우 인벤토리 재보고 요청
.pingkeep-alive
.unknown알 수 없는 이벤트 또는 서명 검증 실패

DeployPayload

public struct DeployPayload: Sendable, Equatable, Decodable { public let jobId: String public let workflowName: String public let debug: Bool public let ref: String? public let params: JSONValue? public let issuedAt: Int64 public let nonce: String public let force: Bool public let forceReason: String? }

TriggerRunResult

public struct TriggerRunResult: Decodable, Sendable, Equatable { public let jobId: String public let status: String public let idempotent: Bool public let timedOut: Bool public let exitCode: Int? public let errorMessage: String? public let output: JSONValue? public let statusUrl: URL? }

CleanupRule

public enum CleanupRule: Sendable, Equatable { case ttl(seconds: Int64) // 60s ≤ seconds ≤ 90일 case persistent case onJobEnd // Agent Files 전용 }

FileMeta

public struct FileMeta: Decodable, Sendable, Equatable { public let id: String public let bindingId: String? public let jobId: String? public let filename: String? public let contentType: String? public let size: Int64? public let status: String? public let cleanupRule: String? public let expiresAt: String? public let createdAt: String? }

PresignedUpload

public struct PresignedUpload: Decodable, Sendable, Equatable { public let fileId: String public let uploadUrl: URL public let uploadHeaders: [String: String]? public let expiresInSeconds: Int? }

LogItem

public enum LogStream: String, Codable, Sendable { case raw, system } public enum LogLevel: String, Codable, Sendable { case info, warn, error } public struct LogItem: Sendable, Equatable { public let seq: Int public let stream: LogStream public let content: String public let stepName: String? public let level: LogLevel? }

JobResult

public enum JobStatus: String, Codable, Sendable { case running, success, failed, timeout, rejected } public struct JobResult: Sendable, Equatable { public let status: JobStatus public let exitCode: Int? public let errorMessage: String? public let output: JSONValue? public let rejection: Rejection? public struct Rejection: Sendable, Equatable { public let reason: String public let limitType: String? public let retryAfterSeconds: Int? public let bypassedLimits: [String] } public static func running() -> JobResult public static func success(exitCode: Int = 0, output: JSONValue? = nil) -> JobResult public static func failed(exitCode: Int? = nil, errorMessage: String? = nil) -> JobResult public static func timeout(errorMessage: String? = nil) -> JobResult public static func rejected(_ rejection: Rejection) -> JobResult }

직접 만들기보다 success·failed 같은 팩토리 사용을 추천드려요.

WorkflowReport

public struct WorkflowReport: Codable, Sendable, Equatable { public let name: String public let verboseSteps: [String] public let secretsKeys: [String] }

JSONValue

public enum JSONValue: Codable, Sendable, Equatable { case null case bool(Bool) case int(Int64) case double(Double) case string(String) case array([JSONValue]) case object([String: JSONValue]) }

리터럴 초기화 지원: let v: JSONValue = ["ref": "main", "count": 3]처럼 직접 작성 가능해요.

예외

DepliteError

public enum DepliteError: Error, Sendable { case api(statusCode: Int, body: String) case unauthorized(statusCode: Int, body: String) case transport(underlying: Error) case decoding(underlying: Error, body: String) case invalidPrivateKey case signing(reason: String) case sseClosed(reason: String) }
케이스발생
.api(statusCode, body)4xx·5xx (401·403 제외)
.unauthorized401·403 — Embedded는 재등록이 필요해요
.transport네트워크·URLSession 오류
.decoding응답 JSON 파싱 실패
.invalidPrivateKey32바이트 아닌 키로 DepliteAgent 생성
.signing서명 자체 실패
.sseClosedSSE 스트림 비정상 종료

추천 처리 패턴

do { _ = try await deplite.triggers.run(triggerId: triggerId) } catch DepliteError.unauthorized { // 토큰 회수·교체 필요 } catch let DepliteError.api(status, _) where status == 429 || status >= 500 { // 백오프 후 재시도 } catch let DepliteError.api(_, _) { // 4xx 클라이언트 오류 } catch { // 네트워크·기타 }

관련 문서

최종 수정 일자: