# Build number App Store Connect: versiune și număr de build

> Versiunea e numărul pe care îl văd clienții, build number-ul identifică fiecare upload. Perechea trebuie să fie unică: cu Expo, EAS crește build-ul pentru tine.

Pagina originală: [Build number App Store Connect: versiune și număr de build](https://devoria.fr/ro/blog/build-number-app-store-connect-versiune)
Autor: [Mehdi Azizi](https://devoria.fr/ro/mehdi-azizi)
Publicare: 2026-11-04
Ultima revizuire a conținutului: 2026-11-04


Build number-ul din App Store Connect e numărul de build: cheia `CFBundleVersion`, care identifică fiecare upload. Versiunea, `CFBundleShortVersionString`, e numărul pe care clienții tăi îl văd în App Store. **Apple cere ca perechea versiune și număr de build să fie unică: un număr de build se folosește o singură dată pentru aceeași versiune.**

Cu Expo, versiunea o setezi tu, iar EAS poate incrementa numărul de build la fiecare build de producție. Ghidul ăsta explică cele două numere, regulile Apple, erorile ITMS-90062 și ITMS-90189, plus ce să verifici când build-ul tău nu apare.

Îmi public aplicațiile iOS cu Expo și EAS, printre ele Solys, TradaZen și Nolera. Setările de mai jos sunt cele din fișierele lor `eas.json`.

## Versiune și număr de build: care e diferența?

Două chei din Info.plist îți identifică aplicația. [Documentația Apple despre CFBundleShortVersionString](https://developer.apple.com/documentation/bundleresources/information-property-list/cfbundleshortversionstring) o descrie ca versiunea vizibilă pentru utilizator: trei numere întregi separate prin puncte, de exemplu 10.14.1. [Cea despre CFBundleVersion](https://developer.apple.com/documentation/bundleresources/information-property-list/cfbundleversion) vorbește despre versiunea build-ului: unul până la trei numere întregi, doar cu cifre și puncte.

| Element        | Cheie iOS                  | Cine o vede  | Câmp Expo         |
| -------------- | -------------------------- | ------------ | ----------------- |
| Versiune       | CFBundleShortVersionString | Clienții tăi | `version`         |
| Număr de build | CFBundleVersion            | Tu și Apple  | `ios.buildNumber` |

Exemplu fictiv: pentru versiunea 1.4.0, trimiți build-urile 12, 13 și 14 în timpul testelor, apoi alegi unul pentru review. [Ajutorul App Store Connect](https://developer.apple.com/help/app-store-connect/manage-builds/upload-builds) rezumă: versiunea leagă build-ul de pagina lui, numărul de build îl identifică peste tot în sistem.

## Regulile Apple de incrementare

1. **Perechea trebuie să fie unică.** Conform [documentației Xcode Cloud](https://developer.apple.com/documentation/xcode/setting-the-next-build-number-for-xcode-cloud-builds), App Store Connect cere o combinație unică de versiune și număr de build. Deci o aplicație de iPhone poate reporni de la 1 pentru o versiune nouă. O aplicație de Mac, nu: numărul ei trebuie să crească mereu.
2. **O versiune aprobată e închisă.** Odată ce Apple a validat versiunea 1.4.0, nu-i mai poți adăuga build-uri. Următoarea trebuie să aibă un număr mai mare.
3. **Fiecare număr se compară ca întreg.** 1.10 vine după 1.9, pentru că 10 e mai mare decât 9. O versiune 1.9 trimisă după o 1.20 aprobată va fi respinsă.

Sfatul meu: **păstrează un număr de build întreg care crește mereu, fără să-l resetezi la 1.** Repornirea de la 1 e permisă pe iPhone, dar un număr unic pe toată viața aplicației te ferește să încurci două build-uri în TestFlight. Asta văd la aplicațiile mele în modul remote: contorul continuă de la o versiune la alta.

## Gestionarea versiunii și a build-ului cu Expo și EAS

[Pagina Expo despre versiuni](https://docs.expo.dev/build-reference/app-versions/), actualizată pe 25 septembrie 2026, separă rolurile. Versiunea (`version` în app.json) rămâne la tine: o schimbi când pregătești o lansare nouă. Numărul de build (`ios.buildNumber`) îl poți lăsa în grija EAS. De altfel, Expo menționează uitarea incrementării lui ca o cauză frecventă de respingere la upload.

Totul se setează în eas.json:

```json
{
  "cli": {
    "appVersionSource": "remote"
  },
  "build": {
    "production": {
      "autoIncrement": true
    }
  }
}
```

- **`"remote"`**: serverele EAS păstrează numărul de build. E comportamentul recomandat din EAS CLI 12. Contorul pornește de la valoarea din configurația ta, sau de la 1, apoi `ios.buildNumber` e ignorat.
- **`"local"`**: configurația ta e sursa de adevăr. Cu `autoIncrement`, EAS modifică `ios.buildNumber` în fișierul tău, iar tu trebuie să faci commit la schimbare după fiecare build.
- **`autoIncrement`**: [referința eas.json](https://docs.expo.dev/eas/json/) acceptă `true` sau `"buildNumber"` pentru build, și `"version"` pentru a crește ultima cifră a versiunii. În modul remote, Expo precizează că `"version"` nu e suportat.

La mine, TradaZen și Nolera sunt pe `remote`. Solys a rămas pe `local`: numărul ei de build stă în app.json și fiecare build de producție îl crește în fișier. **Ambele merg, dar modul remote elimină riscul unui commit uitat.**

Două comenzi completează sistemul. `eas build:version:set` inițializează contorul remote: introdu ultimul număr trimis la Apple. `eas build:version:sync` copiază valorile remote în proiectul tău, util dacă vreodată compilezi cu Xcode. Cu EAS Update, modul remote nu merge cu politica `nativeVersion`: Expo recomandă `appVersion`.

## ITMS-90062: versiunea e deja aprobată

Mesajul arată cam așa (numere fictive):

```text
ERROR ITMS-90062: This bundle is invalid. The value for key
CFBundleShortVersionString [1.4.0] in the Info.plist file must
contain a higher version than that of the previously approved
version [1.4.0].
```

Apple a aprobat deja versiunea 1.4.0: nu mai poți adăuga build-uri la ea. **Crește versiunea în app.json, de exemplu la 1.4.1, apoi pornește un build nou.** Doar schimbarea numărului de build nu ajunge.

Dacă eroarea revine deși `version` e la zi, caută un câmp `ios.version`. Conform [referinței configurației Expo](https://docs.expo.dev/versions/latest/config/app/), are prioritate față de `version` pe iOS. Același remediu pentru eroarea înrudită ITMS-90186, „Invalid Pre-Release Train”, care semnalează o versiune închisă pentru build-uri noi.

## ITMS-90189: Redundant Binary Upload

Aici numărul de build e problema:

```text
ERROR ITMS-90189: Redundant Binary Upload. You've already uploaded
a build with build number '12' for version number '1.4.0'.
```

Perechea 1.4.0 (12) există deja la Apple. Cu Expo, apar des patru cauze:

- **Profilul folosit nu are `autoIncrement`.** Dacă îți faci un profil separat pentru TestFlight, cum e cel de la Nolera, pune opțiunea și acolo.
- **Contorul remote e în urmă.** Ai trecut pe `remote` după upload-uri manuale: rulează `eas build:version:set` cu ultimul număr cunoscut de Apple.
- **Commit-ul a fost uitat în modul local.** Build-ul următor pornește de la numărul vechi.
- **Retrimiți același binar.** Cu `eas submit`, alege build-ul nou, nu pe cel vechi.

**Corectura e mereu aceeași: un build nou cu un număr mai mare.**

## „No builds available”: build-ul tău nu apare

Build-ul a plecat, dar pagina ta nu ți-l propune. Verifică în ordinea asta.

1. **E încă în procesare.** Apple procesează fiecare build înainte să-l afișeze și îți trimite un e-mail la final. [Expo](https://docs.expo.dev/submit/ios/) vorbește în general de 10 până la 15 minute. [Conform Apple](https://developer.apple.com/help/app-store-connect/manage-builds/view-builds-and-metadata), dacă stă peste 24 de ore în procesare, trebuie să deschizi un tichet în Feedback Assistant.
2. **Așteaptă declarația ta de criptare.** E statusul Missing Compliance, detaliat mai jos.
3. **Versiunea nu corespunde.** Un build 1.4.1 nu se încadrează sub o pagină pregătită ca 1.5.0 în App Store Connect. Aliniază-le.
4. **Între timp a ieșit o versiune.** Conform [ajutorului despre alegerea build-ului](https://developer.apple.com/help/app-store-connect/manage-builds/choose-a-build-to-submit), lista arată atunci doar build-urile trimise de la acea lansare.
5. **Testerul e cel care nu-l vede.** În aplicația TestFlight, „no builds available” înseamnă des că build-ul nu e în niciun grup, așteaptă review-ul beta sau a expirat. Detaliile sunt în [TestFlight pentru testarea aplicației de iPhone](https://devoria.fr/ro/blog/testflight-testare-aplicatie-iphone).

### Statusurile de știut

Statusurile care explică cel mai des un build lipsă, conform [listei Apple](https://developer.apple.com/help/app-store-connect/reference/app-build-statuses). Processing și Failed nu apar acolo: sunt statusurile de upload descrise în [urmărirea build-urilor](https://developer.apple.com/help/app-store-connect/manage-builds/view-builds-and-metadata).

| Status             | Ce înseamnă                 | Ce faci                    |
| ------------------ | --------------------------- | -------------------------- |
| Processing         | Apple procesează build-ul   | Aștepți e-mailul           |
| Failed             | Eroare la procesare         | Citești eroarea, retrimiți |
| Missing Compliance | Criptare nedeclarată        | Răspunzi sau Info.plist    |
| Invalid Binary     | Upload neconform            | Corectezi, build nou       |
| Expired            | Peste 90 de zile            | Build nou                  |
| Ready to Submit    | Gata pentru test sau review | Îl adaugi într-un grup     |

### Declară criptarea o dată pentru totdeauna

Fără cheia `ITSAppUsesNonExemptEncryption`, [Apple](https://developer.apple.com/documentation/bundleresources/information-property-list/itsappusesnonexemptencryption) îți pune întrebările de conformitate la fiecare versiune nouă. Cu Expo, câmpul se numește `ios.config.usesNonExemptEncryption`:

```json
{
  "expo": {
    "ios": {
      "config": {
        "usesNonExemptEncryption": false
      }
    }
  }
}
```

`false` înseamnă: fără criptare, sau doar criptare scutită. [Apple precizează](https://developer.apple.com/documentation/security/complying-with-encryption-export-regulations) că criptarea integrată în sistem, cum sunt conexiunile HTTPS, e în general scutită, și că răspunsul acoperă și bibliotecile tale. Toate trei aplicațiile mele declară `false`. **Pune `false` doar dacă e adevărat pentru aplicația ta: declarația te angajează.**

## Poți schimba numărul unui build deja trimis?

Nu. Numărul e înscris în binarul semnat: ca să-l corectezi, îți trebuie un build nou.

Ce poți schimba e build-ul atașat versiunii tale. Apple permite un singur build per versiune, dar [îl poți înlocui de câte ori vrei](https://developer.apple.com/help/app-store-connect/manage-builds/choose-a-build-to-submit) până la trimiterea în review:

1. Deschide versiunea în App Store Connect, secțiunea Build.
2. Treci cu mouse-ul peste build-ul actual și dă clic pe butonul de ștergere, semnul minus.
3. Dă clic pe butonul de adăugare, semnul plus, alege build-ul corect, apoi salvează.

Scoaterea unui build dintr-o versiune nu-l șterge din contul tău. Dacă versiunea e deja în review, [retrage întâi trimiterea](https://developer.apple.com/help/app-store-connect/manage-submissions-to-app-review/remove-a-submission-from-review): review-ul va reîncepe de la zero.

## Înainte de următorul upload

Numărul de build e doar una dintre verificările de la upload. Imaginea de build poate declanșa [ITMS-90725](https://devoria.fr/ro/blog/itms-90725-sdk-version-issue-expo), iar semnarea are capcanele ei, detaliate în [certificat de developer iOS și provisioning profile](https://devoria.fr/ro/blog/certificat-dezvoltator-ios-provisioning-profile-expo). Tot lanțul, de la build la TestFlight, e în [publicarea unei aplicații iOS fără Mac](https://devoria.fr/ro/blog/publicare-aplicatie-ios-fara-mac-expo-eas), iar timpii de review în [durata de validare App Store](https://devoria.fr/ro/blog/durata-review-app-store-aprobare). Toți pașii sunt adunați pe pagina [publicarea unei aplicații în App Store](https://devoria.fr/ro/expertise/publicare-aplicatie-app-store).

Dacă îți pregătești prima lansare, [fă diagnosticul gratuit](https://devoria.fr/ro/diagnostic): îți spune ce blochează în proiectul tău și îți trimite checklist-ul meu anti-respingere Apple. Ca să construiești aplicația, să conectezi abonamentele și s-o publici, [iOS & Android Kit](https://devoria.fr/ro/kits/ios) urmează parcursul în patru etape cu codul de pornire al aplicațiilor mele, în ritmul tău.

## Întrebări frecvente

### Care e diferența dintre versiune și build number în App Store Connect?

Versiunea e numărul public al lansării tale, de exemplu 1.4.0. Build number-ul identifică un binar anume trimis la Apple pentru acea versiune. Poți trimite mai multe build-uri pentru aceeași versiune, fiecare cu numărul lui.

### Trebuie să schimb numărul de build la fiecare upload?

Da, pentru aceeași versiune. Apple respinge un al doilea upload cu aceeași pereche versiune și număr de build, e eroarea ITMS-90189. Cu EAS, `autoIncrement` se ocupă de asta la fiecare build de producție.

### Numărul de build trebuie să repornească de la 1 la fiecare versiune?

Nu e obligatoriu. Pe iPhone, Apple acceptă un număr mai mic pentru o versiune nouă, pentru că doar perechea trebuie să fie unică. Un contor care crește mereu rămâne mai ușor de urmărit.

### Cum schimb build number-ul în App Store Connect?

Nu poți modifica numărul unui build deja trimis. Poți în schimb înlocui build-ul atașat versiunii tale, din secțiunea Build a paginii, cât timp nu e în review. Pentru un număr nou, refă build-ul.

### De ce nu apare build-ul meu în App Store Connect?

Cel mai des, e încă în procesare sau așteaptă declarația ta de criptare. Verifică și că versiunea lui corespunde cu cea a paginii tale. Peste 24 de ore în procesare, Apple cere să deschizi un tichet.


## Proiectul tău

[Review Kit](https://devoria.fr/ro/kits/app-review): Checklistul meu de review App Store, respingerile mele de la Apple rezolvate, checklistul pentru Google Play și trei skilluri Claude Code. 259 RON.

[iOS & Android Kit](https://devoria.fr/ro/kits/ios): Creează-ți aplicația de iPhone și Android cu Claude Code: codul de pornire al aplicațiilor mele, drumul până în store-uri și toate kiturile. 529 RON.

[Diagnostic: ce te desparte de aplicația ta de iPhone](https://devoria.fr/ro/diagnostic): 7 întrebări, 60 de secunde: afli ce te blochează de fapt să-ți publici aplicația de iPhone, traseul tău în 4 etape și kitul potrivit pentru tine.
