Swiftpack.co - VakhoKontridze/VCore as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by VakhoKontridze.
VakhoKontridze/VCore 2.2.0
VCore is a Swift collection containing objects, functions, and extensions that I use for all my projects
⭐️ 27
🕓 1 week ago
iOS
.package(url: "https://github.com/VakhoKontridze/VCore.git", from: "2.2.0")

VCore

Table of Contents

Description

VCore is a Swift collection containing objects, functions, and extensions that I use for all my projects

Library supports iOS 13.0 and up.

Library Structure

Project files are grouped as:

  • Views and ViewContollers. Reusable non-scene views and viewcontrollers.

  • Services and Managers. Services, managers, controllers, and formatters. For instance, NetworkClient.

  • Helpers. Non-service, non-extension objects and methods. For instance, helper methods for creating GenericStateModel's and StandardNavigable.

  • Global Functions. Global functions. For instance, TODO and operators.

  • Extensions. Global extensions. Methods and properties are grouped by frameworks of origin—Foundation, UIKit, and SwiftUI.

Project incudes folder Extra, which contains:

  • XCode Templates. Templates that can be used for accelerating workflow. Currently, templates cover scenes and gateways.

  • Misc. Objects and methods that cannot be included in a library as they require additional customization or access to AppDelegate/SceneDelegate.

Architecture

Library includes templates for developing scenes using a VIPER architecture. Architecture is highly-decoupled, follows modular design, obeys the single-responsibility principle, and is built on the interface communication pattern.

To avoid writing boilerplate for every scene, the project includes XCode templates.

Scene Components

Factory

A factory and a dependency injector that creates a scene and injects all related objects.

Factory takes a viewModel as parameter if there is a data passed from the previous scene in the navigation. Factory is a non-initializable struct with static factory methods. By default, Factory includes a single method, that creates a default instance of the scene.

Since objects are communicating using protocols, some can be swapped out with a non-default implementation. For instance, we can place Presenter and ViewController in a shared framework, and implement different Interactor's and Router's in two separate apps, subsequently reusing the same scene while only changing endpoints that they connect to and scenes to which we can navigate to. When even just one scene component is replaced, a new method must be added to Factory, as it requires a different dependency injection.

Interface

While not technically an object, this file lists all protocols that explain communication within the objects.

Interface has five protocols:

Protocol Conformance Owner Ownership
Viewable ViewController Presenter unowned
Navigable Router Presenter unowned
Presentable Presenter ViewController strong
Routable Router Presenter strong
Interactive Interactor Presenter strong

ViewController (Viewable + Navigable)

Definition

View of the scene.

Responsibilities

Responsibilities of the ViewController include:

  • Initializing and storing views
  • Adding them to subviews
  • Setting up a layout
  • Reconfiguring self and subviews

Responsibilities of the ViewController do not include:

  • Storing and managing data, as it's entirely taken by a Presenter
Viewable

Viewable protocol is used by Presenter for configuring and modifying the view during runtime. Some properties and methods used in the protocol may include:

func setContinueButtonState(to isUserInteractionEnabled: Bool)
func setInfoLabelText(to text: String)
Navigable

Navigable protocol is used by Router to perform navigation and presentation of scenes. By default, Navigable protocol conforms to StandardNavigable protocol—a helper protocol used in all scenes. StandardNavigable has a default implementation for UIViewController, and thus, additional implementation is required. API of StandardNavigable is the following:

protocol StandardNavigable {
    func push(_ viewController: UIViewController)
    func pop()
    func popToRoot()
    
    func present(_ viewController: UIViewController)
    func dismiss()
    
    func setRoot(to viewController: UIViewController)
}

Presenter (Presentable) (Optional)

Definition

The Central object in the scene that controls the logic and binds everything together.

Responsibilities

Responsibilities of the Presenter include:

  • Connecting all scene components
  • Communicating with Router to trigger navigation towards or presentation of scenes, which in turn communicates with ViewController
  • Communicating with Interactor to fetch data
  • Storing the majority of the present in the scene. This includes viewModel passed from the previous scene.

Responsibilities of the Presenter do not include:

  • Importing UIKit and managing UI-specific data, unless absolutely necessary
Presentable

Presentable protocol is used by ViewController to notify Presenter that an event or an action has occurred. Some properties and methods used in the protocol may include:

func viewDidLoad()
func didTapContinueButton()

Router (Routable) (Optional)

Definition

Navigator of the scene that performs navigation towards and presentation of scenes.

