Add Apple platform MVP targets
Seto Elkahfi committed
May 15, 2026 at 11:52 UTC
93028c7a18373061eac1989654167991443df206
36 files changed
+1012
-48
.github/workflows/ci.yml
+50
@@ -58,3 +58,53 @@ jobs:
58
-scheme 'Klepon Mac' \
59
-destination 'platform=macOS' \
60
CODE_SIGNING_ALLOWED=NO
61
+
62
+ tvos-build:
63
+ name: tvOS app build
64
+ runs-on: macos-26
65
+
66
+ steps:
67
+ - name: Checkout
68
+ uses: actions/checkout@v6
69
+
70
+ - name: Install XcodeGen
71
+ run: brew install xcodegen
72
+
73
+ - name: Generate project
74
+ run: xcodegen generate
75
+
76
+ - name: Resolve Swift packages
77
+ run: xcodebuild -project Klepon.xcodeproj -scheme 'Klepon TV' -resolvePackageDependencies
78
+
79
+ - name: Build tvOS app
80
+ run: |
81
+ xcodebuild build \
82
+ -project Klepon.xcodeproj \
83
+ -scheme 'Klepon TV' \
84
+ -destination 'generic/platform=tvOS Simulator' \
85
+ CODE_SIGNING_ALLOWED=NO
86
+
87
+ visionos-build:
88
+ name: visionOS app build
89
+ runs-on: macos-26
90
+
91
+ steps:
92
+ - name: Checkout
93
+ uses: actions/checkout@v6
94
+
95
+ - name: Install XcodeGen
96
+ run: brew install xcodegen
97
+
98
+ - name: Generate project
99
+ run: xcodegen generate
100
+
101
+ - name: Resolve Swift packages
102
+ run: xcodebuild -project Klepon.xcodeproj -scheme 'Klepon Vision' -resolvePackageDependencies
103
+
104
+ - name: Build visionOS app
105
+ run: |
106
+ xcodebuild build \
107
+ -project Klepon.xcodeproj \
108
+ -scheme 'Klepon Vision' \
109
+ -destination 'generic/platform=visionOS Simulator' \
110
+ CODE_SIGNING_ALLOWED=NO
.gitignore
+1
@@ -28,6 +28,7 @@ project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
28
# Xcode build artifacts
29
build/
30
DerivedData/
31
+.worktrees/
32
*.moved-aside
33
*.xccheckout
34
*.xcscmblueprint
Klepon.xcodeproj/project.pbxproj
+406
@@ -10,78 +10,145 @@
10
019B658F26ABE2706231EC9E /* GuideEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0A0935AE4B398B281758834 /* GuideEntry.swift */; };
11
032AFB30CAB4E8A31CDC897D /* SearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7E886BAB66E828950DBED52 /* SearchView.swift */; };
12
03D16A2386EB68FED8D92D52 /* GuideEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0A0935AE4B398B281758834 /* GuideEntry.swift */; };
13
+ 0481C8A85FED1E35C3734816 /* AppRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C82874C90A5FAA32D1B52EB7 /* AppRootView.swift */; };
14
05BF0404B7030EDCD3D8C357 /* GuideArtworkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F2850226B4B05FF758C1F93 /* GuideArtworkView.swift */; };
15
0709F0B92923D97F6859275A /* SearchService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6235AD6792F25476E2A508F0 /* SearchService.swift */; };
16
0977CD6BFFDBDBE3B7795924 /* collections.json in Resources */ = {isa = PBXBuildFile; fileRef = 1FDDB0F88FF430ABD679AD89 /* collections.json */; };
17
+ 0B94C64018A573AD679106E5 /* KleponCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 868C58098969278A542893F3 /* KleponCard.swift */; };
18
0CE2632DF6FB02163D55BB65 /* Klepon Watch.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 9E76510CC840CE068B0FC381 /* Klepon Watch.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
19
0D685E35EE50C926DC6FBE4C /* KleponChip.swift in Sources */ = {isa = PBXBuildFile; fileRef = B83C4F3C8688072191AA16C6 /* KleponChip.swift */; };
20
+ 0E350E68B43067698FE3B05C /* KleponChip.swift in Sources */ = {isa = PBXBuildFile; fileRef = B83C4F3C8688072191AA16C6 /* KleponChip.swift */; };
21
0E69E79C5FADF1633FE3D63F /* KleponColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C675ABBBA25BBA25A8DE29BE /* KleponColor.swift */; };
22
14B7CE6E6A0EB12B709F7B55 /* KleponTypography.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD520C870387E82E9A1533C2 /* KleponTypography.swift */; };
23
+ 14C796CE6777B6013910831C /* SavedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AA2E425D5454602F78D628 /* SavedView.swift */; };
24
+ 16330914DF2EE212C91BC0CA /* KleponCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 868C58098969278A542893F3 /* KleponCard.swift */; };
25
1704DDB60B1E23057C0E1094 /* GuideAnswerService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3719031080B59898133810F7 /* GuideAnswerService.swift */; };
26
1879460ECC35F3386E8E6109 /* KleponChip.swift in Sources */ = {isa = PBXBuildFile; fileRef = B83C4F3C8688072191AA16C6 /* KleponChip.swift */; };
27
19E282A6347C588E17778195 /* DiscoverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4545DC84863788D55B94D31A /* DiscoverView.swift */; };
28
+ 1C2B6971843620B876F5B0C3 /* SavedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AA2E425D5454602F78D628 /* SavedView.swift */; };
29
+ 1E042510F7F75D392A4AC6E7 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AF291E9C2E66209377138E6 /* AppState.swift */; };
30
1E7AAEA8007BFE4ED6FE4892 /* WatchContentLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C77AF5EB4B17D087FA522F6 /* WatchContentLoader.swift */; };
31
1F95A454A641C829BD304A89 /* GuideCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17C0DB3BD620AD9F55B7631 /* GuideCollection.swift */; };
32
1FF490E985C31BB08DA29AFF /* guide_entries.json in Resources */ = {isa = PBXBuildFile; fileRef = 248F359109A08A60F792C42D /* guide_entries.json */; };
33
200AE94E7E7E73B5C83869DD /* FavoritesStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BC0C4C22A5134DB058E41F4 /* FavoritesStore.swift */; };
34
+ 20CDEBB4B6C8AAE007854102 /* ContentRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2891A1AFBB59928FC5B1E66 /* ContentRepository.swift */; };
35
215C4D8A2B2ABF2C3C11C163 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8870F09A11EA6D3F0108DA4D /* SystemConfiguration.framework */; };
36
23E22EC56BE48A20BD1229F7 /* AnswerCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = B02B0EA4B8BA09604D62A62B /* AnswerCard.swift */; };
37
+ 26FA5D01FED96591E78A2293 /* AskSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC6E7DC56DD8E1459EFC892 /* AskSheetView.swift */; };
38
2AB57009245E1BABD1156AFA /* GuideDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7541983FF7CE190C0663294D /* GuideDetailView.swift */; };
39
2AD05B0B7ED109134F013862 /* EmptyStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85E7B5E3D9A1906C2FED3032 /* EmptyStateView.swift */; };
40
2F3047F5078C4526133CB848 /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13418896CA28250CEEE7592E /* OnboardingView.swift */; };
41
+ 2F74C3B8D4A1A38DEF50E39B /* AskSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC6E7DC56DD8E1459EFC892 /* AskSheetView.swift */; };
42
3349FB46691C944112401D6E /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42E152344B39D1D77F1B3943 /* SettingsView.swift */; };
43
+ 3568D735D790330031DCF8F9 /* SectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC438ECC335175B18778C682 /* SectionHeader.swift */; };
44
35B5508906432B3EFE26F4FF /* PlatformViewSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51D6F97615398D511673B98 /* PlatformViewSupport.swift */; };
45
35D43509610D0E2CB3DBD2BB /* testEmptyStateView.saved-empty-state.png in Resources */ = {isa = PBXBuildFile; fileRef = 943670F01925DE3065B92636 /* testEmptyStateView.saved-empty-state.png */; };
46
+ 367BECAC66674A040D99C0DF /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13418896CA28250CEEE7592E /* OnboardingView.swift */; };
47
36AA193A3B7EF7CB25B6E0BE /* KleponWatchApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EFBF98118F066D3C7FA14B2 /* KleponWatchApp.swift */; };
48
37A723A15D19B7DE3DD92B25 /* PlatformViewSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51D6F97615398D511673B98 /* PlatformViewSupport.swift */; };
49
37BD5B2A275426143819B70D /* OndeGuideEngine.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0D53A5F9D5897E15506C20 /* OndeGuideEngine.swift */; };
50
+ 387EE903EFA0D820C646B4DB /* GuideArtworkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F2850226B4B05FF758C1F93 /* GuideArtworkView.swift */; };
51
3A6F67743964C4D04893C321 /* RecentlyViewedStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = E45070309D2C7058BAA44CD2 /* RecentlyViewedStore.swift */; };
52
+ 3C4C5EEBF766D6E8A5D240DA /* PlatformViewSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51D6F97615398D511673B98 /* PlatformViewSupport.swift */; };
53
+ 3EB900CB86D2B32F8DAB434D /* GuideAnswerService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3719031080B59898133810F7 /* GuideAnswerService.swift */; };
54
3F999E04650931C2019BDA17 /* KleponColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C675ABBBA25BBA25A8DE29BE /* KleponColor.swift */; };
55
41F8E173B82809AF87E1B297 /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13418896CA28250CEEE7592E /* OnboardingView.swift */; };
56
43ABAA3C08695B7C8FEE7324 /* KleponMetadataRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7E1C50BFBE2EF5F37941590 /* KleponMetadataRow.swift */; };
57
4609C70D9FB74C55B9DBE832 /* KleponActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52DD909BB2EF68103CB46EDA /* KleponActionButton.swift */; };
58
478FFEBDAA7729189B429A6D /* SearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7E886BAB66E828950DBED52 /* SearchView.swift */; };
59
47B632AF6BF3E25AF628CC01 /* Onde in Frameworks */ = {isa = PBXBuildFile; productRef = 35BDA28E3F43D5441C5FE932 /* Onde */; };
60
+ 4B6E0CF8EAB6FF1D0160E3E6 /* KleponColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C675ABBBA25BBA25A8DE29BE /* KleponColor.swift */; };
61
4D63E231AC9630B2C225DF22 /* WatchHomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDBB4F5D4C98D036AC52E193 /* WatchHomeView.swift */; };
62
5692BBCE950885C5C1193DDF /* collections.json in Resources */ = {isa = PBXBuildFile; fileRef = 1FDDB0F88FF430ABD679AD89 /* collections.json */; };
63
5808C4539EBB98D822BDE99F /* KleponActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52DD909BB2EF68103CB46EDA /* KleponActionButton.swift */; };
64
+ 587F0BB61966B2BB048013DE /* KleponChip.swift in Sources */ = {isa = PBXBuildFile; fileRef = B83C4F3C8688072191AA16C6 /* KleponChip.swift */; };
65
+ 5C3590F8B1A8255C5E175A03 /* PlatformViewSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51D6F97615398D511673B98 /* PlatformViewSupport.swift */; };
66
+ 5D3BDDCB5CA8A8DC32E8ABEA /* Onde in Frameworks */ = {isa = PBXBuildFile; productRef = CECDF5959E6652B49DCF1E18 /* Onde */; };
67
+ 6117CD728CC7FF8D6EB0A8C8 /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13418896CA28250CEEE7592E /* OnboardingView.swift */; };
68
67368394088AA3045EBA14A5 /* OndeEnvironmentBootstrap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B499D3BF7AC80D31907D87F /* OndeEnvironmentBootstrap.swift */; };
69
+ 68479892D13825C6C9977DF9 /* FavoritesStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BC0C4C22A5134DB058E41F4 /* FavoritesStore.swift */; };
70
687418866BCC5554A0F4BFDC /* AnswerCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = B02B0EA4B8BA09604D62A62B /* AnswerCard.swift */; };
71
+ 6B7AE8B1C6D3AD6F973F5757 /* EmptyStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85E7B5E3D9A1906C2FED3032 /* EmptyStateView.swift */; };
72
+ 6FCE6EBC39C7F229A5F52745 /* OndeEnvironmentBootstrap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B499D3BF7AC80D31907D87F /* OndeEnvironmentBootstrap.swift */; };
73
72A88C81BE80344130E0EC0C /* GuideAnswerService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3719031080B59898133810F7 /* GuideAnswerService.swift */; };
74
+ 74A9016453B9820FC486B014 /* SearchService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6235AD6792F25476E2A508F0 /* SearchService.swift */; };
75
+ 76EE3B0D899987557B6741DF /* collections.json in Resources */ = {isa = PBXBuildFile; fileRef = 1FDDB0F88FF430ABD679AD89 /* collections.json */; };
76
+ 78142FDCFE7EF00A3D81A067 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42E152344B39D1D77F1B3943 /* SettingsView.swift */; };
77
+ 7A9B7E0858E7095E18EC7AC6 /* KleponApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEDE2A1E73EB15970A17A894 /* KleponApp.swift */; };
78
7C90532B70C1C4840E49A92B /* GuideDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7541983FF7CE190C0663294D /* GuideDetailView.swift */; };
79
7F1E744AAE60BF1FB132D66C /* KleponCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 868C58098969278A542893F3 /* KleponCard.swift */; };
80
+ 7F726FA99DBDC0155E99E098 /* SectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC438ECC335175B18778C682 /* SectionHeader.swift */; };
81
+ 8189E2DF13801C2B7162AD45 /* AnswerCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = B02B0EA4B8BA09604D62A62B /* AnswerCard.swift */; };
82
+ 819489D60D833AE2AD9185A6 /* RecentSearchStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 643D52BCEDF66CC8FE8A1234 /* RecentSearchStore.swift */; };
83
8401F9C0FA140DC2CF8BA248 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AF291E9C2E66209377138E6 /* AppState.swift */; };
84
+ 841F3B272D0FD82365DE48BD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AF79D8DD27B9CA485140C934 /* Assets.xcassets */; };
85
+ 854C10AE603DCCC521D93BC2 /* ContentRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2891A1AFBB59928FC5B1E66 /* ContentRepository.swift */; };
86
+ 85FC2D60857424B39654DE08 /* RecentSearchStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 643D52BCEDF66CC8FE8A1234 /* RecentSearchStore.swift */; };
87
+ 87E259162B03252EA23A32CF /* GuideEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0A0935AE4B398B281758834 /* GuideEntry.swift */; };
88
8804CFBAD707E1FED63BF214 /* SearchService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6235AD6792F25476E2A508F0 /* SearchService.swift */; };
89
88984B6A8AA504AD200A7F39 /* collections.json in Resources */ = {isa = PBXBuildFile; fileRef = 1FDDB0F88FF430ABD679AD89 /* collections.json */; };
90
889CBF2AF84AABF8012EE737 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AF79D8DD27B9CA485140C934 /* Assets.xcassets */; };
91
895B5369E9CF1E1B26CDF40E /* KleponTypography.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD520C870387E82E9A1533C2 /* KleponTypography.swift */; };
92
+ 8C6D6EC32870A45E021BF3EB /* KleponMetadataRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7E1C50BFBE2EF5F37941590 /* KleponMetadataRow.swift */; };
93
8EBCC9FA074785FDD82B02E5 /* KleponApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEDE2A1E73EB15970A17A894 /* KleponApp.swift */; };
94
+ 906E12C00728B15B676A23DB /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AF291E9C2E66209377138E6 /* AppState.swift */; };
95
910A84B3F28B3F79871FF60E /* SectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC438ECC335175B18778C682 /* SectionHeader.swift */; };
96
926AB007EBCD5315EE77E2A6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AF79D8DD27B9CA485140C934 /* Assets.xcassets */; };
97
+ 935A2F7D98CCC0DEA5EA2782 /* AppRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C82874C90A5FAA32D1B52EB7 /* AppRootView.swift */; };
98
93E938AA978ABF5665737887 /* GuideEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0A0935AE4B398B281758834 /* GuideEntry.swift */; };
99
955D039F4B5D14FCA4E7F2B2 /* GuideArtworkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F2850226B4B05FF758C1F93 /* GuideArtworkView.swift */; };
100
99071E0CB9F44857C0BFC8C9 /* SavedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AA2E425D5454602F78D628 /* SavedView.swift */; };
101
+ 995C5FDC790E09B87CB5F1C4 /* KleponTypography.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD520C870387E82E9A1533C2 /* KleponTypography.swift */; };
102
+ 997D63C43B61CB342C586FB8 /* DiscoverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4545DC84863788D55B94D31A /* DiscoverView.swift */; };
103
+ 9BF8C40A4C12038A9DD2D0D7 /* collections.json in Resources */ = {isa = PBXBuildFile; fileRef = 1FDDB0F88FF430ABD679AD89 /* collections.json */; };
104
9E16F5C37F30B58441780260 /* DiscoverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4545DC84863788D55B94D31A /* DiscoverView.swift */; };
105
+ 9E42E7DE70F8582B66C895F3 /* SearchService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6235AD6792F25476E2A508F0 /* SearchService.swift */; };
106
9ECA989E9DCDF08A2D7C29A3 /* AppRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C82874C90A5FAA32D1B52EB7 /* AppRootView.swift */; };
107
9ECEB59572D3B9D08D1DA896 /* GuideCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17C0DB3BD620AD9F55B7631 /* GuideCollection.swift */; };
108
+ 9F79023304A3FD651D05BB54 /* OndeGuideEngine.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0D53A5F9D5897E15506C20 /* OndeGuideEngine.swift */; };
109
+ A001621A9DB5FF868217D410 /* DiscoverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4545DC84863788D55B94D31A /* DiscoverView.swift */; };
110
+ A0EF936D6223961D25CBC9F6 /* RecentlyViewedStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = E45070309D2C7058BAA44CD2 /* RecentlyViewedStore.swift */; };
111
+ A0F94006F95F2F671D00EEFB /* KleponColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C675ABBBA25BBA25A8DE29BE /* KleponColor.swift */; };
112
+ A18C34880D04EAB4C889BC22 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42E152344B39D1D77F1B3943 /* SettingsView.swift */; };
113
A54D028D8F35FE002B0ACA90 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 054656155630B064F785B0D7 /* Assets.xcassets */; };
114
+ A571A7E1FA449D257951367C /* guide_entries.json in Resources */ = {isa = PBXBuildFile; fileRef = 248F359109A08A60F792C42D /* guide_entries.json */; };
115
+ A5E339F380247E90AEF56DC6 /* GuideCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17C0DB3BD620AD9F55B7631 /* GuideCollection.swift */; };
116
+ A69F302A8F11969D9CD197EE /* guide_entries.json in Resources */ = {isa = PBXBuildFile; fileRef = 248F359109A08A60F792C42D /* guide_entries.json */; };
117
A7001D58E0F2B1BD5F52FF8A /* Onde in Frameworks */ = {isa = PBXBuildFile; productRef = 855EE8DF62A7820E77C05D1A /* Onde */; };
118
+ A76C56EF8CFB6D723B55EE74 /* SearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7E886BAB66E828950DBED52 /* SearchView.swift */; };
119
B1F1D1A453150D3BBB0146EF /* RecentlyViewedStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = E45070309D2C7058BAA44CD2 /* RecentlyViewedStore.swift */; };
120
B34377720179454F9B9184C5 /* OndeGuideEngine.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0D53A5F9D5897E15506C20 /* OndeGuideEngine.swift */; };
121
B4467AA7214B4990D2FC19DA /* KleponCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 868C58098969278A542893F3 /* KleponCard.swift */; };
122
+ B5B076B218DF86269DD7F80D /* GuideArtworkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F2850226B4B05FF758C1F93 /* GuideArtworkView.swift */; };
123
B768150B02B19417B81FE651 /* guide_entries.json in Resources */ = {isa = PBXBuildFile; fileRef = 248F359109A08A60F792C42D /* guide_entries.json */; };
124
B7DE9EC8BE998E6719C88E83 /* guide_entries.json in Resources */ = {isa = PBXBuildFile; fileRef = 248F359109A08A60F792C42D /* guide_entries.json */; };
125
+ B97D6D5885E0B6CFB358B1BC /* KleponActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52DD909BB2EF68103CB46EDA /* KleponActionButton.swift */; };
126
BB70FAD944544125AF261F7C /* SavedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98AA2E425D5454602F78D628 /* SavedView.swift */; };
127
+ BC8102C70075D3DEDE537CDD /* KleponActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52DD909BB2EF68103CB46EDA /* KleponActionButton.swift */; };
128
C15131992039B3AC7DB74DAB /* testGuideArtworkView.guide-artwork.png in Resources */ = {isa = PBXBuildFile; fileRef = 9D6EFA021D4524508DA8E78C /* testGuideArtworkView.guide-artwork.png */; };
129
+ C1DF8DB1F063D1C5258602D6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AF79D8DD27B9CA485140C934 /* Assets.xcassets */; };
130
+ C2A06A0802694BD0C1F39B85 /* SearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7E886BAB66E828950DBED52 /* SearchView.swift */; };
131
C2EA2682A6545802C06E00CC /* WatchBrandSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 217E7D4050D471955FF3AB13 /* WatchBrandSystem.swift */; };
132
+ C62C1ECC5068A50E5C09CEC5 /* Onde in Frameworks */ = {isa = PBXBuildFile; productRef = D977F065ACEF38E106A8FB5C /* Onde */; };
133
+ C6532365C518962FC265ABCD /* GuideCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17C0DB3BD620AD9F55B7631 /* GuideCollection.swift */; };
134
C709C82E7F0BCF398BCD9C2F /* ContentRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2891A1AFBB59928FC5B1E66 /* ContentRepository.swift */; };
135
+ C88013421E507AEDCB41BE96 /* OndeGuideEngine.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0D53A5F9D5897E15506C20 /* OndeGuideEngine.swift */; };
136
+ C8ECF8664277103582D96B45 /* FavoritesStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BC0C4C22A5134DB058E41F4 /* FavoritesStore.swift */; };
137
+ CE5C9946E68E1F7A781F1628 /* AnswerCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = B02B0EA4B8BA09604D62A62B /* AnswerCard.swift */; };
138
+ CE6824D3D8261BF0463F39D8 /* KleponMetadataRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7E1C50BFBE2EF5F37941590 /* KleponMetadataRow.swift */; };
139
+ D2D49509E9CB5CF2BA4EBF6D /* GuideAnswerService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3719031080B59898133810F7 /* GuideAnswerService.swift */; };
140
D6D8A42930EA9A0EA6622108 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AF291E9C2E66209377138E6 /* AppState.swift */; };
141
D99AAE1CDE51139840A52607 /* KleponMetadataRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7E1C50BFBE2EF5F37941590 /* KleponMetadataRow.swift */; };
142
DA915BA8B2F732E7D62CF936 /* EmptyStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85E7B5E3D9A1906C2FED3032 /* EmptyStateView.swift */; };
143
+ DBD7CE5D9AB42EA74CC9F7A1 /* KleponApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEDE2A1E73EB15970A17A894 /* KleponApp.swift */; };
144
+ DDD3529FAEA0D105EBD5C168 /* KleponTypography.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD520C870387E82E9A1533C2 /* KleponTypography.swift */; };
145
+ E17595636392EDF3D6EEE895 /* OndeEnvironmentBootstrap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B499D3BF7AC80D31907D87F /* OndeEnvironmentBootstrap.swift */; };
146
+ E25DE24C663A9579D28F21D4 /* GuideEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0A0935AE4B398B281758834 /* GuideEntry.swift */; };
147
E45F257E3D35DC565B21B299 /* KleponColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C675ABBBA25BBA25A8DE29BE /* KleponColor.swift */; };
148
E599CCDB1FE5331C4A1EB6C6 /* KleponSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 759E92BBAF958F5882F17C37 /* KleponSnapshotTests.swift */; };
149
E87F8A08D6922557A5DBD198 /* testOnboardingView_defaultState.default.png in Resources */ = {isa = PBXBuildFile; fileRef = 414FD1A8945B820DCC4ED192 /* testOnboardingView_defaultState.default.png */; };
150
ECDD606D8AFA776765AA9A31 /* SectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC438ECC335175B18778C682 /* SectionHeader.swift */; };
151
+ EDD126593FECA8D9EB7DBC4A /* EmptyStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85E7B5E3D9A1906C2FED3032 /* EmptyStateView.swift */; };
152
EE2103530984735318E469FD /* AskSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC6E7DC56DD8E1459EFC892 /* AskSheetView.swift */; };
153
EE88AEC7059BB2639687FECF /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = 35214C3FF433B08C1C06C3F7 /* SnapshotTesting */; };
154
F0694A813D1CB57F0B5C0F65 /* FavoritesStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BC0C4C22A5134DB058E41F4 /* FavoritesStore.swift */; };
@@ -89,10 +156,13 @@
156
F2D905B433B0B76CE6B4001F /* OndeEnvironmentBootstrap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B499D3BF7AC80D31907D87F /* OndeEnvironmentBootstrap.swift */; };
157
F46EB4EDFFF125ED88506D89 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 6B67BCC5A459288FB240C6E7 /* Info.plist */; };
158
F5B35C6C771073CE32B4BFD1 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42E152344B39D1D77F1B3943 /* SettingsView.swift */; };
159
+ F64259FB47704FC3E2F15FF7 /* RecentlyViewedStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = E45070309D2C7058BAA44CD2 /* RecentlyViewedStore.swift */; };
160
F87EF3C291B7D3FB9BE8E43A /* ContentRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2891A1AFBB59928FC5B1E66 /* ContentRepository.swift */; };
161
F88972525510344E63D2983C /* AppRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C82874C90A5FAA32D1B52EB7 /* AppRootView.swift */; };
162
+ F9983D842EB95B43620CA52B /* GuideDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7541983FF7CE190C0663294D /* GuideDetailView.swift */; };
163
F9D6FC75A11BE98BD28BBDC2 /* RecentSearchStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 643D52BCEDF66CC8FE8A1234 /* RecentSearchStore.swift */; };
164
FA423A76BE098A9911044246 /* AskSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC6E7DC56DD8E1459EFC892 /* AskSheetView.swift */; };
165
+ FA44F0883B69820D526BF6E4 /* GuideDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7541983FF7CE190C0663294D /* GuideDetailView.swift */; };
166
FD0E1BA888E3CE73875D58FF /* RecentSearchStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 643D52BCEDF66CC8FE8A1234 /* RecentSearchStore.swift */; };
167
/* End PBXBuildFile section */
168
@@ -150,6 +220,7 @@
220
6B67BCC5A459288FB240C6E7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
221
6EFBF98118F066D3C7FA14B2 /* KleponWatchApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KleponWatchApp.swift; sourceTree = "<group>"; };
222
7541983FF7CE190C0663294D /* GuideDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GuideDetailView.swift; sourceTree = "<group>"; };
223
+ 754A7FAB8C92112B8B6228B7 /* Klepon TV.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = "Klepon TV.app"; sourceTree = BUILT_PRODUCTS_DIR; };
224
759E92BBAF958F5882F17C37 /* KleponSnapshotTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KleponSnapshotTests.swift; sourceTree = "<group>"; };
225
7F2850226B4B05FF758C1F93 /* GuideArtworkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GuideArtworkView.swift; sourceTree = "<group>"; };
226
85E7B5E3D9A1906C2FED3032 /* EmptyStateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyStateView.swift; sourceTree = "<group>"; };
@@ -172,6 +243,7 @@
243
CD520C870387E82E9A1533C2 /* KleponTypography.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KleponTypography.swift; sourceTree = "<group>"; };
244
D53EA049112C7D59177F9878 /* Klepon Mac.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Klepon Mac.app"; sourceTree = BUILT_PRODUCTS_DIR; };
245
DEDE2A1E73EB15970A17A894 /* KleponApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KleponApp.swift; sourceTree = "<group>"; };
246
+ E041DB1D0DAA58746AE6F9EA /* Klepon Vision.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = "Klepon Vision.app"; sourceTree = BUILT_PRODUCTS_DIR; };
247
E45070309D2C7058BAA44CD2 /* RecentlyViewedStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentlyViewedStore.swift; sourceTree = "<group>"; };
248
E7E886BAB66E828950DBED52 /* SearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchView.swift; sourceTree = "<group>"; };
249
EDBB4F5D4C98D036AC52E193 /* WatchHomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchHomeView.swift; sourceTree = "<group>"; };
@@ -183,6 +255,22 @@
255
/* End PBXFileReference section */
256
257
/* Begin PBXFrameworksBuildPhase section */
258
+ 2D72F61FB9AD47BC2682FB3F /* Frameworks */ = {
259
+ isa = PBXFrameworksBuildPhase;
260
+ buildActionMask = 2147483647;
261
+ files = (
262
+ 5D3BDDCB5CA8A8DC32E8ABEA /* Onde in Frameworks */,
263
+ );
264
+ runOnlyForDeploymentPostprocessing = 0;
265
+ };
266
+ 614F30649198DB2180250038 /* Frameworks */ = {
267
+ isa = PBXFrameworksBuildPhase;
268
+ buildActionMask = 2147483647;
269
+ files = (
270
+ C62C1ECC5068A50E5C09CEC5 /* Onde in Frameworks */,
271
+ );
272
+ runOnlyForDeploymentPostprocessing = 0;
273
+ };
274
B0052635A882F0E996B81154 /* Frameworks */ = {
275
isa = PBXFrameworksBuildPhase;
276
buildActionMask = 2147483647;
@@ -239,6 +327,8 @@
327
isa = PBXGroup;
328
children = (
329
D53EA049112C7D59177F9878 /* Klepon Mac.app */,
330
+ 754A7FAB8C92112B8B6228B7 /* Klepon TV.app */,
331
+ E041DB1D0DAA58746AE6F9EA /* Klepon Vision.app */,
332
9E76510CC840CE068B0FC381 /* Klepon Watch.app */,
333
5DE91827A635C0B0B72690EC /* Klepon.app */,
334
A48AC0E39277DEFCE5D103CC /* KleponSnapshotTests.xctest */,
@@ -456,6 +546,27 @@
546
/* End PBXGroup section */
547
548
/* Begin PBXNativeTarget section */
549
+ 0322696BE3965C4C0F0E5322 /* Klepon Vision */ = {
550
+ isa = PBXNativeTarget;
551
+ buildConfigurationList = A7E925A77873EC80DF7D2840 /* Build configuration list for PBXNativeTarget "Klepon Vision" */;
552
+ buildPhases = (
553
+ BFE208AF41AAF322DFAB7EED /* Sources */,
554
+ 63B62007E78131109B2F8902 /* Resources */,
555
+ 2D72F61FB9AD47BC2682FB3F /* Frameworks */,
556
+ 201C2DC58537433FDB96C0C5 /* Update CFBundleVersion */,
557
+ );
558
+ buildRules = (
559
+ );
560
+ dependencies = (
561
+ );
562
+ name = "Klepon Vision";
563
+ packageProductDependencies = (
564
+ CECDF5959E6652B49DCF1E18 /* Onde */,
565
+ );
566
+ productName = "Klepon Vision";
567
+ productReference = E041DB1D0DAA58746AE6F9EA /* Klepon Vision.app */;
568
+ productType = "com.apple.product-type.application";
569
+ };
570
2ADB11F6C1D51B9F9A9DB15F /* Klepon */ = {
571
isa = PBXNativeTarget;
572
buildConfigurationList = E1E5A3DF58C9552EE814CC23 /* Build configuration list for PBXNativeTarget "Klepon" */;
@@ -500,6 +611,27 @@
611
productReference = D53EA049112C7D59177F9878 /* Klepon Mac.app */;
612
productType = "com.apple.product-type.application";
613
};
614
+ E153DCB2727ADB891CF09A25 /* Klepon TV */ = {
615
+ isa = PBXNativeTarget;
616
+ buildConfigurationList = 14FFFB40F48F5625253F44DE /* Build configuration list for PBXNativeTarget "Klepon TV" */;
617
+ buildPhases = (
618
+ 00C4D42D71379B10BB8DAD32 /* Sources */,
619
+ 13483CEA676E76809EF16344 /* Resources */,
620
+ 614F30649198DB2180250038 /* Frameworks */,
621
+ 2444E8602E844C7B97E84E9D /* Update CFBundleVersion */,
622
+ );
623
+ buildRules = (
624
+ );
625
+ dependencies = (
626
+ );
627
+ name = "Klepon TV";
628
+ packageProductDependencies = (
629
+ D977F065ACEF38E106A8FB5C /* Onde */,
630
+ );
631
+ productName = "Klepon TV";
632
+ productReference = 754A7FAB8C92112B8B6228B7 /* Klepon TV.app */;
633
+ productType = "com.apple.product-type.application";
634
+ };
635
E8CEBF52617721AEE450A7CF /* Klepon Watch */ = {
636
isa = PBXNativeTarget;
637
buildConfigurationList = 07A758477E97CF9254DDBA82 /* Build configuration list for PBXNativeTarget "Klepon Watch" */;
@@ -549,12 +681,18 @@
681
BuildIndependentTargetsInParallel = YES;
682
LastUpgradeCheck = 2600;
683
TargetAttributes = {
684
+ 0322696BE3965C4C0F0E5322 = {
685
+ ProvisioningStyle = Automatic;
686
+ };
687
2ADB11F6C1D51B9F9A9DB15F = {
688
ProvisioningStyle = Automatic;
689
};
690
676CA86C78E7DB801DEEAF12 = {
691
ProvisioningStyle = Automatic;
692
};
693
+ E153DCB2727ADB891CF09A25 = {
694
+ ProvisioningStyle = Automatic;
695
+ };
696
E8CEBF52617721AEE450A7CF = {
697
ProvisioningStyle = Automatic;
698
};
@@ -583,6 +721,8 @@
721
targets = (
722
2ADB11F6C1D51B9F9A9DB15F /* Klepon */,
723
676CA86C78E7DB801DEEAF12 /* Klepon Mac */,
724
+ E153DCB2727ADB891CF09A25 /* Klepon TV */,
725
+ 0322696BE3965C4C0F0E5322 /* Klepon Vision */,
726
E8CEBF52617721AEE450A7CF /* Klepon Watch */,
727
F10E9562BA0BE60A7E000DB0 /* KleponSnapshotTests */,
728
);
@@ -600,6 +740,26 @@
740
);
741
runOnlyForDeploymentPostprocessing = 0;
742
};
743
+ 13483CEA676E76809EF16344 /* Resources */ = {
744
+ isa = PBXResourcesBuildPhase;
745
+ buildActionMask = 2147483647;
746
+ files = (
747
+ C1DF8DB1F063D1C5258602D6 /* Assets.xcassets in Resources */,
748
+ 9BF8C40A4C12038A9DD2D0D7 /* collections.json in Resources */,
749
+ A571A7E1FA449D257951367C /* guide_entries.json in Resources */,
750
+ );
751
+ runOnlyForDeploymentPostprocessing = 0;
752
+ };
753
+ 63B62007E78131109B2F8902 /* Resources */ = {
754
+ isa = PBXResourcesBuildPhase;
755
+ buildActionMask = 2147483647;
756
+ files = (
757
+ 841F3B272D0FD82365DE48BD /* Assets.xcassets in Resources */,
758
+ 76EE3B0D899987557B6741DF /* collections.json in Resources */,
759
+ A69F302A8F11969D9CD197EE /* guide_entries.json in Resources */,
760
+ );
761
+ runOnlyForDeploymentPostprocessing = 0;
762
+ };
763
667705EEBEDEBBCA43E94EAC /* Resources */ = {
764
isa = PBXResourcesBuildPhase;
765
buildActionMask = 2147483647;
@@ -654,6 +814,46 @@
814
shellScript = "set -eu\n\nSHARED_BUNDLE_VERSION_FILE=\"${BUILD_DIR}/klepon-cfbundleversion.txt\"\nif [ -f \"${SHARED_BUNDLE_VERSION_FILE}\" ]; then\n BUNDLE_VERSION=\"$(cat \"${SHARED_BUNDLE_VERSION_FILE}\")\"\nelse\n BUNDLE_VERSION=\"$(date -u +\"%Y%m%d.%H%M\")\"\n printf '%s' \"${BUNDLE_VERSION}\" > \"${SHARED_BUNDLE_VERSION_FILE}\"\nfi\n\nINFO_PLIST=\"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}\"\n\nif [ ! -f \"${INFO_PLIST}\" ]; then\n echo \"error: Info.plist not found at ${INFO_PLIST}\"\n exit 1\nfi\n\nif ! /usr/libexec/PlistBuddy -c \"Set :CFBundleVersion ${BUNDLE_VERSION}\" \"${INFO_PLIST}\" >/dev/null 2>&1; then\n /usr/libexec/PlistBuddy -c \"Add :CFBundleVersion string ${BUNDLE_VERSION}\" \"${INFO_PLIST}\"\nfi\n\necho \"Updated CFBundleVersion to ${BUNDLE_VERSION}\"\n";
815
showEnvVarsInLog = 0;
816
};
817
+ 201C2DC58537433FDB96C0C5 /* Update CFBundleVersion */ = {
818
+ isa = PBXShellScriptBuildPhase;
819
+ alwaysOutOfDate = 1;
820
+ buildActionMask = 2147483647;
821
+ files = (
822
+ );
823
+ inputFileListPaths = (
824
+ );
825
+ inputPaths = (
826
+ );
827
+ name = "Update CFBundleVersion";
828
+ outputFileListPaths = (
829
+ );
830
+ outputPaths = (
831
+ );
832
+ runOnlyForDeploymentPostprocessing = 0;
833
+ shellPath = /bin/sh;
834
+ shellScript = "set -eu\n\nSHARED_BUNDLE_VERSION_FILE=\"${BUILD_DIR}/klepon-cfbundleversion.txt\"\nif [ -f \"${SHARED_BUNDLE_VERSION_FILE}\" ]; then\n BUNDLE_VERSION=\"$(cat \"${SHARED_BUNDLE_VERSION_FILE}\")\"\nelse\n BUNDLE_VERSION=\"$(date -u +\"%Y%m%d.%H%M\")\"\n printf '%s' \"${BUNDLE_VERSION}\" > \"${SHARED_BUNDLE_VERSION_FILE}\"\nfi\n\nINFO_PLIST=\"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}\"\n\nif [ ! -f \"${INFO_PLIST}\" ]; then\n echo \"error: Info.plist not found at ${INFO_PLIST}\"\n exit 1\nfi\n\nif ! /usr/libexec/PlistBuddy -c \"Set :CFBundleVersion ${BUNDLE_VERSION}\" \"${INFO_PLIST}\" >/dev/null 2>&1; then\n /usr/libexec/PlistBuddy -c \"Add :CFBundleVersion string ${BUNDLE_VERSION}\" \"${INFO_PLIST}\"\nfi\n\necho \"Updated CFBundleVersion to ${BUNDLE_VERSION}\"\n";
835
+ showEnvVarsInLog = 0;
836
+ };
837
+ 2444E8602E844C7B97E84E9D /* Update CFBundleVersion */ = {
838
+ isa = PBXShellScriptBuildPhase;
839
+ alwaysOutOfDate = 1;
840
+ buildActionMask = 2147483647;
841
+ files = (
842
+ );
843
+ inputFileListPaths = (
844
+ );
845
+ inputPaths = (
846
+ );
847
+ name = "Update CFBundleVersion";
848
+ outputFileListPaths = (
849
+ );
850
+ outputPaths = (
851
+ );
852
+ runOnlyForDeploymentPostprocessing = 0;
853
+ shellPath = /bin/sh;
854
+ shellScript = "set -eu\n\nSHARED_BUNDLE_VERSION_FILE=\"${BUILD_DIR}/klepon-cfbundleversion.txt\"\nif [ -f \"${SHARED_BUNDLE_VERSION_FILE}\" ]; then\n BUNDLE_VERSION=\"$(cat \"${SHARED_BUNDLE_VERSION_FILE}\")\"\nelse\n BUNDLE_VERSION=\"$(date -u +\"%Y%m%d.%H%M\")\"\n printf '%s' \"${BUNDLE_VERSION}\" > \"${SHARED_BUNDLE_VERSION_FILE}\"\nfi\n\nINFO_PLIST=\"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}\"\n\nif [ ! -f \"${INFO_PLIST}\" ]; then\n echo \"error: Info.plist not found at ${INFO_PLIST}\"\n exit 1\nfi\n\nif ! /usr/libexec/PlistBuddy -c \"Set :CFBundleVersion ${BUNDLE_VERSION}\" \"${INFO_PLIST}\" >/dev/null 2>&1; then\n /usr/libexec/PlistBuddy -c \"Add :CFBundleVersion string ${BUNDLE_VERSION}\" \"${INFO_PLIST}\"\nfi\n\necho \"Updated CFBundleVersion to ${BUNDLE_VERSION}\"\n";
855
+ showEnvVarsInLog = 0;
856
+ };
857
38259E5F7F0F32D684AE509A /* Update CFBundleVersion */ = {
858
isa = PBXShellScriptBuildPhase;
859
alwaysOutOfDate = 1;
@@ -697,6 +897,44 @@
897
/* End PBXShellScriptBuildPhase section */
898
899
/* Begin PBXSourcesBuildPhase section */
900
+ 00C4D42D71379B10BB8DAD32 /* Sources */ = {
901
+ isa = PBXSourcesBuildPhase;
902
+ buildActionMask = 2147483647;
903
+ files = (
904
+ 8189E2DF13801C2B7162AD45 /* AnswerCard.swift in Sources */,
905
+ 935A2F7D98CCC0DEA5EA2782 /* AppRootView.swift in Sources */,
906
+ 1E042510F7F75D392A4AC6E7 /* AppState.swift in Sources */,
907
+ 26FA5D01FED96591E78A2293 /* AskSheetView.swift in Sources */,
908
+ 854C10AE603DCCC521D93BC2 /* ContentRepository.swift in Sources */,
909
+ 997D63C43B61CB342C586FB8 /* DiscoverView.swift in Sources */,
910
+ 6B7AE8B1C6D3AD6F973F5757 /* EmptyStateView.swift in Sources */,
911
+ C8ECF8664277103582D96B45 /* FavoritesStore.swift in Sources */,
912
+ 3EB900CB86D2B32F8DAB434D /* GuideAnswerService.swift in Sources */,
913
+ B5B076B218DF86269DD7F80D /* GuideArtworkView.swift in Sources */,
914
+ C6532365C518962FC265ABCD /* GuideCollection.swift in Sources */,
915
+ F9983D842EB95B43620CA52B /* GuideDetailView.swift in Sources */,
916
+ E25DE24C663A9579D28F21D4 /* GuideEntry.swift in Sources */,
917
+ B97D6D5885E0B6CFB358B1BC /* KleponActionButton.swift in Sources */,
918
+ DBD7CE5D9AB42EA74CC9F7A1 /* KleponApp.swift in Sources */,
919
+ 16330914DF2EE212C91BC0CA /* KleponCard.swift in Sources */,
920
+ 587F0BB61966B2BB048013DE /* KleponChip.swift in Sources */,
921
+ 4B6E0CF8EAB6FF1D0160E3E6 /* KleponColor.swift in Sources */,
922
+ CE6824D3D8261BF0463F39D8 /* KleponMetadataRow.swift in Sources */,
923
+ DDD3529FAEA0D105EBD5C168 /* KleponTypography.swift in Sources */,
924
+ 6117CD728CC7FF8D6EB0A8C8 /* OnboardingView.swift in Sources */,
925
+ E17595636392EDF3D6EEE895 /* OndeEnvironmentBootstrap.swift in Sources */,
926
+ 9F79023304A3FD651D05BB54 /* OndeGuideEngine.swift in Sources */,
927
+ 3C4C5EEBF766D6E8A5D240DA /* PlatformViewSupport.swift in Sources */,
928
+ 819489D60D833AE2AD9185A6 /* RecentSearchStore.swift in Sources */,
929
+ A0EF936D6223961D25CBC9F6 /* RecentlyViewedStore.swift in Sources */,
930
+ 14C796CE6777B6013910831C /* SavedView.swift in Sources */,
931
+ 74A9016453B9820FC486B014 /* SearchService.swift in Sources */,
932
+ C2A06A0802694BD0C1F39B85 /* SearchView.swift in Sources */,
933
+ 7F726FA99DBDC0155E99E098 /* SectionHeader.swift in Sources */,
934
+ 78142FDCFE7EF00A3D81A067 /* SettingsView.swift in Sources */,
935
+ );
936
+ runOnlyForDeploymentPostprocessing = 0;
937
+ };
938
142193A63A26ACC180E1EB37 /* Sources */ = {
939
isa = PBXSourcesBuildPhase;
940
buildActionMask = 2147483647;
@@ -786,6 +1024,44 @@
1024
);
1025
runOnlyForDeploymentPostprocessing = 0;
1026
};
1027
+ BFE208AF41AAF322DFAB7EED /* Sources */ = {
1028
+ isa = PBXSourcesBuildPhase;
1029
+ buildActionMask = 2147483647;
1030
+ files = (
1031
+ CE5C9946E68E1F7A781F1628 /* AnswerCard.swift in Sources */,
1032
+ 0481C8A85FED1E35C3734816 /* AppRootView.swift in Sources */,
1033
+ 906E12C00728B15B676A23DB /* AppState.swift in Sources */,
1034
+ 2F74C3B8D4A1A38DEF50E39B /* AskSheetView.swift in Sources */,
1035
+ 20CDEBB4B6C8AAE007854102 /* ContentRepository.swift in Sources */,
1036
+ A001621A9DB5FF868217D410 /* DiscoverView.swift in Sources */,
1037
+ EDD126593FECA8D9EB7DBC4A /* EmptyStateView.swift in Sources */,
1038
+ 68479892D13825C6C9977DF9 /* FavoritesStore.swift in Sources */,
1039
+ D2D49509E9CB5CF2BA4EBF6D /* GuideAnswerService.swift in Sources */,
1040
+ 387EE903EFA0D820C646B4DB /* GuideArtworkView.swift in Sources */,
1041
+ A5E339F380247E90AEF56DC6 /* GuideCollection.swift in Sources */,
1042
+ FA44F0883B69820D526BF6E4 /* GuideDetailView.swift in Sources */,
1043
+ 87E259162B03252EA23A32CF /* GuideEntry.swift in Sources */,
1044
+ BC8102C70075D3DEDE537CDD /* KleponActionButton.swift in Sources */,
1045
+ 7A9B7E0858E7095E18EC7AC6 /* KleponApp.swift in Sources */,
1046
+ 0B94C64018A573AD679106E5 /* KleponCard.swift in Sources */,
1047
+ 0E350E68B43067698FE3B05C /* KleponChip.swift in Sources */,
1048
+ A0F94006F95F2F671D00EEFB /* KleponColor.swift in Sources */,
1049
+ 8C6D6EC32870A45E021BF3EB /* KleponMetadataRow.swift in Sources */,
1050
+ 995C5FDC790E09B87CB5F1C4 /* KleponTypography.swift in Sources */,
1051
+ 367BECAC66674A040D99C0DF /* OnboardingView.swift in Sources */,
1052
+ 6FCE6EBC39C7F229A5F52745 /* OndeEnvironmentBootstrap.swift in Sources */,
1053
+ C88013421E507AEDCB41BE96 /* OndeGuideEngine.swift in Sources */,
1054
+ 5C3590F8B1A8255C5E175A03 /* PlatformViewSupport.swift in Sources */,
1055
+ 85FC2D60857424B39654DE08 /* RecentSearchStore.swift in Sources */,
1056
+ F64259FB47704FC3E2F15FF7 /* RecentlyViewedStore.swift in Sources */,
1057
+ 1C2B6971843620B876F5B0C3 /* SavedView.swift in Sources */,
1058
+ 9E42E7DE70F8582B66C895F3 /* SearchService.swift in Sources */,
1059
+ A76C56EF8CFB6D723B55EE74 /* SearchView.swift in Sources */,
1060
+ 3568D735D790330031DCF8F9 /* SectionHeader.swift in Sources */,
1061
+ A18C34880D04EAB4C889BC22 /* SettingsView.swift in Sources */,
1062
+ );
1063
+ runOnlyForDeploymentPostprocessing = 0;
1064
+ };
1065
C2B1B8ADEE7B8E2628B90D1F /* Sources */ = {
1066
isa = PBXSourcesBuildPhase;
1067
buildActionMask = 2147483647;
@@ -979,10 +1255,37 @@
1255
SWIFT_COMPILATION_MODE = wholemodule;
1256
SWIFT_OPTIMIZATION_LEVEL = "-O";
1257
SWIFT_VERSION = 5.0;
1258
+ TVOS_DEPLOYMENT_TARGET = 18.5;
1259
WATCHOS_DEPLOYMENT_TARGET = 9.0;
1260
+ XROS_DEPLOYMENT_TARGET = 1.0;
1261
};
1262
name = Release;
1263
};
1264
+ 9415BE3B8DBFC6BE334F60B6 /* Debug */ = {
1265
+ isa = XCBuildConfiguration;
1266
+ baseConfigurationReference = 13B09D700AA047E07E91F6A2 /* Signing.xcconfig */;
1267
+ buildSettings = {
1268
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIconTV;
1269
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
1270
+ ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
1271
+ CODE_SIGN_ENTITLEMENTS = KleponTV/KleponTV.entitlements;
1272
+ CURRENT_PROJECT_VERSION = 1;
1273
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
1274
+ "EXCLUDED_ARCHS[sdk=appletvsimulator*]" = x86_64;
1275
+ INFOPLIST_FILE = KleponTV/Info.plist;
1276
+ LD_RUNPATH_SEARCH_PATHS = (
1277
+ "$(inherited)",
1278
+ "@executable_path/Frameworks",
1279
+ );
1280
+ MARKETING_VERSION = 1.0.0;
1281
+ PRODUCT_BUNDLE_IDENTIFIER = ai.splitfire.klepon.tv;
1282
+ PRODUCT_NAME = Klepon;
1283
+ SDKROOT = appletvos;
1284
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
1285
+ TARGETED_DEVICE_FAMILY = 3;
1286
+ };
1287
+ name = Debug;
1288
+ };
1289
97B8585F2E74C6C870509FE9 /* Release */ = {
1290
isa = XCBuildConfiguration;
1291
baseConfigurationReference = 13B09D700AA047E07E91F6A2 /* Signing.xcconfig */;
@@ -1007,6 +1310,30 @@
1310
};
1311
name = Release;
1312
};
1313
+ 999F5F439FDE6D455B425C69 /* Release */ = {
1314
+ isa = XCBuildConfiguration;
1315
+ baseConfigurationReference = 13B09D700AA047E07E91F6A2 /* Signing.xcconfig */;
1316
+ buildSettings = {
1317
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIconVision;
1318
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
1319
+ CODE_SIGN_ENTITLEMENTS = KleponVision/KleponVision.entitlements;
1320
+ CURRENT_PROJECT_VERSION = 1;
1321
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
1322
+ "EXCLUDED_ARCHS[sdk=xrsimulator*]" = x86_64;
1323
+ INFOPLIST_FILE = KleponVision/Info.plist;
1324
+ LD_RUNPATH_SEARCH_PATHS = (
1325
+ "$(inherited)",
1326
+ "@executable_path/Frameworks",
1327
+ );
1328
+ MARKETING_VERSION = 1.0.0;
1329
+ PRODUCT_BUNDLE_IDENTIFIER = ai.splitfire.klepon.vision;
1330
+ PRODUCT_NAME = Klepon;
1331
+ SDKROOT = xros;
1332
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
1333
+ TARGETED_DEVICE_FAMILY = 7;
1334
+ };
1335
+ name = Release;
1336
+ };
1337
A3B469B57456DA7C46537A7E /* Release */ = {
1338
isa = XCBuildConfiguration;
1339
baseConfigurationReference = 13B09D700AA047E07E91F6A2 /* Signing.xcconfig */;
@@ -1093,10 +1420,37 @@
1420
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
1421
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
1422
SWIFT_VERSION = 5.0;
1423
+ TVOS_DEPLOYMENT_TARGET = 18.5;
1424
WATCHOS_DEPLOYMENT_TARGET = 9.0;
1425
+ XROS_DEPLOYMENT_TARGET = 1.0;
1426
};
1427
name = Debug;
1428
};
1429
+ B88CFA8CA520549B8189AABE /* Release */ = {
1430
+ isa = XCBuildConfiguration;
1431
+ baseConfigurationReference = 13B09D700AA047E07E91F6A2 /* Signing.xcconfig */;
1432
+ buildSettings = {
1433
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIconTV;
1434
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
1435
+ ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
1436
+ CODE_SIGN_ENTITLEMENTS = KleponTV/KleponTV.entitlements;
1437
+ CURRENT_PROJECT_VERSION = 1;
1438
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
1439
+ "EXCLUDED_ARCHS[sdk=appletvsimulator*]" = x86_64;
1440
+ INFOPLIST_FILE = KleponTV/Info.plist;
1441
+ LD_RUNPATH_SEARCH_PATHS = (
1442
+ "$(inherited)",
1443
+ "@executable_path/Frameworks",
1444
+ );
1445
+ MARKETING_VERSION = 1.0.0;
1446
+ PRODUCT_BUNDLE_IDENTIFIER = ai.splitfire.klepon.tv;
1447
+ PRODUCT_NAME = Klepon;
1448
+ SDKROOT = appletvos;
1449
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
1450
+ TARGETED_DEVICE_FAMILY = 3;
1451
+ };
1452
+ name = Release;
1453
+ };
1454
D2D1439E7A622A6F8019887F /* Debug */ = {
1455
isa = XCBuildConfiguration;
1456
baseConfigurationReference = 13B09D700AA047E07E91F6A2 /* Signing.xcconfig */;
@@ -1121,6 +1475,30 @@
1475
};
1476
name = Debug;
1477
};
1478
+ F007CBD9F576E3B4C7163B40 /* Debug */ = {
1479
+ isa = XCBuildConfiguration;
1480
+ baseConfigurationReference = 13B09D700AA047E07E91F6A2 /* Signing.xcconfig */;
1481
+ buildSettings = {
1482
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIconVision;
1483
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
1484
+ CODE_SIGN_ENTITLEMENTS = KleponVision/KleponVision.entitlements;
1485
+ CURRENT_PROJECT_VERSION = 1;
1486
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
1487
+ "EXCLUDED_ARCHS[sdk=xrsimulator*]" = x86_64;
1488
+ INFOPLIST_FILE = KleponVision/Info.plist;
1489
+ LD_RUNPATH_SEARCH_PATHS = (
1490
+ "$(inherited)",
1491
+ "@executable_path/Frameworks",
1492
+ );
1493
+ MARKETING_VERSION = 1.0.0;
1494
+ PRODUCT_BUNDLE_IDENTIFIER = ai.splitfire.klepon.vision;
1495
+ PRODUCT_NAME = Klepon;
1496
+ SDKROOT = xros;
1497
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
1498
+ TARGETED_DEVICE_FAMILY = 7;
1499
+ };
1500
+ name = Debug;
1501
+ };
1502
/* End XCBuildConfiguration section */
1503
1504
/* Begin XCConfigurationList section */
@@ -1142,6 +1520,15 @@
1520
defaultConfigurationIsVisible = 0;
1521
defaultConfigurationName = Debug;
1522
};
1523
+ 14FFFB40F48F5625253F44DE /* Build configuration list for PBXNativeTarget "Klepon TV" */ = {
1524
+ isa = XCConfigurationList;
1525
+ buildConfigurations = (
1526
+ 9415BE3B8DBFC6BE334F60B6 /* Debug */,
1527
+ B88CFA8CA520549B8189AABE /* Release */,
1528
+ );
1529
+ defaultConfigurationIsVisible = 0;
1530
+ defaultConfigurationName = Debug;
1531
+ };
1532
78899F7C62A9675700D42C5A /* Build configuration list for PBXNativeTarget "Klepon Mac" */ = {
1533
isa = XCConfigurationList;
1534
buildConfigurations = (
@@ -1160,6 +1547,15 @@
1547
defaultConfigurationIsVisible = 0;
1548
defaultConfigurationName = Debug;
1549
};
1550
+ A7E925A77873EC80DF7D2840 /* Build configuration list for PBXNativeTarget "Klepon Vision" */ = {
1551
+ isa = XCConfigurationList;
1552
+ buildConfigurations = (
1553
+ F007CBD9F576E3B4C7163B40 /* Debug */,
1554
+ 999F5F439FDE6D455B425C69 /* Release */,
1555
+ );
1556
+ defaultConfigurationIsVisible = 0;
1557
+ defaultConfigurationName = Debug;
1558
+ };
1559
E1E5A3DF58C9552EE814CC23 /* Build configuration list for PBXNativeTarget "Klepon" */ = {
1560
isa = XCConfigurationList;
1561
buildConfigurations = (
@@ -1206,6 +1602,16 @@
1602
package = AD8C734FB461604D5793769C /* XCRemoteSwiftPackageReference "onde-swift" */;
1603
productName = Onde;
1604
};
1605
+ CECDF5959E6652B49DCF1E18 /* Onde */ = {
1606
+ isa = XCSwiftPackageProductDependency;
1607
+ package = AD8C734FB461604D5793769C /* XCRemoteSwiftPackageReference "onde-swift" */;
1608
+ productName = Onde;
1609
+ };
1610
+ D977F065ACEF38E106A8FB5C /* Onde */ = {
1611
+ isa = XCSwiftPackageProductDependency;
1612
+ package = AD8C734FB461604D5793769C /* XCRemoteSwiftPackageReference "onde-swift" */;
1613
+ productName = Onde;
1614
+ };
1615
/* End XCSwiftPackageProductDependency section */
1616
};
1617
rootObject = 05A5707BDA883282DEB132FF /* Project object */;
Klepon.xcodeproj/xcshareddata/xcschemes/Klepon TV.xcscheme
new
+87
@@ -0,0 +1,87 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<Scheme
3
+ LastUpgradeVersion = "2600"
4
+ version = "1.3">
5
+ <BuildAction
6
+ parallelizeBuildables = "YES"
7
+ buildImplicitDependencies = "YES">
8
+ <BuildActionEntries>
9
+ <BuildActionEntry
10
+ buildForTesting = "YES"
11
+ buildForRunning = "YES"
12
+ buildForProfiling = "YES"
13
+ buildForArchiving = "YES"
14
+ buildForAnalyzing = "YES">
15
+ <BuildableReference
16
+ BuildableIdentifier = "primary"
17
+ BlueprintIdentifier = "E153DCB2727ADB891CF09A25"
18
+ BuildableName = "Klepon.app"
19
+ BlueprintName = "Klepon TV"
20
+ ReferencedContainer = "container:Klepon.xcodeproj">
21
+ </BuildableReference>
22
+ </BuildActionEntry>
23
+ </BuildActionEntries>
24
+ </BuildAction>
25
+ <TestAction
26
+ buildConfiguration = "Debug"
27
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29
+ shouldUseLaunchSchemeArgsEnv = "YES">
30
+ <MacroExpansion>
31
+ <BuildableReference
32
+ BuildableIdentifier = "primary"
33
+ BlueprintIdentifier = "E153DCB2727ADB891CF09A25"
34
+ BuildableName = "Klepon.app"
35
+ BlueprintName = "Klepon TV"
36
+ ReferencedContainer = "container:Klepon.xcodeproj">
37
+ </BuildableReference>
38
+ </MacroExpansion>
39
+ <Testables>
40
+ </Testables>
41
+ </TestAction>
42
+ <LaunchAction
43
+ buildConfiguration = "Debug"
44
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
45
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
46
+ launchStyle = "0"
47
+ useCustomWorkingDirectory = "NO"
48
+ ignoresPersistentStateOnLaunch = "NO"
49
+ debugDocumentVersioning = "YES"
50
+ debugServiceExtension = "internal"
51
+ allowLocationSimulation = "YES">
52
+ <BuildableProductRunnable
53
+ runnableDebuggingMode = "0">
54
+ <BuildableReference
55
+ BuildableIdentifier = "primary"
56
+ BlueprintIdentifier = "E153DCB2727ADB891CF09A25"
57
+ BuildableName = "Klepon.app"
58
+ BlueprintName = "Klepon TV"
59
+ ReferencedContainer = "container:Klepon.xcodeproj">
60
+ </BuildableReference>
61
+ </BuildableProductRunnable>
62
+ </LaunchAction>
63
+ <ProfileAction
64
+ buildConfiguration = "Release"
65
+ shouldUseLaunchSchemeArgsEnv = "YES"
66
+ savedToolIdentifier = ""
67
+ useCustomWorkingDirectory = "NO"
68
+ debugDocumentVersioning = "YES">
69
+ <BuildableProductRunnable
70
+ runnableDebuggingMode = "0">
71
+ <BuildableReference
72
+ BuildableIdentifier = "primary"
73
+ BlueprintIdentifier = "E153DCB2727ADB891CF09A25"
74
+ BuildableName = "Klepon.app"
75
+ BlueprintName = "Klepon TV"
76
+ ReferencedContainer = "container:Klepon.xcodeproj">
77
+ </BuildableReference>
78
+ </BuildableProductRunnable>
79
+ </ProfileAction>
80
+ <AnalyzeAction
81
+ buildConfiguration = "Debug">
82
+ </AnalyzeAction>
83
+ <ArchiveAction
84
+ buildConfiguration = "Release"
85
+ revealArchiveInOrganizer = "YES">
86
+ </ArchiveAction>
87
+</Scheme>
Klepon.xcodeproj/xcshareddata/xcschemes/Klepon Vision.xcscheme
new
+87
@@ -0,0 +1,87 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<Scheme
3
+ LastUpgradeVersion = "2600"
4
+ version = "1.3">
5
+ <BuildAction
6
+ parallelizeBuildables = "YES"
7
+ buildImplicitDependencies = "YES">
8
+ <BuildActionEntries>
9
+ <BuildActionEntry
10
+ buildForTesting = "YES"
11
+ buildForRunning = "YES"
12
+ buildForProfiling = "YES"
13
+ buildForArchiving = "YES"
14
+ buildForAnalyzing = "YES">
15
+ <BuildableReference
16
+ BuildableIdentifier = "primary"
17
+ BlueprintIdentifier = "0322696BE3965C4C0F0E5322"
18
+ BuildableName = "Klepon.app"
19
+ BlueprintName = "Klepon Vision"
20
+ ReferencedContainer = "container:Klepon.xcodeproj">
21
+ </BuildableReference>
22
+ </BuildActionEntry>
23
+ </BuildActionEntries>
24
+ </BuildAction>
25
+ <TestAction
26
+ buildConfiguration = "Debug"
27
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29
+ shouldUseLaunchSchemeArgsEnv = "YES">
30
+ <MacroExpansion>
31
+ <BuildableReference
32
+ BuildableIdentifier = "primary"
33
+ BlueprintIdentifier = "0322696BE3965C4C0F0E5322"
34
+ BuildableName = "Klepon.app"
35
+ BlueprintName = "Klepon Vision"
36
+ ReferencedContainer = "container:Klepon.xcodeproj">
37
+ </BuildableReference>
38
+ </MacroExpansion>
39
+ <Testables>
40
+ </Testables>
41
+ </TestAction>
42
+ <LaunchAction
43
+ buildConfiguration = "Debug"
44
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
45
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
46
+ launchStyle = "0"
47
+ useCustomWorkingDirectory = "NO"
48
+ ignoresPersistentStateOnLaunch = "NO"
49
+ debugDocumentVersioning = "YES"
50
+ debugServiceExtension = "internal"
51
+ allowLocationSimulation = "YES">
52
+ <BuildableProductRunnable
53
+ runnableDebuggingMode = "0">
54
+ <BuildableReference
55
+ BuildableIdentifier = "primary"
56
+ BlueprintIdentifier = "0322696BE3965C4C0F0E5322"
57
+ BuildableName = "Klepon.app"
58
+ BlueprintName = "Klepon Vision"
59
+ ReferencedContainer = "container:Klepon.xcodeproj">
60
+ </BuildableReference>
61
+ </BuildableProductRunnable>
62
+ </LaunchAction>
63
+ <ProfileAction
64
+ buildConfiguration = "Release"
65
+ shouldUseLaunchSchemeArgsEnv = "YES"
66
+ savedToolIdentifier = ""
67
+ useCustomWorkingDirectory = "NO"
68
+ debugDocumentVersioning = "YES">
69
+ <BuildableProductRunnable
70
+ runnableDebuggingMode = "0">
71
+ <BuildableReference
72
+ BuildableIdentifier = "primary"
73
+ BlueprintIdentifier = "0322696BE3965C4C0F0E5322"
74
+ BuildableName = "Klepon.app"
75
+ BlueprintName = "Klepon Vision"
76
+ ReferencedContainer = "container:Klepon.xcodeproj">
77
+ </BuildableReference>
78
+ </BuildableProductRunnable>
79
+ </ProfileAction>
80
+ <AnalyzeAction
81
+ buildConfiguration = "Debug">
82
+ </AnalyzeAction>
83
+ <ArchiveAction
84
+ buildConfiguration = "Release"
85
+ revealArchiveInOrganizer = "YES">
86
+ </ArchiveAction>
87
+</Scheme>
Klepon/App/AppRootView.swift
+24
-9
@@ -5,6 +5,9 @@ struct AppRootView: View {
5
case discover
6
case search
7
case saved
8
+ #if os(tvOS)
9
+ case settings
10
+ #endif
11
}
12
13
@EnvironmentObject private var appState: AppState
@@ -38,17 +41,29 @@ struct AppRootView: View {
41
Label("Saved", systemImage: "heart")
42
}
43
.tag(Tab.saved)
44
+
45
+ #if os(tvOS)
46
+ NavigationStack {
47
+ SettingsView()
48
+ }
49
+ .tabItem {
50
+ Label("Settings", systemImage: "gearshape.2")
51
+ }
52
+ .tag(Tab.settings)
53
+ #endif
54
}
55
.tint(KleponColor.accent)
56
.background(KleponColor.background.ignoresSafeArea())
44
- .sheet(isPresented: $showingSettings) {
45
- NavigationStack {
46
- SettingsView()
57
+ #if !os(tvOS)
58
+ .sheet(isPresented: $showingSettings) {
59
+ NavigationStack {
60
+ SettingsView()
61
+ }
62
+ #if os(macOS) || os(visionOS)
63
+ .frame(minWidth: 480, minHeight: 620)
64
+ #endif
65
}
48
- #if os(macOS)
49
- .frame(minWidth: 480, minHeight: 620)
50
- #endif
51
- }
66
+ #endif
67
.kleponOnboardingPresentation(isPresented: $showingOnboarding) {
68
OnboardingView(
69
onBrowseFirst: {
@@ -58,7 +73,7 @@ struct AppRootView: View {
73
appState.completeOnboarding()
74
}
75
)
61
- #if os(macOS)
76
+ #if os(macOS) || os(visionOS)
77
.frame(minWidth: 640, minHeight: 760)
78
#endif
79
}
@@ -69,7 +84,7 @@ struct AppRootView: View {
84
.onChange(of: appState.hasCompletedOnboarding) { _, newValue in
85
showingOnboarding = !newValue
86
}
72
- #if os(macOS)
87
+ #if os(macOS) || os(visionOS)
88
.frame(minWidth: 980, minHeight: 720)
89
#endif
90
}
Klepon/App/KleponApp.swift
+1
-1
@@ -16,7 +16,7 @@ struct KleponApp: App {
16
.preferredColorScheme(.light)
17
#endif
18
}
19
- #if os(macOS)
19
+ #if os(macOS) || os(visionOS)
20
.defaultSize(width: 1100, height: 760)
21
#endif
22
}
Klepon/App/PlatformViewSupport.swift
+12
-1
@@ -4,6 +4,8 @@ extension ToolbarItemPlacement {
4
static var kleponPrimaryAction: ToolbarItemPlacement {
5
#if os(macOS)
6
return .primaryAction
7
+ #elseif os(tvOS) || os(visionOS)
8
+ return .automatic
9
#else
10
return .topBarTrailing
11
#endif
@@ -11,6 +13,15 @@ extension ToolbarItemPlacement {
13
}
14
15
extension View {
16
+ @ViewBuilder
17
+ func kleponInteractiveButtonStyle() -> some View {
18
+ #if os(tvOS) || os(visionOS)
19
+ self.buttonStyle(.automatic)
20
+ #else
21
+ self.buttonStyle(.plain)
22
+ #endif
23
+ }
24
+
25
@ViewBuilder
26
func kleponInlineNavigationTitle() -> some View {
27
#if os(iOS)
@@ -34,7 +45,7 @@ extension View {
45
isPresented: Binding<Bool>,
46
@ViewBuilder content: @escaping () -> Content
47
) -> some View {
37
- #if os(macOS)
48
+ #if os(macOS) || os(tvOS) || os(visionOS)
49
self.sheet(isPresented: isPresented, content: content)
50
#else
51
self.fullScreenCover(isPresented: isPresented, content: content)
Klepon/Assets.xcassets/AppIconTV.appiconset/AppIconTV-Large.png
Binary files /dev/null and b/Klepon/Assets.xcassets/AppIconTV.appiconset/AppIconTV-Large.png differ
Klepon/Assets.xcassets/AppIconTV.appiconset/AppIconTV-Large@2x.png
Binary files /dev/null and b/Klepon/Assets.xcassets/AppIconTV.appiconset/AppIconTV-Large@2x.png differ
Klepon/Assets.xcassets/AppIconTV.appiconset/AppIconTV-Small.png
Binary files /dev/null and b/Klepon/Assets.xcassets/AppIconTV.appiconset/AppIconTV-Small.png differ
Klepon/Assets.xcassets/AppIconTV.appiconset/AppIconTV-Small@2x.png
Binary files /dev/null and b/Klepon/Assets.xcassets/AppIconTV.appiconset/AppIconTV-Small@2x.png differ
Klepon/Assets.xcassets/AppIconTV.appiconset/Contents.json
new
+12
@@ -0,0 +1,12 @@
1
+{
2
+ "images" : [
3
+ { "idiom" : "tv", "size" : "400x240", "scale" : "1x", "filename" : "AppIconTV-Small.png" },
4
+ { "idiom" : "tv", "size" : "400x240", "scale" : "2x", "filename" : "AppIconTV-Small@2x.png" },
5
+ { "idiom" : "tv", "size" : "1280x768", "scale" : "1x", "filename" : "AppIconTV-Large.png" },
6
+ { "idiom" : "tv", "size" : "1280x768", "scale" : "2x", "filename" : "AppIconTV-Large@2x.png" }
7
+ ],
8
+ "info" : {
9
+ "author" : "xcode",
10
+ "version" : 1
11
+ }
12
+}
Klepon/Assets.xcassets/AppIconVision.appiconset/Contents.json
new
+17
@@ -0,0 +1,17 @@
1
+{
2
+ "images" : [
3
+ { "idiom" : "iphone", "size" : "20x20", "scale" : "2x", "filename" : "Icon-20@2x.png" },
4
+ { "idiom" : "iphone", "size" : "20x20", "scale" : "3x", "filename" : "Icon-20@3x.png" },
5
+ { "idiom" : "iphone", "size" : "29x29", "scale" : "2x", "filename" : "Icon-29@2x.png" },
6
+ { "idiom" : "iphone", "size" : "29x29", "scale" : "3x", "filename" : "Icon-29@3x.png" },
7
+ { "idiom" : "iphone", "size" : "40x40", "scale" : "2x", "filename" : "Icon-40@2x.png" },
8
+ { "idiom" : "iphone", "size" : "40x40", "scale" : "3x", "filename" : "Icon-40@3x.png" },
9
+ { "idiom" : "iphone", "size" : "60x60", "scale" : "2x", "filename" : "Icon-60@2x.png" },
10
+ { "idiom" : "iphone", "size" : "60x60", "scale" : "3x", "filename" : "Icon-60@3x.png" },
11
+ { "idiom" : "ios-marketing", "size" : "1024x1024", "scale" : "1x", "filename" : "Icon-1024.png" }
12
+ ],
13
+ "info" : {
14
+ "author" : "xcode",
15
+ "version" : 1
16
+ }
17
+}
Klepon/Assets.xcassets/AppIconVision.appiconset/Icon-1024.png
Binary files /dev/null and b/Klepon/Assets.xcassets/AppIconVision.appiconset/Icon-1024.png differ
Klepon/Assets.xcassets/AppIconVision.appiconset/Icon-20@2x.png
Binary files /dev/null and b/Klepon/Assets.xcassets/AppIconVision.appiconset/Icon-20@2x.png differ
Klepon/Assets.xcassets/AppIconVision.appiconset/Icon-20@3x.png
Binary files /dev/null and b/Klepon/Assets.xcassets/AppIconVision.appiconset/Icon-20@3x.png differ
Klepon/Assets.xcassets/AppIconVision.appiconset/Icon-29@2x.png
Binary files /dev/null and b/Klepon/Assets.xcassets/AppIconVision.appiconset/Icon-29@2x.png differ
Klepon/Assets.xcassets/AppIconVision.appiconset/Icon-29@3x.png
Binary files /dev/null and b/Klepon/Assets.xcassets/AppIconVision.appiconset/Icon-29@3x.png differ
Klepon/Assets.xcassets/AppIconVision.appiconset/Icon-40@2x.png
Binary files /dev/null and b/Klepon/Assets.xcassets/AppIconVision.appiconset/Icon-40@2x.png differ
Klepon/Assets.xcassets/AppIconVision.appiconset/Icon-40@3x.png
Binary files /dev/null and b/Klepon/Assets.xcassets/AppIconVision.appiconset/Icon-40@3x.png differ
Klepon/Assets.xcassets/AppIconVision.appiconset/Icon-60@2x.png
Binary files /dev/null and b/Klepon/Assets.xcassets/AppIconVision.appiconset/Icon-60@2x.png differ
Klepon/Assets.xcassets/AppIconVision.appiconset/Icon-60@3x.png
Binary files /dev/null and b/Klepon/Assets.xcassets/AppIconVision.appiconset/Icon-60@3x.png differ
Klepon/DesignSystem/KleponActionButton.swift
+1
-1
@@ -34,7 +34,7 @@ struct KleponActionButton: View {
34
)
35
.foregroundStyle(foregroundColor)
36
}
37
- .buttonStyle(.plain)
37
+ .kleponInteractiveButtonStyle()
38
.disabled(isDisabled || isLoading)
39
.opacity((isDisabled || isLoading) && tone == .primary ? 0.85 : 1)
40
}
Klepon/Features/Ask/AskSheetView.swift
+20
-8
@@ -73,7 +73,7 @@ struct AskSheetView: View {
73
)
74
.foregroundStyle(KleponColor.textPrimary)
75
}
76
- .buttonStyle(.plain)
76
+ .kleponInteractiveButtonStyle()
77
.disabled(isLoading)
78
}
79
}
@@ -82,12 +82,24 @@ struct AskSheetView: View {
82
VStack(alignment: .leading, spacing: 12) {
83
SectionHeader("Your question")
84
85
- TextField(
86
- "Ask about taste, ingredients, or what to try next", text: $question,
87
- axis: .vertical
88
- )
89
- .textFieldStyle(.roundedBorder)
90
- .lineLimit(2...5)
85
+ #if os(tvOS)
86
+ TextField(
87
+ "Ask about taste, ingredients, or what to try next", text: $question
88
+ )
89
+ .padding(.horizontal, 14)
90
+ .padding(.vertical, 12)
91
+ .background(
92
+ RoundedRectangle(cornerRadius: 18, style: .continuous)
93
+ .fill(KleponColor.surfaceSecondary)
94
+ )
95
+ #else
96
+ TextField(
97
+ "Ask about taste, ingredients, or what to try next", text: $question,
98
+ axis: .vertical
99
+ )
100
+ .textFieldStyle(.roundedBorder)
101
+ .lineLimit(2...5)
102
+ #endif
103
104
KleponActionButton(
105
title: isLoading ? "Thinking" : "Get answer",
@@ -266,7 +278,7 @@ private struct AnswerCardView: View {
278
)
279
.foregroundStyle(KleponColor.textPrimary)
280
}
269
- .buttonStyle(.plain)
281
+ .kleponInteractiveButtonStyle()
282
.disabled(isInteractionDisabled)
283
}
284
}
Klepon/Features/Detail/GuideDetailView.swift
+2
-2
@@ -80,7 +80,7 @@ struct GuideDetailView: View {
80
}
81
}
82
}
83
- .buttonStyle(.plain)
83
+ .kleponInteractiveButtonStyle()
84
}
85
}
86
}
@@ -184,7 +184,7 @@ struct GuideDetailView: View {
184
)
185
.foregroundStyle(KleponColor.textPrimary)
186
}
187
- .buttonStyle(.plain)
187
+ .kleponInteractiveButtonStyle()
188
}
189
}
190
}
Klepon/Features/Discover/DiscoverView.swift
+14
-12
@@ -39,7 +39,7 @@ struct DiscoverView: View {
39
} label: {
40
FeaturedEntryCard(entry: featuredEntry)
41
}
42
- .buttonStyle(.plain)
42
+ .kleponInteractiveButtonStyle()
43
} else {
44
EmptyStateView(
45
title: "Curated dishes are on the way",
@@ -75,7 +75,7 @@ struct DiscoverView: View {
75
} label: {
76
EntryListCard(entry: entry)
77
}
78
- .buttonStyle(.plain)
78
+ .kleponInteractiveButtonStyle()
79
}
80
}
81
}
@@ -92,7 +92,7 @@ struct DiscoverView: View {
92
} label: {
93
EntryListCard(entry: entry)
94
}
95
- .buttonStyle(.plain)
95
+ .kleponInteractiveButtonStyle()
96
}
97
}
98
}
@@ -105,16 +105,18 @@ struct DiscoverView: View {
105
.background(KleponColor.background.ignoresSafeArea())
106
.navigationTitle("Klepon")
107
.kleponLargeNavigationTitle()
108
- .toolbar {
109
- ToolbarItem(placement: .kleponPrimaryAction) {
110
- Button {
111
- showingSettings = true
112
- } label: {
113
- Image(systemName: "gearshape.2")
108
+ #if !os(tvOS)
109
+ .toolbar {
110
+ ToolbarItem(placement: .kleponPrimaryAction) {
111
+ Button {
112
+ showingSettings = true
113
+ } label: {
114
+ Image(systemName: "gearshape.2")
115
+ }
116
+ .tint(KleponColor.accent)
117
}
115
- .tint(KleponColor.accent)
118
}
117
- }
119
+ #endif
120
}
121
122
private var introSection: some View {
@@ -302,7 +304,7 @@ private struct CollectionRail: View {
304
.fill(KleponColor.surfaceSecondary)
305
)
306
}
305
- .buttonStyle(.plain)
307
+ .kleponInteractiveButtonStyle()
308
}
309
}
310
}
Klepon/Features/Saved/SavedView.swift
+2
-2
@@ -40,7 +40,7 @@ struct SavedView: View {
40
}
41
.frame(maxWidth: .infinity, alignment: .leading)
42
}
43
- .buttonStyle(.plain)
43
+ .kleponInteractiveButtonStyle()
44
45
Button {
46
favoritesStore.toggle(entry.id)
@@ -50,7 +50,7 @@ struct SavedView: View {
50
.padding(10)
51
.background(Circle().fill(KleponColor.surfaceSecondary))
52
}
53
- .buttonStyle(.plain)
53
+ .kleponInteractiveButtonStyle()
54
}
55
}
56
}
Klepon/Features/Search/SearchView.swift
+4
-4
@@ -35,7 +35,7 @@ struct SearchView: View {
35
} label: {
36
KleponChip(title: recentQuery, icon: "clock")
37
}
38
- .buttonStyle(.plain)
38
+ .kleponInteractiveButtonStyle()
39
}
40
}
41
}
@@ -56,7 +56,7 @@ struct SearchView: View {
56
appState.recentSearchStore.record(entry.title)
57
}
58
)
59
- .buttonStyle(.plain)
59
+ .kleponInteractiveButtonStyle()
60
}
61
62
if !recentEntries.isEmpty {
@@ -69,7 +69,7 @@ struct SearchView: View {
69
} label: {
70
SearchResultCard(entry: entry)
71
}
72
- .buttonStyle(.plain)
72
+ .kleponInteractiveButtonStyle()
73
}
74
}
75
}
@@ -94,7 +94,7 @@ struct SearchView: View {
94
appState.recentSearchStore.record(query)
95
}
96
)
97
- .buttonStyle(.plain)
97
+ .kleponInteractiveButtonStyle()
98
}
99
}
100
}
Klepon/Features/Settings/SettingsView.swift
+11
-7
@@ -144,7 +144,9 @@ struct SettingsView: View {
144
145
KleponActionButton(title: "Show welcome again", tone: .secondary) {
146
appState.hasCompletedOnboarding = false
147
- dismiss()
147
+ #if !os(tvOS)
148
+ dismiss()
149
+ #endif
150
}
151
}
152
}
@@ -168,13 +170,15 @@ struct SettingsView: View {
170
}
171
.background(KleponColor.background.ignoresSafeArea())
172
.navigationTitle("Settings")
171
- .toolbar {
172
- ToolbarItem(placement: .kleponPrimaryAction) {
173
- Button("Done") {
174
- dismiss()
173
+ #if !os(tvOS)
174
+ .toolbar {
175
+ ToolbarItem(placement: .kleponPrimaryAction) {
176
+ Button("Done") {
177
+ dismiss()
178
+ }
179
+ .tint(KleponColor.accent)
180
}
176
- .tint(KleponColor.accent)
181
}
178
- }
182
+ #endif
183
}
184
}
KleponTV/Info.plist
new
+26
@@ -0,0 +1,26 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+ <key>CFBundleDevelopmentRegion</key>
6
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
7
+ <key>CFBundleExecutable</key>
8
+ <string>$(EXECUTABLE_NAME)</string>
9
+ <key>CFBundleIdentifier</key>
10
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11
+ <key>CFBundleInfoDictionaryVersion</key>
12
+ <string>6.0</string>
13
+ <key>CFBundleName</key>
14
+ <string>$(PRODUCT_NAME)</string>
15
+ <key>CFBundlePackageType</key>
16
+ <string>APPL</string>
17
+ <key>CFBundleShortVersionString</key>
18
+ <string>$(MARKETING_VERSION)</string>
19
+ <key>CFBundleVersion</key>
20
+ <string>$(CURRENT_PROJECT_VERSION)</string>
21
+ <key>ITSAppUsesNonExemptEncryption</key>
22
+ <false/>
23
+ <key>UILaunchScreen</key>
24
+ <dict/>
25
+</dict>
26
+</plist>
KleponTV/KleponTV.entitlements
new
+10
@@ -0,0 +1,10 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+ <key>com.apple.security.application-groups</key>
6
+ <array>
7
+ <string>group.com.ondeinference.apps</string>
8
+ </array>
9
+</dict>
10
+</plist>
KleponVision/Info.plist
new
+26
@@ -0,0 +1,26 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+ <key>CFBundleDevelopmentRegion</key>
6
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
7
+ <key>CFBundleExecutable</key>
8
+ <string>$(EXECUTABLE_NAME)</string>
9
+ <key>CFBundleIdentifier</key>
10
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11
+ <key>CFBundleInfoDictionaryVersion</key>
12
+ <string>6.0</string>
13
+ <key>CFBundleName</key>
14
+ <string>$(PRODUCT_NAME)</string>
15
+ <key>CFBundlePackageType</key>
16
+ <string>APPL</string>
17
+ <key>CFBundleShortVersionString</key>
18
+ <string>$(MARKETING_VERSION)</string>
19
+ <key>CFBundleVersion</key>
20
+ <string>$(CURRENT_PROJECT_VERSION)</string>
21
+ <key>ITSAppUsesNonExemptEncryption</key>
22
+ <false/>
23
+ <key>UILaunchScreen</key>
24
+ <dict/>
25
+</dict>
26
+</plist>
KleponVision/KleponVision.entitlements
new
+10
@@ -0,0 +1,10 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+ <key>com.apple.security.application-groups</key>
6
+ <array>
7
+ <string>group.com.ondeinference.apps</string>
8
+ </array>
9
+</dict>
10
+</plist>
README.md
+20
-1
@@ -16,11 +16,15 @@ Klepon is a small SwiftUI guide to Indonesian dishes, ingredients, and food trad
16
- curated local content
17
- private on-device follow-up answers with [Onde Inference](https://ondeinference.com)
18
- search, saved items, and recently viewed
19
+- Apple TV support with tvOS focus-friendly navigation
20
+- visionOS window support, kept intentionally simple for v1
21
- watchOS companion support
22
23
## Repo
24
23
-- `Klepon/` app source
25
+- `Klepon/` shared iOS, macOS, tvOS, and visionOS app source
26
+- `KleponTV/` tvOS target configuration
27
+- `KleponVision/` visionOS target configuration
28
- `Klepon.xcodeproj/` Xcode project
29
- `Scripts/validate_content.py` content validation
30
- `AppStore/` store assets and release notes
@@ -34,6 +38,21 @@ iOS simulator:
38
xcodebuild -project Klepon.xcodeproj -scheme Klepon -destination 'generic/platform=iOS Simulator' CODE_SIGNING_ALLOWED=NO build
39
```
40
41
+macOS:
42
+```/dev/null/sh#L1-1
43
+xcodebuild -project Klepon.xcodeproj -scheme 'Klepon Mac' -destination 'platform=macOS' CODE_SIGNING_ALLOWED=NO build
44
+```
45
+
46
+tvOS simulator:
47
+```/dev/null/sh#L1-1
48
+xcodebuild -project Klepon.xcodeproj -scheme 'Klepon TV' -destination 'generic/platform=tvOS Simulator' CODE_SIGNING_ALLOWED=NO build
49
+```
50
+
51
+visionOS simulator:
52
+```/dev/null/sh#L1-1
53
+xcodebuild -project Klepon.xcodeproj -scheme 'Klepon Vision' -destination 'generic/platform=visionOS Simulator' CODE_SIGNING_ALLOWED=NO build
54
+```
55
+
56
watchOS simulator:
57
```/dev/null/sh#L1-1
58
xcodebuild -project Klepon.xcodeproj -scheme 'Klepon Watch' -destination 'generic/platform=watchOS Simulator' CODE_SIGNING_ALLOWED=NO build
project.yml
+169
@@ -3,6 +3,8 @@ options:
3
deploymentTarget:
4
iOS: "18.5"
5
macOS: "15.0"
6
+ tvOS: "18.5"
7
+ visionOS: "1.0"
8
watchOS: "9.0"
9
xcodeVersion: "26.0"
10
generateEmptyDirectories: false
@@ -61,6 +63,30 @@ schemes:
63
config: Release
64
profile:
65
config: Release
66
+ Klepon TV:
67
+ build:
68
+ targets:
69
+ Klepon TV: all
70
+ run:
71
+ config: Debug
72
+ analyze:
73
+ config: Debug
74
+ archive:
75
+ config: Release
76
+ profile:
77
+ config: Release
78
+ Klepon Vision:
79
+ build:
80
+ targets:
81
+ Klepon Vision: all
82
+ run:
83
+ config: Debug
84
+ analyze:
85
+ config: Debug
86
+ archive:
87
+ config: Release
88
+ profile:
89
+ config: Release
90
91
targets:
92
Klepon:
@@ -229,6 +255,149 @@ targets:
255
Release:
256
SWIFT_OPTIMIZATION_LEVEL: -O
257
258
+ KleponTV:
259
+ name: Klepon TV
260
+ type: application
261
+ platform: tvOS
262
+ sources:
263
+ - path: Klepon
264
+ excludes:
265
+ - Info.plist
266
+ - Klepon.entitlements
267
+ info:
268
+ path: KleponTV/Info.plist
269
+ properties:
270
+ CFBundleShortVersionString: $(MARKETING_VERSION)
271
+ CFBundleVersion: $(CURRENT_PROJECT_VERSION)
272
+ ITSAppUsesNonExemptEncryption: false
273
+ UILaunchScreen: {}
274
+ entitlements:
275
+ path: KleponTV/KleponTV.entitlements
276
+ properties:
277
+ com.apple.security.application-groups:
278
+ - group.com.ondeinference.apps
279
+ configFiles:
280
+ Debug: Configs/Signing.xcconfig
281
+ Release: Configs/Signing.xcconfig
282
+ dependencies:
283
+ - package: Onde
284
+ product: Onde
285
+ postBuildScripts:
286
+ - name: Update CFBundleVersion
287
+ shell: /bin/sh
288
+ basedOnDependencyAnalysis: false
289
+ showEnvVars: false
290
+ script: |
291
+ set -eu
292
+
293
+ SHARED_BUNDLE_VERSION_FILE="${BUILD_DIR}/klepon-cfbundleversion.txt"
294
+ if [ -f "${SHARED_BUNDLE_VERSION_FILE}" ]; then
295
+ BUNDLE_VERSION="$(cat "${SHARED_BUNDLE_VERSION_FILE}")"
296
+ else
297
+ BUNDLE_VERSION="$(date -u +"%Y%m%d.%H%M")"
298
+ printf '%s' "${BUNDLE_VERSION}" > "${SHARED_BUNDLE_VERSION_FILE}"
299
+ fi
300
+
301
+ INFO_PLIST="${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
302
+
303
+ if [ ! -f "${INFO_PLIST}" ]; then
304
+ echo "error: Info.plist not found at ${INFO_PLIST}"
305
+ exit 1
306
+ fi
307
+
308
+ if ! /usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${BUNDLE_VERSION}" "${INFO_PLIST}" >/dev/null 2>&1; then
309
+ /usr/libexec/PlistBuddy -c "Add :CFBundleVersion string ${BUNDLE_VERSION}" "${INFO_PLIST}"
310
+ fi
311
+
312
+ echo "Updated CFBundleVersion to ${BUNDLE_VERSION}"
313
+ settings:
314
+ base:
315
+ PRODUCT_BUNDLE_IDENTIFIER: ai.splitfire.klepon.tv
316
+ PRODUCT_NAME: Klepon
317
+ MARKETING_VERSION: "1.0.0"
318
+ CURRENT_PROJECT_VERSION: 1
319
+ ASSETCATALOG_COMPILER_APPICON_NAME: AppIconTV
320
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME: AccentColor
321
+ ENABLE_USER_SCRIPT_SANDBOXING: NO
322
+ TARGETED_DEVICE_FAMILY: 3
323
+ "EXCLUDED_ARCHS[sdk=appletvsimulator*]": x86_64
324
+ configs:
325
+ Debug:
326
+ SWIFT_OPTIMIZATION_LEVEL: -Onone
327
+ Release:
328
+ SWIFT_OPTIMIZATION_LEVEL: -O
329
+
330
+ KleponVision:
331
+ name: Klepon Vision
332
+ type: application
333
+ platform: visionOS
334
+ sources:
335
+ - path: Klepon
336
+ excludes:
337
+ - Info.plist
338
+ - Klepon.entitlements
339
+ info:
340
+ path: KleponVision/Info.plist
341
+ properties:
342
+ CFBundleShortVersionString: $(MARKETING_VERSION)
343
+ CFBundleVersion: $(CURRENT_PROJECT_VERSION)
344
+ ITSAppUsesNonExemptEncryption: false
345
+ UILaunchScreen: {}
346
+ entitlements:
347
+ path: KleponVision/KleponVision.entitlements
348
+ properties:
349
+ com.apple.security.application-groups:
350
+ - group.com.ondeinference.apps
351
+ configFiles:
352
+ Debug: Configs/Signing.xcconfig
353
+ Release: Configs/Signing.xcconfig
354
+ dependencies:
355
+ - package: Onde
356
+ product: Onde
357
+ postBuildScripts:
358
+ - name: Update CFBundleVersion
359
+ shell: /bin/sh
360
+ basedOnDependencyAnalysis: false
361
+ showEnvVars: false
362
+ script: |
363
+ set -eu
364
+
365
+ SHARED_BUNDLE_VERSION_FILE="${BUILD_DIR}/klepon-cfbundleversion.txt"
366
+ if [ -f "${SHARED_BUNDLE_VERSION_FILE}" ]; then
367
+ BUNDLE_VERSION="$(cat "${SHARED_BUNDLE_VERSION_FILE}")"
368
+ else
369
+ BUNDLE_VERSION="$(date -u +"%Y%m%d.%H%M")"
370
+ printf '%s' "${BUNDLE_VERSION}" > "${SHARED_BUNDLE_VERSION_FILE}"
371
+ fi
372
+
373
+ INFO_PLIST="${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
374
+
375
+ if [ ! -f "${INFO_PLIST}" ]; then
376
+ echo "error: Info.plist not found at ${INFO_PLIST}"
377
+ exit 1
378
+ fi
379
+
380
+ if ! /usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${BUNDLE_VERSION}" "${INFO_PLIST}" >/dev/null 2>&1; then
381
+ /usr/libexec/PlistBuddy -c "Add :CFBundleVersion string ${BUNDLE_VERSION}" "${INFO_PLIST}"
382
+ fi
383
+
384
+ echo "Updated CFBundleVersion to ${BUNDLE_VERSION}"
385
+ settings:
386
+ base:
387
+ PRODUCT_BUNDLE_IDENTIFIER: ai.splitfire.klepon.vision
388
+ PRODUCT_NAME: Klepon
389
+ MARKETING_VERSION: "1.0.0"
390
+ CURRENT_PROJECT_VERSION: 1
391
+ ASSETCATALOG_COMPILER_APPICON_NAME: AppIconVision
392
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME: AccentColor
393
+ ENABLE_USER_SCRIPT_SANDBOXING: NO
394
+ "EXCLUDED_ARCHS[sdk=xrsimulator*]": x86_64
395
+ configs:
396
+ Debug:
397
+ SWIFT_OPTIMIZATION_LEVEL: -Onone
398
+ Release:
399
+ SWIFT_OPTIMIZATION_LEVEL: -O
400
+
401
KleponWatch:
402
name: Klepon Watch
403
type: application