2 คะแนน โดย GN⁺ 4 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • เมื่อทำการตั้งค่าบัญชี Apple และใบรับรองเริ่มต้นเสร็จแล้ว ก็สามารถทำระบบอัตโนมัติสำหรับการบิลด์ เซ็น และเผยแพร่แอป Mac และ iOS ได้ด้วย เครื่องมือ CLI ภายใน Xcode.app เพียงอย่างเดียว
  • ใช้ XcodeGen ใน project.yml เพื่อสร้าง .xcodeproj ขึ้นใหม่ และจัดการตั้งแต่การสร้างโปรเจ็กต์ไปจนถึงการ notarize บน Mac และติดตั้งลง iPhone ด้วย xcodebuild, notarytool, stapler, devicectl
  • การเผยแพร่บน Mac ใช้เพียง scripts/release.sh ตัวเดียวเพื่อรันตามลำดับคือ archive, เซ็นด้วย Developer ID, notarize, staple ticket, ตรวจสอบกับ Gatekeeper และติดตั้งไปยัง /Applications โดยจะหยุดทันทีเมื่อเกิดข้อผิดพลาด
  • สำหรับการคอมไพล์และทดสอบอย่างรวดเร็วสามารถใช้ CODE_SIGNING_ALLOWED=NO ได้ แต่ บิลด์แบบเซ็นชั่วคราว นี้จะไม่ผ่าน Gatekeeper และสิทธิ์อย่าง iCloud KVS กับ App Group ก็จะไม่ผูกกับ Team ID จริง
  • ให้เก็บ private key สำหรับการเซ็นและรหัสผ่านสำหรับ notarization ไว้ใน login keychain และบันทึกคำสั่งกับกฎการเผยแพร่ไว้ใน CLAUDE.md หรือ AGENTS.md เพื่อให้เอเจนต์อย่าง Claude Code รันเวิร์กโฟลว์ทั้งหมดซ้ำได้

สิ่งที่ทำได้โดยไม่ใช้ Xcode GUI

  • ยังต้องติดตั้ง Xcode แต่ไม่จำเป็นต้องเปิดใช้งาน และ xcodebuild, notarytool, stapler, devicectl ล้วนเป็น เครื่องมือเชลล์ภายใน Xcode.app ที่รันแยกได้
  • การตั้งค่าเริ่มต้น เช่น ล็อกอิน Apple ID, สร้างใบรับรอง Developer ID, และบันทึกรหัสผ่านสำหรับ notarization ยังต้องใช้ GUI หรือเทอร์มินัลแบบโต้ตอบ
  • หลังตั้งค่าเริ่มต้นเสร็จแล้ว สามารถทำทุกอย่างได้โดยไม่ต้องใช้เมาส์ ตั้งแต่สร้างโปรเจ็กต์, บิลด์, archive, export แอปที่เซ็นแล้ว, notarize, ตรวจสอบ, ติดตั้ง ไปจนถึง deploy ลง iPhone จริง
  • หากติดขัดเรื่องการตั้งค่าหรือการเขียนสคริปต์ สามารถให้ Claude Code หรือเครื่องมือโค้ดดิ้ง LLM อื่น ๆ สร้างเวิร์กโฟลว์ได้ โดยส่งความต้องการงานและค่าที่เฉพาะกับโปรเจ็กต์ให้

เลือกใช้ toolchain ของ Xcode แบบเต็ม

  • ควรตรวจสอบก่อนว่าผลของ xcode-select -p เป็น /Applications/Xcode.app/Contents/Developer หรือไม่
  • หากเลือกใช้ Command Line Tools แบบแยกอยู่ ให้ระบุ toolchain ของ Xcode แบบเต็ม ด้วยคำสั่งต่อไปนี้
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
  • /Library/Developer/CommandLineTools ที่ติดตั้งด้วย xcode-select --install มี clang และ git แต่ไม่มีเครื่องมือพัฒนาแอปครบชุด เช่น iOS SDK, notarytool, devicectl
  • หากติดตั้ง Xcode ไว้แล้ว ก็ไม่จำเป็นต้องติดตั้งแพ็กเกจ Command Line Tools แยกต่างหาก
  • การยอมรับไลเซนส์และติดตั้งส่วนประกอบเพิ่มเติมก็ทำผ่าน CLI ได้
sudo xcodebuild -license accept
sudo xcodebuild -runFirstLaunch

สร้างโปรเจ็กต์ซ้ำได้ด้วย XcodeGen

  • XcodeGen ใช้จัดการการตั้งค่าโปรเจ็กต์ Xcode ด้วย YAML และจะสร้าง .xcodeproj ใหม่ทุกครั้งที่บิลด์
  • สามารถ ดาวน์โหลดจาก GitHub หรือติดตั้งผ่าน Homebrew ได้
