Wersja vs kompilacja w Xcode

660

Mam aplikację, którą opracowałem przy pomocy Xcode 3, a ostatnio rozpocząłem edycję przy pomocy Xcode 4. W podsumowaniu celu mam formularz docelowy aplikacji na iOS z polami: identyfikator, wersja, kompilacja, urządzenia i cel wdrożenia. Pole wersji jest puste, a pole kompilacji to 3.4.0 (co odpowiada wersji aplikacji od czasu, gdy wciąż edytowałem za pomocą Xcode 3).

Moje pytania to:

  1. Jaka jest różnica między polami wersji i kompilacji?

  2. Dlaczego pole wersji było puste po aktualizacji do Xcode 4?

Chris
źródło
Po pierwsze, myślę, że jest to numer kompilacji, który pojawia się na liście archiwów Xcode Organizer. Poza tym nie jestem pewien, do czego służy.
Daniel Dickison,

Odpowiedzi:

1224

Apple trochę zmieniło / zmieniło przeznaczenie pól.

Idąc dalej, jeśli spojrzysz na zakładkę Informacje o celu aplikacji, powinieneś użyć „Ciągu wersji pakietu, krótkiego” jako swojej wersji (np. 3.4.0) i „Wersji pakietu” jako swojej wersji (np. 500 lub 1A500 ). Jeśli nie widzisz ich obu, możesz je dodać. Będą one mapowane do odpowiednich wersji i budują pola tekstowe na karcie Podsumowanie; są to te same wartości.

Przeglądając kartę Informacje, kliknięcie prawym przyciskiem myszy i wybranie opcji Pokaż surowe klucze / wartości spowoduje wyświetlenie rzeczywistych nazw CFBundleShortVersionString(Wersja) i CFBundleVersion(Kompilacja).

Wersja jest zwykle używana tak, jak wyglądasz na Xcode 3. Nie jestem pewien, na jakim poziomie pytasz o różnicę Wersja / Kompilacja, więc odpowiem na nią filozoficznie.

Istnieje wiele rodzajów schematów, ale popularny jest:

{MajorVersion}. {MinorVersion}. {Revision}

  • Wersja główna - Główne zmiany, przeprojektowania i zmiany funkcjonalności
  • Drobna wersja - Drobne ulepszenia, dodatki do funkcjonalności
  • Wersja - Numer poprawki poprawek błędów

Następnie kompilacja jest używana osobno, aby wskazać całkowitą liczbę kompilacji dla wydania lub przez cały okres użytkowania produktu.

Wielu programistów rozpoczyna numer kompilacji od 0 i za każdym razem, gdy budują, zwiększają liczbę o jeden, zwiększając na zawsze. W moich projektach mam skrypt, który automatycznie zwiększa liczbę kompilacji za każdym razem, gdy buduję. Zobacz instrukcje poniżej.

  • Wersja 1.0.0 może być kompilacją 542. Potrzebne były 542 kompilacje, aby uzyskać wersję 1.0.0.
  • Wersja 1.0.1 może być kompilacją 578.
  • Wersja 1.1.0 może być kompilacją 694.
  • Wersja 2.0.0 może być kompilacją 949.

Inni programiści, w tym Apple, mają numer kompilacji składający się z wersji głównej + wersji podrzędnej + liczby kompilacji do wydania. Są to rzeczywiste numery wersji oprogramowania, w przeciwieństwie do wartości używanych w marketingu.

Jeśli przejdziesz do menu Xcode > Informacje o Xcode , zobaczysz numery wersji i kompilacji. Jeśli naciśniesz przycisk Więcej informacji ... zobaczysz kilka różnych wersji. Ponieważ Info Więcej ... przycisk został usunięty w Xcode 5, informacja ta jest również dostępna z Software> Deweloper sekcji System Information aplikacji dostępnych poprzez otwarcie firmy Apple menu> Ten Mac > Raport Systemu ... .

Na przykład Xcode 4.2 (4C139). Wersja marketingowa 4.2 to Kompilacja główna wersja 4, Kompilacja pomocnicza wersja C i Kompilacja numer 139. Następna wersja (prawdopodobnie 4.3) prawdopodobnie będzie Kompilacja wersja 4D, a numer Kompilacji rozpocznie się od 0 i będzie wzrastał stamtąd.

Numery wersji / kompilacji iPhone'a są takie same, jak iPhone'y, komputery Mac itp.

  • 3.2: (7W367a)
  • 4.0: (8A400)
  • 4.1: (8B117)
  • 4.2: (8C134)
  • 4.3: (8H7)

