norsez / MyTimeline

An example iOS app project based on MVVM, RxSwift and Realm

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

MyTimeLine

An example iOS MVVM app with RxSwift with Realm.

Architecture

Use MVVM with RxSwift on the app (except on the simplistic PostViewConroller screen to avoid overengineering.)

Model

  • Post represents posts in the timeline implemented as a Realm object.

ViewModel

These view models use RxSwift to update their associated views. The pattern is:

  • Their variables are Observables. The view's UIControls can bind to them to update the screen.
  • Their callback are Observables. The view can bind to them to receive the view model method's responses.

TimelineViewModel

It presents the view model of the first screen, `Timeline`. It keeps a list of `[Post]` that are displayed in the view's `UITableView`, and another list of `[Post]` for the `UISearchController`.

ComposeViewModel

It presents the view model of the `Compose` screen. It keeps a `Post` for the view's input form, which then will be saved to the `Realm` database once the user tap `Create`.

View

For each screen, the views are the SDK's `UIViewController`s This app has 3 main screens: `TimelineViewController`, `ComposeViewController` and `PostViewController`. Each of first 2 screens has their associated `ViewModel`. The last screen does not as it doesn't require any reactive functionality.

The reactive views own their associated view models. (See createCallback) The view can call a view model's method and receive the method's response by binding the view model's events.

The views also are subscribe to the changes of the view model's changes on the models in order to correctly update the screens. (See bindViewtoViewModel)

TimelineCell

It implements UITableViewCell used by TimelineViewController. It uses customed NSLayoutConstraint to programmatically adjust the layout to display different number of photos.

Database

This app uses Realm for database. It stores 1 model class, Post.

Note that Post database doesn't directly store image binary into the Realm database. When a Post object is saved, it first copies images to the user's documents directory, then only saves the file names in the Post object. This will scale better the read/write time performance when the database grows with more and larger images.

When the app first launches, it does so with pre-populated data for the ease of demo. See SeedData class.

Tests

The XCTest is used to test model's logic and operations.

  • TestUtils tests the foundation logic and outputs.
  • TestViewmodels tests the view models themselves and the model CRUD. When running these unit tests, we switch to use in-memory Realm database config so that it does not mess up the app's current database.

The XCUITest is used to test the UI interactions implying correctness of the app's navigation and view mode's reactive wiring. Each time UI test is runned, the database resets to its test data state. The test automation recorded is strictly dependent on the test data created by the SeedData class.

  • MyTimelineUITests tests each part of the navigation of the main 3 screens, search and full image viewer.

About

An example iOS app project based on MVVM, RxSwift and Realm


Languages

Language:Swift 98.6%Language:Ruby 1.4%