Responsibilities

Router has access to ViewController view Navigable protocol, which allows it to access the navigation stack. By default, Navigable protocol conforms to StandardNavigable protocol.

Routable

Routable protocol is used by Presenter to trigger navigation towards or presentation of scenes. Some methods used in the protocol may include:

func toSomeScene()
func toSomeOtherScene(viewModel: SomeOtherSceneViewModel)

Interactor (Interactive) (Optional)

Definition

Performs fetch request to remote or local databases.

Responsibilities

Responsibilities of the Interactor include:

  • Calling Gateway's for fetch request. That's why an Interactive has a combined protocol body of all the Gateway's it has access to.

Responsibilities of the Interactor do not include:

  • Performing fetch requests on its own independent of a Gateway.
Interactive

Interacive protocol is used by Presenter to perform fetch requests. Some methods used in the protocol may include:

func fetchSomeData(parameters: SomeParameters) async throws -> SomeEntity

ViewModel (Optional)

Definition

Data passed to the scene from the previous one.

Responsibilities

Owned by Presenter.

Model (Optional)

Definition

A non-initalizable static object that contains information needed for laying out a ViewController.

Responsibilities

Object breaks down into 5 sub-objects—Layout, Colors, Fonts, Animations, and Misc.

Gateway

Protocol that defines a method by which a single fetch request is performed to a relational database—either remote or local.

To avoid writing boilerplate for every gateway, the project includes XCode templates.

Gateway Components

Gatewayable

Defines an interface by which a fetch request can occur. Gateway should only contain a single method.

Parameters

Parameters used for the fetch request. A struct, that can conform to Encodable.

Entity

Entity that's returned from the fetch request. Also a struct, that can conform to Decodable.

_ Gateway

A specific implementation of a gateway. To differentiate the gateways from one another, a prefix is used. For instance, UpdateUserDataNetworkGateway or UpdateUserDataCoreDataGateway.

Interactor-Gateway Relation

Although an Interactor component in VIPER is part of the scene, Gateways are not bound to specific scenes.

This design choice follows CLEAN architecture. But we are not using UseCase's as their responsibility is entirely covered by Interactor's.

Relation between an Interactor and Gateway is the following:

protocol UpdateUserDataGatewayable {
    func fetch(with parameters: UpdateUserDataParameters) async throws -> UpdateUserDataEntity
}

struct UpdateUserDataNetworkGateway: UpdateUserDataGatewayable {
    func fetch(with parameters: UpdateUserDataParameters) async throws -> UpdateUserDataEntity {
        // Implementation
    }
}
protocol HomeInteractive {
    func updateUserData(with parameters: UpdateUserDataParameters) async throws -> UpdateUserDataEntity
}

struct HomeInteractor: HomeInteractive {
    func updateUserData(with parameters: UpdateUserDataParameters) async throws -> UpdateUserDataEntity {
        try await UpdateUserDataNetworkGateway().fetch(with: parameters)
    }
}

Demo

Project contains demo app, that can be used to test functionality of the library.

Installation

Library doesn't support CocoaPods or Carthage.

Swift Package Manager

Add https://github.com/VakhoKontridze/VCore as a Swift Package in Xcode and follow the instructions.

SPM1

Manual

  1. Download VCore.xcframework.

  2. Extract the zip.

  3. Drag VCore.xcframework into your project.

ManualInstallation1

  1. Select "Copy items if needed" and click Finish.

ManualInstallation2

  1. Go to the target settings for your app, under "General" tab, find "Frameworks, Libraries, and Embedded Content". Set the VCore.xcframework to “Embed & Sign”.

ManualInstallation3

Building Your Own Target

Since VCore is open-source, you can clone the project and build the framework target yourself.

Versioning

Major. Major changes, such as big overhauls

Minor. Minor changes, such as new objects, function, and extensions

Patch. Bug fixes and improvements

Contact

e-mail: vakho.kontridze@gmail.com

GitHub

link
Stars: 27
Last commit: 1 week ago
jonrohan Something's broken? Yell at me @ptrpavlik. Praise and feedback (and money) is also welcome.

Related Packages

Release Notes

2.2.0
1 week ago
  • Issues with fixedInRange methods with steps have been fixed
  • Issues with conditional View function if have been fixed
  • minimumScaleFactor parameter has been added to UILabel configuration methods
  • UIView (Dynamic Model) XCode Templates now has a default parameter value for model in init
  • fixedInRange function has been renamed to bound

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics