Root cause: a data-integrity bug, not visual. The month grid is built from
.weekOfMonth (respects Calendar.current.firstWeekday), but the weekday header
was hardcoded Sunday-first ("S M T W T F S") and the week-number label was gated
on isSunday (weekday == 1). On any non-Sunday-first locale (or when the user sets
"Start Week On" = Monday) every column was mislabeled by one and the W-number
landed on the wrong column — e.g. June 1 2026 (a Monday) appearing under "S".
Fix:
- Extract pure, testable date math into CalendarGrid (monthGrid + weekdaySymbols).
- Header now derived from firstWeekday, so it always matches the grid.
- Week-number label gated on isWeekStart (weekday == firstWeekday), not Sunday.
- Document that week numbers are locale weekOfYear (consistent with the layout),
not ISO.
- gridDays() and the year-view mini-month dedupe to CalendarGrid.
Verification:
- New KisaniCalTests target with 9 tests, all passing on simulator: exact
Sunday-first June 2026 grid, header↔grid alignment for firstWeekday 1...7,
cell date identity, month navigation (May/Jul/Feb 2026 + Feb 2028 leap +
Dec 2026→Jan 2027), and event-day bucketing (all-day, late-night, midnight-
crossing) across 4 timezones.
- Verified in the running app: header S M T W T F S, May 31 in the Sunday
column, June 1 under Monday, June 24 (Wednesday) selected.
Adds a DEBUG-only KISANI_INITIAL_TAB launch env (compiled out of Release) used
to screenshot the calendar past the sign-in gate.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
132 lines
4.5 KiB
YAML
132 lines
4.5 KiB
YAML
name: KisaniCal
|
|
options:
|
|
bundleIdPrefix: com.kutesir
|
|
deploymentTarget:
|
|
iOS: "16.0"
|
|
xcodeVersion: "15.0"
|
|
createIntermediateGroups: true
|
|
|
|
settings:
|
|
base:
|
|
DEVELOPMENT_TEAM: K8BLMMR883
|
|
MARKETING_VERSION: "2.0"
|
|
CURRENT_PROJECT_VERSION: "9"
|
|
|
|
schemes:
|
|
KisaniCal:
|
|
build:
|
|
targets:
|
|
KisaniCal: all
|
|
run:
|
|
config: Debug
|
|
test:
|
|
config: Debug
|
|
targets:
|
|
- KisaniCalTests
|
|
profile:
|
|
config: Release
|
|
analyze:
|
|
config: Debug
|
|
archive:
|
|
config: Release
|
|
|
|
targets:
|
|
KisaniCal:
|
|
type: application
|
|
platform: iOS
|
|
deploymentTarget: "16.0"
|
|
sources:
|
|
- path: KisaniCal
|
|
dependencies:
|
|
- target: KisaniCalWidgets
|
|
embed: true
|
|
# WenzaWatch is built/embedded only when the watchOS platform is installed.
|
|
# Re-enable shipping it on the Watch by uncommenting the embed below (requires
|
|
# Xcode > Settings > Components > watchOS):
|
|
# - target: WenzaWatch
|
|
# embed: true
|
|
settings:
|
|
base:
|
|
SWIFT_VERSION: 5.9
|
|
TARGETED_DEVICE_FAMILY: "1,2"
|
|
GENERATE_INFOPLIST_FILE: YES
|
|
INFOPLIST_KEY_UIApplicationSceneManifest_Generation: YES
|
|
INFOPLIST_KEY_UILaunchStoryboardName: LaunchScreen
|
|
INFOPLIST_KEY_CFBundleDisplayName: "Wenza"
|
|
INFOPLIST_KEY_UIStatusBarStyle: UIStatusBarStyleDefault
|
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad: "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"
|
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone: "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"
|
|
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
|
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME: AccentColor
|
|
INFOPLIST_KEY_NSSupportsLiveActivities: YES
|
|
CODE_SIGN_STYLE: Automatic
|
|
CODE_SIGN_ENTITLEMENTS: KisaniCal/KisaniCal.entitlements
|
|
ENABLE_PREVIEWS: YES
|
|
INFOPLIST_KEY_NSCalendarsUsageDescription: "Wenza shows your calendar events alongside tasks."
|
|
INFOPLIST_KEY_NSCalendarsFullAccessUsageDescription: "Wenza shows your calendar events alongside tasks."
|
|
INFOPLIST_KEY_NSHealthShareUsageDescription: "Wenza reads your steps, energy, heart rate, and workouts to show health stats on your dashboard."
|
|
INFOPLIST_KEY_NSHealthUpdateUsageDescription: "Wenza saves workouts you complete to the Health app."
|
|
|
|
KisaniCalTests:
|
|
type: bundle.unit-test
|
|
platform: iOS
|
|
deploymentTarget: "16.0"
|
|
sources:
|
|
- path: KisaniCalTests
|
|
dependencies:
|
|
- target: KisaniCal
|
|
settings:
|
|
base:
|
|
SWIFT_VERSION: 5.9
|
|
GENERATE_INFOPLIST_FILE: YES
|
|
|
|
KisaniCalWidgets:
|
|
type: app-extension
|
|
platform: iOS
|
|
deploymentTarget: "18.0"
|
|
sources:
|
|
- path: KisaniCalWidgets
|
|
- path: KisaniCal/Managers/AppGroup.swift
|
|
- path: KisaniCal/Managers/TaskActivityAttributes.swift
|
|
info:
|
|
path: KisaniCalWidgets/Info.plist
|
|
properties:
|
|
CFBundleDisplayName: "Wenza Widgets"
|
|
CFBundleShortVersionString: "$(MARKETING_VERSION)"
|
|
CFBundleVersion: "$(CURRENT_PROJECT_VERSION)"
|
|
NSExtension:
|
|
NSExtensionPointIdentifier: com.apple.widgetkit-extension
|
|
settings:
|
|
base:
|
|
SWIFT_VERSION: 5.9
|
|
CODE_SIGN_STYLE: Automatic
|
|
GENERATE_INFOPLIST_FILE: NO
|
|
PRODUCT_BUNDLE_IDENTIFIER: com.kutesir.KisaniCal.KisaniCalWidgets
|
|
LD_RUNPATH_SEARCH_PATHS: "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"
|
|
APPLICATION_EXTENSION_API_ONLY: YES
|
|
CODE_SIGN_ENTITLEMENTS: KisaniCalWidgets/KisaniCalWidgets.entitlements
|
|
|
|
WenzaWatch:
|
|
type: application
|
|
platform: watchOS
|
|
deploymentTarget: "10.0"
|
|
sources:
|
|
- path: WenzaWatch
|
|
info:
|
|
path: WenzaWatch/Info.plist
|
|
properties:
|
|
CFBundleDisplayName: "Wenza"
|
|
CFBundleShortVersionString: "$(MARKETING_VERSION)"
|
|
CFBundleVersion: "$(CURRENT_PROJECT_VERSION)"
|
|
WKApplication: true
|
|
WKCompanionAppBundleIdentifier: com.kutesir.KisaniCal
|
|
settings:
|
|
base:
|
|
SWIFT_VERSION: 5.9
|
|
GENERATE_INFOPLIST_FILE: NO
|
|
PRODUCT_BUNDLE_IDENTIFIER: com.kutesir.KisaniCal.watchkitapp
|
|
TARGETED_DEVICE_FAMILY: "4"
|
|
CODE_SIGN_STYLE: Automatic
|
|
CODE_SIGN_ENTITLEMENTS: WenzaWatch/WenzaWatch.entitlements
|
|
INFOPLIST_KEY_CFBundleDisplayName: "Wenza"
|