Skip to content

Commit 786fbca

Browse files
Added docs
1 parent 399e864 commit 786fbca

12 files changed

Lines changed: 1972 additions & 6 deletions

File tree

0 Bytes
Binary file not shown.

ScalablePackageNavigation/AppRouter/Sources/AppRouter/AppRouter.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ public enum Route {
1313
public class AppRouter: ObservableObject {
1414
@Published public var path: [Route] = []
1515
@Published public var cartItems: [String] = []
16-
public init() {} // Add public initializer
16+
public init() {}
1717
}

ScalablePackageNavigation/OrderSummaryPackage/Sources/OrderSummaryPackage/OrderSummaryView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public struct OrderSummaryView: View {
1010

1111
public var body: some View {
1212
VStack(spacing: 20) {
13-
Text("📦 Order Summary")
13+
Text(" Order Summary 📦")
1414
.font(.largeTitle)
1515
ForEach(router.cartItems, id: \.self) { item in
1616
Text("Ordered: \(item)")
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# ScalablePackageNavigation
2+
3+
A modular iOS application demonstrating scalable package-based navigation architecture using SwiftUI and Swift Package Manager.
4+
5+
## 📱 Overview
6+
7+
This project showcases a clean, modular approach to iOS app development by separating concerns into distinct Swift packages. The application implements a simple pizza ordering system with three main screens: Dashboard, Cart, and Order Summary.
8+
9+
## 🏗️ Architecture
10+
11+
The project follows a modular architecture pattern with the following components:
12+
13+
### Core Packages
14+
15+
1. **AppRouter** - Central navigation and state management
16+
2. **CartPackage** - Shopping cart functionality
17+
3. **OrderSummaryPackage** - Order summary and checkout flow
18+
19+
### Main App
20+
21+
- **ScalablePackageNavigation** - Main iOS application that orchestrates all packages
22+
23+
## 📦 Package Structure
24+
25+
```
26+
ScalablePackageNavigation/
27+
├── AppRouter/ # Navigation and state management
28+
│ ├── Package.swift
29+
│ └── Sources/AppRouter/
30+
│ └── AppRouter.swift
31+
├── CartPackage/ # Shopping cart functionality
32+
│ ├── Package.swift
33+
│ └── Sources/CartPackage/
34+
│ └── CartView.swift
35+
├── OrderSummaryPackage/ # Order summary and checkout
36+
│ ├── Package.swift
37+
│ └── Sources/OrderSummaryPackage/
38+
│ └── OrderSummaryView.swift
39+
└── ScalablePackageNavigation/ # Main iOS application
40+
├── AppViews/
41+
│ ├── DashboardView.swift
42+
│ └── ModularCartApp.swift
43+
└── ScalablePackageNavigation.xcodeproj/
44+
```
45+
46+
## 🚀 Features
47+
48+
- **Modular Design**: Each feature is contained within its own Swift package
49+
- **Centralized Navigation**: Single router manages all navigation state
50+
- **Shared State Management**: Cart items are shared across all modules
51+
- **SwiftUI Integration**: Modern UI framework with declarative syntax
52+
- **Package Dependencies**: Clean dependency management using Swift Package Manager
53+
54+
## 🛠️ Technical Implementation
55+
56+
### AppRouter Package
57+
58+
The `AppRouter` package serves as the central nervous system of the application:
59+
60+
- **Route Enum**: Defines all possible navigation destinations
61+
- **AppRouter Class**: ObservableObject that manages navigation state and shared data
62+
- **Published Properties**: `path` for navigation stack and `cartItems` for shared cart state
63+
64+
### Navigation Flow
65+
66+
1. **Dashboard** → Add items to cart → Navigate to Cart
67+
2. **Cart** → Review items → Place order → Navigate to Summary
68+
3. **Order Summary** → Complete order → Return to Dashboard
69+
70+
### State Management
71+
72+
- Uses `@EnvironmentObject` to inject the router into all views
73+
- `@Published` properties ensure UI updates when state changes
74+
- Navigation stack is managed through the `path` array
75+
76+
## 📋 Requirements
77+
78+
- iOS 13.0+
79+
- Xcode 14.0+
80+
- Swift 6.2+
81+
82+
## 🏃‍♂️ Getting Started
83+
84+
1. Clone the repository
85+
2. Open `ScalablePackageNavigation.xcodeproj` in Xcode
86+
3. Build and run the project
87+
4. Navigate through the app to see the modular navigation in action
88+
89+
## 🔧 Development
90+
91+
### Adding New Features
92+
93+
1. Create a new Swift package in the project root
94+
2. Define dependencies in `Package.swift`
95+
3. Create your feature views
96+
4. Add new routes to the `Route` enum in `AppRouter`
97+
5. Update the main app's navigation destination switch
98+
99+
### Package Dependencies
100+
101+
- **AppRouter**: No dependencies (core package)
102+
- **CartPackage**: Depends on AppRouter
103+
- **OrderSummaryPackage**: Depends on AppRouter
104+
- **Main App**: Depends on all three packages
105+
106+
## 🎯 Benefits of This Architecture
107+
108+
1. **Scalability**: Easy to add new features as separate packages
109+
2. **Maintainability**: Clear separation of concerns
110+
3. **Reusability**: Packages can be reused in other projects
111+
4. **Testing**: Each package can be tested independently
112+
5. **Team Collaboration**: Different teams can work on different packages
113+
6. **Dependency Management**: Clear dependency graph with Swift Package Manager
114+
115+
## 📚 Code Examples
116+
117+
### Adding Items to Cart
118+
```swift
119+
Button("Add Pizza to Cart") {
120+
router.cartItems.append("Pizza")
121+
router.path.append(.cart)
122+
}
123+
```
124+
125+
### Navigation
126+
```swift
127+
router.path.append(.summary) // Navigate to summary
128+
router.path = [] // Clear navigation stack
129+
```
130+
131+
### Environment Object Usage
132+
```swift
133+
@EnvironmentObject var router: AppRouter
134+
```
135+
136+
## 🤝 Contributing
137+
138+
1. Fork the repository
139+
2. Create a feature branch
140+
3. Make your changes
141+
4. Test thoroughly
142+
5. Submit a pull request
143+
144+
## 📄 License
145+
146+
This project is open source and available under the [MIT License](LICENSE).
147+
148+
## 🆘 Support
149+
150+
For questions or issues, please open an issue in the repository.

ScalablePackageNavigation/ScalablePackageNavigation.xcodeproj/project.pbxproj

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,26 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
4F1204732E464F250023D2FE /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 4F1204722E464F250023D2FE /* README.md */; };
11+
4F12047B2E464F2C0023D2FE /* DEVELOPMENT_GUIDE.md in Resources */ = {isa = PBXBuildFile; fileRef = 4F1204762E464F2C0023D2FE /* DEVELOPMENT_GUIDE.md */; };
12+
4F12047C2E464F2C0023D2FE /* QUICK_START.md in Resources */ = {isa = PBXBuildFile; fileRef = 4F1204772E464F2C0023D2FE /* QUICK_START.md */; };
13+
4F12047D2E464F2C0023D2FE /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 4F1204782E464F2C0023D2FE /* README.md */; };
14+
4F12047E2E464F2C0023D2FE /* TROUBLESHOOTING.md in Resources */ = {isa = PBXBuildFile; fileRef = 4F1204792E464F2C0023D2FE /* TROUBLESHOOTING.md */; };
15+
4F12047F2E464F2C0023D2FE /* ARCHITECTURE.md in Resources */ = {isa = PBXBuildFile; fileRef = 4F1204752E464F2C0023D2FE /* ARCHITECTURE.md */; };
16+
4F1204802E464F2C0023D2FE /* API_REFERENCE.md in Resources */ = {isa = PBXBuildFile; fileRef = 4F1204742E464F2C0023D2FE /* API_REFERENCE.md */; };
1017
4F381BEB2E4648FF006B6CDA /* AppRouter in Frameworks */ = {isa = PBXBuildFile; productRef = 4F381BEA2E4648FF006B6CDA /* AppRouter */; };
1118
4FC6A5072E463C0E0034244F /* OrderSummaryPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 4FC6A5062E463C0E0034244F /* OrderSummaryPackage */; };
1219
4FC6A50A2E463C140034244F /* CartPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 4FC6A5092E463C140034244F /* CartPackage */; };
1320
/* End PBXBuildFile section */
1421

1522
/* Begin PBXFileReference section */
23+
4F1204722E464F250023D2FE /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
24+
4F1204742E464F2C0023D2FE /* API_REFERENCE.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = API_REFERENCE.md; sourceTree = "<group>"; };
25+
4F1204752E464F2C0023D2FE /* ARCHITECTURE.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = ARCHITECTURE.md; sourceTree = "<group>"; };
26+
4F1204762E464F2C0023D2FE /* DEVELOPMENT_GUIDE.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = DEVELOPMENT_GUIDE.md; sourceTree = "<group>"; };
27+
4F1204772E464F2C0023D2FE /* QUICK_START.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = QUICK_START.md; sourceTree = "<group>"; };
28+
4F1204782E464F2C0023D2FE /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
29+
4F1204792E464F2C0023D2FE /* TROUBLESHOOTING.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = TROUBLESHOOTING.md; sourceTree = "<group>"; };
1630
4FC6A4DC2E4628C50034244F /* ScalablePackageNavigation.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ScalablePackageNavigation.app; sourceTree = BUILT_PRODUCTS_DIR; };
1731
/* End PBXFileReference section */
1832

@@ -38,9 +52,24 @@
3852
/* End PBXFrameworksBuildPhase section */
3953

4054
/* Begin PBXGroup section */
55+
4F12047A2E464F2C0023D2FE /* docs */ = {
56+
isa = PBXGroup;
57+
children = (
58+
4F1204742E464F2C0023D2FE /* API_REFERENCE.md */,
59+
4F1204752E464F2C0023D2FE /* ARCHITECTURE.md */,
60+
4F1204762E464F2C0023D2FE /* DEVELOPMENT_GUIDE.md */,
61+
4F1204772E464F2C0023D2FE /* QUICK_START.md */,
62+
4F1204782E464F2C0023D2FE /* README.md */,
63+
4F1204792E464F2C0023D2FE /* TROUBLESHOOTING.md */,
64+
);
65+
path = docs;
66+
sourceTree = "<group>";
67+
};
4168
4FC6A4D32E4628C50034244F = {
4269
isa = PBXGroup;
4370
children = (
71+
4F12047A2E464F2C0023D2FE /* docs */,
72+
4F1204722E464F250023D2FE /* README.md */,
4473
4FC6A4DE2E4628C50034244F /* ScalablePackageNavigation */,
4574
4FC6A4DD2E4628C50034244F /* Products */,
4675
);
@@ -127,6 +156,13 @@
127156
isa = PBXResourcesBuildPhase;
128157
buildActionMask = 2147483647;
129158
files = (
159+
4F1204732E464F250023D2FE /* README.md in Resources */,
160+
4F12047B2E464F2C0023D2FE /* DEVELOPMENT_GUIDE.md in Resources */,
161+
4F12047C2E464F2C0023D2FE /* QUICK_START.md in Resources */,
162+
4F12047D2E464F2C0023D2FE /* README.md in Resources */,
163+
4F12047E2E464F2C0023D2FE /* TROUBLESHOOTING.md in Resources */,
164+
4F12047F2E464F2C0023D2FE /* ARCHITECTURE.md in Resources */,
165+
4F1204802E464F2C0023D2FE /* API_REFERENCE.md in Resources */,
130166
);
131167
runOnlyForDeploymentPostprocessing = 0;
132168
};
@@ -203,6 +239,7 @@
203239
SDKROOT = iphoneos;
204240
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
205241
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
242+
SWIFT_VERSION = 6.0;
206243
};
207244
name = Debug;
208245
};
@@ -258,6 +295,7 @@
258295
MTL_FAST_MATH = YES;
259296
SDKROOT = iphoneos;
260297
SWIFT_COMPILATION_MODE = wholemodule;
298+
SWIFT_VERSION = 6.0;
261299
VALIDATE_PRODUCT = YES;
262300
};
263301
name = Release;
@@ -295,7 +333,7 @@
295333
SWIFT_OBJC_BRIDGING_HEADER = "ScalablePackageNavigation/AppViews/ScalablePackageNavigation-Bridging-Header.h";
296334
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
297335
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
298-
SWIFT_VERSION = 5.0;
336+
SWIFT_VERSION = 6.0;
299337
TARGETED_DEVICE_FAMILY = 1;
300338
};
301339
name = Debug;
@@ -332,7 +370,7 @@
332370
SWIFT_EMIT_LOC_STRINGS = YES;
333371
SWIFT_OBJC_BRIDGING_HEADER = "ScalablePackageNavigation/AppViews/ScalablePackageNavigation-Bridging-Header.h";
334372
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
335-
SWIFT_VERSION = 5.0;
373+
SWIFT_VERSION = 6.0;
336374
TARGETED_DEVICE_FAMILY = 1;
337375
};
338376
name = Release;

ScalablePackageNavigation/ScalablePackageNavigation/AppViews/ModularCartApp.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ struct ScalableNavigationApp: App {
1111
WindowGroup {
1212
NavigationStack(path: $router.path) {
1313
DashboardView()
14-
.environmentObject(router) // 👈 inject here
14+
.environmentObject(router)
1515
.navigationDestination(for: Route.self) { route in
1616
switch route {
1717
case .cart:
1818
CartView()
19-
.environmentObject(router) // 👈 inject here too
19+
.environmentObject(router)
2020
case .summary:
2121
OrderSummaryView()
2222
.environmentObject(router)

0 commit comments

Comments
 (0)