Aktualizacja : na żądanie, oto kroki, aby utworzyć skrypt, który będzie uruchamiany za każdym razem, gdy budujesz aplikację w Xcode, aby odczytać numer kompilacji, zwiększyć go i zapisać z powrotem do {App}-Info.plistpliku aplikacji . Istnieją opcjonalne dodatkowe kroki, jeśli chcesz zapisać numery wersji / kompilacji w swoich Settings.bundle/Root*.plistplikach.

Jest to rozszerzone z artykułu z poradnikiem tutaj .

W Xcode 4.2 - 5.0:

  1. Załaduj swój projekt Xcode.
  2. W lewym panelu kliknij swój projekt na samym szczycie hierarchii. Spowoduje to załadowanie edytora ustawień projektu.
  3. Po lewej stronie środkowego panelu okna kliknij swoją aplikację pod nagłówkiem CELE . Musisz skonfigurować tę konfigurację dla każdego celu projektu.
  4. Wybierz kartę Fazy ​​budowania .
    • W Xcode 4 w prawym dolnym rogu kliknij przycisk Dodaj fazę kompilacji i wybierz Dodaj skrypt uruchamiania .
    • W Xcode 5 wybierz menu Edytor > Dodaj fazę kompilacji > Dodaj fazę kompilacji skryptu uruchamiania .
  5. Przeciągnij i upuść nową fazę Uruchom skrypt, aby przenieść ją tuż przed fazą Kopiuj zasoby pakietu (kiedy plik app-info.plist zostanie dołączony do Twojej aplikacji).
  6. W nowym Run Script fazie ustawić Shell : /bin/bash.
  7. Skopiuj i wklej następujące elementy w obszarze skryptu dla liczb całkowitych kompilacji:

    buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
    buildNumber=$(($buildNumber + 1))
    /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"

    Jak wskazał @Bdebeez, dostępne jest również narzędzie Apple Generic Versioning Tool ( agvtool). Jeśli wolisz go używać, musisz najpierw zmienić kilka rzeczy:

    • Wybierz kartę Ustawienia kompilacji .
    • W sekcji Wersjonowanie ustaw bieżącą wersję projektu na początkowy numer kompilacji, którego chcesz użyć, np . 1 .
    • Z powrotem na karcie Fazy ​​kompilacji przeciągnij i upuść fazę Uruchom skrypt po fazie Kopiuj zasoby pakietu, aby uniknąć sytuacji wyścigu podczas próby zarówno kompilacji, jak i aktualizacji pliku źródłowego zawierającego numer kompilacji.

    Zauważ, że dzięki agvtoolmetodzie nadal możesz okresowo otrzymywać nieudane / anulowane kompilacje bez błędów. Z tego powodu nie polecam używać agvtooltego skryptu.

    Niemniej jednak w fazie uruchamiania skryptu możesz użyć następującego skryptu:

    "${DEVELOPER_BIN_DIR}/agvtool" next-version -all

    next-versionZwiększa Argument numer kompilacji ( bumpjest aliasem dla tej samej rzeczy) i -allaktualizacje Info.plisto nowym numerze kompilacji.

  8. A jeśli masz pakiet ustawień, w którym wyświetlasz wersję i kompilację, możesz dodać na końcu skryptu, aby zaktualizować wersję i kompilację. Uwaga: zmień PreferenceSpecifierswartości, aby pasowały do ​​ustawień. PreferenceSpecifiers:2oznacza spojrzenie na pozycję o indeksie 2 pod PreferenceSpecifierstablicą w pliku plist, więc dla indeksu opartego na 0 jest to trzecie ustawienie preferencji w tablicy.

    productVersion=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "$INFOPLIST_FILE")
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:2:DefaultValue $buildNumber" Settings.bundle/Root.plist
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $productVersion" Settings.bundle/Root.plist

    Jeśli używasz agvtoolzamiast czytać Info.plistbezpośrednio, możesz zamiast tego dodać do skryptu:

    buildNumber=$("${DEVELOPER_BIN_DIR}/agvtool" what-version -terse)
    productVersion=$("${DEVELOPER_BIN_DIR}/agvtool" what-marketing-version -terse1)
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:2:DefaultValue $buildNumber" Settings.bundle/Root.plist
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $productVersion" Settings.bundle/Root.plist
  9. A jeśli masz uniwersalną aplikację na iPada i iPhone'a, możesz również ustawić ustawienia dla pliku iPhone'a:

    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:2:DefaultValue $buildNumber" Settings.bundle/Root~iphone.plist    
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $productVersion" Settings.bundle/Root~iphone.plist
nekno
źródło
17
„W moich projektach mam skrypt, który automatycznie zwiększa liczbę kompilacji za każdym razem, gdy buduję” - czy możesz podzielić się tym, jak to robisz? dzięki za szczegóły anwers i oryginalne pytanie.
Zsolt,
2
@Andrews - zaktualizowałem swoją odpowiedź szczegółowymi informacjami o skrypcie kompilacji.
nekno
9
Aby zwiększyć liczbę szesnastkową, możesz użyćbuildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE") dec=$((0x$buildNumber)) buildNumber=$(($dec + 1)) hex=$(printf "%X" $buildNumber) /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $hex" "$INFOPLIST_FILE"
Alon Amir
8
W skrócie: HEX nie jest dozwolony w AppStore.
Nicolas Miari
3
(Użytkownicy Xcode 5) Może być konieczna zmiana kroku 5, aby przeczytać: „Z
paska
72

