---
title: "sdk/ios"
description: "ASWebAuthenticationSession, PKCE S256 인증 코드 흐름, Keychain 토큰 저장소를 사용하는 iOS 및 macOS용 Swift SDK."
locale: "ko"
---

> Documentation Index
> Fetch the locale documentation index at: https://xid.dev/ko/llms.txt
> Use this file to discover all available pages before exploring further.

# sdk/ios

## 상태

패키지 상태: **구현됨 · 로컬 검증 완료**. 단위 테스트(19개 통과)가 iOS 시뮬레이터를 타깃으로 macOS에서 실행됩니다. 실행 중인 XID 인스턴스에 대한 실제 IdP 왕복 테스트는 수동 검증 대기 중입니다. 이 페이지는 구현된 동작을 문서화하며, 프로덕션 준비 완료를 의미하지 않습니다.

## 요구 사항

- iOS 16 이상 / macOS 13 이상
- Swift 5.9 이상 및 Xcode 15 이상
- 서드파티 의존성 없음 — Apple 시스템 프레임워크만 사용합니다

## 설치

Xcode에서 Swift Package Manager를 통해(파일 -&gt; 패키지 의존성 추가) 또는 `Package.swift`에 직접 패키지를 추가하세요:

```swift
// Package.swift
dependencies: [
.package(url: "https://github.com/StringKe/xid", from: "0.1.0"),
],
targets: [
.target(name: "YourApp", dependencies: [.product(name: "Xid", package: "xid")]),
]
```

## 빠른 시작

```swift
import Xid

// 1. Configure in @main App.init
Xid.shared.configure(options: XidConfiguration(
issuer: URL(string: "https://xid.dev")!,
clientId: "your_client_id",
redirectUri: URL(string: "com.example.app://auth/callback")!,
scopes: ["openid", "profile", "email", "offline_access"]
))

// 2. Sign in (opens ASWebAuthenticationSession)
try await Xid.shared.signIn()

// 3. Handle redirect in SceneDelegate
let session = try await Xid.shared.handleRedirect(url: callbackUrl)

// 4. Get current session (auto-refreshes near expiry)
if let session = try await Xid.shared.getSession() {
let token = try await Xid.shared.getAccessToken()
}

// 5. Sign out
try await Xid.shared.signOut(callEndSession: true)
```

## 핵심 API

| 방법 | 설명 |
| --- | --- |
| `configure(options:)` | issuer, clientId, redirectUri, scopes로 초기화합니다. 다른 메서드보다 먼저 호출하세요. |
| `signIn(options:) async throws` | PKCE S256 인증 URL로 ASWebAuthenticationSession을 엽니다. 브라우저 세션이 종료될 때 반환합니다. |
| `handleRedirect(url:) async throws -> XidSession` | OAuth state를 검증하고 token 엔드포인트에서 인증 코드를 교환하며 토큰을 Keychain에 저장한 후 세션을 반환합니다. |
| `getSession() async throws -> XidSession?` | 저장된 세션을 반환하며 만료가 임박한 경우 refresh 토큰 교체를 트리거합니다. |
| `getAccessToken(forceRefresh:) async throws -> String` | 유효한 액세스 토큰 문자열을 반환하며 필요 시 자동으로 갱신합니다. |
| `signOut(callEndSession:) async throws` | Keychain 토큰을 삭제합니다. true를 전달하면 브라우저를 통해 end\_session 엔드포인트를 호출합니다. |
| `setTokenStorage(_:) throws` | 기본 KeychainTokenStorage를 사용자 정의 TokenStorageAdapter 구현으로 교체합니다. |

## 저장소 어댑터

기본 저장소는 `kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly`가 있는 Keychain을 사용합니다. 토큰은 iCloud Keychain에 동기화되지 않습니다. 엔터프라이즈 Keychain 정책을 사용하려면 `TokenStorageAdapter` 프로토콜을 구현하세요:

```swift
struct EnterpriseKeychain: TokenStorageAdapter {
func save(key: String, value: String) throws { /* ... */ }
func load(key: String) throws -> String? { /* ... */ }
func delete(key: String) throws { /* ... */ }
}
try Xid.shared.setTokenStorage(EnterpriseKeychain())
```

## 보안

- 공개 클라이언트 — client secret이 저장되거나 전송되지 않습니다.
- PKCE S256만 사용합니다. 서버는 plain challenge 방식을 거부합니다.
- 요청마다 생성되는 무작위 OAuth state; CSRF를 방지하기 위해 리디렉션 시 검증됩니다.
- PKCE code\_verifier는 인증 흐름 동안만 Keychain에 기록되며 코드 교환 즉시 삭제됩니다.
- 앱 간 브라우저 cookie 공유를 방지하기 위해 prefersEphemeralWebBrowserSession = true로 시작된 ASWebAuthenticationSession.

## 알려진 제한 사항

- JWKS 기반 ES256/RS256 ID token 검증, end\_session logout, refresh single-flight는 구현되어 로컬 테스트를 통과했습니다. L4 지원 전에는 iOS 기기 또는 simulator의 IdP 검증이 필요합니다.
- Keychain 동작은 Xcode 기기 또는 simulator test에서 검증해야 합니다.

Source: https://xid.dev/ko/sdks/ios/index.mdx
