cards-native/project.yml
Till JS 505aa9db19 feat(study): Typing-Karten + Levenshtein-Match-Logik
CardRenderer für typing ist nicht mehr Placeholder. Web-Vorbild:
TypingView.svelte + cards-domain/typing.ts.

Typing.swift (Sources/Core/Domain/):
- check(input:answer:aliases:) → TypingMatch (correct/close/wrong)
- Normalisierung: trim + lowercase + NFD-Decomp + Combining-Marks
  strippen (Diakritika: ä → a)
- Aliases-Support (Komma-getrennt aus card.fields["aliases"])
- Levenshtein-Threshold max(1, floor(len * 0.2)) → "close"

TypingCardView (Features/Study/):
- TextField mit Auto-Focus 0.15s nach onAppear, Return = Submit
- Submit-Button mit Return-Symbol + primary background
- Nach Submit: Badge (✓ Richtig / ≈ Fast / ✗ Falsch) + User-
  Eingabe in „…" Quotes + Divider + erwartete Antwort
- Haptic-Feedback: heavy bei correct, light bei close/wrong
- Reset on card.id change

TypingTests: 8 Tests für check() — exact, case+whitespace,
NFD-Umlauts, aliases, Levenshtein-close (Berln → Berlin),
empty-input, sowie Levenshtein-Helper-Sanity.

Build 8 → 9. 43 Tests grün (war 35).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 17:39:39 +02:00

204 lines
6.3 KiB
YAML

name: CardsNative
options:
bundleIdPrefix: ev.mana
createIntermediateGroups: true
xcodeVersion: "16.0"
deploymentTarget:
iOS: "18.0"
macOS: "15.0"
developmentLanguage: de
groupSortPosition: top
generateEmptyDirectories: true
packages:
ManaSwiftCore:
path: ../mana-swift-core
settings:
base:
SWIFT_VERSION: "6.0"
SWIFT_STRICT_CONCURRENCY: complete
CURRENT_PROJECT_VERSION: "1"
MARKETING_VERSION: "0.1.0"
GENERATE_INFOPLIST_FILE: "NO"
ENABLE_USER_SCRIPT_SANDBOXING: "YES"
DEAD_CODE_STRIPPING: "YES"
CLANG_ENABLE_MODULES: "YES"
# mana e.V. Apple-Developer-Team-ID. Muss matchen mit dem AASA-
# Eintrag auf https://cardecky.mana.how/.well-known/apple-app-site-association
# (siehe cards/infrastructure/docker-compose.production.yml).
DEVELOPMENT_TEAM: QP3GLU8PH3
targets:
CardsNative:
type: application
supportedDestinations: [iOS, macOS]
dependencies:
- package: ManaSwiftCore
product: ManaCore
- package: ManaSwiftCore
product: ManaTokens
- target: CardsWidgetExtension
embed: true
- target: CardsShareExtension
embed: true
sources:
- path: Sources/App
- path: Sources/Features
- path: Sources/Core
- path: Sources/Resources
excludes:
- "Info.plist"
- "CardsNative.entitlements"
info:
path: Sources/Resources/Info.plist
properties:
CFBundleShortVersionString: "0.1.0"
CFBundleVersion: "9"
CFBundleDevelopmentRegion: de
CFBundleDisplayName: Cardecky
LSApplicationCategoryType: "public.app-category.education"
UILaunchScreen: {}
UISupportedInterfaceOrientations:
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
UISupportedInterfaceOrientations~ipad:
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationPortraitUpsideDown
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
CFBundleURLTypes:
- CFBundleURLName: ev.mana.cardecky
CFBundleURLSchemes:
- cards
NSUserActivityTypes:
- NSUserActivityTypeBrowsingWeb
NSPhotoLibraryUsageDescription: "Cardecky greift auf deine Fotos zu, damit du Bilder zu Image-Occlusion-Karten hinzufügen kannst."
ITSAppUsesNonExemptEncryption: false
entitlements:
path: Sources/Resources/CardsNative.entitlements
properties:
com.apple.security.app-sandbox: true
com.apple.security.network.client: true
com.apple.security.files.user-selected.read-write: true
keychain-access-groups:
- $(AppIdentifierPrefix)ev.mana.cardecky
com.apple.developer.associated-domains:
- applinks:cardecky.mana.how
com.apple.security.application-groups:
- group.ev.mana.cardecky
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: ev.mana.cardecky
CODE_SIGN_STYLE: Automatic
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME: AccentColor
ENABLE_PREVIEWS: "YES"
CardsShareExtension:
type: app-extension
supportedDestinations: [iOS]
sources:
- path: ShareExtension
excludes:
- "Resources/Info.plist"
- "Resources/CardsShareExtension.entitlements"
- path: Sources/Core/Sync/PendingShareStore.swift
info:
path: ShareExtension/Resources/Info.plist
properties:
CFBundleDisplayName: Als Karte speichern
CFBundleShortVersionString: "0.1.0"
CFBundleVersion: "9"
NSExtension:
NSExtensionPointIdentifier: com.apple.share-services
NSExtensionPrincipalClass: $(PRODUCT_MODULE_NAME).ShareViewController
NSExtensionAttributes:
NSExtensionActivationRule:
NSExtensionActivationSupportsText: true
NSExtensionActivationSupportsWebURLWithMaxCount: 1
entitlements:
path: ShareExtension/Resources/CardsShareExtension.entitlements
properties:
com.apple.security.application-groups:
- group.ev.mana.cardecky
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: ev.mana.cardecky.share
CODE_SIGN_STYLE: Automatic
SKIP_INSTALL: "YES"
CardsWidgetExtension:
type: app-extension
supportedDestinations: [iOS]
sources:
- path: Widgets/CardsWidget
excludes:
- "Resources/Info.plist"
- "Resources/CardsWidgetExtension.entitlements"
- path: Sources/Core/Sync/WidgetSnapshot.swift
info:
path: Widgets/CardsWidget/Resources/Info.plist
properties:
CFBundleDisplayName: Cardecky Widget
CFBundleShortVersionString: "0.1.0"
CFBundleVersion: "9"
NSExtension:
NSExtensionPointIdentifier: com.apple.widgetkit-extension
entitlements:
path: Widgets/CardsWidget/Resources/CardsWidgetExtension.entitlements
properties:
com.apple.security.application-groups:
- group.ev.mana.cardecky
dependencies:
- sdk: WidgetKit.framework
- sdk: SwiftUI.framework
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: ev.mana.cardecky.widget
CODE_SIGN_STYLE: Automatic
SKIP_INSTALL: "YES"
INFOPLIST_KEY_CFBundleDisplayName: Cardecky Widget
CardsNativeTests:
type: bundle.unit-test
supportedDestinations: [iOS, macOS]
sources:
- Tests/UnitTests
dependencies:
- target: CardsNative
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: ev.mana.cardecky.tests
GENERATE_INFOPLIST_FILE: "YES"
CardsNativeUITests:
type: bundle.ui-testing
supportedDestinations: [iOS, macOS]
sources:
- Tests/UITests
dependencies:
- target: CardsNative
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: ev.mana.cardecky.uitests
GENERATE_INFOPLIST_FILE: "YES"
schemes:
CardsNative:
build:
targets:
CardsNative: all
CardsNativeTests: [test]
CardsNativeUITests: [test]
test:
targets:
- CardsNativeTests
- CardsNativeUITests
gatherCoverageData: false
run:
config: Debug
archive:
config: Release