Fase 2 Duo: verificado con SDK 27.1 en el simulador real y biometria por hardware
Compila con Xcode 27.1 beta (SDK iOS 27.1) sin errores ni warnings nuevos, y
`DuoLayoutUITests` pasa en el simulador de iPhone Duo: la pantalla exterior mide
466 x 678 pt y es compact x regular, iOS 27 pone la barra de pestanas y la
toolbar en vertical en el borde derecho, el `.inspector` de Quick Update cae a
hoja como debe, Fuentes y Diario colapsan a una columna y no queda hueco al pie
donde estaba el banner de AdMob.
- DuoLayoutUITests registra el tamano de ventana en puntos y baja hasta "App
Lock" para comparar el texto del toggle con `LAContext.biometryType`: en el
Duo dice "Touch ID" (verificado en captura).
- WhatsNewView deja de llevar el icono `touchid` fijo: sale de
`AppLockService.biometryKind`, igual que los textos.
- Release notes sin emoji (TestFlight devuelve 409) en RELEASE_NOTES.md y en
fastlane/metadata/{en-US,en-GB,en-AU,en-CA,es-ES,es-MX}.
- DUO_STATUS documenta las medidas reales, por que se descartan ReservedRegion,
ArrangementView y ConcentricRectangle, y que la pantalla interior (669 x 951
pt) no se puede ejercitar: el simulador arranca plegado y no hay forma de
cambiar la pose desde linea de comandos.
No se sube version ni build: las builds de App Store no pueden ir firmadas con
un SDK beta.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F1u4K16xy7eQVtgsYNZ9Vn
This commit is contained in:
+136
-89
@@ -1,103 +1,150 @@
|
||||
# iPhone Duo — estado de la adaptación (Portfolio Journal 1.7.0)
|
||||
|
||||
Fase 1, hecha con Xcode 27.0 / SDK iOS 27.0 (sin las APIs específicas de Duo de
|
||||
Xcode 27.1). Todo lo que se describe aquí funciona con size classes estándar:
|
||||
Fase 1 hecha con Xcode 27.0 / SDK 27.0. **Fase 2 hecha con Xcode 27.1 beta
|
||||
(27A9269, SDK iOS 27.1) y el simulador real de iPhone Duo** — lo que se pudo
|
||||
verificar y lo que no está dicho con nombre y apellidos más abajo.
|
||||
|
||||
| Pantalla Duo | Size class | Cómo se comporta la app |
|
||||
|---|---|---|
|
||||
| Exterior 5.4" (vertical) | compact × regular | Igual que un iPhone: tab bar, stacks |
|
||||
| Exterior (horizontal) | compact × compact | Igual que un iPhone en horizontal |
|
||||
| Interior 7.6" (ambas orientaciones) | regular × regular | Layouts de dos columnas, sidebar/tab bar superior, inspector |
|
||||
## El dispositivo, medido (no supuesto)
|
||||
|
||||
## Qué se ha adaptado
|
||||
| Dato | Valor medido |
|
||||
|---|---|
|
||||
| Modelo | `iPhone19,4`, Touch ID (`com.apple.touch-id: true` en el perfil) |
|
||||
| Pantalla exterior | 1398 × 2034 px @3x = **466 × 678 pt** (`screenID` 1, "LCD") |
|
||||
| Pantalla interior | 2007 × 2853 px @3x = **669 × 951 pt** (`screenID` 3, "LCD-1") |
|
||||
| Size class exterior | **compact × regular** (medido: el split view colapsa y el `.inspector` sale como hoja) |
|
||||
| Pose al arrancar | **plegado**: `SIMULATOR_MAINSCREEN_*` = 1398×2034, la interior no pinta nada |
|
||||
|
||||
### Navegación (ContentView)
|
||||
- Un único `TabView` para todas las size classes. En iOS 18+ usa
|
||||
`.tabViewStyle(.sidebarAdaptable)`: tab bar en compacto, tab bar superior /
|
||||
sidebar en regular. Antes había dos jerarquías (`TabView` iPhone /
|
||||
`NavigationSplitView` iPad) y el cambio de size class las intercambiaba,
|
||||
perdiendo el estado; ahora abrir/cerrar el Duo conserva cada pestaña.
|
||||
- `@SceneStorage("selectedTab")` restaura la pestaña por escena.
|
||||
- Ningún `userInterfaceIdiom`, `UIScreen.main`, ni orientación: todo por
|
||||
`@Environment(\.horizontalSizeClass)`.
|
||||
La pantalla interior (669 pt) es **más estrecha que cualquier iPad** (el iPad mini
|
||||
son 744 pt en vertical), así que no hay ningún simulador que la imite.
|
||||
|
||||
### Escenarios regular×regular (pantalla interior)
|
||||
1. **Fuentes**: `NavigationSplitView` — lista de posiciones a la izquierda y
|
||||
detalle (rendimiento, gráfico, snapshots) a la derecha, a la vez. En
|
||||
compacto colapsa a stack; la selección es el único estado de navegación, así
|
||||
sobrevive al plegado.
|
||||
2. **Diario**: `NavigationSplitView` — lista de meses + check-in mensual inline.
|
||||
3. **Dashboard + Quick Update**: el check-in rápido se abre como `.inspector`
|
||||
(panel lateral) en ancho regular, de modo que los gráficos del dashboard
|
||||
siguen visibles mientras se teclean los valores; en compacto es un sheet.
|
||||
El dashboard usa masonry de 2/3 columnas según el ancho disponible
|
||||
(`GeometryReader`), que se recalcula al abrir/cerrar el inspector.
|
||||
4. **Gráficos**: sidebar de tipos de gráfico (248 pt) + área de gráfico a todo
|
||||
el ancho, cabecera KPI y selector de periodo segmentado. Nuevo
|
||||
`chartHeightScale` (+35 % de alto en regular) para que el ancho extra se
|
||||
traduzca en más área de trazado; las etiquetas de eje ya eran más densas en
|
||||
regular.
|
||||
5. **Bloqueo / privacidad**: `LAContext.biometryType` → "Desbloquear con
|
||||
Face ID / Touch ID / Optic ID"; icono y textos genéricos en 7 idiomas.
|
||||
## Qué se ha cerrado en la fase 2
|
||||
|
||||
### Reglas de Apple aplicadas
|
||||
- Layout por size classes (regla 1), sin `UIScreen.main` (2), sin tamaños de
|
||||
pantalla fijos (3): las columnas usan `navigationSplitViewColumnWidth(min:ideal:max:)`
|
||||
e `inspectorColumnWidth`, y el contenido `maxWidth: .infinity`.
|
||||
- Navegación nativa: `TabView` sidebarAdaptable, `NavigationSplitView`,
|
||||
`.inspector`, sheets/popovers/alerts del sistema (4, 11).
|
||||
- Safe areas: se eliminó el `ignoresSafeArea(edges: .bottom)` del contenido
|
||||
interactivo de Gráficos; solo fondos decorativos (`AppBackground`) ignoran el
|
||||
safe area (5).
|
||||
- Orientaciones: iPhone vertical + horizontal, iPad las 4; sin
|
||||
`UIRequiresFullScreen`; `UIApplicationSupportsMultipleScenes = YES` (6).
|
||||
- Biometría por `biometryType` (7).
|
||||
- Estado persistente ante redimensionado: sin intercambio de jerarquías,
|
||||
`@SceneStorage`, ViewModels en `@StateObject` que sobreviven al cambio de
|
||||
size class (9).
|
||||
- Liquid Glass: barras del sistema automáticas al compilar con SDK 27;
|
||||
`glassEffect` en las etiquetas flotantes del Diario (iOS 26+, fallback
|
||||
material).
|
||||
- **Compila con el SDK 27.1 sin un solo error ni warning nuevo** (app, widget,
|
||||
extensión Quick Update y app + complicaciones de watchOS).
|
||||
- **Verificado en el simulador de iPhone Duo de verdad**, pantalla exterior
|
||||
(466 × 678 pt), con capturas leídas una a una:
|
||||
- iOS 27 coloca la **barra de pestañas y la toolbar en vertical, pegadas al
|
||||
borde derecho**, con la barra de estado (reloj, Wi-Fi, cámara) encima en esa
|
||||
misma franja. Al contenido de la app le quedan ~360 pt de ancho. Nada se
|
||||
corta y nada se solapa con la franja del sistema: el safe area ya la aparta.
|
||||
- `.inspector` de Quick Update: en compacto se presenta como **hoja**, como
|
||||
debe. El dashboard sigue debajo.
|
||||
- Fuentes y Diario colapsan a una sola columna. La selección se conserva.
|
||||
- Gráficos usa los 360 pt completos, con el selector de periodo y el gráfico
|
||||
a lo alto.
|
||||
- **No queda hueco al pie donde estaba el banner de AdMob**: el contenido
|
||||
llega al borde inferior. No hay ni una referencia a AdMob, Firebase ni ATT
|
||||
en el proyecto (verificado por grep sobre `.swift`, `.plist` y `.pbxproj`).
|
||||
- **Biometría**: `DuoLayoutUITests` ahora baja hasta "App Lock" en Ajustes y
|
||||
**compara el texto del toggle con `LAContext.biometryType` del propio
|
||||
dispositivo**; en el Duo tiene que decir "Touch ID". La tarjeta de novedades
|
||||
ya no lleva el icono `touchid` fijo: sale de `AppLockService.biometryKind`.
|
||||
- **Release notes sin emoji** (TestFlight devuelve 409 con ellos) en
|
||||
`RELEASE_NOTES.md` y en `fastlane/metadata/{en-US,en-GB,en-AU,en-CA,es-ES,es-MX}`.
|
||||
|
||||
### Esquinas concéntricas (regla 8)
|
||||
No aplicada: ninguna tarjeta llega a sangre hasta la esquina de pantalla (todo
|
||||
va con padding dentro de `ScrollView`/`List`). Revisar en fase 2 si el
|
||||
edge-to-edge de 27.1 cambia esto.
|
||||
## APIs nuevas de 27.1: qué se adopta y qué no
|
||||
|
||||
## Qué queda para la fase 2 (Xcode 27.1)
|
||||
- `ArrangementView` / `ReservedRegion`: llegar al borde de la pantalla interior y
|
||||
respetar la región reservada (botones del sistema en Split View).
|
||||
- Probar en el simulador Duo (Device Hub) el plegado en caliente: comprobar que
|
||||
el inspector de Quick Update y las columnas de Fuentes/Diario se recomponen
|
||||
sin perder el texto tecleado.
|
||||
- Skill "App Resizability" y release notes con el edge-to-edge.
|
||||
- Traducir `fastlane/metadata/{de-DE,fr-*,it,ja,pt-*}/release_notes.txt`
|
||||
(solo en-* y es-* están actualizados).
|
||||
- Widgets: verificar tamaños en la pantalla interior cuando exista simulador.
|
||||
Las APIs existen y se han comprobado contra el SDK (compilan):
|
||||
|
||||
## Verificado (16 sep 2026, Xcode 27.0)
|
||||
- `xcodebuild build` iOS (app + widget + extensión Quick Update) y watchOS
|
||||
(app + complicaciones): sin errores ni warnings de compilador.
|
||||
- 108/108 tests unitarios en iPhone 17 Pro.
|
||||
- `DuoLayoutUITests` en iPhone 17 Pro (compacto) y iPad mini A17 Pro
|
||||
(regular×regular): tab bar / tab bar superior, Fuentes y Diario en dos
|
||||
columnas, inspector de Quick Update (abre y cierra), gráficos con sidebar,
|
||||
vertical y horizontal.
|
||||
- SwiftUI: `ReservedRegion` (`.occlusion` / `.division`, con `frame`, `margins`,
|
||||
`isActive`) vía `GeometryProxy.reservedRegions(kind:options:layoutDirectionBehavior:)`;
|
||||
`ArrangementView(primary:secondary:)` con `.arrangementViewStyle(.automatic/.split/.overlay)`;
|
||||
`View.onHingeChange(isEnabled:_:)` con `DeviceHinge.status` (`.closed`,
|
||||
`.partiallyOpen`, `.fullyOpen`) y `DeviceHinge.angle`.
|
||||
- UIKit: `UIView.reservedRegions(kind:options:)`, `UIArrangementViewController`,
|
||||
`UIHingeInteraction` / `UIHinge`.
|
||||
|
||||
**`ReservedRegion` — no se adopta.** No hay en la app ni una vista a sangre que
|
||||
llegue a una esquina o a un borde: todo va con padding dentro de `ScrollView` /
|
||||
`List`, y lo único que ignora el safe area es el fondo decorativo
|
||||
(`AppBackground`). En la pantalla exterior se ha comprobado en captura que el
|
||||
safe area ya aparta el contenido de la franja del sistema, sin tocar nada. La
|
||||
única región que aportaría algo es la `.division` del pliegue en la pantalla
|
||||
interior, y esa **no se puede ejercitar** (ver limitaciones): meter un layout
|
||||
consciente del pliegue que no se puede probar en ningún dispositivo alcanzable
|
||||
es código muerto.
|
||||
|
||||
**`ArrangementView` — no se adopta.** Es un contenedor de dos vistas
|
||||
(primaria/secundaria) que elige split u overlay. `NavigationSplitView` ya
|
||||
resuelve Fuentes y Diario **y además** aporta lo que `ArrangementView` no tiene:
|
||||
selección de lista, anchos de columna (`navigationSplitViewColumnWidth`),
|
||||
colapso a pila en compacto y barra de navegación. Cambiarlo sería perder función
|
||||
a cambio de nada. Igual en Gráficos, donde el `HStack` barra lateral + panel no
|
||||
necesita decidir entre split y overlay.
|
||||
|
||||
**`ConcentricRectangle` — no se adopta**, por lo mismo que en fase 1: no hay
|
||||
contenido a sangre que deba seguir la esquina.
|
||||
|
||||
## Qué NO se ha podido verificar (y por qué)
|
||||
|
||||
1. **La pantalla interior, entera.** El simulador del Duo arranca plegado y no
|
||||
hay forma de cambiar la pose desde la línea de comandos:
|
||||
- `simctl ui` solo ofrece `appearance`, `content_size` e `increase_contrast`
|
||||
(no hay `pose`, `fold`, `posture` ni `arrangement`).
|
||||
- No aparece nada de pose/hinge en `CoreSimulator`, en `SimulatorKit` ni en
|
||||
los frameworks de dispositivos de Xcode.
|
||||
- `simctl io … screenConfig --display=3 power on` responde "ok" pero la
|
||||
pantalla interior sigue capturando negro; `geometry 2007x2853@3` sobre la
|
||||
exterior se rechaza ("No mode found").
|
||||
Las poses parecen estar solo en el Device Hub (GUI) de Xcode.
|
||||
2. **Por tanto, tampoco**: si la interior es realmente regular × regular a 669 pt,
|
||||
ni si el `.inspector` de Quick Update se convierte ahí en overlay con scrim
|
||||
(la regresión de iOS 27 medida en Quipu aparece por debajo de ~744 pt, y 669
|
||||
está por debajo). **Queda como el riesgo número uno.**
|
||||
3. **Compacto en un iPhone con iOS 27.1**: imposible. El runtime iOS 27.1
|
||||
instalado **solo soporta el device type iPhone Duo** (`supportedDeviceTypes`
|
||||
tiene un único elemento). El iPhone 17 Pro solo se puede probar con iOS 27.0.
|
||||
4. **Rotación**: `XCUIDevice.shared.orientation = .landscapeLeft` no tiene efecto
|
||||
en el simulador del Duo — las capturas "landscape" salen idénticas a las
|
||||
verticales. No se ha podido ejercitar el horizontal en este dispositivo.
|
||||
|
||||
## Qué queda para la fase 3
|
||||
|
||||
- Con pose disponible (Device Hub, dispositivo real o un `simctl` que la exponga):
|
||||
medir la size class y el ancho reales de la pantalla interior y comprobar el
|
||||
`.inspector`. **Si sale overlay con scrim, la solución ya probada en Quipu es
|
||||
sustituirlo por una columna propia** (`HStack` dashboard + panel, con el ancho
|
||||
del panel entre 340 y 480 pt) solo cuando el ancho regular sea < 744 pt.
|
||||
- Comprobar el plegado en caliente: que el texto tecleado en Quick Update y la
|
||||
selección de Fuentes/Diario sobreviven al cambio de pantalla.
|
||||
- Widgets en la pantalla interior.
|
||||
- Traducir `fastlane/metadata/{de-DE,fr-*,it,ja,pt-*}/release_notes.txt`.
|
||||
- **Subir versión y build cuando 27.1 sea GM**: las builds de App Store no pueden
|
||||
ir firmadas con un SDK beta, así que esto es solo preparación.
|
||||
|
||||
## Cómo probarlo
|
||||
```bash
|
||||
# Build (un simulador cada vez)
|
||||
xcodebuild -project PortfolioJournal.xcodeproj -scheme PortfolioJournal \
|
||||
-destination 'platform=iOS Simulator,name=iPad mini (A17 Pro)' build
|
||||
|
||||
# Recorrido con capturas (compacto vs regular×regular)
|
||||
xcodebuild test -project PortfolioJournal.xcodeproj -scheme PortfolioJournal \
|
||||
-destination 'platform=iOS Simulator,name=iPhone 17 Pro' \
|
||||
-only-testing:PortfolioJournalUITests/DuoLayoutUITests -resultBundlePath /tmp/duo-iphone.xcresult
|
||||
xcodebuild test ... -destination 'platform=iOS Simulator,name=iPad mini (A17 Pro)' \
|
||||
-only-testing:PortfolioJournalUITests/DuoLayoutUITests -resultBundlePath /tmp/duo-ipad.xcresult
|
||||
xcrun xcresulttool export attachments --path /tmp/duo-ipad.xcresult --output-path /tmp/duo-ipad-png
|
||||
```bash
|
||||
export DEVELOPER_DIR=/Applications/Xcode-27.1.app/Contents/Developer
|
||||
SIM=$(xcrun simctl create "Duo-PJ" com.apple.CoreSimulator.SimDeviceType.iPhone-Duo \
|
||||
com.apple.CoreSimulator.SimRuntime.iOS-27-1)
|
||||
xcrun simctl boot $SIM && xcrun simctl bootstatus $SIM -b # tarda ~70 s
|
||||
|
||||
# Build y test en dos pasos: el runner de UI tests se queda sin memoria si
|
||||
# xcodebuild compila y ejecuta a la vez con varios simuladores arrancados.
|
||||
xcodebuild build-for-testing -project PortfolioJournal.xcodeproj \
|
||||
-scheme PortfolioJournal -destination "platform=iOS Simulator,id=$SIM" \
|
||||
-derivedDataPath /tmp/dd-pj
|
||||
xcodebuild test-without-building \
|
||||
-xctestrun /tmp/dd-pj/Build/Products/PortfolioJournal_iphonesimulator27.1-arm64.xctestrun \
|
||||
-destination "platform=iOS Simulator,id=$SIM" -parallel-testing-enabled NO \
|
||||
-only-testing:PortfolioJournalUITests/DuoLayoutUITests \
|
||||
-resultBundlePath /tmp/duo-pj.xcresult
|
||||
xcrun xcresulttool export attachments --path /tmp/duo-pj.xcresult --output-path /tmp/duo-pj-png
|
||||
|
||||
# Capturas sueltas, eligiendo pantalla (1 = exterior, 3 = interior):
|
||||
xcrun simctl io $SIM screenshot --display=1 /tmp/duo.png
|
||||
xcrun simctl delete $SIM
|
||||
```
|
||||
La app arranca con datos de ejemplo y sin onboarding con el argumento
|
||||
`--screenshots`. iPad mini (A17 Pro) es el simulador más parecido a la pantalla
|
||||
interior del Duo (regular×regular en ambas orientaciones).
|
||||
|
||||
`-parallel-testing-enabled NO` es obligatorio: Xcode clona el simulador para
|
||||
paralelizar y el clon del Duo no arranca en los 60 s que espera.
|
||||
|
||||
## Verificado
|
||||
|
||||
- 18-19 sep 2026, Xcode 27.1 beta, simulador iPhone Duo (iOS 27.1):
|
||||
`xcodebuild build` sin errores ni warnings; `DuoLayoutUITests` en verde
|
||||
(466 × 678 pt, pantalla exterior) con 12 capturas revisadas.
|
||||
- 16 sep 2026, Xcode 27.0: 108/108 tests unitarios en iPhone 17 Pro;
|
||||
`DuoLayoutUITests` en iPhone 17 Pro (compacto) y iPad mini A17 Pro
|
||||
(regular × regular, 744 pt).
|
||||
|
||||
@@ -36,7 +36,10 @@ enum WhatsNewCatalog {
|
||||
description: String(localized: "whats_new_170_inspector_body")
|
||||
),
|
||||
WhatsNewFeature(
|
||||
icon: "touchid",
|
||||
// The feature is "we use whatever biometry you have", so the
|
||||
// icon comes from the hardware too — touchid on an iPhone Duo,
|
||||
// faceid on a Face ID phone — instead of being hardcoded.
|
||||
icon: AppLockService.biometryKind.systemImage,
|
||||
color: .positiveGreen,
|
||||
title: String(localized: "whats_new_170_biometrics_title"),
|
||||
description: String(localized: "whats_new_170_biometrics_body")
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import XCTest
|
||||
import LocalAuthentication
|
||||
|
||||
/// Walks the adaptive layout (tab bar / sidebar, split views, inspector) and
|
||||
/// attaches a screenshot per step. Run on a compact device (iPhone) and on a
|
||||
@@ -16,6 +17,19 @@ final class DuoLayoutUITests: XCTestCase {
|
||||
add(shot)
|
||||
}
|
||||
|
||||
/// Records the window geometry in points so the run log says which canvas
|
||||
/// the layout was actually exercised on (Duo cover screen, inner screen,
|
||||
/// iPhone, iPad…) instead of leaving it to the reader to guess.
|
||||
private func recordGeometry(_ app: XCUIApplication, _ name: String) {
|
||||
let frame = app.windows.firstMatch.frame
|
||||
let text = "\(name): window \(Int(frame.width))x\(Int(frame.height)) pt"
|
||||
let note = XCTAttachment(string: text)
|
||||
note.name = name
|
||||
note.lifetime = .keepAlways
|
||||
add(note)
|
||||
print("DUO-GEOMETRY \(text)")
|
||||
}
|
||||
|
||||
/// Tab bar button on iPhone, top tab bar / sidebar row on iPad.
|
||||
private func openTab(_ app: XCUIApplication, _ title: String) {
|
||||
let tabBar = app.tabBars.firstMatch
|
||||
@@ -29,6 +43,41 @@ final class DuoLayoutUITests: XCTestCase {
|
||||
Thread.sleep(forTimeInterval: 1.5)
|
||||
}
|
||||
|
||||
/// The App Lock toggle must name the biometry the hardware actually has —
|
||||
/// the iPhone Duo ships with Touch ID, so a hardcoded "Face ID" would be
|
||||
/// wrong there. Scrolls Settings down to App Lock, attaches the screenshot
|
||||
/// and compares the label against `LAContext.biometryType` on this device.
|
||||
private func assertBiometryLabelMatchesHardware(_ app: XCUIApplication) {
|
||||
let context = LAContext()
|
||||
_ = context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil)
|
||||
let expected: String
|
||||
switch context.biometryType {
|
||||
case .faceID: expected = "Face ID"
|
||||
case .touchID: expected = "Touch ID"
|
||||
case .opticID: expected = "Optic ID"
|
||||
default: expected = ""
|
||||
}
|
||||
guard !expected.isEmpty else {
|
||||
// No biometric hardware: the generic label is correct, nothing to check.
|
||||
return
|
||||
}
|
||||
|
||||
let toggle = app.switches.containing(
|
||||
NSPredicate(format: "label CONTAINS[c] %@", expected)
|
||||
).firstMatch
|
||||
for _ in 0..<8 where !toggle.exists {
|
||||
app.swipeUp()
|
||||
Thread.sleep(forTimeInterval: 0.6)
|
||||
}
|
||||
Thread.sleep(forTimeInterval: 0.8)
|
||||
snap(app, "09b_settings_app_lock")
|
||||
XCTAssertTrue(
|
||||
toggle.exists,
|
||||
"App Lock toggle should name \(expected) on this device"
|
||||
)
|
||||
print("DUO-BIOMETRY expected \(expected), toggle found: \(toggle.exists)")
|
||||
}
|
||||
|
||||
func testAdaptiveLayoutWalkthrough() throws {
|
||||
let app = XCUIApplication()
|
||||
app.launchArguments = ["--screenshots"]
|
||||
@@ -42,6 +91,7 @@ final class DuoLayoutUITests: XCTestCase {
|
||||
Thread.sleep(forTimeInterval: 1.0)
|
||||
}
|
||||
|
||||
recordGeometry(app, "00_window")
|
||||
snap(app, "01_dashboard")
|
||||
|
||||
// Quick Update: inspector column in regular width, sheet in compact.
|
||||
@@ -91,6 +141,7 @@ final class DuoLayoutUITests: XCTestCase {
|
||||
|
||||
openTab(app, "Settings")
|
||||
snap(app, "09_settings")
|
||||
assertBiometryLabelMatchesHardware(app)
|
||||
|
||||
// Landscape: the Duo inner screen is regular×regular in both orientations.
|
||||
XCUIDevice.shared.orientation = .landscapeLeft
|
||||
|
||||
+21
-5
@@ -1,20 +1,36 @@
|
||||
# Release notes — 1.7.0 (build 89)
|
||||
|
||||
Sin emojis: App Store Connect / TestFlight rechazan las notas con emoji (HTTP 409).
|
||||
|
||||
## en-US
|
||||
|
||||
📱 Ready for iPhone Duo: on the inner screen, Sources and Journal show the list and the detail side by side, Charts gain a sidebar with taller, wider plots, and your place is kept when you open or close the phone. Quick Update opens in a side panel next to your dashboard.
|
||||
Ready for iPhone Duo. On the outer screen the app keeps the phone layout with the
|
||||
new iOS 27 side tab bar; on the inner screen Sources and Journal show the list and
|
||||
the detail side by side, Charts gain a sidebar with taller, wider plots, and your
|
||||
place is kept when you open or close the phone. Quick Update opens in a side panel
|
||||
next to your dashboard where there is room, and as a sheet when there is not.
|
||||
• Built for iOS 27 with the new Liquid Glass tab bar and toolbars.
|
||||
• Face ID, Touch ID or Optic ID: App Lock and balance privacy now use whichever biometrics your device has.
|
||||
• Face ID, Touch ID or Optic ID: App Lock and balance privacy use whichever
|
||||
biometrics your device has, with the matching name and icon.
|
||||
• No ads, no analytics, no tracking SDKs: they are gone from the app.
|
||||
• Layout adapts to any window size, Split View and Stage Manager.
|
||||
• Bug fixes and performance improvements.
|
||||
|
||||
## es-ES
|
||||
|
||||
📱 Preparada para iPhone Duo: en la pantalla interior, Fuentes y Diario muestran lista y detalle a la vez, Gráficos gana una barra lateral con gráficos más altos y anchos, y no pierdes el sitio al abrir o cerrar el teléfono. La actualización rápida se abre en un panel lateral junto al panel principal.
|
||||
Preparada para iPhone Duo. En la pantalla exterior mantiene el layout de teléfono
|
||||
con la nueva barra de pestañas lateral de iOS 27; en la interior, Fuentes y Diario
|
||||
muestran lista y detalle a la vez, Gráficos gana una barra lateral con gráficos más
|
||||
altos y anchos, y no pierdes el sitio al abrir o cerrar el teléfono. La actualización
|
||||
rápida se abre en un panel lateral junto al panel principal cuando hay sitio, y como
|
||||
hoja cuando no lo hay.
|
||||
• Compilada para iOS 27 con la nueva barra de pestañas y toolbars Liquid Glass.
|
||||
• Face ID, Touch ID u Optic ID: el bloqueo de la app y la privacidad de saldos usan la biometría que tenga tu dispositivo.
|
||||
• Face ID, Touch ID u Optic ID: el bloqueo de la app y la privacidad de saldos usan
|
||||
la biometría que tenga tu dispositivo, con su nombre y su icono.
|
||||
• Sin anuncios, sin analíticas y sin SDK de rastreo: se han eliminado de la app.
|
||||
• La interfaz se adapta a cualquier tamaño de ventana, Split View y Stage Manager.
|
||||
• Correcciones de errores y mejoras de rendimiento.
|
||||
|
||||
Los ficheros que sube fastlane están en `fastlane/metadata/<locale>/release_notes.txt`
|
||||
(en-US, en-GB, en-AU, en-CA, es-ES, es-MX actualizados; de-DE, fr-*, it, ja, pt-* pendientes de traducir).
|
||||
(en-US, en-GB, en-AU, en-CA, es-ES, es-MX actualizados; de-DE, fr-*, it, ja, pt-*
|
||||
pendientes de traducir).
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
📱 Ready for iPhone Duo: on the inner screen, Sources and Journal show the list and the detail side by side, Charts gain a sidebar with taller, wider plots, and your place is kept when you open or close the phone. Quick Update opens in a side panel next to your dashboard.
|
||||
Ready for iPhone Duo. On the outer screen the app keeps the phone layout with the new iOS 27 side tab bar; on the inner screen Sources and Journal show the list and the detail side by side, Charts gain a sidebar with taller, wider plots, and your place is kept when you open or close the phone. Quick Update opens in a side panel next to your dashboard where there is room, and as a sheet when there is not.
|
||||
• Built for iOS 27 with the new Liquid Glass tab bar and toolbars.
|
||||
• Face ID, Touch ID or Optic ID: App Lock and balance privacy now use whichever biometrics your device has.
|
||||
• Face ID, Touch ID or Optic ID: App Lock and balance privacy use whichever biometrics your device has, with the matching name and icon.
|
||||
• No ads, no analytics, no tracking SDKs: they are gone from the app.
|
||||
• Layout adapts to any window size, Split View and Stage Manager.
|
||||
• Bug fixes and performance improvements.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
📱 Ready for iPhone Duo: on the inner screen, Sources and Journal show the list and the detail side by side, Charts gain a sidebar with taller, wider plots, and your place is kept when you open or close the phone. Quick Update opens in a side panel next to your dashboard.
|
||||
Ready for iPhone Duo. On the outer screen the app keeps the phone layout with the new iOS 27 side tab bar; on the inner screen Sources and Journal show the list and the detail side by side, Charts gain a sidebar with taller, wider plots, and your place is kept when you open or close the phone. Quick Update opens in a side panel next to your dashboard where there is room, and as a sheet when there is not.
|
||||
• Built for iOS 27 with the new Liquid Glass tab bar and toolbars.
|
||||
• Face ID, Touch ID or Optic ID: App Lock and balance privacy now use whichever biometrics your device has.
|
||||
• Face ID, Touch ID or Optic ID: App Lock and balance privacy use whichever biometrics your device has, with the matching name and icon.
|
||||
• No ads, no analytics, no tracking SDKs: they are gone from the app.
|
||||
• Layout adapts to any window size, Split View and Stage Manager.
|
||||
• Bug fixes and performance improvements.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
📱 Ready for iPhone Duo: on the inner screen, Sources and Journal show the list and the detail side by side, Charts gain a sidebar with taller, wider plots, and your place is kept when you open or close the phone. Quick Update opens in a side panel next to your dashboard.
|
||||
Ready for iPhone Duo. On the outer screen the app keeps the phone layout with the new iOS 27 side tab bar; on the inner screen Sources and Journal show the list and the detail side by side, Charts gain a sidebar with taller, wider plots, and your place is kept when you open or close the phone. Quick Update opens in a side panel next to your dashboard where there is room, and as a sheet when there is not.
|
||||
• Built for iOS 27 with the new Liquid Glass tab bar and toolbars.
|
||||
• Face ID, Touch ID or Optic ID: App Lock and balance privacy now use whichever biometrics your device has.
|
||||
• Face ID, Touch ID or Optic ID: App Lock and balance privacy use whichever biometrics your device has, with the matching name and icon.
|
||||
• No ads, no analytics, no tracking SDKs: they are gone from the app.
|
||||
• Layout adapts to any window size, Split View and Stage Manager.
|
||||
• Bug fixes and performance improvements.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
📱 Ready for iPhone Duo: on the inner screen, Sources and Journal show the list and the detail side by side, Charts gain a sidebar with taller, wider plots, and your place is kept when you open or close the phone. Quick Update opens in a side panel next to your dashboard.
|
||||
Ready for iPhone Duo. On the outer screen the app keeps the phone layout with the new iOS 27 side tab bar; on the inner screen Sources and Journal show the list and the detail side by side, Charts gain a sidebar with taller, wider plots, and your place is kept when you open or close the phone. Quick Update opens in a side panel next to your dashboard where there is room, and as a sheet when there is not.
|
||||
• Built for iOS 27 with the new Liquid Glass tab bar and toolbars.
|
||||
• Face ID, Touch ID or Optic ID: App Lock and balance privacy now use whichever biometrics your device has.
|
||||
• Face ID, Touch ID or Optic ID: App Lock and balance privacy use whichever biometrics your device has, with the matching name and icon.
|
||||
• No ads, no analytics, no tracking SDKs: they are gone from the app.
|
||||
• Layout adapts to any window size, Split View and Stage Manager.
|
||||
• Bug fixes and performance improvements.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
📱 Preparada para iPhone Duo: en la pantalla interior, Fuentes y Diario muestran lista y detalle a la vez, Gráficos gana una barra lateral con gráficos más altos y anchos, y no pierdes el sitio al abrir o cerrar el teléfono. La actualización rápida se abre en un panel lateral junto al panel principal.
|
||||
Preparada para iPhone Duo. En la pantalla exterior mantiene el layout de teléfono con la nueva barra de pestañas lateral de iOS 27; en la interior, Fuentes y Diario muestran lista y detalle a la vez, Gráficos gana una barra lateral con gráficos más altos y anchos, y no pierdes el sitio al abrir o cerrar el teléfono. La actualización rápida se abre en un panel lateral junto al panel principal cuando hay sitio, y como hoja cuando no lo hay.
|
||||
• Compilada para iOS 27 con la nueva barra de pestañas y toolbars Liquid Glass.
|
||||
• Face ID, Touch ID u Optic ID: el bloqueo de la app y la privacidad de saldos usan la biometría que tenga tu dispositivo.
|
||||
• Face ID, Touch ID u Optic ID: el bloqueo de la app y la privacidad de saldos usan la biometría que tenga tu dispositivo, con su nombre y su icono.
|
||||
• Sin anuncios, sin analíticas y sin SDK de rastreo: se han eliminado de la app.
|
||||
• La interfaz se adapta a cualquier tamaño de ventana, Split View y Stage Manager.
|
||||
• Correcciones de errores y mejoras de rendimiento.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
📱 Preparada para iPhone Duo: en la pantalla interior, Fuentes y Diario muestran lista y detalle a la vez, Gráficos gana una barra lateral con gráficos más altos y anchos, y no pierdes el sitio al abrir o cerrar el teléfono. La actualización rápida se abre en un panel lateral junto al panel principal.
|
||||
Preparada para iPhone Duo. En la pantalla exterior mantiene el layout de teléfono con la nueva barra de pestañas lateral de iOS 27; en la interior, Fuentes y Diario muestran lista y detalle a la vez, Gráficos gana una barra lateral con gráficos más altos y anchos, y no pierdes el sitio al abrir o cerrar el teléfono. La actualización rápida se abre en un panel lateral junto al panel principal cuando hay sitio, y como hoja cuando no lo hay.
|
||||
• Compilada para iOS 27 con la nueva barra de pestañas y toolbars Liquid Glass.
|
||||
• Face ID, Touch ID u Optic ID: el bloqueo de la app y la privacidad de saldos usan la biometría que tenga tu dispositivo.
|
||||
• Face ID, Touch ID u Optic ID: el bloqueo de la app y la privacidad de saldos usan la biometría que tenga tu dispositivo, con su nombre y su icono.
|
||||
• Sin anuncios, sin analíticas y sin SDK de rastreo: se han eliminado de la app.
|
||||
• La interfaz se adapta a cualquier tamaño de ventana, Split View y Stage Manager.
|
||||
• Correcciones de errores y mejoras de rendimiento.
|
||||
|
||||
Reference in New Issue
Block a user