
AI 코딩 도구를 iOS 개발에 쓰다 보면 한계가 분명하게 드러나는 순간이 있다.
코드는 빠르게 작성해주지만, 실제 화면이 어떻게 보이는지는 결국 개발자가 Xcode에서 직접 확인해야 한다.
Figma를 기준으로 SwiftUI 화면을 구현한다고 해보자.
기존 작업 흐름은 보통 이렇다.
Figma 확인
→ AI가 SwiftUI 코드 작성
→ 개발자가 Xcode Preview 확인
→ 차이점을 다시 설명
→ AI가 코드 수정
코드 작성 속도는 빨라졌지만 화면 확인과 피드백 전달은 여전히 사람이 맡는다.
최근 iOS 개발 커뮤니티에서 Xcode MCP 서버의 RenderPreview를 JSON-RPC로 직접 호출해 SwiftUI Preview를 렌더링하는 사례가 소개됐다.
구조를 단순화하면 다음과 같다.
SwiftUI 코드 작성
→ Xcode MCP의 RenderPreview 호출
→ Preview 이미지 생성
→ 렌더링 결과 확인
→ 코드 수정
중요한 점은 AI가 코드를 생성하는 데서 끝나지 않는다는 것이다.
자신이 만든 SwiftUI 화면을 실제로 렌더링하고, 결과를 확인하고, 필요한 부분을 다시 수정하는 흐름까지 연결할 수 있다.
⸻
기존 AI 코딩 도구는 주로 소스 파일을 중심으로 동작했다.
파일 읽기
코드 작성
컴파일 오류 수정
테스트 코드 생성
리팩토링
일반적인 로직 작업에서는 이것만으로도 꽤 유용하다.
하지만 UI 작업은 다르다.
SwiftUI 코드가 문법적으로 올바르고 빌드까지 통과하더라도 실제 화면은 디자인 의도와 다를 수 있다.
padding이 예상보다 크다.
텍스트가 다른 위치에서 줄바꿈된다.
버튼 높이가 Figma와 다르다.
아이콘과 텍스트의 중심선이 맞지 않는다.
다크 모드에서 배경색이 어색하다.
긴 텍스트에서 전체 레이아웃이 밀린다.
이런 문제는 코드만 읽어서 완전히 판단하기 어렵다.
실제로 화면을 렌더링해야 확인할 수 있다.
Xcode MCP를 연결하면 AI 코딩 도구가 Xcode가 제공하는 기능을 외부 도구처럼 호출할 수 있다.
Preview 렌더링까지 가능하다면 코드 작성과 화면 확인을 하나의 작업 흐름으로 묶을 수 있다.
코드 작성
→ Xcode 기능 호출
→ Preview 렌더링
→ 결과 확인
→ 수정
기존에는 개발자가 직접 수행하던 화면 확인 과정 일부가 도구 호출로 바뀌는 것이다.
⸻
MCP는 AI 클라이언트와 외부 도구를 연결하기 위한 프로토콜이다.
MCP 서버는 자신이 제공하는 도구를 공개하고, 클라이언트는 도구 목록을 조회한 뒤 필요한 기능을 호출한다.
기본 흐름은 다음과 같다.
MCP Client
→ tools/list
→ 사용 가능한 도구 확인
→ tools/call
→ 도구 실행 결과 수신
MCP 메시지는 JSON-RPC 형식을 사용한다.
도구 목록을 요청하는 메시지는 개념적으로 다음과 같다.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}
특정 도구를 호출할 때는 이런 구조가 된다.
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "RenderPreview",
"arguments": {
"sourceFilePath": "MyApp/Features/Profile/ProfileView.swift"
}
}
}
실제 RenderPreview의 인자와 반환값은 Xcode 버전이나 MCP 연결 방식에 따라 달라질 수 있다.
중요한 것은 정확한 JSON 한 줄이 아니다.
Xcode의 기능을 반드시 Xcode 화면 안에서만 사용할 필요가 없어졌다는 점이다.
사람이 버튼을 누르는 개발 도구
→ 외부 프로그램이 호출할 수 있는 개발 도구
이 변화가 UI 자동화의 범위를 크게 넓힌다.
⸻
SwiftUI Preview는 원래 개발자가 Xcode Canvas에서 UI를 빠르게 확인하기 위한 기능이다.
#Preview("Default") {
ProfileCardView(
model: .preview
)
.padding()
}
Xcode는 이 Preview 선언을 기준으로 화면을 렌더링한다.
RenderPreview를 외부에서 호출할 수 있다면 이 렌더링 과정을 개발 워크플로 안으로 가져올 수 있다.
전체 흐름은 다음과 같다.
1. SwiftUI 파일에 #Preview 작성
2. AI 코딩 도구가 Xcode MCP 서버에 연결
3. tools/list로 RenderPreview 사용 가능 여부 확인
4. 대상 파일이나 Preview 정보 전달
5. Xcode가 Preview 렌더링
6. Snapshot 또는 결과 경로 반환
7. 결과를 Artifact로 저장
결과 파일은 프로젝트 안에 남길 수 있다.
artifacts/
└── previews/
├── profile-card-default.png
├── profile-card-long-text.png
├── profile-card-loading.png
└── profile-card-dark.png
이 이미지들은 다음 작업에 사용할 수 있다.
AI 자체 검토
Figma 기준 비교
PR 화면 첨부
디자인 리뷰
변경 전후 비교
상태별 UI 확인
Preview가 개발자 눈으로만 확인하는 화면에서, 자동화 워크플로가 소비할 수 있는 결과물로 바뀌는 것이다.
⸻
현재 가장 일반적인 방식은 개발자가 직접 Preview를 확인하는 구조다.
AI가 SwiftUI 코드 작성
→ 개발자가 Preview 실행
→ 화면 차이를 확인
→ 자연어로 문제 설명
→ AI가 다시 수정
개발자는 보통 이런 식으로 피드백한다.
카드의 위아래 padding이 조금 큽니다.
아이콘과 타이틀 간격을 줄여주세요.
긴 이름에서 오른쪽 버튼이 밀립니다.
이 방식은 충분히 사용할 수 있지만 한계가 있다.
시각적 차이가 자연어로 다시 압축된다.
조금 크다.
약간 밀렸다.
Figma보다 답답하다.
중심이 미묘하게 안 맞는다.
이런 표현은 수치가 명확하지 않다.
AI가 수정한 결과가 정확한지 확인하려면 개발자가 다시 Preview를 봐야 한다.
결국 화면 확인 과정은 계속 사람에게 남는다.
⸻
RenderPreview를 워크플로에 넣으면 화면 확인 과정을 더 구조화할 수 있다.
AI가 SwiftUI 코드 작성
→ RenderPreview 호출
→ Snapshot 생성
→ 기준 이미지와 비교
→ 차이점 정리
→ 코드 수정
→ 다시 렌더링
다만 AI에게 단순히 “화면을 보고 알아서 고쳐”라고 하면 안 된다.
먼저 검증 기준을 파일로 정의하는 것이 좋다.
# Preview Validation
## Target
- View: ProfileCardView
- Device: iPhone 16 Pro
- Color Scheme: Light / Dark
## Required States
- 기본 상태
- 긴 이름
- 프로필 이미지 없음
- 로딩 상태
- 에러 상태
## Review Items
- 외부 padding
- 아이콘과 타이틀 간격
- 텍스트 줄바꿈
- 버튼 높이
- 카드 radius
- 다크 모드 색상
렌더링 결과는 이 기준에 따라 검토한다.
Expected:
외부 horizontal padding 20pt
Rendered:
외부 horizontal padding 약 24pt
Suggested Fix:
ProfileCardView의 container padding을 20으로 변경
이렇게 하면 수정 이유와 대상 파일이 명확해진다.
AI가 이미지를 보고 막연히 수정하는 것이 아니라, 정의된 기준과 렌더링 결과를 비교해 필요한 부분만 바꾸게 된다.
⸻
세 도구를 함께 사용할 필요는 없다.
현재 사용 중인 AI 코딩 도구 하나에 Xcode MCP를 연결해도 같은 흐름을 만들 수 있다.
공통 구조는 다음과 같다.
AI 코딩 도구
→ Xcode MCP 연결
→ SwiftUI 코드 수정
→ RenderPreview 호출
→ Snapshot 확인
→ 필요한 부분 수정
각 도구의 설정 방식과 작업 인터페이스는 다르지만 핵심 원리는 같다.
⸻
Codex를 주로 사용하는 개발자는 코드 수정과 Preview 확인을 하나의 작업으로 묶을 수 있다.
작업 요청은 다음처럼 구성할 수 있다.
ProfileCardView.swift를 Figma 기준에 맞게 수정해줘.
작업 순서:
1. layout-contract.json 확인
2. 기존 DesignSystem 토큰 확인
3. SwiftUI 코드 수정
4. 상태별 #Preview 추가
5. Xcode MCP의 RenderPreview 사용 가능 여부 확인
6. 기본 상태와 긴 텍스트 상태 렌더링
7. 결과와 남은 문제 보고
제약:
- DesignSystem 수정 금지
- 새 색상 토큰 추가 금지
- API 로직 수정 금지
- 관련 없는 파일 수정 금지
Codex는 저장소 안에서 실제 파일을 수정하고, 렌더링 결과를 확인한 뒤 같은 작업 안에서 수정 사항을 반영하는 방식으로 사용할 수 있다.
완료 보고에는 다음이 포함되어야 한다.
수정 파일
실행한 RenderPreview 요청
생성된 Snapshot 경로
남은 시각적 차이
사람이 확인해야 할 부분
⸻
Claude Code를 주로 사용한다면 프로젝트 규칙과 UI 검증 기준을 문서로 제공하는 방식이 잘 맞는다.
다음 문서를 먼저 읽어줘.
- layout-contract.json
- design-tokens.json
- component-map.md
- preview-validation.md
그다음 ProfileCardView.swift를 수정하고,
Xcode MCP의 RenderPreview로 결과를 확인해줘.
완료 보고:
- 수정 파일
- 렌더링한 Preview 목록
- 발견한 mismatch
- 수정한 내용
- 사람이 검토할 부분
프로젝트 루트의 CLAUDE.md에는 공통 UI 규칙을 둘 수 있다.
# UI Rules
- 기존 DesignSystem 토큰만 사용한다.
- Figma 수치는 layout-contract.json을 따른다.
- Preview 없이 시각적으로 일치한다고 보고하지 않는다.
- 긴 텍스트와 다크 모드 상태를 확인한다.
- 관련 없는 파일은 수정하지 않는다.
Claude Code 하나만 사용하더라도 구현, Preview 렌더링, 결과 검토, 수정 반복 흐름을 구성할 수 있다.
⸻
Cursor를 사용하는 개발자는 Agent 작업 안에 Preview 렌더링을 완료 조건으로 포함할 수 있다.
CheckoutSummaryCard를 구현해줘.
기준:
- layout-contract.json
- design-tokens.json
- component-map.md
- preview-validation.md
구현 후:
1. 상태별 #Preview 작성
2. Xcode MCP에서 RenderPreview 실행
3. Default와 Dark Mode Snapshot 확인
4. 디자인 수치와 다른 부분만 수정
5. 관련 없는 파일은 변경하지 않기
Cursor에서도 중요한 것은 코드 작성만 요청하지 않는 것이다.
구현 완료 조건:
코드 작성
+ Preview 렌더링
+ Snapshot 확인
+ 남은 차이 보고
어떤 도구를 사용하든 Xcode MCP 서버 연결 방법과 실제 제공 도구는 현재 사용하는 버전에서 직접 확인해야 한다.
⸻
Figma 기반 UI를 AI에게 맡길 때 화면 이미지만 제공하면 많은 수치를 추측하게 된다.
더 안정적인 방식은 Figma의 수치와 디자인 토큰을 계약 파일로 만드는 것이다.
.ai/ui-tasks/profile-card/
├── task.md
├── layout-contract.json
├── design-tokens.json
├── component-map.md
├── preview-validation.md
├── render-request.json
└── artifacts/
└── previews/
layout-contract.json에는 구현에 필요한 수치를 넣는다.
{
"component": "ProfileCard",
"container": {
"padding": 20,
"spacing": 16,
"cornerRadius": 16
},
"avatar": {
"size": 48
},
"title": {
"fontToken": "titleMedium"
}
}
전체 흐름은 다음처럼 연결된다.
Figma Node
→ Layout Contract 생성
→ SwiftUI 구현
→ RenderPreview 실행
→ Snapshot 생성
→ Figma Reference와 비교
→ 차이 수정
각 자료의 역할은 분리해야 한다.
Figma Metadata
→ 실제 구현 수치
Design Token
→ 코드에서 사용할 색상과 폰트
RenderPreview Snapshot
→ 현재 구현된 실제 화면
Figma Reference
→ 최종 시각 검토 기준
이렇게 하면 AI가 이미지를 보고 감으로 코딩하는 것이 아니라, 수치를 기준으로 구현하고 렌더링 결과로 검증하게 된다.
⸻
자동 UI 검증을 제대로 사용하려면 Preview 코드부터 잘 작성해야 한다.
기본 상태 하나만 있는 Preview로는 부족하다.
enum ProfileCardPreviewFixture {
static let normal = ProfileCardModel(
name: "김개발",
subtitle: "iOS Developer",
imageURL: nil,
isLoading: false
)
static let longText = ProfileCardModel(
name: "아주 긴 이름을 가진 사용자입니다",
subtitle: "긴 설명이 두 줄 이상 표시되는 상태입니다",
imageURL: nil,
isLoading: false
)
static let loading = ProfileCardModel(
name: "",
subtitle: "",
imageURL: nil,
isLoading: true
)
}
상태별 Preview를 작성한다.
#Preview("Normal") {
ProfileCardView(
model: ProfileCardPreviewFixture.normal
)
.padding()
}
#Preview("Long Text") {
ProfileCardView(
model: ProfileCardPreviewFixture.longText
)
.padding()
}
#Preview("Loading") {
ProfileCardView(
model: ProfileCardPreviewFixture.loading
)
.padding()
}
UI 검증용 Preview는 단순한 개발 편의 기능이 아니다.
테스트 Fixture와 비슷한 역할을 한다.
Normal
Long Text
Loading
Error
Empty
Dark Mode
Large Dynamic Type
UI가 깨질 가능성이 높은 상태를 미리 정의해야 한다.
⸻
렌더링할 Preview를 매번 자연어로 설명하지 말고 내부 계약 파일로 관리할 수 있다.
{
"sourceFilePath": "MyApp/Features/Profile/ProfileCardView.swift",
"previewNames": [
"Normal",
"Long Text",
"Loading"
],
"device": "iPhone 16 Pro",
"colorSchemes": [
"light",
"dark"
],
"outputDirectory": "artifacts/previews",
"timeout": 120
}
이 파일은 팀 내부 워크플로의 기준이다.
실제 스크립트나 에이전트가 이 정보를 Xcode MCP 요청으로 변환한다.
장점은 사용하는 AI 도구가 바뀌어도 같은 렌더링 기준을 유지할 수 있다는 점이다.
Codex
Claude Code
Cursor
다른 MCP 클라이언트
어떤 도구를 사용하더라도 같은 render-request.json을 읽고 같은 Preview를 렌더링할 수 있다.
⸻
Xcode MCP를 직접 호출하는 로직을 AI 프롬프트 안에 반복해서 넣는 것은 좋지 않다.
팀 내부 래퍼 스크립트를 하나 두는 편이 안정적이다.
scripts/
└── render-preview.ts
스크립트의 역할은 단순하다.
1. render-request.json 읽기
2. Xcode MCP 서버 연결
3. tools/list로 RenderPreview 확인
4. tools/call 실행
5. Snapshot 경로 추출
6. artifacts/previews로 정리
7. render-result.json 생성
개념 코드는 다음과 같다.
type RenderPreviewRequest = {
sourceFilePath: string;
previewName?: string;
timeout: number;
};
type RenderPreviewResult = {
status: "passed" | "failed";
snapshotPath?: string;
errorMessage?: string;
};
async function renderPreview(
request: RenderPreviewRequest
): Promise<RenderPreviewResult> {
const response = await callJsonRpc({
method: "tools/call",
params: {
name: "RenderPreview",
arguments: {
sourceFilePath: request.sourceFilePath,
timeout: request.timeout
}
}
});
if (response.error) {
return {
status: "failed",
errorMessage: response.error.message
};
}
return {
status: "passed",
snapshotPath: response.result?.previewSnapshotPath
};
}
실제 요청과 응답 필드는 현재 Xcode MCP의 Schema를 확인해야 한다.
래퍼 스크립트가 필요한 이유는 Xcode 쪽 인터페이스가 변경될 때 수정 범위를 한곳으로 제한할 수 있기 때문이다.
AI 코딩 도구
→ 팀 내부 render-preview 스크립트
→ Xcode MCP 서버
AI 도구가 Xcode MCP 세부 구현을 직접 알 필요가 없게 만드는 것이다.
⸻
렌더링 이미지만 저장하면 다음 단계에서 상태를 판단하기 어렵다.
결과도 구조화해 남기는 것이 좋다.
성공한 경우는 다음과 같다.
{
"status": "passed",
"sourceFilePath": "MyApp/Features/Profile/ProfileCardView.swift",
"snapshots": [
{
"name": "Normal",
"path": "artifacts/previews/profile-card-normal.png"
},
{
"name": "Long Text",
"path": "artifacts/previews/profile-card-long-text.png"
}
],
"durationMs": 4210,
"warnings": []
}
실패한 경우는 다음처럼 기록한다.
{
"status": "failed",
"sourceFilePath": "MyApp/Features/Profile/ProfileCardView.swift",
"error": {
"code": "preview_timeout",
"message": "RenderPreview timed out after 120 seconds."
},
"suggestedAction": "Preview 의존성을 줄이거나 timeout을 늘려 확인한다."
}
이렇게 해야 AI가 렌더링 실패와 UI 불일치를 구분할 수 있다.
RenderPreview 실행 실패
≠
UI 디자인 검증 실패
둘은 완전히 다른 문제다.
⸻
두 방식은 비슷해 보이지만 목적이 다르다.
Snapshot Test는 보통 회귀 감지에 사용한다.
이전 이미지와 현재 이미지가 달라졌는가?
RenderPreview 워크플로는 구현 중 시각적 피드백에 가깝다.
현재 구현된 UI가 어떻게 보이는가?
Figma와 어디가 다른가?
어떤 코드를 다시 수정해야 하는가?
Figma 비교는 디자인 기준 검증이다.
Figma Reference
→ 기대 화면
RenderPreview Snapshot
→ 현재 구현 화면
세 가지 역할을 정리하면 다음과 같다.
RenderPreview
→ 현재 화면 렌더링
Figma Comparison
→ 디자인과 차이 확인
Snapshot Test
→ 이후 변경에서 회귀 감지
세 방식은 경쟁 관계가 아니라 연결해서 사용하는 것이 좋다.
⸻
렌더링 결과를 로컬에서만 보고 끝내지 말고 PR 검토 자료로 남길 수 있다.
## UI Preview Validation
### Rendered States
- Normal
- Long Text
- Loading
- Dark Mode
### Artifacts
- `artifacts/previews/profile-card-normal.png`
- `artifacts/previews/profile-card-long-text.png`
- `artifacts/previews/profile-card-loading.png`
- `artifacts/previews/profile-card-dark.png`
### Validation Result
- RenderPreview: Passed
- Figma comparison: Minor mismatch
- Snapshot regression: Not configured
### Human Review Focus
- 긴 타이틀 줄바꿈
- 이미지 없는 상태의 정렬
- 다크 모드 배경 대비
리뷰어는 코드 diff뿐 아니라 실제 렌더링 화면을 함께 볼 수 있다.
UI PR의 검토 품질이 올라간다.
⸻
실무에서는 작업별로 다음 구조를 둘 수 있다.
.ai/ui-preview/
└── profile-card/
├── task.md
├── layout-contract.json
├── design-tokens.json
├── component-map.md
├── preview-validation.md
├── render-request.json
├── render-result.json
├── review-result.json
└── artifacts/
└── previews/
├── normal.png
├── long-text.png
├── loading.png
└── dark.png
각 파일의 역할은 분명하다.
task.md
→ 작업 범위
layout-contract.json
→ 레이아웃 수치
design-tokens.json
→ 색상과 폰트
component-map.md
→ Figma와 코드 컴포넌트 매핑
preview-validation.md
→ 검토할 상태와 항목
render-request.json
→ 렌더링 요청
render-result.json
→ 렌더링 결과
review-result.json
→ 시각 검토 결과
AI에게 긴 설명을 반복하는 대신 파일을 기준으로 작업하게 한다.
⸻
AI가 렌더링 결과를 검토할 때 긴 자연어만 반환하게 두면 수정 단계에서 다시 해석해야 한다.
검토 결과도 구조화할 수 있다.
{
"verdict": "needs_changes",
"mismatches": [
{
"id": "ui-001",
"severity": "medium",
"area": "container",
"expected": "horizontal padding 20pt",
"actual": "approximately 24pt",
"targetFile": "ProfileCardView.swift",
"suggestedChange": "container horizontal padding을 20으로 변경"
},
{
"id": "ui-002",
"severity": "low",
"area": "title",
"expected": "한 줄 표시",
"actual": "긴 텍스트에서 예상보다 일찍 줄바꿈",
"targetFile": "ProfileCardView.swift",
"suggestedChange": "title 영역의 layoutPriority 확인"
}
],
"humanReview": [
"다크 모드에서 배경 대비가 디자인 의도와 맞는지 확인"
]
}
다음 수정 작업은 mismatches에 기록된 항목만 처리하게 한다.
불필요한 재설계를 막을 수 있다.
⸻
AI에게 Xcode 기능 전체를 자동 허용하면 안 된다.
Preview 렌더링은 비교적 위험이 낮지만 프로젝트 설정 변경과 셸 실행은 다르다.
xcode_tools:
RenderPreview:
mode: allow
Diagnostics:
mode: allow
ReadFile:
mode: allow
WriteFile:
mode: ask
ModifyProjectSettings:
mode: ask
DeleteFile:
mode: deny
RunShellScript:
mode: ask
특히 다음 작업은 자동으로 실행하지 않는 편이 좋다.
Signing 설정 변경
Build Setting 변경
Package 추가
Script Phase 수정
파일 삭제
Fastlane 실행
배포 명령
렌더링 권한과 프로젝트 변경 권한을 분리해야 한다.
⸻
Xcode MCP 서버가 제공하는 도구 이름과 입력 Schema는 버전에 따라 달라질 수 있다.
따라서 RenderPreview가 항상 같은 이름과 인자를 유지한다고 가정하면 안 된다.
안전한 흐름은 다음과 같다.
Xcode 업데이트
→ tools/list 재확인
→ RenderPreview 존재 여부 확인
→ inputSchema 확인
→ 래퍼 스크립트 테스트
도구 이름을 여러 AI 프롬프트와 스크립트에 흩어놓기보다 래퍼 한곳에 모아두는 이유도 여기에 있다.
⸻
SwiftUI Preview는 프로젝트 상태와 빌드 환경에 영향을 받는다.
환경 객체 누락
Preview Fixture 부족
의존성 로딩 실패
시뮬레이터 Runtime 부족
패키지 빌드 실패
렌더링 Timeout
Preview가 실패했다고 해서 SwiftUI 코드가 반드시 잘못된 것은 아니다.
결과를 최소한 세 상태로 나누는 것이 좋다.
passed
→ Preview 렌더링 성공
failed
→ 코드 또는 Preview 구성 문제
environment_error
→ Xcode, Simulator, 의존성 환경 문제
AI가 환경 문제를 UI 코드 문제로 오해해 불필요한 수정에 들어가는 것을 막아야 한다.
⸻
로컬에서 동작하는 RenderPreview 흐름이 CI에서도 바로 안정적으로 동작한다고 보장하기 어렵다.
처음부터 필수 Merge Gate로 두기보다는 단계적으로 적용하는 것이 좋다.
1단계
로컬에서 RenderPreview 자동화
2단계
생성된 Preview를 PR에 첨부
3단계
핵심 컴포넌트만 Snapshot 비교
4단계
안정화된 작업만 CI 검증
5단계
실패 유형과 재시도 정책 정리
Preview 환경 문제 때문에 모든 PR이 막히는 상황은 피해야 한다.
⸻
RenderPreview 사례에서 중요한 것은 SwiftUI Preview 하나만이 아니다.
개발 도구를 사용하는 방식 자체가 바뀌고 있다는 점이다.
기존에는 사람이 Xcode UI를 직접 조작했다.
Xcode 열기
Canvas 확인
Build 실행
오류 확인
테스트 결과 확인
MCP를 통해 같은 기능을 프로그램이나 에이전트가 호출할 수 있다.
도구 목록 조회
Preview 렌더링
진단 정보 수집
테스트 실행
결과 Artifact 저장
AI 코딩 도구는 채팅으로 답변하는 보조 도구에서, 실제 개발 환경을 사용하는 클라이언트로 바뀌고 있다.
iOS UI 작업도 다음 흐름으로 발전할 수 있다.
요구사항
→ SwiftUI 구현
→ Xcode Preview 렌더링
→ 이미지 검토
→ 코드 수정
→ 테스트
→ PR Artifact 생성
AI에게 필요한 것은 코드를 많이 만드는 능력만이 아니다.
자신이 만든 결과를 개발 도구로 확인하고, 검증 결과를 근거로 수정하는 능력이다.
⸻
Xcode MCP의 RenderPreview를 외부에서 호출하는 방식은 SwiftUI UI 작업의 시각적 피드백 과정을 자동화하는 데 활용할 수 있다.
기존에는 AI가 코드를 작성한 뒤 개발자가 화면을 확인해야 했다.
이제는 다음 흐름을 구성할 수 있다.
SwiftUI 코드 작성
→ RenderPreview 호출
→ Snapshot 생성
→ Figma 기준과 비교
→ 차이 수정
→ 다시 렌더링
Codex, Claude Code, Cursor 중 어떤 도구를 사용하든 기본 원칙은 같다.
현재 사용하는 AI 코딩 도구 하나에 Xcode MCP를 연결한다.
상태별 Preview Fixture를 준비한다.
렌더링 요청과 결과를 JSON으로 관리한다.
Snapshot을 Artifact로 남긴다.
시각적 검증을 완료 조건에 포함한다.
렌더링 권한과 프로젝트 수정 권한을 분리한다.
앞으로 iOS 개발자가 AI 도구를 활용할 때 중요한 것은 코드 생성 속도만이 아니다.
Figma, SwiftUI, Xcode Preview, Snapshot, PR 리뷰를 하나의 검증 가능한 작업 흐름으로 연결하는 능력이다.
AI가 SwiftUI 코드를 작성하는 것에서 끝나지 않고, 실제 화면을 렌더링하고 결과를 확인한 뒤 필요한 부분만 다시 수정하게 만드는 것이 이 흐름의 핵심이다.