Overview

This section describes the Beagles' dependencies and their properties for iOS environments.

What is it?

The dependecies file is where you can change the Beagle’s default behavior in your application.

How does it work?

The BeagleConfigurator calls the static method setup(dependencies: BeagleDependencies) that receives an BeagleDependencies object. This object will hold all dependencies’s properties. Here follows an example:

public struct BeagleDependencies {
    
    // MARK: Custom Dependencies
    public var coder: CoderProtocol
    public var urlBuilder: UrlBuilderProtocol
    public var theme: ThemeProtocol
    public var viewClient: ViewClientProtocol
    public var imageDownloader: ImageDownloaderProtocol
    public var logger: LoggerProtocol?
    public var analyticsProvider: AnalyticsProviderProtocol?
    public var deepLinkHandler: DeepLinkScreenManagerProtocol?
    public var networkClient: NetworkClientProtocol?
    
    // MARK: Public Dependencies
    public var appBundle: BundleProtocol
    public let globalContext: GlobalContextProtocol
    public var navigator: NavigationProtocol
    public var operationsProvider: OperationsProviderProtocol
}

Therefore, it is appropriate to make this Beagle initial configuration during the application startup process, that is, in the the AppDelegate function didFinishLaunchingWithOptions as shown below:

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    func application(_ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        var dependencies = BeagleDependencies()
        dependencies.theme = AppTheme.theme
        dependencies.urlBuilder = UrlBuilder(baseUrl: URL(string: .baseURL))
        dependencies.navigator.setDefaultAnimation(.init(
            pushTransition: .init(type: .fade, subtype: .fromRight, duration: 0.1),
            modalPresentationStyle: .formSheet
        ))
        dependencies.coder.register(type: CustomComponent.self)
        dependencies.coder.register(type: CustomAction.self)
        BeagleConfigurator.setup(dependencies: dependencies)
        let rootViewController = MainScreen().screenController()
        window?.rootViewController = rootViewController
        return true
    }
}

Examples

Below we have an example on how to clear the global context content at some point when executing the application:

@Injected var globalContext: GlobalContextProtocol
globalContext.clear()
@OptionalInjected var logger: LoggerProtocol?
logger?.log(Log.network(.httpRequest(request: .init(url: urlRequest))))

Customizable Dependencies

Here follow a few Default dependencies implementations that can be customized.

CoderProtocol

It is responsible for the encoding and decoding Beagle’s logic. It exposes the register method so that it is possible to register new components and actions.

Below you can find an example on how to register a new component and a custom action:

dependencies.coder.register(component: CustomWidget.self)
dependencies.coder.register(action: CustomAction.self)

UrlBuilderProtocol

It is responsible for creating a Beagle request URL from relative URLs that are received from an BFF (in navigation flows for example) and a configured base URL.

This is an example on how to use it:

dependencies.urlBuilder = UrlBuilder(baseUrl: URL(string: "SUA URL BASE"))

ThemeProtocol

It stores all your styles and knows how to apply them to your components.

Some widgets have a variable that allows you to define the style. The name of each one must be passed to the Theme dependency, so that that style can be used in its respective component.

To configure custom styles, follow these steps:

Step 1: Create a function that receives a representation of the UIKit of the Widget you want to apply styles at.

static func blackTextNormalStyle() -> (UITextView?) -> Void {
    return {
        $0?.font = .systemFont(ofSize: 16)
        $0?.textColor = .black
    }
}

Step 2: Instantiate AppTheme with an array of key values representing the style name and the corresponding function.

let theme = AppTheme(styles: [
    "myStyleName": blackTextNormalStyle
])

Step 3: Add the custom theme dependency to Beagles' dependencies

dependencies.theme = theme

ViewClientProtocol

It is responsible for fetching screens from the backend using the fetch and prefetch methods. It has an internal implementation that assembles urls from a urlBuilder and makes a request from networkClient.

ImageDownloaderProtocol

It is responsible for making remote image requests from the fetchImage method. Beagle has a default implementation for this dependency, which simply calls the networkClient to fetch the images and does not perform any caching.

Optional Dependencies

Dependencies which are not default and therefore should be implemented before used.

LoggerProtocol

It is responsible for triggering the log messages produced when running Beagle streams from the log method. These logs follow the LogType protocol, which has the following parameters:

  • category: log subject;
  • message: log message;
  • level: classifies the criticity level.

NetworkClientProtocol

It is responsible for executing network requests. Beagle does not provide a default implementation for this dependency, so it is mandatory that an implementation be provided for this dependency so that Beagle can communicate with the backend.

DeepLinkHandlerProtocol

This handler is used for a deep link navigation action. The variable has a default value, you can add new screens or replace them with others in the application.

Below you can see a code on how to add a screen with a possible route for a deep linking using a default value:

let deepLinkHandler = DeeplinkScreenManager.shared
deepLinkHandler["MyDeepLinkScreen"] = MyDeepLinkScreenClass.self
dependencies.deepLinkHandler = deepLinkHandler
BeagleConfigurator.setup(dependencies: dependencies)

AnalyticsProviderProtocol

It is a protocol that can be implemented to track the screen appearance, actions and click events.

See the example below:

class AnalyticsSample: Analytics {
    func trackEventOnScreenAppeared(_ event: AnalyticsScreen) {
        print("Screen \(event.screenName) appeared")
    }
    func trackEventOnScreenDisappeared(_ event: AnalyticsScreen) {
        print("Screen \(event.screenName) disappeared")
    }
    func trackEventOnClick(_ event: AnalyticsClick) {
        print("Button touch with:\ncategory = \(event.category)\nlabel = \(event.label ?? "empty")\nvalue = \(event.value ?? "empty")")
    }
}

Public dependencies that are not customizable

Here we list a few dependencies that could not be customized but have public APIs for configuring Beagle.

The navigator handles the navigate actions in your application.

It exposes a custom navigation controller registration methods and a navigation animation.

GlobalContextProtocol

It is responsible for managing the Beagle global context, it exposes the get, set and clear functions, so that it is possible to access and change the Global context attributes outside the Beagle scope.

OperationsProviderProtocol

It is responsible for providing context operations, exposing the register function so that it is possible to register custom operations in Beagle’s default OperationsProvider.

BundleProtocol

It is responsible for providing the application’s Bundle so that Beagle has access to local images contained, it is initialized with Bundle.main but this can be easily changed:

dependencies.appBundle.bundle = Bundle(identifier: "myBundleId")

Deeplink Handler

In this section, you will find information about Beagle’s deeplink handler for iOS.

ImageDownloader

You will find here the description of ImageDownloader, the description about its methods and how you can change it.

Log System

View Client

This section describes the ViewClient e and how to modify it.

Network Layer

You will find here information about Beagles’s network layer and how to modify it.

IOS

Here, you’ll find how to make components' stylization on iOS' projects.


Last modified March 10, 2022: feat: Translate docs 2.0 (#868) (4aa7430c)