Skip to content

Commit ad4be66

Browse files
committed
Merge branch 'chore/add-examples-3' into develop
2 parents ae4f7d0 + d06c293 commit ad4be66

File tree

16 files changed

+622
-161
lines changed

16 files changed

+622
-161
lines changed

LighterExamples.xcodeproj/project.pbxproj

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
/* Begin PBXBuildFile section */
1010
E81B195128A06525003A0F1C /* ProductCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E81B195028A06525003A0F1C /* ProductCell.swift */; };
11-
E81B195328A065A6003A0F1C /* Sidebar.swift in Sources */ = {isa = PBXBuildFile; fileRef = E81B195228A065A6003A0F1C /* Sidebar.swift */; };
11+
E81B195328A065A6003A0F1C /* NavViewSidebar.swift in Sources */ = {isa = PBXBuildFile; fileRef = E81B195228A065A6003A0F1C /* NavViewSidebar.swift */; };
1212
E81B195528A065DD003A0F1C /* ProductPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = E81B195428A065DD003A0F1C /* ProductPage.swift */; };
1313
E81B195728A07563003A0F1C /* ProductForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = E81B195628A07563003A0F1C /* ProductForm.swift */; };
1414
E81B195928A0769D003A0F1C /* Ambiguities.swift in Sources */ = {isa = PBXBuildFile; fileRef = E81B195828A0769D003A0F1C /* Ambiguities.swift */; };
@@ -21,10 +21,15 @@
2121
E8224FBE28A0066800246A1F /* WebDependencies in Frameworks */ = {isa = PBXBuildFile; productRef = E8224FBD28A0066800246A1F /* WebDependencies */; };
2222
E8224FCA28A0071100246A1F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E8224FC928A0071100246A1F /* Assets.xcassets */; };
2323
E8224FCE28A0071100246A1F /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E8224FCD28A0071100246A1F /* Preview Assets.xcassets */; };
24-
E8224FD528A0073000246A1F /* NorthwindSwiftUIApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8224FD328A0073000246A1F /* NorthwindSwiftUIApp.swift */; };
24+
E8224FD528A0073000246A1F /* NorthwindApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8224FD328A0073000246A1F /* NorthwindApp.swift */; };
2525
E8224FD628A0073000246A1F /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8224FD428A0073000246A1F /* ContentView.swift */; };
2626
E8224FDA28A0076E00246A1F /* AppDependencies in Frameworks */ = {isa = PBXBuildFile; productRef = E8224FD928A0076E00246A1F /* AppDependencies */; };
2727
E8224FE128A05CB900246A1F /* ProductsList.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8224FE028A05CB900246A1F /* ProductsList.swift */; };
28+
E87B410D28A3C40500576D8A /* NavView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E87B410C28A3C40500576D8A /* NavView.swift */; };
29+
E87B411228A3C4B900576D8A /* NavVIewProductsList.swift in Sources */ = {isa = PBXBuildFile; fileRef = E87B411128A3C4B900576D8A /* NavVIewProductsList.swift */; };
30+
E87B411428A3C58500576D8A /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E87B411328A3C58500576D8A /* MainView.swift */; };
31+
E87B411628A3C7EB00576D8A /* Sidebar.swift in Sources */ = {isa = PBXBuildFile; fileRef = E87B411528A3C7EB00576D8A /* Sidebar.swift */; };
32+
E87D45FF28A3C341008E04EA /* NavViewMain.swift in Sources */ = {isa = PBXBuildFile; fileRef = E87D45FE28A3C341008E04EA /* NavViewMain.swift */; };
2833
/* End PBXBuildFile section */
2934

3035
/* Begin PBXCopyFilesBuildPhase section */
@@ -41,7 +46,7 @@
4146

