Release 1.3.0: onboarding UX, charts paywall banner, re-engagement notifications, Crashlytics

- Crashlytics: add FirebaseCrashlytics framework + dSYM upload build phase
- Onboarding: useSampleData off by default, Add First Investment as primary CTA
- AddSourceView: contextual placeholder and footer explaining what a source is
- Charts: CompactPaywallBanner visible to free users on every visit
- Notifications: re-engagement (7d) and monthly check-in local notifications
- Paywall: decorative chart preview replacing static crown icon
- Localization: all new strings in en + es-ES
This commit is contained in:
alexandrev-tibco
2026-05-01 09:26:37 +02:00
parent 10f6d0ca20
commit 94ed4d17eb
11 changed files with 340 additions and 131 deletions
+32 -5
View File
@@ -10,9 +10,21 @@ ARCHIVE_DIR="${ARCHIVE_DIR:-$ROOT_DIR/build/appstore}"
ARCHIVE_PATH="${ARCHIVE_PATH:-$ARCHIVE_DIR/${SCHEME}.xcarchive}"
EXPORT_PATH="${EXPORT_PATH:-$ARCHIVE_DIR/export}"
EXPORT_OPTIONS_PLIST="${EXPORT_OPTIONS_PLIST:-$ARCHIVE_DIR/ExportOptions.plist}"
KEY_ID="${APPSTORE_KEY_ID:-YJLSGZGP79}"
ISSUER_ID="${APPSTORE_ISSUER_ID:-33f82bb1-0dbd-4b3f-a0ef-1a863dfd9453}"
TEAM_ID="${DEVELOPMENT_TEAM_ID:-2825Q76T7H}"
# Credenciales desde pass (GPG store). Se puede sobreescribir con variables de entorno.
_pass_or_env() {
local env_val="$1" pass_key="$2"
if [[ -n "$env_val" ]]; then
echo "$env_val"
elif command -v pass >/dev/null 2>&1; then
pass show "$pass_key" 2>/dev/null || fail "No se encontro la credencial en pass: $pass_key"
else
fail "pass no esta disponible y la variable de entorno no esta definida para: $pass_key"
fi
}
KEY_ID="$(_pass_or_env "${APPSTORE_KEY_ID:-}" appstore/api-key-id)"
ISSUER_ID="$(_pass_or_env "${APPSTORE_ISSUER_ID:-}" appstore/issuer-id)"
TEAM_ID="$(_pass_or_env "${DEVELOPMENT_TEAM_ID:-}" appstore/team-id)"
P8_PATH="${APPSTORE_P8_PATH:-}"
P8_DIR=""
@@ -22,18 +34,33 @@ fail() {
}
find_p8_file() {
# 1. Variable de entorno explícita
if [[ -n "$P8_PATH" ]]; then
[[ -f "$P8_PATH" ]] || fail "No existe el fichero APPSTORE_P8_PATH=$P8_PATH"
echo "$P8_PATH"
return
fi
# 2. Extraer de pass y escribir en fichero temporal
if command -v pass >/dev/null 2>&1 && pass show appstore/api-key-p8 &>/dev/null; then
local tmp_p8
tmp_p8="$(mktemp /tmp/AuthKey_XXXXXX.p8)"
pass show appstore/api-key-p8 > "$tmp_p8"
chmod 600 "$tmp_p8"
# Registrar para limpieza al salir
trap "rm -f '$tmp_p8'" EXIT
echo "$tmp_p8"
return
fi
# 3. Fichero por defecto en HOME
local default_path="$HOME/AuthKey_${KEY_ID}.p8"
if [[ -f "$default_path" ]]; then
echo "$default_path"
return
fi
# 4. Único .p8 en HOME
local matches=("${HOME}"/*.p8(N))
if (( ${#matches[@]} == 1 )); then
echo "${matches[1]}"
@@ -41,10 +68,10 @@ find_p8_file() {
fi
if (( ${#matches[@]} > 1 )); then
fail "Hay varios ficheros .p8 en $HOME. Define APPSTORE_P8_PATH con la ruta correcta."
fail "Hay varios ficheros .p8 en $HOME. Define APPSTORE_P8_PATH o inserta la clave en pass: appstore/api-key-p8"
fi
fail "No se encontro AuthKey_${KEY_ID}.p8 ni un unico fichero .p8 en $HOME."
fail "No se encontro la clave .p8. Insértala con: cat AuthKey.p8 | pass insert -f -e appstore/api-key-p8"
}
create_export_options() {