(Zostawiam to tutaj dla własnego odniesienia). Spowoduje to wyświetlenie wersji i kompilacji dla pól „wersja” i „kompilacja” widocznych w celu Xcode:

- (NSString*) version {
    NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
    NSString *build = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
    return [NSString stringWithFormat:@"%@ build %@", version, build];
}

W Swift

func version() -> String {
    let dictionary = NSBundle.mainBundle().infoDictionary!
    let version = dictionary["CFBundleShortVersionString"] as? String
    let build = dictionary["CFBundleVersion"] as? String
    return "\(version) build \(build)"
}
Dan Rosenstark
źródło
2
OT: Masz wyciek w swojej metodzie - ty alloc/ initłańcuch, który zachowuje łańcuch, ale go nie zwalniasz. Na obiekcie, który powrócisz z metody, powinieneś na ogół użyć metody wygodnej, aby ciąg był automatycznie wydawany automatycznie lub wywoływał autorelease. Albo: return [NSString stringWithFormat:@"%@ build %@", version, build]; OR return [[[NSString alloc] initWithFormat:@"%@ build %@", version, build] autorelease];
nekno
1
Dzięki @nekno, zmieniłem odpowiedź, więc jest ARC lub nie jest przyjazna dla ARC.
Dan Rosenstark,
2
Prawdopodobnie lepiej jest użyć stałych, jeśli są dostępne (np. KCFBundleVersionKey), aby uniknąć literówek. Chociaż nie mogłem znaleźć jednego dla „CFBundleShortVersionString” :)
DannyA
Masz błąd w szybkim kodzie - dzwonisz do CFBundleShortVersionString dwa razy
Nissim
Dzięki @ yar1vn, naprawiłem to i NIE to nie jest wstecz.
Dan Rosenstark
53

Numer kompilacji to wewnętrzny numer wskazujący bieżący stan aplikacji. Różni się od numeru wersji tym, że zwykle nie jest przeznaczony dla użytkownika i nie oznacza żadnej różnicy / funkcji / aktualizacji, jak zwykle numer wersji.

Pomyśl o tym w ten sposób:

  • Build ( CFBundleVersion): numer kompilacji. Zwykle zaczynasz od 1 i zwiększasz o 1 z każdą wersją aplikacji. Szybko pozwala na porównania, które kompilacje są nowsze i oznacza poczucie postępu bazy kodowej. Mogą one być niezwykle cenne podczas pracy z kontrolą jakości i muszą mieć pewność, że błędy są rejestrowane w odpowiednich kompilacjach.
  • Wersja marketingowa ( CFBundleShortVersionString): numer użytkownika, którego używasz do oznaczenia tej wersji aplikacji. Zwykle jest to zgodne ze schematem wersji Major.minor (np. MyAwesomeApp 1.2), aby poinformować użytkowników, które wersje są mniejszymi aktualizacjami konserwacyjnymi, a które nowymi.

Aby skutecznie wykorzystać to w swoich projektach, Apple zapewnia doskonałe narzędzie o nazwie agvtool. Zdecydowanie polecam korzystanie z tego, ponieważ jest WIELE O wiele prostsze niż pisanie skryptów zmian w liście odtwarzania. Pozwala łatwo ustawić zarówno numer kompilacji, jak i wersję marketingową. Jest to szczególnie przydatne podczas tworzenia skryptów (na przykład w celu łatwej aktualizacji numeru kompilacji na każdej kompilacji lub nawet zapytania o bieżący numer kompilacji). Może nawet robić bardziej egzotyczne rzeczy, takie jak oznaczanie SVN dla Ciebie podczas aktualizacji numeru kompilacji.

