Phát hành app iOS không cần Mac: hướng dẫn Expo và EAS
Bởi Mehdi Azizi
Cập nhật ngày , 9 phút
Từ máy tính Windows, Expo và EAS biên dịch và gửi app iOS của bạn cho Apple. Những gì làm được khi không có Mac, những gì vướng, và vì sao bạn cần iPhone.
Có thể phát hành app iOS mà không cần Mac không?
Có. Bạn có thể phát hành app iOS mà không cần Mac nếu xây dựng nó bằng Expo và React Native. EAS Build biên dịch app của bạn trên các máy Mac do Expo vận hành trên cloud, sau đó EAS Submit gửi nó lên App Store Connect. Tài liệu của Expo nói rõ: EAS Submit chạy được trên macOS, Linux và Windows, nên bạn không cần Mac để gửi một bản build iOS.
Ngược lại, bạn cần ba thứ không gì thay thế được: một tài khoản Apple Developer trả phí, một chiếc iPhone để test app thật sự, và một trình duyệt để điền trang thông tin app trong App Store Connect. Phần còn lại của bài hướng dẫn này nói chi tiết những gì làm được từ máy Windows, những gì vướng, và thứ tự các bước.
Tất cả app iOS của mình đều đi qua chuỗi này: Expo, EAS Build, rồi EAS Submit. Solys và TradaZen lên App Store theo cách đó. Mình làm việc trên Mac, nhưng không bước phát hành nào phụ thuộc vào nó: các bản build được tạo trên cloud của Expo và việc gửi cho Apple thực hiện qua dòng lệnh.
Expo và EAS thay thế Mac như thế nào
Để hiểu điều gì khả thi, cần biết vì sao trước đây Mac là bắt buộc. Một app iOS phải được biên dịch bằng Xcode, công cụ của Apple, chỉ chạy trên macOS, và phải là phiên bản đủ mới để tránh bị từ chối với lỗi ITMS-90725. Sau đó app phải được ký bằng một chứng chỉ gắn với tài khoản developer của bạn, rồi gửi lên App Store Connect.
Expo chia công việc này thành ba công cụ:
- Expo và React Native: bạn viết app bằng JavaScript hoặc TypeScript, trên bất kỳ máy tính nào.
- EAS Build: bạn chạy lệnh từ PC, code được gửi lên một máy Mac của Expo, máy này biên dịch và ký app thay bạn. Bạn nhận về một file sẵn sàng để cài đặt hoặc gửi đi.
- EAS Submit: lấy bản build đó và gửi lên App Store Connect. Sau khi Apple xử lý, chẳng hạn kiểm tra icon (ITMS-90717), nó xuất hiện trong TestFlight.
Mac vẫn có mặt trong chuỗi. Chỉ là nó không còn là máy của bạn. Nếu muốn hiểu vì sao mình khuyên người mới dùng stack này, hãy đọc trang React Native và Expo cho app di động.
Những gì làm được từ máy Windows
Viết code cho app
Toàn bộ việc phát triển làm được trên Windows mà không bị hạn chế: trình soạn thảo của bạn (VS Code, Cursor), Node.js, terminal. Nếu bạn code với sự trợ giúp của Claude hay ChatGPT, cũng không có gì thay đổi. Về chủ đề này, hãy đọc tạo app iOS bằng AI.
Xem app trên iPhone trong lúc code
Để bắt đầu, app Expo Go cài trên iPhone sẽ quét một mã QR hiển thị trong terminal và tải dự án của bạn. Mỗi thay đổi xuất hiện trên điện thoại chỉ sau vài giây. Rất lý tưởng cho những màn hình đầu tiên. Từ tháng 5/2026, phiên bản Expo Go trên App Store dừng ở SDK 54: hãy tạo dự án và chọn tương thích với phiên bản này, hoặc dùng eas go và TestFlight cho SDK mới hơn.
Expo Go có một giới hạn: nó chỉ chứa các module native do Expo cung cấp. Ngay khi app dùng một thư viện native không có sẵn trong đó, như SDK của RevenueCat cho gói đăng ký, bạn cần một development build: một phiên bản app của riêng bạn, do EAS Build biên dịch, mà bạn cài lên iPhone.
Cài bản build lên iPhone mà không qua App Store
EAS có tính năng phân phối nội bộ. Bạn đăng ký iPhone bằng lệnh eas device:create, rồi chạy một bản build với kiểu phân phối internal. Bạn nhận được một link cài đặt. Apple giới hạn cách này: mỗi tài khoản chỉ phân phối được cho tối đa 100 iPhone mỗi năm, và mỗi thiết bị mới cần một bản build mới hoặc ký lại. Cho riêng bạn và vài người thân thì dư sức.
Quản lý chứng chỉ mà không cần Xcode
Ký app là thứ làm nhiều người mới kẹt nhất ngay cả khi dùng Mac, đến mức gặp lỗi ITMS-90034 lúc gửi. Với EAS, bạn đăng nhập tài khoản Apple từ dòng lệnh, và công cụ có thể tự tạo chứng chỉ phân phối và provisioning profile. Bạn không bao giờ phải mở Keychain Access.
Gửi app cho Apple và phát hành
eas submit --platform ios gửi bản build của bạn lên App Store Connect. Bạn cũng có thể gộp hai bước bằng tùy chọn --auto-submit của eas build. Mọi thứ còn lại diễn ra trong trình duyệt: trang App Store, ảnh chụp màn hình, khai báo quyền riêng tư, gói đăng ký, TestFlight và gửi xét duyệt. App Store Connect là ứng dụng web, chạy rất tốt trên Windows.
Những gì không làm được (hoặc khó hơn) khi không có Mac
Simulator iOS chạy local
Simulator iOS là một phần của Xcode, nên không chạy trên Windows. Trên thực tế, chuyện này không nghiêm trọng: iPhone của bạn test tốt hơn simulator. Tháng 9/2026, Expo đã công bố một simulator iOS trên cloud, EAS Simulator, vẫn đang ở dạng truy cập giới hạn vào thời điểm mình viết bài. Đừng xây cách làm việc của bạn dựa trên nó khi nó chưa mở cho tất cả mọi người.
Debug code native
Nếu app crash do code native (Swift, Objective-C, một thư viện cấu hình sai), các công cụ chẩn đoán của Apple nằm trong Xcode. Không có Mac, bạn phụ thuộc vào log build của EAS và một công cụ như Sentry, công cụ báo về các crash của app đã cài. Làm được, nhưng chậm hơn. Vì vậy với app đầu tiên, nên dùng các thư viện tương thích với Expo và còn được bảo trì, việc này cũng giúp tránh bị từ chối với lỗi ITMS-90338 khi gửi.
Tự viết extension native
Widget, notification extension, các target native riêng: Expo làm được nhờ config plugin, nhưng không có Xcode để kiểm tra dự án được sinh ra, mỗi lỗi lại tốn thêm một bản build. Với app đầu tiên, hãy để những tính năng này cho sau.
Build local
Build local của EAS (tùy chọn --local) không được hỗ trợ trên Windows. Trên PC, các bản build iOS của bạn vì thế phải đi qua cloud của Expo. Gói miễn phí của EAS gồm số lượng build giới hạn mỗi tháng, kèm hàng đợi: hãy kiểm tra điều kiện hiện hành trên trang bảng giá của Expo trước khi lên kế hoạch cho một tuần làm việc cường độ cao.
Tài khoản Apple Developer: bắt buộc, không có ngoại lệ
Không mẹo nào lách được điểm này, kể cả Apple Developer Enterprise Program, vốn dành cho app nội bộ của các tổ chức lớn. Không tham gia Apple Developer Program thì không có App Store Connect, không có TestFlight, không có phân phối nội bộ, và không gửi được lên App Store. Phí tham gia là 99 USD mỗi năm, trừ bằng đơn vị tiền tệ của bạn.
Hai lời khuyên trước khi đăng ký:
- Chọn kỹ giữa tài khoản cá nhân và tổ chức. Với tài khoản cá nhân, tên bạn hiển thị là người bán trên App Store. Với tổ chức, đó là tên công ty của bạn, nhưng khi đó Apple yêu cầu số D-U-N-S và quá trình xác minh lâu hơn.
- Dự trù vài ngày. Việc xác nhận tài khoản không phải lúc nào cũng ngay lập tức. Hãy đăng ký ngay khi biết mình sẽ phát hành, đừng để đến hôm trước ngày gửi.
Nhu cầu thực sự về iPhone để test
Về kỹ thuật, bạn có thể phát hành app iOS mà chưa từng cầm nó trên tay. Mình thật sự khuyên bạn đừng làm vậy, và Apple cũng thế: quy tắc xét duyệt của họ (guideline 2.1) yêu cầu app phải được test trên thiết bị, về lỗi và độ ổn định, trước khi gửi. Còn người dùng của bạn thì chỉ có đúng thứ đó: một chiếc iPhone thật.
Đây là những gì chỉ iPhone thật mới cho bạn thấy:
- Lần khởi chạy thật đầu tiên, không có server phát triển: đây là chỗ ẩn nấp của các lỗi crash lúc mở app.
- Mua hàng trong app ở môi trường test, để kiểm tra paywall hiển thị đúng giá và gói đăng ký thật sự mở khóa app.
- Thông báo, camera, rung, quyền truy cập, những thứ hoạt động khác đi hoặc hoàn toàn không hoạt động ở nơi khác.
- Bố cục thực tế: tai thỏ hoặc Dynamic Island, thanh Home, bàn phím che mất một ô nhập.
- Độ mượt, thứ mà một máy tính mạnh thường che giấu.
Một chiếc iPhone cũ đời gần đây là đủ, miễn là nó chạy được phiên bản iOS mà phiên bản SDK Expo của bạn hỗ trợ. Và nếu được, hãy mượn thêm một chiếc iPhone kích thước khác: app hiển thị ổn trên màn hình lớn có thể bị cắt trên màn hình nhỏ. Đó chính xác là lý do Solys của mình bị từ chối, mình kể trong bài vì sao Apple từ chối app.
Không có Mac thì vẫn được. Không có iPhone, bạn gửi cho Apple một app mà bạn chưa từng thấy nó chạy.
Các bước theo thứ tự, từ Windows
- Tạo dự án bằng
npx create-expo-appvà test những màn hình đầu tiên với Expo Go. - Cài EAS CLI bằng
npm install -g eas-cli, rồi chạyeas loginvàeas build:configure. - Đăng ký Apple Developer Program ngay khi dự án bắt đầu thành hình.
- Đăng ký iPhone bằng
eas device:createvà chạy một development build. - Tạo trang app trong App Store Connect, với cùng bundle identifier như trong cấu hình Expo.
- Chạy bản build production bằng
eas build --platform ios. - Gửi nó đi bằng
eas submit --platform ios, rồi test trong TestFlight. Bài hướng dẫn dùng TestFlight để test app nói chi tiết bước này. - Điền trang thông tin và gửi xét duyệt từ trình duyệt. Còn văn bản quảng cáo thì sau này đổi được mà không cần phiên bản mới.
Có ba cái bẫy hay gặp ở giai đoạn này. Số build phải tăng sau mỗi lần gửi: bật tính năng tự động tăng của EAS để khỏi phải nhớ. Câu hỏi về mã hóa sẽ chặn mọi bản build cho đến khi bạn trả lời: bạn có thể khai báo một lần cho tất cả trong cấu hình app. Và bundle identifier phải giống nhau ở mọi nơi, nếu không EAS Submit sẽ không tìm thấy app của bạn. Cho phần tiếp theo, từ trang thông tin đến khi được duyệt, trang phát hành app lên App Store đi qua từng bước.
Phát hành app đầu tiên, không cần Mac và không bị lạc
Mac không còn là trở ngại thật sự. Trở ngại thật nằm ở chỗ khác: chọn một app có cơ hội kiếm tiền, tích hợp gói đăng ký chạy đúng, chuẩn bị hồ sơ mà Apple chấp nhận. Đó là nội dung của lộ trình bốn bước trong iOS Kit, theo nhịp độ của riêng bạn. Về hồ sơ, Apple Review Kit gom checklist của mình trước khi gửi và các ghi chú cho người duyệt. Trang chủ cho thấy cách tạo app di động mà không phải bắt đầu từ con số không với Expo và Claude Code, dù có Mac hay không.
Quyết định cuối cùng về việc phát hành app của bạn vẫn nằm ở Apple, và không kit nào đảm bảo được điều đó. Thứ mình có thể mang lại cho bạn là phương pháp mình áp dụng cho chính các app của mình.
Câu hỏi thường gặp
Làm sao phát hành app iOS mà không cần Mac?
Với Expo và React Native, một máy Mac do Expo vận hành sẽ thay cho máy của bạn. Bạn code trên bất kỳ máy tính nào, EAS Build biên dịch và ký app trên cloud, rồi EAS Submit gửi nó lên App Store Connect. Bạn cũng cần một tài khoản Apple Developer trả phí, một trình duyệt để điền trang thông tin app và một chiếc iPhone để test app thật sự.
Các bước phát hành app iOS từ Windows là gì?
Tạo dự án bằng Expo, cài EAS CLI và đăng ký Apple Developer Program. Đăng ký iPhone, chạy một development build, rồi tạo trang app trong App Store Connect với cùng bundle identifier như trong cấu hình Expo. Sau đó chạy bản build production, gửi nó bằng EAS Submit và test trong TestFlight, rồi điền trang thông tin và gửi app xét duyệt từ trình duyệt.
Phát hành app lên App Store tốn bao nhiêu tiền?
Phí tham gia Apple Developer Program là 99 USD mỗi năm, trừ bằng đơn vị tiền tệ của bạn. Đây là khoản bắt buộc: không có nó thì không có App Store Connect, TestFlight, phân phối nội bộ, cũng không gửi được lên App Store. Về phía Expo, gói miễn phí của EAS gồm số lượng build giới hạn mỗi tháng, kèm hàng đợi: hãy kiểm tra điều kiện hiện hành trên trang bảng giá của Expo.
Có cần iPhone để phát hành app iOS khi không có Mac không?
Về kỹ thuật thì không, nhưng mình thật sự khuyên bạn đừng làm vậy, và Apple cũng thế: quy tắc xét duyệt của họ (guideline 2.1) yêu cầu app phải được test trên thiết bị về lỗi và độ ổn định trước khi gửi. Một chiếc iPhone cũ đời gần đây là đủ, miễn là nó chạy được phiên bản iOS mà phiên bản SDK Expo của bạn hỗ trợ.
Làm sao test app iOS khi không có Mac?
Cài app Expo Go lên iPhone: nó quét một mã QR hiển thị trong terminal và tải dự án của bạn, mỗi thay đổi hiện ra chỉ sau vài giây. Expo Go chỉ chứa các module native do Expo cung cấp. Ngay khi app dùng một thư viện native không có sẵn, như SDK của RevenueCat, bạn cần một development build do EAS Build biên dịch. Để test bản build cuối cùng, hãy đọc dùng TestFlight để test app.
Phát triển iOS không có Mac có những giới hạn gì?
Bạn không dùng được simulator iOS chạy local: nó là một phần của Xcode, nên không chạy trên Windows. Build local của EAS (--local) không được hỗ trợ trên Windows: các bản build iOS của bạn phải đi qua cloud của Expo. Debug code native và tự viết extension native vẫn làm được, nhưng khó hơn, vì các công cụ của Apple nằm trong Xcode.