brew install xcodegen
  • .xcodeproj เป็นโฟลเดอร์ที่บน macOS ดูเหมือนไฟล์ และเนื่องจาก Xcode เปลี่ยนไฟล์ภายในกับ reference อยู่เรื่อย ๆ จึงอาจเกิด conflict หรือความเปลี่ยนแปลงที่ไม่จำเป็นใน Git repository
  • หาก commit เฉพาะ project.yml ลง Git และ ignore .xcodeproj ที่สร้างขึ้น ก็จะทำให้การตั้งค่าโปรเจ็กต์ยังคง reproducible
xcodegen generate

ตั้งค่าบัญชีนักพัฒนา Apple และใบรับรอง

  • ต้องเพิ่ม Apple ID ใน Settings → Accounts ของ Xcode
  • การเผยแพร่แอปและ notarization ต้องใช้ บัญชี Apple Developer แบบเสียเงิน
  • สร้างใบรับรองสำหรับการเผยแพร่ได้ที่ Settings → Accounts → Apple ID → Manage Certificates… → + → Developer ID Application
  • Apple Development และ Developer ID Application ใช้คนละกรณี
    • Apple Development ใช้สำหรับรันบนอุปกรณ์ของตัวเองหรือส่งไปยัง iPhone เพื่อดีบักแบบโลคัล
    • Developer ID Application จำเป็นเมื่อต้องเผยแพร่ .app ที่ notarize แล้วและผ่าน Gatekeeper บน Mac ของผู้อื่น
  • เมื่อสร้างใบรับรอง Developer ID Application แล้ว ตัวใบรับรองและ private key ที่จับคู่กันจะถูกติดตั้งไว้ใน login keychain
  • การเซ็นจริงจะใช้ private key และไม่สามารถดาวน์โหลดใหม่ได้ ดังนั้นอย่าลบ และควร สำรอง keychain ไว้

เก็บ credential สำหรับ notarization ไว้ใน keychain

  • การ notarize แอป Mac คือกระบวนการอัปโหลดแอปที่เซ็นแล้วไปให้ Apple ตรวจสอบมัลแวร์
  • notarytool จะยืนยันตัวตนด้วยโปรไฟล์ที่เก็บไว้ใน keychain และตอนสร้างโปรไฟล์ครั้งแรกต้องกรอกรหัสผ่านเฉพาะแอปแบบโต้ตอบ
xcrun notarytool store-credentials App-Name \
  --apple-id "you@example.com" \
  --team-id YOUR-TEAM-ID
  • ไม่ควรยืมใช้โปรไฟล์ notarization ของแอปอื่น ควร สร้างตามชื่อแอปนั้น ๆ เพื่อหลีกเลี่ยงการล้มเหลวแบบเงียบ ๆ ในสภาพแวดล้อมอื่น
  • รหัสผ่านเฉพาะแอปไม่เหมือนกับรหัสผ่าน Apple ID และสร้างได้จาก Sign-In & Security → App-Specific Passwords ที่ เว็บไซต์ Apple ID
  • หากเปลี่ยนรหัสผ่าน Apple ID รหัสผ่านเฉพาะแอปอาจหมดอายุโดยไม่มีการแจ้งเตือนแยก
    • ถ้าเกิด 401 invalid credentials ระหว่าง notarization ก่อนจะสงสัยว่าการตั้งค่าทั้งหมดผิด ควรตรวจสอบก่อนว่ารหัสผ่านเฉพาะแอปหมดอายุหรือไม่
  • ตรวจสอบได้ว่าบันทึกโปรไฟล์แล้วหรือยังด้วยคำสั่งนี้
xcrun notarytool history --keychain-profile App-Name
  • หากเก็บรหัสผ่านเฉพาะแอปไว้ในคลัง 1Password ที่ Claude Code เข้าถึงได้ ก็สามารถให้เอเจนต์สร้างโปรไฟล์ notarization สำหรับแอปใหม่ได้เช่นกัน
  • แม้จะสามารถทำให้การกรอกรหัสผ่านอัตโนมัติด้วย --password ได้ แต่ อาจทิ้งรหัสผ่านไว้ใน shell history ดังนั้นจึงควรกรอกเองครั้งเดียวแล้วเก็บไว้ใน keychain หรือ 1Password

แยกการตั้งค่าการเซ็นในเครื่องกับข้อมูลลับ

  • Team ID และ bundle prefix ที่จำเป็นต่อการเซ็นจริงให้เก็บไว้ใน Local.xcconfig
cp Local.xcconfig.example Local.xcconfig
BUNDLE_PREFIX     = your.real.prefix
DEVELOPMENT_TEAM  = YOUR-TEAM-ID
  • ควรเพิ่ม Local.xcconfig ลงใน .gitignore เพื่อไม่ให้การตั้งค่าโลคัลของแต่ละโปรเจ็กต์เข้าไปอยู่ใน repository
  • private key สำหรับการเซ็นจะอยู่ใน login keychain ส่วนรหัสผ่านเฉพาะแอปสำหรับ notarization จะอยู่ใน keychain profile ของ notarytool ดังนั้น ข้อมูลลับจะไม่ถูกบันทึกลง Git