Aby go użyć:

  • Ustaw swój projekt w Xcode, w obszarze Wersjonowanie, aby użyć „Apple Generic”.
  • W terminalu
    • agvtool new-version 1 (ustaw numer kompilacji na 1)
    • agvtool new-marketing-version 1.0 (ustaw wersję marketingową na 1.0)

Zobacz stronę podręcznika użytkownika, agvtoolaby uzyskać mnóstwo dobrych informacji

Bdebeez
źródło
kolejny artykuł na temat agvtool łatwego wersjonowania aplikacji iPhone za pomocą agvtool
Gon
25

Skrypt do automatycznej inkrementacji numeru kompilacji w powyższej odpowiedzi nie działał dla mnie, jeśli numer kompilacji jest wartością zmiennoprzecinkową, więc trochę go zmodyfikowałem:

#!/bin/bash    
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=`echo $buildNumber +1|bc`
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"
ale84
źródło
21

Numer wydania marketingowego przeznaczony jest dla klientów i nazywa się numerem wersji . Zaczyna się od 1.0 i idzie do głównych aktualizacji 2.0 , 3.0 , drobnych aktualizacji 1.1 , 1.2 i poprawek błędów do 1.0.1 , 1.0.2 . Liczba ta dotyczy wydań i nowych funkcji.

Numer kompilacji jest głównie wewnętrzny numer buduje , które zostały wykonane do tej pory. Ale niektórzy używają innych liczb, takich jak numer oddziału repozytorium. Ta liczba powinna być unikalna, aby rozróżnić różne prawie te same kompilacje.

Jak widać, numer kompilacji nie jest konieczny i od Ciebie zależy, jakiego numeru kompilacji chcesz użyć. Jeśli więc zaktualizujesz swoją Xcodewersję główną, pole kompilacji będzie puste. Pole wersji może nie być puste!


Aby uzyskać numer kompilacji jako NSStringzmienną:

NSString * appBuildString = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];

Aby uzyskać numer wersji jako NSStringzmienną:

NSString * appVersionString = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];

Jeśli chcesz oba w jednym NSString:

NSString * versionBuildString = [NSString stringWithFormat:@"Version: %@ (%@)", appVersionString, appBuildString];

Jest to testowane z Xcode w wersji 4.6.3 (4H1503) . Numer kompilacji jest często zapisywany w nawiasach / nawiasach klamrowych. Numer kompilacji jest zapisany w systemie szesnastkowym lub dziesiętnym.

buildandversion


W Xcode możesz automatycznie zwiększać numer kompilacji jako dziesiętną , umieszczając następujące elementy w Run scriptfazie kompilacji w ustawieniach projektu

#!/bin/bash    
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"

W przypadku szesnastkowej liczby kompilacji użyj tego skryptu

buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
buildNumber=$((0x$buildNumber)) 
buildNumber=$(($buildNumber + 1)) 
buildNumber=$(printf "%X" $buildNumber)
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"

ustawienia_projektu

Binarian
źródło
6

Dzięki @nekno i @ ale84 za świetne odpowiedzi.

Jednak zmodyfikowałem skrypt @ ale84, aby nieznacznie zwiększać liczby kompilacji dla liczb zmiennoprzecinkowych.

wartość parametru inc można zmienić zgodnie z wymaganiami dotyczącymi formatu zmiennoprzecinkowego. Na przykład: jeśli włączone = .01, format wyjściowy to ... 1,19, 1,20, 1,21 ...

buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$INFOPLIST_FILE")
incl=.01
buildNumber=`echo $buildNumber + $incl|bc`
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$INFOPLIST_FILE"
iHS
źródło
1

Innym sposobem jest ustawienie numeru wersji w appDelegate didFinishLaunchingWithOptions:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
     NSString * ver = [self myVersion];
     NSLog(@"version: %@",ver);

     NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
     [userDefaults setObject:ver forKey:@"version"];
     return YES;
}

- (NSString *) myVersion {
    NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
    NSString *build = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
    return [NSString stringWithFormat:@"%@ build %@", version, build];
}
mark VanderWiele
źródło