4247
/* Begin PBXFileReference section */
4348
E81B195028A06525003A0F1C /* ProductCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductCell.swift; sourceTree = "<group>"; };
44-
E81B195228A065A6003A0F1C /* Sidebar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sidebar.swift; sourceTree = "<group>"; };
49+
E81B195228A065A6003A0F1C /* NavViewSidebar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavViewSidebar.swift; sourceTree = "<group>"; };
4550
E81B195428A065DD003A0F1C /* ProductPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductPage.swift; sourceTree = "<group>"; };
4651
E81B195628A07563003A0F1C /* ProductForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductForm.swift; sourceTree = "<group>"; };
4752
E81B195828A0769D003A0F1C /* Ambiguities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ambiguities.swift; sourceTree = "<group>"; };
@@ -65,12 +70,18 @@
6570
E8224FC928A0071100246A1F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
6671
E8224FCB28A0071100246A1F /* NorthwindSwiftUI.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NorthwindSwiftUI.entitlements; sourceTree = "<group>"; };
6772
E8224FCD28A0071100246A1F /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
68-
E8224FD328A0073000246A1F /* NorthwindSwiftUIApp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NorthwindSwiftUIApp.swift; sourceTree = "<group>"; };
73+
E8224FD328A0073000246A1F /* NorthwindApp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NorthwindApp.swift; sourceTree = "<group>"; };
6974
E8224FD428A0073000246A1F /* ContentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
7075
E8224FDB28A0557000246A1F /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
7176
E8224FDC28A0557000246A1F /* CONTRIBUTING.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CONTRIBUTING.md; sourceTree = "<group>"; };
7277
E8224FDD28A0557000246A1F /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
7378
E8224FE028A05CB900246A1F /* ProductsList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductsList.swift; sourceTree = "<group>"; };
79+
E87B410C28A3C40500576D8A /* NavView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavView.swift; sourceTree = "<group>"; };
80+
E87B411128A3C4B900576D8A /* NavVIewProductsList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavVIewProductsList.swift; sourceTree = "<group>"; };
81+
E87B411328A3C58500576D8A /* MainView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = "<group>"; };
82+
E87B411528A3C7EB00576D8A /* Sidebar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sidebar.swift; sourceTree = "<group>"; };
83+
E87B411728A3CF9D00576D8A /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
84+
E87D45FE28A3C341008E04EA /* NavViewMain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavViewMain.swift; sourceTree = "<group>"; };
7485
/* End PBXFileReference section */
7586

7687
/* Begin PBXFrameworksBuildPhase section */
@@ -180,22 +191,36 @@
180191
E8224FD228A0073000246A1F /* NorthwindSwiftUI */ = {
181192
isa = PBXGroup;
182193
children = (
183-
E8224FD328A0073000246A1F /* NorthwindSwiftUIApp.swift */,
194+
E87B411728A3CF9D00576D8A /* README.md */,
195+
E8224FD328A0073000246A1F /* NorthwindApp.swift */,
184196
E8224FD428A0073000246A1F /* ContentView.swift */,
185-
E81B195228A065A6003A0F1C /* Sidebar.swift */,
197+
E87B411328A3C58500576D8A /* MainView.swift */,
198+
E87B411528A3C7EB00576D8A /* Sidebar.swift */,
186199
E8224FE028A05CB900246A1F /* ProductsList.swift */,
187200
E81B195028A06525003A0F1C /* ProductCell.swift */,
188201
E81B195428A065DD003A0F1C /* ProductPage.swift */,
189202
E81B195628A07563003A0F1C /* ProductForm.swift */,
190203
E81B195A28A0782D003A0F1C /* SupplierForm.swift */,
191204
E81B195C28A07836003A0F1C /* CategoryInfo.swift */,
192205
E81B195E28A078B8003A0F1C /* Picture.swift */,
206+
E87D45FD28A3C2FE008E04EA /* NavigationViewBasedUI */,
193207
E81B195828A0769D003A0F1C /* Ambiguities.swift */,
194208
);
195209
name = NorthwindSwiftUI;
196210
path = Sources/NorthwindSwiftUI;
197211
sourceTree = "<group>";
198212
};
213+
E87D45FD28A3C2FE008E04EA /* NavigationViewBasedUI */ = {
214+
isa = PBXGroup;
215+
children = (
216+
E87B410C28A3C40500576D8A /* NavView.swift */,
217+
E87D45FE28A3C341008E04EA /* NavViewMain.swift */,
218+
E81B195228A065A6003A0F1C /* NavViewSidebar.swift */,
219+
E87B411128A3C4B900576D8A /* NavVIewProductsList.swift */,
220+
);
221+
path = NavigationViewBasedUI;
222+
sourceTree = "<group>";
223+
};
199224
/* End PBXGroup section */
200225

