# Guideline 2.5.1: API công khai và SDK cập nhật với Expo

> Guideline 2.5.1: chỉ dùng API công khai, app chạy được trên iOS hiện tại, framework đúng mục đích. Với Expo, hãy kiểm tra các module native trước tiên.

Trang gốc: [Guideline 2.5.1: API công khai và SDK cập nhật với Expo](https://devoria.fr/vi/blog/guideline-2-5-1-api-cong-khai-sdk-expo)
Tác giả: [Mehdi Azizi](https://devoria.fr/vi/mehdi-azizi)
Ngày đăng: 2026-11-04
Lần sửa nội dung gần nhất: 2026-11-04


Guideline 2.5.1 đặt ra bốn yêu cầu: chỉ dùng API công khai, chạy được trên phiên bản iOS hiện tại, bỏ những gì Apple đã đánh dấu deprecated và dùng mỗi framework đúng mục đích của nó. **Với Expo, rủi ro hiếm khi đến từ code JavaScript của bạn: nó đến từ các module native bạn cài và SDK bạn dùng để build.**

Mình phát hành Solys, TradaZen và Nolera bằng Expo SDK 57. Solys dựa vào API Screen Time của Apple, một framework có quy định sử dụng chặt chẽ. Bài này nói về quy tắc review. Nếu bạn gặp lỗi lúc upload build, hãy đọc bài [ITMS-90338](https://devoria.fr/vi/blog/itms-90338-non-public-api-usage-expo). Về các chế độ chạy nền, nằm cùng phần này, hãy đọc bài [guideline 2.5.4](https://devoria.fr/vi/blog/guideline-2-5-4-apple-tu-choi-che-do-chay-nen).

## Guideline 2.5.1 nói gì?

Quy tắc nằm trong phần 2.5, "Software Requirements", của [App Review Guidelines](https://developer.apple.com/app-store/review/guidelines/#2.5.1): "Apps may only use public APIs and must run on the currently shipping OS. Keep your apps up-to-date and make sure you phase out any deprecated features, frameworks or technologies that will no longer be supported in future versions of an OS. Apps should use APIs and frameworks for their intended purposes and indicate that integration in their app description."

Nói đơn giản, có bốn nghĩa vụ:

1. **Chỉ dùng API công khai**, tức là được Apple ghi trong tài liệu.
2. **App chạy được trên phiên bản iOS hiện hành**, là iOS 27 kể từ tháng 9/2026.
3. **Không dùng thứ gì deprecated sắp biến mất**: bạn thay thế những gì Apple thông báo sắp ngừng hỗ trợ.
4. **Mỗi framework đúng chỗ, và được nhắc trong phần mô tả**: HomeKit cho nhà thông minh, HealthKit cho sức khỏe và thể thao, kết nối với app Health.

Vì vậy tiêu đề của lời từ chối là: "Guideline 2.5.1 - Performance - Software Requirements".

## API công khai: rủi ro nằm ở đâu trong một app Expo

API private là một hàm hệ thống mà Apple không công bố tài liệu. Apple không đảm bảo hành vi của nó, cũng không đảm bảo nó còn tồn tại ở phiên bản iOS tiếp theo, nên mới cấm.

Code JavaScript của bạn không bao giờ chạm trực tiếp vào iOS: nó đi qua các module native. Các module trong SDK Expo do đội Expo bảo trì. **Những module khác chứa code bạn không viết, và Apple xem xét nó như code của chính bạn.** Bài [ITMS-90683](https://devoria.fr/vi/blog/itms-90683-missing-purpose-string-expo) cho thấy cùng cơ chế với các câu xin quyền: Apple đánh giá code có trong build, không phải những gì app thực sự làm.

Với Solys, tính đến ngày 15/10/2026, có 42 dependency trực tiếp chứa code iOS native, trong đó 14 cái nằm ngoài SDK Expo. Trong số đó có RevenueCat, Sentry, AppsFlyer và `react-native-device-activity`, cầu nối tới API Screen Time.

API private có thể bị phát hiện ở hai thời điểm. Lúc upload, bộ phân tích tự động của App Store Connect có thể trả về lỗi ITMS-90338. Trong lúc review, reviewer sẽ trích dẫn guideline 2.5.1.

## API deprecated: từ UIWebView đến UIScene

Ví dụ nổi tiếng nhất là UIWebView, component cũ để hiển thị nội dung web. Apple đã [ngừng chấp nhận nó](https://developer.apple.com/news/?id=12232019b) trong app mới từ tháng 4/2020, rồi trong các bản cập nhật từ tháng 12/2020. Một thư viện cũ vẫn tham chiếu tới nó là chặn luôn việc upload. Với Solys, lệnh tìm kiếm trong checklist bên dưới không tìm thấy tham chiếu nào.

Thay đổi tiếp theo đã được thông báo. Ghi chú kỹ thuật [TN3187](https://developer.apple.com/documentation/technotes/tn3187-migrating-to-the-uikit-scene-based-life-cycle) của Apple viết: "In the next major release following iOS 26, UIScene lifecycle will be required when building with the latest SDK; otherwise, your app won't launch." Nói đơn giản, một app build bằng SDK iOS 27 mà không có vòng đời theo scene sẽ không khởi động được.

Ba mốc thời gian cần nối lại với nhau:

- **Từ tháng 4/2026**, Apple yêu cầu Xcode 26: đây là chủ đề của bài [ITMS-90725](https://devoria.fr/vi/blog/itms-90725-sdk-version-issue-expo).
- **Tháng 4/2027**, [trang upload của Apple](https://developer.apple.com/app-store/submitting/) thông báo SDK iOS 27 sẽ là bắt buộc.
- **Expo SDK 58**, bản beta từ ngày 15/9/2026, đã tự tạo phần xử lý scene, theo [thông báo của Expo](https://expo.dev/changelog/sdk-58-beta).

Với Expo SDK 57 và Xcode 26, bạn vẫn build bằng SDK iOS 26: hiện tại chưa có gì hỏng. **Các module chỉnh sửa AppDelegate sẽ phải cập nhật theo trước tháng 4/2027.**

## Framework bị dùng sai mục đích

Reviewer kiểm tra xem một framework nhạy cảm có phục vụ một tính năng hiển thị rõ ràng không, và trang app của bạn có nhắc đến nó không.

- **HealthKit** dành cho sức khỏe và thể thao. [Hướng dẫn giao diện của Apple](https://developer.apple.com/design/human-interface-guidelines/healthkit) ghi rõ: "If your app doesn't provide health and fitness functionality, don't request access to people's private health data."
- **HomeKit** dành cho nhà thông minh, và không gì khác.
- **PushKit** dành cho cuộc gọi VoIP. [Tài liệu của PushKit](https://developer.apple.com/documentation/pushkit/responding-to-voip-notifications-from-pushkit) nói thẳng: "If you are unable to support CallKit in your app, you cannot use PushKit to handle push notifications." Một thông báo VoIP đánh thức app mà không có cuộc gọi nào là dùng sai mục đích.
- **Family Controls**, tức API Screen Time, đòi hỏi một quyền đặc biệt. [Tài liệu](https://developer.apple.com/documentation/familycontrols) của nó nêu rõ: "Before submitting your app to the App Store, you must request permission to use the entitlement."

Với Solys, mình đã xin quyền phân phối này vào ngày 23/9/2026, và Apple cấp ngay trong ngày. Cách dùng khớp với framework: người dùng chọn các app cần tạm dừng, và Solys chặn chúng trong 30, 45 hoặc 60 phút sau khi thức dậy. Phần mô tả trên trang app nói điều đó trong một câu: "Solys dùng quyền Screen Time của Apple để tạm dừng các app đã chọn." **Đó chính là điều phần cuối của 2.5.1 yêu cầu: nhắc đến việc tích hợp trong phần mô tả.**

## Bản beta: TestFlight thì được, App Store thì không

[Ghi chú phát hành của App Store Connect](https://developer.apple.com/help/app-store-connect/release-notes/) cho thấy quy tắc này trong thực tế. Ngày 14/10/2026, các build làm bằng Xcode 27.2 beta 3 được chấp nhận "for internal and external testing", tức là cho TestFlight. Ngày 5/10, các build từ Xcode 27.1 RC được chấp nhận "for the App Store".

**Một build compile bằng bản beta của Xcode được lên TestFlight, nhưng không bao giờ được gửi review.** Để submit, bạn cần một phiên bản chính thức, hoặc một bản RC mà Apple đã mở cho App Store.

Hai lưu ý cho app Expo:

- **Bản beta của Expo không phải là bản beta của Apple.** Apple kiểm soát phiên bản Xcode và SDK iOS, không phải phiên bản Expo. Thông báo SDK 58 còn cho biết các image EAS với Xcode 27 sắp ra mắt.
- **Vẫn bắt buộc phải test trên iOS hiện tại**, kể cả khi bạn build bằng SDK iOS 26. Hãy khởi động nguội app trên một iPhone hoặc simulator đã cập nhật.

## Checklist: dependency native trước khi submit

Chạy qua checklist này trước mỗi build production. Các lệnh chạy ở thư mục gốc của project Expo:

```bash
npx expo-doctor
npx expo install --check
grep -rlw "UIWebView" node_modules --include='*.m' --include='*.mm' --include='*.swift' --include='*.h'
```

1. **`npx expo-doctor` không báo lỗi nào.** Với Solys, ngày 15/10/2026: 20 trên 21 bước kiểm tra đạt. Lỗi còn lại đến từ 13 package Expo chậm một bản vá, và `npx expo install --check` đồng bộ lại chúng.
2. **Mỗi module ngoài SDK Expo đều có trong React Native Directory.** Expo Doctor kiểm tra điều này theo mặc định, như [tài liệu của Expo](https://docs.expo.dev/versions/latest/config/package-json/) cho biết. Một package lạ đáng để bạn đọc code iOS của nó.
3. **Mỗi module native theo kịp phiên bản React Native của bạn.** [Bảng phiên bản của Expo](https://docs.expo.dev/versions/latest/) ghép SDK 57 với React Native 0.86. Một module không phát hành bản mới qua nhiều phiên bản là một dấu hiệu cảnh báo.
4. **Lệnh tìm UIWebView không trả về kết quả nào.** Làm tương tự với mọi API mà Apple thông báo sắp ngừng hỗ trợ.
5. **Mỗi framework nhạy cảm có tính năng hiển thị rõ ràng**: sức khỏe, Screen Time, cuộc gọi, nhà thông minh. Phần mô tả có nhắc đến, và quyền đặc biệt đã được cấp.
6. **Build được tạo từ một bản Xcode chính thức.** Kiểm tra phiên bản trong log build của EAS.
7. **App khởi động nguội được trên phiên bản iOS hiện tại**, với một tài khoản mới.
8. **Các module đụng tới AppDelegate đã công bố hỗ trợ UIScene** trước khi bạn chuyển sang SDK iOS 27.

## Trả lời một lời từ chối 2.5.1 thế nào?

Thông báo thường nêu tên API hoặc framework có vấn đề. Có hai trường hợp:

- **Framework không phục vụ tính năng hiển thị nào**: gỡ module hoặc capability, build lại, rồi trả lời trong hai câu.
- **Framework phục vụ một tính năng thực sự**: đưa ra đường dẫn chính xác, một ảnh chụp màn hình hoặc một video ngắn, và nhắc đến việc tích hợp trong phần mô tả trên trang app.

**Gỡ một module native sẽ thay đổi binary: cập nhật từ xa là không đủ.** Bài [guideline 2.1](https://devoria.fr/vi/blog/guideline-2-1-app-store-tu-choi) giải thích vì sao reviewer chỉ thấy code được đóng gói trong build. Cuộc trao đổi sau đó diễn ra trong App Store Connect, như trong bài hướng dẫn [trả lời App Review](https://devoria.fr/vi/blog/resolution-center-apple-tra-loi-app-review-tu-choi).

## Kiểm tra project của bạn trước khi upload

[Review Kit](https://devoria.fr/vi/kits/app-review) gom checklist trước khi upload của mình, các lần bị từ chối mình đã sửa và các skill Claude Code để rà soát project Expo của bạn. Nếu muốn một người xem trực tiếp, [đặt lịch một giờ với mình](https://devoria.fr/vi/coaching): chúng ta sẽ cùng đọc thông báo của Apple và các dependency của bạn. Toàn bộ quy trình có trên trang [app bị Apple từ chối](https://devoria.fr/vi/expertise/ung-dung-bi-apple-tu-choi).

Bạn đang chuẩn bị phát hành app đầu tiên? [Làm bài chẩn đoán miễn phí](https://devoria.fr/vi/diagnostic): bạn sẽ nhận được checklist chống bị Apple từ chối của mình.

## Câu hỏi thường gặp

### "Guideline 2.5.1 - Performance - Software Requirements" nghĩa là gì?

Đó là tiêu đề lời từ chối khi Apple cho rằng app của bạn dùng API không công khai, công nghệ deprecated hoặc framework sai mục đích. Thông báo thường nêu tên thành phần có vấn đề.

### Guideline 2.5.1 khác gì với lỗi ITMS-90338?

ITMS-90338 là lỗi tự động nhận được khi upload build, lúc bộ phân tích phát hiện một symbol không công khai. 2.5.1 là quy tắc review do con người áp dụng, bao gồm cả framework bị dùng sai mục đích và công nghệ deprecated.

### Có thể submit app build bằng bản beta của Xcode không?

Không. App Store Connect chỉ chấp nhận các build đó cho TestFlight. Để gửi review, hãy build bằng phiên bản Xcode chính thức, hoặc một bản RC mà Apple đã mở cho App Store trong ghi chú phát hành.

### App Expo có thể dùng API private mà không biết không?

Có, thông qua một module native bên thứ ba. Code JavaScript của bạn không tự gọi iOS, nhưng mỗi package native đều chứa code Objective-C hoặc Swift. Hãy đọc danh sách các module ngoài SDK Expo trước mỗi phiên bản.

### Có cần lên Expo SDK 58 ngay không?

Không cần cho 2.5.1 tính đến ngày 15/10/2026: SDK 57 build bằng SDK iOS 26, vẫn còn được chấp nhận. Hãy lên kế hoạch nâng cấp trước tháng 4/2027, khi Apple yêu cầu SDK iOS 27 và vòng đời theo scene.


## Dự án của bạn

[Review Kit](https://devoria.fr/vi/kits/app-review): Checklist duyệt App Store của mình, các lần Apple từ chối đã sửa, checklist Google Play và ba skill Claude Code. 1.399.000 ₫.

[iOS & Android Kit](https://devoria.fr/vi/kits/ios): Tạo app iPhone và Android với Claude Code: code khởi đầu từ các app của mình, lộ trình đến tận store và tất cả các kit. 2.799.000 ₫.

[Chẩn đoán: điều gì ngăn bạn có app iPhone](https://devoria.fr/vi/diagnostic): 7 câu hỏi, 60 giây: bạn biết điều gì thật sự cản bạn đăng app iPhone, lộ trình 4 bước và kit phù hợp với bạn.
