Receigen, iTunes Connect und CFBundleVersion

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Receigen, iTunes Connect und CFBundleVersion

    Hallo zusammen,

    ich habe gerade einen spassigen Nachmittag mit der Receipt-Validierung unter iOS mittels Receigen verbracht. Vielleicht erspart dieser Post ja manch anderen dieses zweifelhafte Vergnügen ... Um es vorweg zu nehmen: "Wer lesen kann, ist klar im Vorteil..." :D

    Kurze Vorgeschichte: Ich nutze in einer macOS-App Receigen, um mir das Verarbeiten von Receipts und In-App-Käufen leichter zu machen und bin davon sehr angetan. Nun sollte auch eine iOS-App mit IAP ausgestattet werden. Also habe ich eine Klasse zu Händeln der verschiedenen Store-Aktivitäten geschrieben und eine Receigen-Datei generiert, die (1.) das Receipt validieren und (2.) durch die In-App-Käufe iterieren sollte. So weit, so gut.

    Leider scheiterte die Receipt-Überprüfung immer bei der Bundle-Version, die Fehlermeldung leider wenig sprechend: "Receipt version mismatch (expecting '(null)' but actual value is '(null)')". Super, dann mal los:
    • Eintrag im iTunes Connect geprüft, der war wie erwartet: "2.15.0"
    • Info.plist geprüft: Hier wird aus git-Tags heraus der CFBundleShortVersionString gesetzt und eine hochzählende Buildnummer in CFBundleVersion geschrieben. Das sieht dann z. B. so aus 2.15.0 (1234) und ermöglicht mir, im iTC neue Builds einer Version hochzuladen, ohne mich um ein manuelles Setzen zu kümmern. Bewert und geliebt.
    • Ich vermutete also einen Fehler in dem Sandbox-Receipt von Apple.
    • Um wenigstens etwas weiter Testen zu können, wollte ich Receigen mit der Präprozessor-Definition RECEIGEN_LOOSE_VERSION_CHECK überreden, den Check auszulassen, leider ohne Erfolg ... wahrscheinlich eigene Dummheit.
    Nach vielem Hin-und-her lese ich noch einmal genau die Dokumentation von Receigen - ja, das hätte ich früher machen sollen: Anders als bei macOS prüft dieses bei iOS die Bundle-Version mit CFBundleVersion. Ihr erinnert Euch, diese wurde bei mir automatisch als Build-Nummer hochgezählt und stimmte natürlich nie mit dem in der Receigen-Generierung angegebenen Versions-String 2.15.0 überein. WTF!

    Wer hat sich dieses Mischmasch zwischen beiden Plattformen eigentlich ausgedacht? Halt, ich weiß, wer ... und die wollen mir etwas von universalen Apps für beide Plattformen erzählen :cursing:

    Meine Lösung ist einfach, aber unschön: Ich verabschiede mich von dem o. g. Automatismus und setzte nun wieder - wie in Anfangszeiten - CFBundleShortVersionString (2.15.0) und CFBundleVersion (2.15.0.0) manuell für das Target. Da iTC auf aufsteigende Werte besteht, wird der letzte Wert bei neuen Submits - z. B. für TestFlight - erhöht, während der andere die "offizielle" Version darstellt, die ich auch im Settings-Bundle anzeige.

    Habe ich etwas verpasst und einer von Euch hat eine bessere Idee? Dann bitte her damit!

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • In diesem Zusammenhang sei auch auf die TN2420 hingewiesen

    TN2420 schrieb:

    Important: For macOS apps, build numbers must monotonically increase even across different versions. In other words, for macOS apps you cannot use the same build numbers again in different release trains. iOS apps have no such restriction and you can re-use the same build numbers again in different release trains.
    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Also bei mir klappt das, hab es als Buildphase-script, da lese ich dann die git-revision entspr. aus dem git-commit aus:

    Shell-Script

    1. # Receigen binary
    2. RECEIGEN="/Applications/Receigen.app/Contents/MacOS/Receigen"
    3. git=`sh /etc/profile; which git`
    4. appBuild=`"$git" rev-list --count HEAD`
    5. echo "Bundle version: $appBuild"
    6. # Expand information if needed
    7. EXPANDED_BUNDLE_ID=$PRODUCT_BUNDLE_IDENTIFIER
    8. EXPANDED_BUNDLE_VERSION=`eval "echo $appBuild"`
    9. # Make sure the destination directory exists
    10. mkdir -p "$DERIVED_FILES_DIR"
    11. HEADER="$DERIVED_FILES_DIR/receipt.h"
    12. # Check if the generation is needed
    13. if [ -e "$HEADER" ]; then
    14. # On iOS, check CFBundleIdentifier and CFBundleShortVersionString
    15. SKIP=`egrep -q "CFBundleIdentifier.+:.+$EXPANDED_BUNDLE_ID" "$HEADER" && egrep -q "CFBundleVersion.+:.+$EXPANDED_BUNDLE_VERSION" "$HEADER" && echo "YES"`
    16. fi
    17. # Generate the header file if needed
    18. if [ "x$SKIP" = "x" ]; then
    19. # On iOS, call Receigen with options
    20. "$RECEIGEN" --identifier "$EXPANDED_BUNDLE_ID" --version "$EXPANDED_BUNDLE_VERSION" --os ios -p 'ThePrefix' -s 'callblock' -f 'refreshreceipt' > "$HEADER"
    21. fi
    Alles anzeigen
  • Und dann noch ne Extra-Buildphase "Set build number from git"

    Shell-Script

    1. #
    2. # Set the build number to the current git commit count.
    3. # If we're using the Dev scheme, then we'll suffix the build
    4. # number with the current branch name, to make collisions
    5. # far less likely across feature branches.
    6. # Based on: http://w3facility.info/question/how-do-i-force-xcode-to-rebuild-the-info-plist-file-in-my-project-every-time-i-build-the-project/
    7. #
    8. plist="${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
    9. git=`sh /etc/profile; which git`
    10. appBuild=`"$git" rev-list --count HEAD`
    11. #gitHash=`"$git" rev-parse --short HEAD`
    12. #appVersion=`/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" "$plist"`
    13. /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $appBuild" "$plist"
    14. #/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $appVersion ($gitHash)" "$plist"
    15. echo "Updated $plist build number to $appBuild"
    Alles anzeigen
  • Markus Müller schrieb:

    Ja genau, aber das geht ja automatisiert über das Script. Schöne Grüße, Markus
    Danke nochmal, Markus!

    Ich hatte auch an diese Automatisierung gedacht, wollte aber nicht bei jedem Build eine neue .h-Datei in meinem git-Commit haben. Nicht gedacht habe ich an die Verwendung von $DERIVED_FILES_DIR.

    Mt den richtigen Stichworten lande ich dann auch auf dem passenden Artikel auf SO :D

    Dann werde ich am Wochenende mein geliebtes git-Script wiederbeleben...

    Mattes

    Edit: ... auch auf der Receigen-WebSite, Thema „Automation“ ... ich war wohl zu fixiert auf mein Problem, vielleicht auch etwas neben der Spur.
    Diese Seite bleibt aus technischen Gründen unbedruckt.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von MyMattes () aus folgendem Grund: Hinweis auf Receigen-WebSite ergänzt

  • Kurze Rückmeldung: Das schwuppt super!

    Ich habe wieder automatische CFBundleVersion und CFBundleShortVersionString, Receigen generiert sich seinen Header in einer Build-Phase vor'm Kompilieren und meine git-Commits werden nicht mit unnötigen Änderungen zugemüllt.

    Sehr schön, danke!

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.