201226
/* Begin PBXNativeTarget section */
@@ -268,6 +293,8 @@
268293
Base,
269294
);
270295
mainGroup = E8224F8228A005CF00246A1F;
296+
packageReferences = (
297+
);
271298
productRefGroup = E8224F8C28A005CF00246A1F /* Products */;
272299
projectDirPath = "";
273300
projectRoot = "";
@@ -307,15 +334,20 @@
307334
files = (
308335
E81B195528A065DD003A0F1C /* ProductPage.swift in Sources */,
309336
E81B195D28A07836003A0F1C /* CategoryInfo.swift in Sources */,
310-
E81B195328A065A6003A0F1C /* Sidebar.swift in Sources */,
337+
E87B411628A3C7EB00576D8A /* Sidebar.swift in Sources */,
338+
E81B195328A065A6003A0F1C /* NavViewSidebar.swift in Sources */,
339+
E87B410D28A3C40500576D8A /* NavView.swift in Sources */,
311340
E81B195F28A078B8003A0F1C /* Picture.swift in Sources */,
341+
E87B411428A3C58500576D8A /* MainView.swift in Sources */,
312342
E81B195728A07563003A0F1C /* ProductForm.swift in Sources */,
343+
E87D45FF28A3C341008E04EA /* NavViewMain.swift in Sources */,
344+
E87B411228A3C4B900576D8A /* NavVIewProductsList.swift in Sources */,
313345
E8224FE128A05CB900246A1F /* ProductsList.swift in Sources */,
314346
E81B195128A06525003A0F1C /* ProductCell.swift in Sources */,
315347
E81B195928A0769D003A0F1C /* Ambiguities.swift in Sources */,
316348
E81B195B28A0782D003A0F1C /* SupplierForm.swift in Sources */,
317349
E8224FD628A0073000246A1F /* ContentView.swift in Sources */,
318-
E8224FD528A0073000246A1F /* NorthwindSwiftUIApp.swift in Sources */,
350+
E8224FD528A0073000246A1F /* NorthwindApp.swift in Sources */,
319351
);
320352
runOnlyForDeploymentPostprocessing = 0;
321353
};
@@ -485,10 +517,10 @@
485517
"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
486518
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
487519
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
488-
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
520+
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
489521
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
490522
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
491-
MACOSX_DEPLOYMENT_TARGET = 12.5;
523+
MACOSX_DEPLOYMENT_TARGET = 12.4;
492524
MARKETING_VERSION = 1.0;
493525
PRODUCT_BUNDLE_IDENTIFIER = de.zeezide.lighter.NorthwindSwiftUI;
494526
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -521,10 +553,10 @@
521553
"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
522554
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
523555
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
524-
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
556+
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
525557
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
526558
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
527-
MACOSX_DEPLOYMENT_TARGET = 12.5;
559+
MACOSX_DEPLOYMENT_TARGET = 12.4;
528560
MARKETING_VERSION = 1.0;
529561
PRODUCT_BUNDLE_IDENTIFIER = de.zeezide.lighter.NorthwindSwiftUI;
530562
PRODUCT_NAME = "$(TARGET_NAME)";

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@ Examples for the Lighter SQLite environment, SwiftUI and server side.
77

88
Note: The examples requires Swift 5.7 / Xcode 14b for proper plugin support.
99