ทำระบบอัตโนมัติสำหรับการเผยแพร่บน Mac ด้วย release.sh

  • scripts/release.sh ใน repository จะรัน pipeline การเผยแพร่แอป Mac ทั้งหมดด้วยคำสั่งเดียว
./scripts/release.sh
  • สคริปต์ทำงานตามลำดับดังนี้

    1. ตรวจสอบล่วงหน้าว่ามี xcodegen และโปรไฟล์ notarization อยู่หรือไม่
    2. สร้างโปรเจ็กต์ใหม่ด้วย xcodegen generate
    3. สร้าง Release archive ด้วย xcodebuild archive
    4. export แอปที่เซ็นด้วย Developer ID โดยใช้ ExportOptions.plist และ xcodebuild -exportArchive
    5. zip แอปแล้วส่งให้ Apple ด้วย notarytool submit --wait
    6. ติด ticket notarization ด้วย stapler staple
    7. ตรวจสอบว่า Gatekeeper อนุญาตหรือไม่ด้วย spctl
    8. ปิดโปรเซสเดิมแล้วคัดลอกแอปไปยัง /Applications
    9. ลงทะเบียนแอปที่ติดตั้งแล้วด้วย lsregister
    10. ตรวจสอบ ticket และสถานะ Gatekeeper ของ bundle ที่ติดตั้งแล้วอีกครั้ง
  • แม้โมเดลจะรู้ขั้นตอนการเผยแพร่ทั่วไป แต่ข้อมูลเฉพาะโปรเจ็กต์ เช่น ชื่อ scheme, Team ID, ชื่อโปรไฟล์ notarization, ตำแหน่งติดตั้ง ยังต้องให้ผู้ใช้ระบุ

  • หากสคริปต์ตัวแรกทำงานล้มเหลว ก็ต้องปรับแก้ตามผลลัพธ์ที่รันออกมาก่อน แต่เมื่อเวิร์กโฟลว์นิ่งแล้ว ก็สามารถรันคำสั่งเผยแพร่ได้โดยไม่ต้องแก้เพิ่ม

  • ป้องกันความล้มเหลวและการเผยแพร่ที่ไม่สมบูรณ์

    • set -euo pipefail จะหยุดสคริปต์ทันทีเมื่อมีคำสั่งใดคำสั่งหนึ่งล้มเหลว เพื่อไม่ให้สถานะที่ไม่สมบูรณ์ถูกมองว่าสำเร็จ
    • cd "$(dirname "$0")/.." จะย้ายไปยัง root ของ repository ไม่ว่าสคริปต์จะถูกเรียกจากไดเรกทอรีใด
    • บล็อกตรวจสอบล่วงหน้า ใช้เช็ก xcodegen และโปรไฟล์ notarization ก่อนเข้าสู่ขั้นตอน archive ที่ใช้เวลานาน
    • ไม่เพียงตรวจสอบแอปที่ export แล้ว แต่ยังตรวจสอบแอปที่คัดลอกไปไว้ใน /Applications อีกครั้ง เพื่อจับกรณีที่ bundle เสียหายระหว่างการคัดลอก
    • หากต้องใช้โปรไฟล์ notarization อื่น ก็สามารถ override ด้วย environment variable ได้
    TZED_NOTARY_PROFILE=<name> ./scripts/release.sh
    

ส่งต่อกฎการเผยแพร่ให้เอเจนต์

  • หาก release.sh สามารถเผยแพร่ได้ด้วยคำสั่งเดียว CLAUDE.md หรือ AGENTS.md ก็จะทำให้เอเจนต์ใช้คำสั่งนั้นทุก session โดยไม่ต้องสั่งเพิ่ม
  • ในเอกสารควรบันทึกการสร้างโปรเจ็กต์ใหม่, unit test, การบิลด์ macOS แบบรวดเร็ว, และคำสั่งเผยแพร่จริง
xcodegen generate
swift test

xcodebuild -project YOUR-APP-NAME.xcodeproj \
  -scheme YOUR-APP-NAME-macOS \
  -destination 'platform=macOS' \
  CODE_SIGNING_ALLOWED=NO build

./scripts/release.sh
  • ควรระบุความต่างของเส้นทางบิลด์ทั้งสองแบบไว้ในเอกสารด้วย
    • บิลด์ CODE_SIGNING_ALLOWED=NO เหมาะกับ CI และการตรวจสอบโลคัลแบบรวดเร็ว
    • หากเป็นการเผยแพร่แอปเมนูบาร์จริง การผ่านคุณสมบัติ quarantine และการซิงก์ iCloud จำเป็นต้องใช้ release.sh ที่ทำการเซ็นด้วย Developer ID และ notarize
  • หากสั่งให้ไปอ้างอิงรูปแบบที่ทำไว้ในอีกแอปหนึ่งบน repository อื่น Claude Code ก็สามารถคัดลอกการตั้งค่าเดียวกันไปใช้กับแอปถัดไปได้

