This iOS app is structured with a modular architecture and split into multiple Swift packages for better scalability and maintainability. It utilizes dependency injection to ensure that components are loosely coupled and easily testable.
-
Dependency Injection: The project uses dependency injection to manage dependencies between components. The project uses a protocol
DataServiceProtocolto define the interface for data services. TheDataServiceclass implements this protocol to fetch data from a remote service, while theMockDataServiceclass provides mock data for testing. -
SwiftData: Using Query and Modalcontainer to fetch and save data. UI queries data from database.
try modelContext.transaction {
for item in list {
modelContext.insert(item)
}
do {
try modelContext.save()
} catch {
self.error = error.localizedDescription
}
}
....
init(searchText: String) {
let predicate = (searchText.isEmpty) ? nil : #Predicate<Person> {$0.name.contains(searchText)}
_people = Query(filter: predicate,
sort: [SortDescriptor(\Person.name)])
}
@Query private var people: [Person]- Protocol: A protocol is defined to outline the required methods for data services.
protocol DataServiceProtocol {
func getPersonList() async throws -> [Person]
}- Mock Data Service: A mock data service is implemented to simulate data operations for testing purposes. which uses
Corepackage to load a json file
public actor MockDataService: DataServiceProtocol {
var throwError: Bool
public init(throwError: Bool = false) {
self.throwError = throwError
}
public func getPersonList() async throws -> [Person] {
guard throwError == false else {
throw CustomError.undefined
}
return try Core.FileManager.contents(of: "people", in: Bundle.module) as [Person]
}
}- ViewModel: The PersonViewModel class uses the data service to load and filter user data.
extension PeopleView {
@Observable @MainActor
class ViewModel {
private let service: DataServiceProtocol
// Implementation of view model
}
}This project is licensed under the BSD 3-Clause License - see the LICENSE file for details.