10-
When embedding a package using Lighter (like
10+
When embedding a package using Enlighter (like
1111
[NorthwindSQLite.swift](https://github.com/Lighter-swift/NorthwindSQLite.swift.git)),
1212
[a local package](https://developer.apple.com/documentation/xcode/organizing-your-code-with-local-packages)
13-
seems to be required w/ the Xcode 14 beta.
13+
seems to be required w/ the Xcode 14 beta (3...5).
1414
Otherwise the Swift package plugins do not seem to run.
1515
In the example project this is the "AppLogic" package.
16+
If Xcode gets stuck or doesn't run the plugin, a package update sometimes
17+
help.
18+
1619

1720
### Northwind Database
1821

Sources/NorthwindSwiftUI/ContentView.swift

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,11 @@ import Northwind
44
struct ContentView: View {
55

66
var body: some View {
7-
NavigationView {
8-
Sidebar()
9-
10-
ProductsList()
11-
12-
ZStack {
13-
Text("Nothing Selected")
14-
.font(.title)
15-
.foregroundColor(.accentColor)
16-
}
17-
.layoutPriority(2)
7+
if #available(iOS 16, macOS 13, *) {
8+
MainView()
9+
}
10+
else {
11+
NavView.MainView()
1812
}
19-
.frame(minWidth: 640, minHeight: 340)
2013
}
2114
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import SwiftUI
2+
import Northwind
3+
4+
@available(iOS 16.0, macOS 13, *)
5+
struct MainView: View {
6+
7+
enum Section: String {
8+
case products
9+
}
10+
enum Detail {
11+
case product(Product)
12+
}
13+
14+
/// The active section in the sidebar
15+
@State private var section : Section? = .products
16+
17+
/// The array of products that got fetched
18+
@State private var products : [ Product ] = []
19+
20+
/// We track the currently selected product
21+
@State private var selectedProductID : Product.ID?
22+
23+
24+
private var selectedProduct : Product? {
25+
selectedProductID.flatMap { id in products.first(where: { $0.id == id })}
26+
}
27+
28+
private func updateSavedProduct(_ product: Product) {
29+
guard let idx = products.firstIndex(where: { $0.id == product.id }) else {
30+
return // not in the list?
31+
}
32+
products[idx] = product
33+
}
34+
35+
36+
var body: some View {
37+
NavigationSplitView(
38+
39+
sidebar: {
40+
Sidebar(section: $section)
41+
},
42+
43+
content: {
44+
switch section {
45+
case .products:
46+
ProductsList(products: $products,
47+
selectedProduct: $selectedProductID)
48+
49+
case .none:
50+
Text("No section is selected")
51+
}
52+
},
53+
54+
detail: {
55+
if let product = selectedProduct {
56+
ProductPage(snapshot: product, onSave: updateSavedProduct)
57+
}
58+
else {
59+
Text("Nothing Selected")
60+
.font(.title)
61+
.foregroundColor(.accentColor)
62+
}
63+
}
64+
)
65+
}
66+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import SwiftUI
2+
import Northwind
3+
4+
@available(iOS, introduced: 13.0, deprecated: 16.0)
5+
@available(macOS, introduced: 10.15, deprecated: 13.0)
6+
extension NavView {
7+
8+
struct ProductsList: View {
9+
10+
/// The database is passed down by the App struct in the environment.
11+
@Environment(\.database) private var database
12+
13+
/// In this state we keep the list of currently fetched products.
14+
@State private var products : [ Product ] = []
15+
16+
/// We track the currently selected product
17+
@State private var selectedProduct : Product.ID?
18+
19+
/// For current search string
20+
@State private var searchString = ""
21+
22+
private func updateSavedProduct(_ product: Product) {
23+
guard let idx = products.firstIndex(where: { $0.id == product.id }) else {
24+
return // not in the list?
25+
}
26+
products[idx] = product
27+
}
28+
29+
var body: some View {
30+
List {
31+
ForEach(products) { product in
32+
NavigationLink(
33+
destination: ProductPage(snapshot: product,
34+
onSave: updateSavedProduct),
35+
tag: product.id, selection: $selectedProduct
36+
)
37+
{
38+
ProductCell(product: product)
39+
}
40+
}
41+
}
42+
.searchable(text: $searchString)
43+
.task(id: searchString) {
44+
45+
do {
46+
// Here we are using a query builder to filter by column. Alternatively
47+
// one can use an arbitrary Swift closure using `filter`.
48+
products = try await database.products.fetch(orderBy: \.productName) {
49+
$0.productName.contains(
50+
searchString.trimmingCharacters(in: .whitespacesAndNewlines),
51+
caseInsensitive: true
52+
)
53+
}
54+
55+
// Pre-select the first match if none is selected
56+
if selectedProduct == nil, let product = products.first {
57+
selectedProduct = product.id
58+
}
59+
}
60+
catch { // really, do proper error handling :-)
61+
print("Fetch failed:", error)
62+
}
63+
}
64+
65+
#if os(macOS)
66+
// Doesn't update without? (i.e. the one attached to the item is ignored)
67+
.navigationTitle(selectedProduct.flatMap { selectedID in
68+
products.first { $0.id == selectedID }?.productName
69+
} ?? "Products")
70+
#else
71+
.navigationTitle("Products")
72+
#endif
73+
}
74+
}
75+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import SwiftUI
2+
3+
/**
4+
* Just a holder for the `NavigationView` based UI that works
5+
* on macOS 11.
6+
*/
7+
@available(iOS, introduced: 13.0, deprecated: 16.0)
8+
@available(macOS, introduced: 10.15, deprecated: 13.0)
9+
enum NavView {}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import SwiftUI
2+
3+
@available(iOS, introduced: 13.0, deprecated: 16.0)
4+
@available(macOS, introduced: 10.15, deprecated: 13.0)
5+
extension NavView {
6+
7+
struct MainView: View {
8+
9+
var body: some View {
10+
NavigationView {
11+
12+
// Column 1
13+
Sidebar()
14+
15+
// Column 2
16+
ProductsList()
17+
18+
// Column 3
19+
ZStack {
20+
Text("Nothing Selected")
21+
.font(.title)
22+
.foregroundColor(.accentColor)
23+
}
24+
.layoutPriority(2)
25+
}
26+
}
27+
}
28+
}

0 commit comments

Comments
 (0)