This sample app use the Star Wars public api to show a list of characters

Overview

StarWars-MVVM

In this sample app, I use the Star Wars public api to show a list of characters from the Star Wars movie series. There are two goals I wish to accomplish with this repository:

  1. Show a project that is built with the MVVM architecture design pattern.
  2. Add unit tests with XCTest that test more UI logic than before

MVVM

MVVM stands for Model View ViewModel. The view model portion is where state and presentation logic go. Doing so allows the view controller to be basic and simple. The view controller then binds to the view model and does what it's told.

Testing

MVVM allows us to more fully test the state and presentation logic of the view with just the XCTest framework. Testing UI logic beyond that is normally done by the XCUITest framework. However, with a few tips and tricks in XCTest we can also test things like:

  1. Pushing a view into the view hirearchy
  2. Presenting a view

For examples of this see PersonsViewControllerTests.swift

Guidelines

View model should reside in an extension of the view controller it's associated with

extension ExampleViewController {
  class ViewModel {
    ...  
  }
}

Use @Published over PassthroughSubject or CurrentValueSubject

class ViewModel {
  @Published private(set) var results: [PersonProtocol] = []
  // other variables here
  
  ...
}
  • We will be using @Published which will act as the publisher for communicating with the view controllers and SwiftUI views. The @Published properwrapper is class contrained so the view model must be a class.
  • Since all view model operations are dealing with updating the UI, it is reasonable to have all of our view models be marked with @MainActor. This ensures all attributes and methods called are done so on the main thread.
  • To keep the integrity of the variables in the view model, it is good practice to set them at private(set) so that the variables are only able to be set inside the view model. If there is a need to update the values from the view then just create a method with to handle that update and handle all the validation there to safely update the variables.

We should limit the content of the view model to be: 1) presentation logic and 2) state.

State

Generally speaking, there should be no need for the view controller or SwiftUI view to hold variable related to state.

Presentation Logic

All presentation logic should reside in the view model. The following are some examples of presentation logic:

  1. Calculating data source values of a UITableView/UICollectionView
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.viewModel.getNumPersons()
}
    
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: PersonTableViewCell.identifier, for: indexPath) as! PersonTableViewCell
    cell.configureCell(self.viewModel.getPerson(for: indexPath))
    return cell
}
  1. Deciding when the UI should be updated to a different state

(Example: telling the UI to show a loading indicator)

class ViewModel {
  ...

  func loadAllPersons() async throws {
        self.loading = true
        do {
            let persons = try await service.getAllPersons()
            self.results = persons
            self.filteredResults = persons
        } catch let error {
            self.error = error
        }
        self.loading = false
  }
}

  1. Logic to decide what text should be displayed based on certain conditions
class ViewModel {
  ...

  func calculateTitleText() -> String {
      if Date().isWeekDay {
        return NSLocalizedString("Week")
      } else {
        return NSLocalizedString("Weekend")
      }
  }
}
You might also like...
Sample app to demonstrate the integration code and working of Dyte SDK for iOS, using Swift
Sample app to demonstrate the integration code and working of Dyte SDK for iOS, using Swift

docs-template by dyte ADD_DESCRIPTION_HERE Explore the docs » View Demo · Report Bug · Request Feature Table of Contents About the Project Built With

A sample app that will display some airport information using MVVM pattern

Simulator.Screen.Recording.-.iPhone.11.-.2021-11-15.at.14.27.41.mp4 AirportDisplayApp A sample app that will display some airport information using MV

 Sample iOS App  - A collection of examples and patterns for Unit Testing, UI Testing, handling Result/Optionals, writing documentation
 Sample iOS App - A collection of examples and patterns for Unit Testing, UI Testing, handling Result/Optionals, writing documentation

 Sample iOS App - A collection of examples and patterns for Unit Testing, UI Testing, handling Result/Optionals, writing documentation, and more

Apple ExtensionFoundation/ExtensionKit sample app
Apple ExtensionFoundation/ExtensionKit sample app

TextTransformer: an ExtensionKit sample app This year's WWDC introduced many new APIs, two of which caught my attention: ExtensionFoundation and Exten

A simple app that downloads a list of albums from iTunes and displays it in a table

A simple, sample app that downloads a list of albums from iTunes and displays it in a table. It also allows the user to bookmark albums which are then

This project is built to show how to support accessibility features in iOS applications in UIKit.
This project is built to show how to support accessibility features in iOS applications in UIKit.

ACCESSIBILITY EXAMPLE This project is built to show how to support accessibility features in iOS applications in a blog post. For the sake of Accessib

Sample Code for WWDC21

WWDC21 Sample Code Accessibility Create Accessible Experiences for watchOS Creating Accessible Views WWDC21 Challenge: Large Text Challenge WWDC21 Cha

REDUX like architecture sample for iOS

perdux_sample_swiftUI REDUX like architecture sample for iOS (target 14.*) Motivation: to share reactive architecture approach with single direction d

Apple cloudkit sample encryption

CloudKit Samples: Encryption Goals This project demonstrates using encrypted values with CloudKit and iCloud containers. CloudKit encrypts data with k

Owner
Paul O'Neill
iOS
Paul O'Neill
CarListing app allows user to see list of cars on map as well as in the list

Car Listing CarListing app allows user to see list of cars on map as well as in the list. Features See List of cars on map in the home screen. User ca

Niraj Kumar Jha 0 Oct 13, 2021
UIKit Chat List Sample

When I tried to make a UI like this, I faced a problem. When keyboard appears, TableView doesn't scroll automatically. I wanted to make the feature tableview scrolls automatically so I tried to make this project. Below images describe the difference without feature and with feature properly.

null 3 Jan 1, 2022
Code Swift iOS app showcasing basic movies list from Orange TV API.

iOS Code Test - Optiva Media Code Swift iOS app showcasing basic movies list from Orange TV API. Built using XCode 13.0 (Swift 5) How to run the examp

Manu Martinez 1 Oct 17, 2021
iOS App showing a list of Top Movies from The Movie Database API, with a movies searcher

TMDBTest App para iOS que muestra un listado de películas destacadas haciendo uso de la API de "The Movie Database". Además la app dispone de un busca

Alex Zaragoza 1 May 5, 2022
AnimeSearch - A simple app that shows how to use Anilist GraphQL based API with Apollo

AnimeSearch A simple app that shows how to use Anilist GraphQL based API with Ap

Pedro J Fernandez 1 Apr 26, 2022
Sample app to demonstrate using Firebase features

Photoram Sample app to demonstrate using Firebase features Uses: Firebase authentification for login and registrations Firebase storage to keep image

Anna Zharkova 3 Jun 4, 2021
This is a sample project that supplements the tutorial written over at my blog on 'Building a music recognization app in SwiftUI with ShazamKit'

Shazam-Kit-Tutorial This is a sample project that supplements the tutorial written over at my blog on 'Building a music recognization app in SwiftUI w

Swapnanil Dhol 7 Mar 17, 2022
A sample iOS app built using the Clean Swift architecture

Main Purpose is to create a simple project for Clean-Swift This project wrote with using Clean-Swift and MVP Design Pattern

Eyup Cimen 8 Oct 24, 2022
InputMethodKit Sample App with macOS11, Xcode13, Swift5.5 in 2021.

What is this? This is a sample implementation of IMKit App with Swift/SwiftUI. Working Environment macOS 11.5 Swift 5.5 Xcode13 (beta) Procedure to ma

ensan 19 Nov 4, 2022