บิลด์และทดสอบแบบเร็วโดยไม่เซ็นจริง

  • unit test ที่อิงกับ Swift Package Manager สามารถรันได้โดยไม่ต้องบิลด์ผ่าน Xcode
swift test
  • การตรวจสอบการคอมไพล์ของแอป macOS แบบรวดเร็วทำได้โดยปิดการเซ็น
xcodebuild -project TZed.xcodeproj \
  -scheme TZed-macOS \
  -destination 'platform=macOS' \
  CODE_SIGNING_ALLOWED=NO build
  • การบิลด์สำหรับ iOS app และ widget extension บน simulator ก็ทำได้ด้วยวิธีเดียวกัน
xcodebuild -project TZed.xcodeproj \
  -scheme TZed-iOS \
  -destination 'generic/platform=iOS Simulator' \
  CODE_SIGNING_ALLOWED=NO build
  • บิลด์แบบเซ็นชั่วคราว ที่สร้างด้วย CODE_SIGNING_ALLOWED=NO ใช้สำหรับคอมไพล์และรันบน simulator ได้
  • แต่บิลด์นี้จะถูก Gatekeeper ปฏิเสธ และเนื่องจากไม่มี team prefix จึงไม่สามารถผูกสิทธิ์อย่าง iCloud KVS และ App Group ได้ จึงใช้สำหรับการเผยแพร่ไม่ได้

ทำ headless deploy ลง iPhone จริง

  • การ deploy ไปยังอุปกรณ์ iOS ไม่มีขั้นตอน notarization แบบเดียวกับแอป Mac และใช้ xcodebuild กับ devicectl
  • แอปสำหรับอุปกรณ์จริงจะถูกบิลด์และเซ็นด้วยใบรับรอง Apple Development และ development provisioning profile
xcodebuild -project TZed.xcodeproj \
  -scheme TZed-iOS \
  -destination 'generic/platform=iOS' \
  -allowProvisioningUpdates \
  -derivedDataPath build/ios \
  archive -archivePath build/TZed-iOS.xcarchive
  • .app ที่สร้างขึ้นสามารถติดตั้งได้โดยระบุ UDID ของอุปกรณ์ที่เชื่อมต่ออยู่
xcrun devicectl device install app \
  --device <DEVICE-UDID> build/ios/…/TZed.app
  • devicectl list devices จะแสดงอุปกรณ์ที่เชื่อมต่อและจับคู่แล้วพร้อม UDID
  • เมื่อระบุ -allowProvisioningUpdates ระบบจะดึง development provisioning profile ที่จำเป็นมาให้

การทำงานของ code signing โดยไม่ใช้ GUI

  • เมื่อสร้างใบรับรอง Developer ID Application, Apple จะออกใบรับรอง ส่วน Mac จะสร้าง private key ที่จับคู่กันและเก็บทั้งคู่ไว้ใน login keychain

  • codesign ที่ถูกเรียกโดย xcodebuild จะใช้ private key เซ็นไบนารี และฝังใบรับรองที่เชื่อมโยงไปถึง Apple root certificate ลงในแอปเพื่อให้ตรวจสอบผู้เซ็นได้

  • หากใช้ signingStyle: automatic, xcodebuild จะเลือกใบรับรองที่ตรงกับ Team ID และดึง provisioning profile ที่จำเป็นจาก Apple

  • ดังนั้นจึงไม่จำเป็นต้อง commit provisioning profile ลงใน repository

  • สิทธิ์, notarization, และการ staple

    • ไฟล์ .entitlements ของแต่ละ target จะมีสิทธิ์ต่าง ๆ เช่น sandbox, network client, iCloud KVS, App Group
    • สิทธิ์เหล่านี้จะถูกผูกเข้ากับ Team ID จริงตอนเซ็นจริง ดังนั้นในบิลด์แบบเซ็นชั่วคราว iCloud และ App Group จะไม่ทำงานอย่างถูกต้อง
    • การเซ็นและการ notarize เป็นคนละขั้นตอนกัน
    • การเซ็นคือการพิสูจน์ว่าใครเป็นผู้สร้างแอป
    • การ notarize คือกระบวนการที่ Apple ตรวจสอบมัลแวร์ในแอปที่เซ็นแล้วและออก ticket ให้
    • การ staple คือการแนบ ticket นั้นเข้าไปในแอป เพื่อให้ Gatekeeper เชื่อถือได้แม้อยู่แบบออฟไลน์
    • สำหรับแอปเมนูบาร์แบบ LSUIElement ที่ใช้ UI ซ่อนอยู่ การ notarize จำเป็นต่อการหลีกเลี่ยงการถูกตรวจจับโดย XProtect
  • คำสั่งตรวจสอบด้วยตนเอง

    codesign -dv --verbose=4 /Applications/TZed.app
    spctl -a -vvv -t exec /Applications/TZed.app
    stapler validate /Applications/TZed.app
    
    • codesign ใช้ตรวจสอบผู้เซ็นและใบรับรอง
    • spctl ใช้ตรวจสอบว่า Gatekeeper จะอนุญาตให้รันหรือไม่
    • stapler validate ใช้ตรวจว่ามี ticket notarization ถูกแนบไว้แล้วหรือไม่

