크리에이티브 옵스·iOS 릴리스 담당은 AppIcon.appiconset PNG와 Contents.json이 어긋날 때마다 늦은 Xcode 오류와 스토어 심사 리스크를 감수합니다. 아래는 2026년 기준 재현 가능한 원격 Mac 플레이북입니다. OpenClaw로 워커를 구성하고, 실제 픽셀을 JSON에서 유도한 기대값과 일괄 비교한 뒤 Markdown 수정 보고서를 남기고, 디바운스된 폴더 감시나 launchd 슬라이스로 디자인 납품 자동화를 고정합니다. 슬롯 수학은 iOS 앱 아이콘 납품 매트릭스와 함께 두면 팀 언어가 맞습니다.
카탈로그 드리프트가 나는 이유
- 스케일 산술 오류: 마스터를 2×·3×로 복사만 하고 픽셀을 다시 계산하지 않아, 파일명은
Contents.json과 맞지만 실제 해상도가 다릅니다. - 낡은 JSON: PNG 이름만 바꾸고
images항목을 모두 갱신하지 않으면 고아·누락 참조가 생깁니다. - 조용한 리사이즈: 최적화·패딩 단계에서 한 변만 바뀌어도 미리보기는 정상처럼 보일 수 있습니다.
머지 전·업로드 전에 한 번 게이트를 두면 이런 문제가 야간 빌드 파손 대신 보고서 한 줄로 떨어집니다.
자동화 형태 선택
| 모드 | 적합한 경우 | 트레이드오프 |
|---|---|---|
| 수동 CLI | 스토어 제출 직전 일회 감사 | 설정은 가볍지만 마감에 밀리면 빠뜨리기 쉬움 |
| OpenClaw + 디바운스 감시 | 디자이너가 공유 원격 Mac inbox에보낸 세트를 올리는 팀 | 부분 쓰기와 레이스를 피하려면 유휴 구간 튜닝 필요 |
OpenClaw + launchd 슬라이스 |
15분·야간 등 고정 주기 배치 | 용량 계획은 단순하지만 다음 틱까지 지연 |
설치·구성·실행(다섯 단계)
- OpenClaw·보조 도구: 워커에서 OpenClaw 설치 가이드를 따르고, 없으면
jq를 설치합니다. 샘플 PNG에sips -g pixelWidth -g pixelHeight가 동작하는지 확인합니다. - 카탈로그 고정:
APPICON_DIR=/path/to/AppIcon.appiconset,REPORT_PATH=./logs/appicon_fix_report.md등 환경 변수를 export합니다. 보고서 상단에git rev-parse HEAD를 적어 추적 가능하게 합니다. Contents.json린트:plutil -lint Contents.json으로 문법을 먼저 통과시킵니다. JSON이 깨지면 픽셀 로직 이전에 오탐·미검이 납니다.- 기대 픽셀 계산:
images[]에서filename이 있는 항목마다size(예60x60)와scale(2x등)을 읽습니다. 변 길이는 베이스 포인트에 정수 스케일(2×→2, 3×→3)을 곱해 구합니다. - 측정·diff: 참조된 PNG마다 실제 가로·세로를 읽고 다르면 Markdown 행을 추가합니다. 불일치가 남으면 0이 아닌 exit code로 종료해 CI·OpenClaw가 잡을 수 있게 합니다.
감시 훅·배치 스크립트 템플릿
디바운스 감시: inbox/appicon/이 약 45초 무작업이 되면 work/로 복사해 검증하고, 통과 시 report.md와 함께 out/으로 승격, 실패는 failed/로 옮깁니다.
배치 슬라이스: 화이트라벨 저장소라면 Assets.xcassets 아래 모든 *.appiconset을 순회해 야간에 Markdown을 이어 붙일 수 있습니다.
#!/usr/bin/env bash
set -euo pipefail
DIR="${1:?path to AppIcon.appiconset}"
REPORT="${2:-./appicon_validation_report.md}"
JSON="$DIR/Contents.json"
{
echo "# AppIcon validation"
echo "- host: $(hostname)"
echo "- path: $DIR"
echo ""
echo "| filename | expected | actual | status |"
echo "|---|---:|---:|---|"
} > "$REPORT"
while read -r name w h; do
[[ -z "${name:-}" ]] && continue
fp="$DIR/$name"
if [[ ! -f "$fp" ]]; then
echo "| $name | ${w}x${h} | missing | FIX: add file |" >> "$REPORT"
continue
fi
read -r aw ah < <(sips -g pixelWidth -g pixelHeight "$fp" \
| awk '/pixelWidth/ {w=$2} /pixelHeight/ {print w, $2}')
if [[ "$aw" -eq "$w" && "$ah" -eq "$h" ]]; then
echo "| $name | ${w}x${h} | ${aw}x${ah} | OK |" >> "$REPORT"
else
echo "| $name | ${w}x${h} | ${aw}x${ah} | FIX: re-export |" >> "$REPORT"
fi
done < <(jq -r '.images[] | select(.filename!=null)
| [.filename,
((.size|split("x")[0]|tonumber) * (.scale|sub("x";"")|tonumber)),
((.size|split("x")[1]|tonumber) * (.scale|sub("x";"")|tonumber))]
| @tsv' "$JSON")
echo "Wrote $REPORT"
jq 필터는 ipad 전용 행이나 scale 생략 케이스에 맞게 확장하세요. 기하 검증이 끝나면 OpenClaw PNG 일괄 QC로 알파·ICC·용량 상한을 이어 붙이면 디자인 납품 자동화가 한 층 더 촘촘해집니다.
숫자·정책 메모
- 클래식 스케일: 1×/2×/3×는
Contents.json의size포인트에 곱하는 배수가 1·2·3입니다. - 디바운스·보관: 감시 트리는 30~60초 유휴를 권장합니다.
logs/옆에 Markdown 또는 JSONL을 약 30일 보관하면 릴리스 간 diff가 쉽습니다.
FAQ: 자주 나는 오류
Contents.json에서 jq·parse error
먼저 plutil -lint를 실행하고, 머지 충돌 마커를 제거하며 UTF-8 BOM 없이 저장합니다. 신규 Xcode 카탈로그 템플릿과 한 번 비교해 보세요.
sips가 PNG를 읽지 못함
0바이트, WebP를 PNG로 오인한 경우, 아직 쓰기 중인 파일일 수 있습니다. 유휴 윈도우를 지키고, 익스포트 플러그인이 지원하면 .done 사이드카를 요구하세요.
수치는 맞는데 Xcode만 불만인 경우
idiom별 필수 슬롯, 1024 마케팅 알파, 배포 타깃에 필요한 아이콘 세트를 확인하세요. 기하 검증은 필요 조건이지 스토어 정책 전체를 대체하지 않습니다.
노트북은 창작에 두고, 검증은 전용 원격 Mac에서 돌리면 야간·CI 부하를 분리할 수 있습니다. 위 세 문서 링크로 슬롯 표·도구 설치·PNG QC를 한 번에 이어가면 됩니다.
Mac 노드를 비교해 App Icon 검증 워커를 올리기
MacPng에서 요금과 구매·대여를 로그인 없이 확인한 뒤, 도움말(SSH/VNC)로 대여 호스트에 동일 스크립트를 붙여 넣으면 됩니다.