|
| 1 | +<!DOCTYPE html> |
| 2 | +<html lang="ko"> |
| 3 | +<head> |
| 4 | +<meta charset="UTF-8"> |
| 5 | +<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| 6 | +<title>💳 구독형 앱 만들기 — HIG Lab</title> |
| 7 | +<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300;400;500;600;700;900&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet"> |
| 8 | +<style> |
| 9 | +:root{--bg:#fafafa;--surface:#fff;--text:#1d1d1f;--text-2:#6e6e73;--accent:#0071e3;--green:#34c759;--border:#d2d2d7;--code-bg:#1e1e2e;--radius:16px} |
| 10 | +*{margin:0;padding:0;box-sizing:border-box}body{font-family:'Noto Sans KR',-apple-system,sans-serif;background:var(--bg);color:var(--text);line-height:1.8} |
| 11 | +.top-bar{position:sticky;top:0;z-index:100;background:rgba(250,250,250,0.88);backdrop-filter:blur(20px);border-bottom:.5px solid var(--border)} |
| 12 | +.top-bar-inner{max-width:800px;margin:0 auto;padding:12px 24px;display:flex;justify-content:space-between} |
| 13 | +.top-logo{font-size:16px;font-weight:700;text-decoration:none;color:var(--text)}.top-logo span{color:var(--accent)} |
| 14 | +article{max-width:800px;margin:0 auto;padding:48px 24px 120px} |
| 15 | +h1{font-size:clamp(32px,5vw,44px);font-weight:900;letter-spacing:-1.5px;line-height:1.2;margin-bottom:16px} |
| 16 | +h2{font-size:26px;font-weight:800;margin:48px 0 16px}p{margin-bottom:16px} |
| 17 | +.code-block{background:var(--code-bg);border-radius:12px;margin:20px 0;overflow:hidden} |
| 18 | +.code-header{padding:10px 16px;background:rgba(255,255,255,0.05);border-bottom:1px solid rgba(255,255,255,0.08);display:flex;justify-content:space-between} |
| 19 | +.code-filename{font-size:13px;color:#cdd6f4;font-family:'JetBrains Mono',monospace} |
| 20 | +pre.code-body{margin:0;padding:16px;font-family:'JetBrains Mono',monospace;font-size:13px;line-height:1.6;color:#cdd6f4;white-space:pre;overflow-x:auto} |
| 21 | +.code-body .kw{color:#cba6f7}.code-body .type{color:#89b4fa}.code-body .str{color:#a6e3a1}.code-body .func{color:#89dceb}.code-body .prop{color:#f5c2e7}.code-body .comment{color:#6c7086} |
| 22 | +</style> |
| 23 | +</head> |
| 24 | +<body> |
| 25 | +<div class="top-bar"><div class="top-bar-inner"><a href="../index.html" class="top-logo">HIG <span>Lab</span></a></div></div> |
| 26 | +<article> |
| 27 | +<h1>💳 구독형 앱 만들기</h1> |
| 28 | +<p>StoreKit 2의 현대적인 async/await API로 구독 시스템을 구현합니다.</p> |
| 29 | + |
| 30 | +<h2>📦 Product 로딩</h2> |
| 31 | +<div class="code-block"><div class="code-header"><span class="code-filename">StoreManager.swift</span></div> |
| 32 | +<pre class="code-body"><span class="kw">func</span> <span class="func">loadProducts</span>() <span class="kw">async</span> { |
| 33 | + products = <span class="kw">try await</span> <span class="type">Product</span>.products(<span class="kw">for</span>: productIDs) |
| 34 | +}</pre></div> |
| 35 | + |
| 36 | +<h2>💰 구매 처리</h2> |
| 37 | +<div class="code-block"><div class="code-header"><span class="code-filename">Purchase.swift</span></div> |
| 38 | +<pre class="code-body"><span class="kw">let</span> result = <span class="kw">try await</span> product.purchase() |
| 39 | +<span class="kw">switch</span> result { |
| 40 | +<span class="kw">case</span> .success(<span class="kw">let</span> verification): |
| 41 | + <span class="kw">guard case</span> .verified(<span class="kw">let</span> transaction) = verification <span class="kw">else</span> { <span class="kw">return</span> } |
| 42 | + <span class="kw">await</span> transaction.finish() |
| 43 | +<span class="kw">case</span> .userCancelled, .pending: |
| 44 | + <span class="kw">break</span> |
| 45 | +}</pre></div> |
| 46 | + |
| 47 | +<h2>🎨 페이월 UI (HIG)</h2> |
| 48 | +<p>Apple HIG 페이월 가이드라인: 기능 가치 먼저 보여주기, 명확한 가격, 쉬운 복원 경로</p> |
| 49 | + |
| 50 | +</article> |
| 51 | +</body> |
| 52 | +</html> |
0 commit comments