เครื่องมือมาตรฐานที่เอเจนต์ใช้รัน

  • ไม่จำเป็นต้องมี MCP server สำหรับบิลด์หรือปลั๊กอินเฉพาะทางแยกต่างหาก โดย Claude Code จะรัน CLI มาตรฐานผ่าน non-interactive shell
  • เครื่องมือที่ใช้คือ xcodebuild, xcrun notarytool, xcrun stapler, spctl, codesign, devicectl, xcodegen, swift
  • CLAUDE.md ใช้บอกเอเจนต์ถึงกฎการตั้งชื่อโปรไฟล์ notarization, ความต่างระหว่างบิลด์แบบเร็วกับการเผยแพร่จริง, และกฎว่าต้องใช้ release.sh ตอนเผยแพร่
  • มีเพียงขั้นตอนแรกของ notarytool store-credentials เท่านั้นที่ยังเป็นแบบโต้ตอบ ส่วนขั้นตอนหลังจากนั้นทั้งหมดสามารถทำอัตโนมัติได้

แทนที่งานใน Xcode GUI ด้วย CLI

  • การสร้าง .xcodeproj ที่ปกติ Xcode จัดการให้ สามารถแทนด้วย project.yml และ xcodegen generate
  • ⌘B หรือปุ่ม Run ตรงกับ xcodebuild … build
  • Product → Archive ทำได้ด้วย xcodebuild … archive
  • การเผยแพร่แอปผ่าน Organizer สามารถแทนได้ด้วย xcodebuild -exportArchive
  • การอัปโหลดผ่าน Organizer ทำได้ด้วย xcrun notarytool submit --wait
  • การแนบ ticket อัตโนมัติใช้ xcrun stapler staple
  • ขั้นตอนติดตั้งด้วยการลากแล้ววางไปยัง /Applications สามารถแทนด้วย cp -R และ lsregister
  • การกด Run บน iPhone จริง แทนได้ด้วย xcodebuild archive และ devicectl device install
  • เมื่อทำครบทั้งการติดตั้ง Xcode และ XcodeGen, การตั้งค่า credential ครั้งแรก, และการเขียน release.sh กับ CLAUDE.md แล้ว การเผยแพร่บิลด์ใหม่ในครั้งถัดไปจะทำได้ด้วย ประโยคเดียวหรือคำสั่งเดียว

1 ความคิดเห็น

 
GN⁺ 4 시간 전
ความคิดเห็นจาก Hacker News
  • มีหลายอย่างที่แก้ในแซนด์บ็อกซ์ไม่ได้ จึงรันเอเจนต์ AI โดยตรงบน Mac แต่พอเห็น เหตุการณ์ที่ xAI อัปโหลดโฮมไดเรกทอรีที่มีแม้กระทั่งคีย์ SSH รวมอยู่ด้วย ก็ทำให้ต้องกลับมาคิดทบทวนทางเลือกนี้อย่างจริงจัง
    ไม่ได้กังวลมากนักว่าตัวเครื่องจะพัง เพราะส่วนใหญ่สำรองไว้หรือ commit ไว้ใน Git แล้ว จึงกู้คืนได้ภายในไม่กี่ชั่วโมง แต่ไม่ต้องการให้ไดเรกทอรี .ssh ถูกส่งไปยังเอเจนต์ AI เด็ดขาด และไม่ควรพยายามกันด้วยพรอมป์ต์ แต่ควร บล็อกในระดับระบบ กำลังพิจารณาวิธีสร้างผู้ใช้แยกต่างหากและตั้งสิทธิ์ 700 ให้โฮมไดเรกทอรี ความปลอดภัยเหมือนถอยกลับไปยุค 1990 แต่ก็มีอีกด้านคือแลกกับการทำงานให้เสร็จได้เร็วอย่างไม่เคยมีมาก่อน ผมเองก็ใช้วิธีเสี่ยงแบบนี้อยู่ จึงไม่ได้จะตำหนิคนอื่น

    • ไม่จำเป็นต้องรันบนโฮสต์ Mac เสมอไป Mac รุ่นใหม่รองรับ virtualization ที่แทบไม่มีการสูญเสียประสิทธิภาพ จึงใช้ VM ของ macOS หรือ Linux ที่เป็นสถาปัตยกรรมเดียวกันเพื่อพัฒนาได้อย่างง่ายดาย
      ถ้าต้องการโซลูชันแบบแพ็กเกจ สามารถใช้โอเพนซอร์สอย่าง Tart https://tart.run/ หรือ VirtualBuddy https://github.com/insidegui/VirtualBuddy ได้ หรือจะ vibe coding เครื่องมือที่ห่อหุ้ม OS API https://developer.apple.com/documentation/virtualization เองก็ได้ ช่วงหลังยังมี Apple container https://github.com/apple/container ออกมาด้วย
    • กำลังทำเครื่องมือ wrapper สำหรับรัน Claude ในฐานะ ผู้ใช้แยกต่างหาก ชื่อ agent เมื่อหนึ่งปีก่อนเคยล้มเหลวเพราะ OAuth และ keychain แต่เมื่อไม่นานมานี้ Claude แนะนำว่าสามารถใช้ CLAUDE_CODE_OAUTH_TOKEN ได้ จึงทำสำเร็จ
      ต้องมีเครื่องมือช่วยตั้งสิทธิ์ด้วย ACL แต่ตอนนี้ใช้งานได้บน macOS ระดับความเสี่ยงอยู่ประมาณกึ่งกลางระหว่างแซนด์บ็อกซ์ Claude พื้นฐานกับการแยกแบบคอนเทนเนอร์/เครื่องเต็มรูปแบบ พอแซนด์บ็อกซ์ของ Claude เองดีขึ้น ก็เคยสงสัยว่าการลงทุนกับโปรเจกต์ป้องกันสองชั้นนี้คุ้มหรือไม่ แต่เมื่อดูความเป็นไปได้ที่โฮมไดเรกทอรีจะรั่ว ก็มีเหตุผลเพียงพอที่จะทำต่อ ยังไม่ได้เปิดเป็นโอเพนซอร์ส แต่ยินดีคุยกับคนที่สนใจ
    • รัน AI ใน คอนเทนเนอร์ Docker แบบ headless และให้เข้าถึงเฉพาะ Git เพื่อให้ช่วย contribute เฉพาะโค้ด หากต้องใช้ secret ก็จัดหา Docker container ที่เก็บไว้ใน repository ให้ และหากต้องใช้อินฟราก็ให้สร้าง ticket ใน Jira เป็นเวิร์กโฟลว์แบบนี้
    • สงสัยว่าจัดการงานลงทะเบียน bundle identifier โดยไม่เปิด Xcode อย่างไร
  • กำลังลอง ใช้แค่ Linux เพื่อ build และทดสอบแอป iOS สนุก ๆ อยู่ ซึ่งง่ายอย่างน่าประหลาดใจ และ https://github.com/xtool-org/xtool ก็ทำงานได้ดีมาก
    แม้บน Linux ก็สามารถติดตั้งลง iPhone โดยตรงผ่าน USB ได้ โดยไม่ต้องอัปโหลดขึ้น TestFlight หรือ App Store หากยังไม่แน่ใจ สามารถขอให้ coding agent สร้างแอป iOS Hello World แล้วอัปโหลดให้ ก็เริ่มต้นได้ง่าย

    • ผมก็ทำงานในวิธีเดียวกัน ยกเว้นแค่รัน Linux บน WSL ของ Windows ใช้ Sideloadly ย้าย IPA ไปยังโทรศัพท์ และใช้งานได้ดี
    • หลังจากส่งแอปผ่าน USB แล้ว ยังต้อง เสียบ iPhone ค้างไว้ ต่อไปหรือไม่?
    • พวก coding agent รู้จัก xtool กันอยู่แล้วหรือเปล่า?
  • โปรเจกต์โอเพนซอร์สของผม Axiom ช่วยให้เครื่องมือรันโค้ดทำงานด้านการพัฒนาสำหรับระบบปฏิบัติการของ Apple ได้อย่างมีประสิทธิภาพ
    นอกจากเทคนิคและเอเจนต์หลากหลายแบบแล้ว ยังมีเครื่องมือสำหรับ LLM อย่าง xclog, xcprof, xcsym, xcui ด้วย เครื่องมือเหล่านี้เปิดเผยฟังก์ชันที่จำเป็นอย่างประหยัดโทเค็น และมีประโยชน์ต่อเทคนิคหรือเอเจนต์ภายนอก Axiom เช่นกัน Axiom: https://charleswiltgen.github.io/Axiom/, เครื่องมือ CLI: https://charleswiltgen.github.io/Axiom/tools/

    • จะทำงานได้ดีใน โค้ดเบส Kotlin Multiplatform ด้วยหรือไม่? แม้จะมีโค้ด Swift native อยู่บ้าง แต่สงสัยว่าประสิทธิภาพหรือพฤติกรรมจะเป็นอย่างไรเมื่อแชร์ลอจิกบางส่วน
    • คิดว่าพรมแดนถัดไปของเครื่องมือแอป iOS คือ เซิร์ฟเวอร์ build บน Linux ที่โฮสต์เองได้ อยากทราบความเห็นเกี่ยวกับเรื่องนี้
    • ใช้กับ Flutter ได้หรือไม่?
  • พออ่านประโยคที่ว่า “ให้ Claude Code ทำสคริปต์ที่ archive, ลงนาม Developer ID, notarize, staple, ติดตั้งลง /Applications โดยไม่ต้องเปิด Xcode และให้หยุดอย่างชัดเจนหากขั้นตอนไหนล้มเหลว” แล้วรู้สึกแปลก ๆ เพราะบทความที่กำลังอ่านอยู่นี้เองก็เหมือน Claude กำลังพูดกับเรา
    ในแทบทุกขั้นตอนของบทความยังมีคำแนะนำซ้ำ ๆ ทำนองว่า “เอาบทความนี้ให้ Claude Code หรือเครื่องมือ coding LLM ที่ต้องการดู แล้วให้มันจัดการเอง”, “ถ้าไม่รู้ก็ถาม LLM ให้ช่วยตั้งค่า”, “จุดประสงค์ของการใช้ LLM คือหลีกเลี่ยงงาน manual ที่ไม่ต้องการ”, “ให้มันสร้าง workflow ให้” ซึ่งทำให้รู้สึกแปลกที่ แนะนำให้กลับไปถาม LLM อีกที

    • บทความนี้ไม่ได้เขียนโดย Claude แต่ ผมเขียนเอง
    • ดูเหมือนโครงสร้างวนลูปที่เอาเว็บไซต์ที่ Claude เขียนไปให้ Claude ดู แล้วให้ Claude สร้างสภาพแวดล้อมสำหรับ build
    • ตอนแรกคิดว่าไม่ได้เขียนโดย AI เพราะมีข้อผิดพลาดในบทความ แต่ตอนนี้เริ่มคิดว่า AI อาจจงใจทำผิดพลาดก็ได้
  • จากมุมมองของคนที่พัฒนาแอป Mac และ iOS ด้วยเอเจนต์มานานกว่าหนึ่งปี ผมมองว่าบทความนี้เป็นคำแนะนำที่ไม่ดี โดยเฉพาะอย่างยิ่ง Xcode MCP ที่ยอดเยี่ยมนั้นต้องให้ Xcode กำลังทำงานอยู่
    เมื่อใช้เครื่องมือ MCP จะเข้าถึงฟังก์ชันต่าง ๆ ได้เร็วและกระชับกว่า xcodebuild มาก และยังสร้างและเรนเดอร์ #Preview ซึ่งทำไม่ได้หากปิด Xcode ไปแล้วได้ด้วย MCP และเอเจนต์ในตัวของ Xcode 27 ยังควบคุม simulator ได้ดีมากผ่าน DeviceHub โดย DeviceHub มาแทนที่ Simulator.app และดูเหมือนว่าเอเจนต์จะเข้าใจและจัดการได้โดยไม่ต้องใช้เครื่องมืออย่าง axe ไปดัดแปลง Accessibility API แบบอ้อม ๆ
    Xcode MCP ไม่ได้สมบูรณ์แบบ ปัญหาที่หน้าต่างขอสิทธิ์เด้งขึ้นมาทุกครั้งที่เรียกใช้เอเจนต์นั้น ผมเลี่ยงด้วยการให้ Keyboard Maestro อนุมัติอัตโนมัติ ถึงอย่างนั้น Xcode 27 ก็ปรับปรุง ความใช้งานได้ของการ vibe coding บน Xcode ไปมาก ตอนนี้ผมไม่ได้จัดการ MCP แยกต่างหาก แต่รัน Codex จาก UI เอเจนต์ของ Xcode เอง ซึ่งสภาพแวดล้อมการรันนี้ช่วยชี้นำโมเดลให้ใช้เครื่องมือที่มีอยู่ได้ดีขึ้น สุดท้ายจึงได้สิ่งที่สำคัญที่สุดคือ feedback ที่เร็วขึ้นและการตรวจสอบที่แข็งแรงขึ้น

    • มี Xcode-mcp-proxy ที่ทำหน้าที่ proxy Xcode MCP พร้อมคลิกกล่องโต้ตอบและกู้คืนการเชื่อมต่อให้ด้วย สงสัยว่าการทดสอบแอป macOS ใช้ Peekaboo หรือใช้การทำ screenshot automation ทั่วไป
    • Xcode MCP ของ Sentry ก็น่าลองเช่นกัน ครอบคลุมกว่ามาก และไม่จำเป็นต้องเปิด Xcode ค้างไว้ด้วย
  • ถ้าอยากแตะ IDE ของ iOS และ Android ให้น้อยที่สุด React Native กับ Expo ก็เป็นตัวเลือกที่ดี
    Xcode และ Android Studio ใช้เฉพาะตอนติดตั้ง device simulator ส่วนที่เหลือไปจนถึงการปล่อยขึ้นสโตร์ toolchain ของ Expo จะจัดการให้ บน Windows ที่ติดตั้ง Xcode ไม่ได้ หากใช้แอปแบบ managed ของ Expo ก็สามารถรันแอป iOS บน iPhone ได้โดยตรง จุดเริ่มต้นบนพื้นฐาน RN และ Expo ที่ดูแลดีคือ Ignite ซึ่งยอดเยี่ยม: https://github.com/infinitered/ignite

  • พูดอย่างเคร่งครัดแล้วก็ยังเป็นการ ใช้ Xcode อยู่ดี Xcode คือ GUI ที่บั๊กเยอะมาก ซึ่งห่อหุ้มยูทิลิตีและแอประดับระบบ UNIX หลายตัวที่โดยรวมค่อนข้างเสถียร
    วิธีปล่อยแอปผ่าน CLI เป็นแนวปฏิบัติเก่าแก่ และทำได้อย่างน้อยก็ตั้งแต่ปี 2012 ตอนที่ผมปล่อยแอป Xcode ตัวแรก

    • เรื่องนั้นรู้อยู่แล้ว แต่ประเด็นสำคัญคือคนที่ใช้ Xcode ไม่ใช่ผม แต่เป็น Claude
    • พอได้เปิด Xcode ดูแล้ว เจอกำแพงการเริ่มต้นสูงจนไม่เคยคิดด้วยซ้ำว่าจะลองทำโปรแกรมสำหรับ macOS
  • อย่างน้อยในการดีบักบางส่วน ทุกคนก็ หลีกเลี่ยงการใช้ Xcode ไม่ได้
    เรื่อง build นั้นเอเจนต์สามารถจัดการส่วนใหญ่จาก command line ได้อยู่แล้ว และถ้าให้คำสั่งที่ชัดเจนตามสถานการณ์ก็ build ได้เร็วขึ้น หากใช้ file system synchronization groups ของ Xcode อยู่ XcodeGen อาจเป็นงานเสริมที่ไม่จำเป็นก็ได้
    สำหรับ iOS สิ่งที่อยากแนะนำที่สุดคือเพิ่ม ฟังก์ชัน App Store Connect ให้เอเจนต์: https://github.com/rorkai/App-Store-Connect-CLI แบบนั้นไม่เพียงไม่ต้องเปิด Xcode ค้างไว้ตลอด แต่ยังไม่ต้องอยู่ใกล้ MacBook ด้วย คุณแก้ผ่าน Codex บน iPhone แล้วสั่ง asc ให้ build และอัปโหลดไป TestFlight จากนั้นดาวน์โหลดเวอร์ชันใหม่มารันแล้ววนซ้ำได้เลย

    • ผมทำแอป iOS ทั้งตัวด้วยเอเจนต์จนเกือบเสร็จ และเอเจนต์ยังจัดการไปถึง การปล่อยบน App Store และโปรโมตบนโซเชียล ด้วย Xcode ใช้เฉพาะตอนตรวจ build ล่วงหน้าบนอุปกรณ์และกำหนดทิศทาง prompt ถัดไปเท่านั้น
  • ยังรู้สึกติดใจอยู่เรื่อย ๆ กับความเป็นจริงที่ว่านักพัฒนาที่งบไม่พอซื้อ Mac แทบจะถูก กันออกจากการพัฒนา iOS โดยปริยาย ทุกครั้งที่ราคาผลิตภัณฑ์ Apple สูงขึ้น ก็ยิ่งมีคนที่เข้าร่วมพัฒนาไม่ได้มากขึ้น

    • เป็นเรื่องน่าเสียดายที่มีคนเข้าถึงเทคโนโลยีไม่ได้ แต่ช่วงนี้ Apple ก็มีอุปกรณ์ราคาย่อมเยาเมื่อเทียบกับคู่แข่งสเปกใกล้เคียงหรือสูงกว่า ตัวอย่างหนึ่งคือ Apple Silicon MacBook Air ที่ใส่หน่วยความจำมาอย่างเหมาะสม
  • ถ้าจะ vibe coding แอป ระยะยาวแล้ว Expo เป็นตัวเลือกที่ดีกว่า เพราะใช้ React เป็นพื้นฐาน ทำให้ในข้อมูลฝึกของ LLM มีโค้ด React มากกว่า Swift มาก และคุณภาพของโค้ดผลลัพธ์ก็ดีกว่าด้วย
    ทำทุกอย่างจาก command line ได้ และเพราะเป็น web view การดีบักก็ง่าย หลัง compile เป็นแอป iOS native แล้ว ความรู้สึกใช้งานก็คล้ายแอป native อื่น ๆ เมื่อจับคู่ Expo กับ Fastlane จะทำให้การส่งและ deploy บน iOS เป็นอัตโนมัติได้ทั้งหมด จนสามารถอัปเวอร์ชันใหม่ขึ้น App Store ได้ด้วยคำสั่งเดียว

    • ตอนสร้างแอปใหม่ ก็ยังมีขั้นตอนที่ ทำอัตโนมัติไม่ได้ อย่างการลงทะเบียนตัวแอปเองอยู่ไม่ใช่หรือ?
    • Expo ที่พูดถึงคือ https://expo.dev/ ใช่ไหม? ตอนนี้ถ้าเข้าไปจะเห็นข้อความว่า “โค้ดพังและเกิดข้อผิดพลาดที่ต้องตรวจสอบ”