From 29559d51ac8da2e3670e0eed15a1ebe6ea1da226 Mon Sep 17 00:00:00 2001 From: Zvonimir Medak Date: Wed, 13 Nov 2024 14:23:57 +0100 Subject: [PATCH 1/6] update contributing.md --- CONTRIBUTING.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4639537..2cb209f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,10 +6,17 @@ Welcome to our project! We appreciate your interest in helping us improve it. There are multiple ways in which you can help us make this project even better. +- Reporting bugs or suggesting new features - Contributing code improvements or new features - Writing, updating, or fixing tests - Improving documentation, including inline comments, user manuals, and developer guides +## Issue reporting + +If you found a bug or have an idea for a new feature, please open an issue. Be sure to include a clear and descriptive title, as well as a detailed description of the bug or feature. + +To avoid duplicate issues, please check if a similar issue has already been created. + ## Making changes To make changes to the project, please follow these steps: @@ -28,11 +35,14 @@ Once we check everything, we will merge the changes into the main branch and inc When submitting a pull request, please ensure that: +- Your pull request is concise and well-scoped - Your code is properly tested - Your code adheres to the project's coding standards and style guidelines - Your commit message is clear and descriptive - Your pull request includes a description of the changes you have made and why you have made them +Try to avoid creating large pull requests that include multiple unrelated changes. Instead, break them down into smaller, more focused pull requests. This will make it easier for us to review and merge your changes. + ## Code of conduct We want to ensure a welcoming environment for everyone. With that in mind, all contributors are expected to follow our [code of conduct](/CODE_OF_CONDUCT.md). From 6cb4f07892dc97bb7679946182aee9273e27eb6a Mon Sep 17 00:00:00 2001 From: Zvonimir Medak Date: Wed, 13 Nov 2024 14:32:08 +0100 Subject: [PATCH 2/6] add the codeowners file --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..00f6063 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @nikolamajcen @ZvonimirMedak \ No newline at end of file From ee22fc8f7b02df0df8b2fa5801cfc4821690c5ee Mon Sep 17 00:00:00 2001 From: Zvonimir Medak Date: Wed, 13 Nov 2024 14:33:57 +0100 Subject: [PATCH 3/6] update pull_request_template.md --- .github/pull_request_template.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 56d630d..663370c 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -2,10 +2,10 @@ +**Related issue**: + ## Changes ### Type @@ -39,4 +39,4 @@ \ No newline at end of file +--> From d8f07673095995da8b97a99d153f013edc504b30 Mon Sep 17 00:00:00 2001 From: Zvonimir Medak Date: Wed, 13 Nov 2024 14:39:51 +0100 Subject: [PATCH 4/6] add template yml files --- .github/ISSUE_TEMPLATE/bug_report.md | 43 ----------------- .github/ISSUE_TEMPLATE/bug_report.yml | 55 ++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 19 -------- .github/ISSUE_TEMPLATE/feature_request.yml | 18 +++++++ 4 files changed, 73 insertions(+), 62 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 91b7dd2..0000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -name: Bug report -about: File a bug report -title: 'Bug report: ' -labels: bug ---- - -## Description - - - -## Environment - -**Device**: - -**Operating System**: - -**Software Information**: - -## Reproduction steps - - - -## Expected behavior - - - -## Additional information - - \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..6468254 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,55 @@ +name: Bug report +description: File a bug report. +labels: bug +body: + - type: textarea + id: description + attributes: + label: Description + description: A clear and concise description of what the bug is. + validations: + required: true + - type: textarea + id: environment + attributes: + label: Environment + description: | + An environment information where issue occurred. Try to provide as much information as possible, including: + - device name, model and manufacturer + - operating system version + - software name, version and build number + - additional information (e.g. dependencies, IDE, etc.) + value: | + - Device: + - Operating system: + - Software information: + - Additional information: + validations: + required: true + - type: textarea + id: reproduction-steps + attributes: + label: Reproduction steps + description: Steps to reproduce the behavior. + value: | + 1. + 2. + 3. + ... + validations: + required: true + - type: textarea + id: expected-behavior + attributes: + label: Expected behavior + description: A clear and concise description of what you expected to happen. + validations: + required: true + - type: textarea + id: additional-information + attributes: + label: Additional information + description: Any additional information that might be helpful in solving the issue. + validations: + required: false + \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 2e00ade..0000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: Feature request -about: Propose a new feature or an idea for this project -title: 'Feature request: ' -labels: enhancement ---- - -## Feature description - - - -## Additional information - - \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..c479a8b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,18 @@ +name: Feature request +description: Propose a new feature or an idea for Sentinel. +labels: enhancement +body: + - type: textarea + id: feature-description + attributes: + label: Feature description + description: A clear and concise description of the feature request, including what problem it solves. + validations: + required: true + - type: textarea + id: additional-information + attributes: + label: Additional information + description: An additional information or screenshots about the feature request. + validations: + required: false From c0e459a1b8005194958736da7e526e69a1a66652 Mon Sep 17 00:00:00 2001 From: Zvonimir Medak Date: Wed, 13 Nov 2024 15:39:48 +0100 Subject: [PATCH 5/6] update readme --- README.md | 137 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 91 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 6d87489..4b0a49c 100644 --- a/README.md +++ b/README.md @@ -6,14 +6,16 @@ [![Build Status](https://app.bitrise.io/app/56dc4082e9c3bb9e/status.svg?token=aHG6rIR2XDrJ3xNOIO2hXw&branch=master)](https://app.bitrise.io/app/56dc4082e9c3bb9e) [![Version](https://img.shields.io/cocoapods/v/Sentinel.svg?style=flat)](https://cocoapods.org/pods/Sentinel) -[![License](https://img.shields.io/cocoapods/l/Sentinel.svg?style=flat)](https://cocoapods.org/pods/Sentinel) +[![License](https://img.shields.io/cocoapods/l/Sentinel.svg?style=flat)](https://cocoapods.org/pods/Sentinel#license) [![Platform](https://img.shields.io/cocoapods/p/Sentinel.svg?style=flat)](https://cocoapods.org/pods/Sentinel) ## Description **Sentinel** is a simple library that gives developers the possibility to configure one entry point for every debug tool. The idea of **Sentinel** is to give the ability to developers to configure a screen with multiple debug tools which are available via some event (e.g. shake, notification). -**Sentinel** has a tab bar that contains five screens. Three of those aren't configurable, and two of them are. The first screen is the **Device** screen which allows the user to look into some of the device-specific information. The second screen is the **Application** screen which allows the user to look into some of the application-specific information from the info.plist. The third, the first configurable screen, is the **Tools** screen. **Tools** screen allows you to add as much `Tool` object as your heart desires which can be used by the user to find out some specific information. The fourth, last configurable screen, is the **Preferences** screen. **Preferences** screen allows you to add options that allow or deny some activity inside the app. The last, but not the least, is the **Performance** screen which contains performance-specific information. Later on, we'll explain how you can configure those screens. +**Sentinel** has a tab bar that contains five screens. Three of those aren't configurable, and two of them are. The first screen is the **Device** screen which allows the user to look into some of the device-specific information. The second screen is the **Application** screen which allows the user to look into some of the application-specific information from the info.plist. The third, the first configurable screen, is the **Tools** screen. **Tools** screen allows you to add as much `Tool` object as your heart desires which can be used by the user to find out some specific information. The fourth, last configurable screen, is the **Preferences** screen. **Preferences** screen allows you to add options that allow or deny some activity inside the app. **Preferences** tab can also be used as a feature control entry point, the user will be able to enable or disable the features by pressing on the option button. The last, but not the least, is the **Performance** screen which contains performance-specific information. Later on, we'll explain how you can configure those screens. + +**Sentinel** contains a few custom tools which can be used. You can find out more in the [Usage](#usage) part. This library supports both **Swift** and **Objective-C**. @@ -28,7 +30,7 @@ This library supports both **Swift** and **Objective-C**. ## Requirements -* iOS 10 and above +* iOS 11 and above * Xcode 10 and above ## Getting started @@ -37,85 +39,117 @@ This library supports both **Swift** and **Objective-C**. #### CocoaPods -Sentinel is available through [CocoaPods](https://cocoapods.org). To install +*Sentinel* is available through [CocoaPods](https://cocoapods.org). To install it, simply add the following line to your Podfile: ```ruby pod 'Sentinel' ``` +*Sentinel* is made of multiple subspects: +- `Core` which will install only the core features for the *Sentinel* to be usable +- `UserDefaults` which will add the `UserDefaultsTool` +- `EmailSendel` which will add the `EmailSenderTool` +- `CustomLocation` which will add the `CustomLocationTool` +- `TextEditing` which will add the `TextEditingTool` +- `Default` - which will install `UserDefaults`, `Core`, `CustomLocation`, and `TextEditing` + +*NOTE: All of the subspecs add `Core` as a dependency* + #### Swift Package Manager If you are using SPM for your dependency manager, add this to the dependencies in your `Package.swift` file: ```swift dependencies: [ - .package(url: "https://github.com/infinum/ios-sentinel.git") +.package(url: "https://github.com/infinum/ios-sentinel.git") ] ``` -To add the *Sentinel* to your project, install the library as instructed above. After that, define *Sentinel* configuration with mandatory parameters and call `Sentinel.shared.setup:` in the `AppDelegate` method `application(_:didFinishLaunchingWithOptions:)`. - -```swift -let configuration = Sentinel.Configuration( - sourceScreenProvider: SourceScreenProviders.default, - trigger: Triggers.shake, - tools: [ - GeneralInfoTool(), - UserDefaultsTool(), - LoggieTool(), - ], - preferences: [ - OptionSwitchItem( - name: "Analytics", - setter: { AppSwitches.analyticsEnabled = $0 }, - getter: { AppSwitches.analyticsEnabled }, - userDefaults: .standard, - userDefaultsKey: "com.infinum.sentinel.optionSwitch.analytics" - ) - ] -) - -Sentinel.shared.setup(with: configuration) -``` - ## Usage ### Basics -`Sentinel` is the main class used to setup the *Sentinel* which will be used in the application. The `Sentinel` object can configured via `setup:` method by `Configuration` object. +`Sentinel` is the main class used to setup the *Sentinel* which will be used in the application. The `Sentinel` object can configured via `setup:` method by `Configuration` object. The `setup:` can be called in the `AppDelegate` method `application(_:didFinishLaunchingWithOptions:)`. + +```swift + let configuration = Sentinel.Configuration( + trigger: Triggers.shake, + tools: [ + UserDefaultsTool(), + CustomLocationTool() + ], + preferences: optionSwitchItems + ) + + Sentinel.shared.setup(with: configuration) +``` ### Configuration To be able to configure the `Sentinel` object, the `Configuration` object is introduced. This object contains multiple objects which define general *Sentinel* behaviour. The inputs which this object needs are; `trigger`, `sourceScreenProvider`, `tools`, and `preferences`. -The `trigger` object is a type of `Trigger` which defines on which event the *Sentinel* will be triggered. Currently, three types of are supported; `ShakeTrigger`, `ScreenshotTrigger`, `NotificationTrigger`. New triggers can be added as well, just by conforming the `Trigger` protocol. +The `trigger` object is a type of `Trigger` which defines on which event the *Sentinel* will be triggered. Currently, three types of are supported; `ShakeTrigger`, `ScreenshotTrigger`, `NotificationTrigger`. New triggers can be added as well, just by conforming the `Trigger` protocol. Currently available triggers can be accessed from the `Triggers` class by using its designated static properties like `shake`, `screenshot` or `notification(forName:)`. + +In any case that there's a need for another `Trigger`, take a look at the currently implemented ones to gain some information on how it should be done. -The `sourceScreenProvider` object is a type of `SourceScreenProvider` which should provide a view controller from where will *Sentinel* be presented. Currently, one type is supported; `default`. +```swift +/// Defines interaction with trigger. +@objc +public protocol Trigger: NSObjectProtocol { + + /// Subscribes to the triggering event. + /// + /// - Parameter events: The block which will be called when notification arrives. + @objc(subscribeOnEvents:) + func subscribe(on events: @escaping () -> ()) +} +``` + +The `sourceScreenProvider` object is a type of `SourceScreenProvider` which should provide a view controller from where will *Sentinel* be presented. Currently, one type is supported; `default`, and the initializer will default to it. The `SourceScreenProvider.default` uses the the current top ViewController to be the one providing the *Sentinel* screens. The `tools` object is an array of `Tool` objects. `Tool` objects represent tools which will be available from *Sentinel*. There are multiple tools already supported by the library, but custom tools can be created and added to the *Sentinel*. -The last, but not the least, is the `preferences` object which is an array of `OptionSwitchItem` objects. `OptionSwitchItem` is used to allow the user to switch of some of the preferences which are contained in the app. e.g. The app supports Analitycs and you can add an `OptionSwitchTool` which will be shown on the `Preferences` screen and the user can turn it off if he doesn't want it. +The last, but not the least, is the `preferences` object which is an array of `OptionSwitchItem` objects. `OptionSwitchItem` is used to allow the user to switch of some of the preferences which are contained in the `UserDefaults`. To allow the user the interaction, you will have to add a `getter`, and a `setter` for the property from the `UserDefaults` object. + +e.g. The app supports Analitycs and you can add an `OptionSwitchTool` which will be shown on the `Preferences` screen and the user can turn it off if he doesn't want it. + +```swift + OptionSwitchItem( + name: "Analytics", + setter: { AppSwitches.analyticsEnabled = $0 }, + getter: { AppSwitches.analyticsEnabled }, + userDefaults: .standard, + userDefaultsKey: "com.infinum.sentinel.optionSwitch.analytics" + ) +``` ### Custom tools To be able to create a custom tool that will be available through the *Sentinel*, a new class should be created which conforms the `Tool` protocol. This protocol is defined as: ```swift +/// Defines tool behaviour. +@objc public protocol Tool { + + /// The name of the tool. var name: String { get } + /// Presents the tool view controller from provided view controller. + /// + /// - Parameter viewController: The view controller used for presenting tool view controller. + @objc(presentPreviewFromViewController:) func presentPreview(from viewController: UIViewController) } - ``` -Based on this, only `name` should be provided as well as `presentPreview:` method which will present the tool view controller from the `sourceScreenProvider` view controller defined in the Sentinel configuration. +The `name` property will be available in the `Tools` tab as one of the cells. The `presentPreview` method needs to instantiate the screen you want to show, and it will use the view controller from the `sourceScreenProvider` to show your custom tool. -A common custom tool that might be needed is `Pulse` network logger. It can be defined in the following way: +At Infinum, we're using `Pulse` network logger. We only use it for internal builds, and it helps a lot if we can somehow access the logs from `Pulse`, as well as other debug tools. That's why we have a need to create the `PulseTool` which will be an example on how to create your own tool. ```swift -class PulseTool: Tool { +final class PulseTool: Tool { var name: String { "Pulse" } func presentPreview(from viewController: UIViewController) { @@ -124,9 +158,20 @@ class PulseTool: Tool { viewController.present(pulseNavigation, animated: true) } } - ``` +### Available custom tools + +*CustomInfoTool* is used on the `Device`, and `Application` tabs. It's primary use is to list out properties and their values. + +*CustomLocationTool* is used to give the ability to change the current user location. After changing the location, the application will have to be restarted. + +*TextEditingTool* is used to give the ability to edit a value. Where you have to provide a `getter`, and a `setter` for the property you want to change dynamically. + +*UserDefaultsTool* is used to give an overview of all the `UserDefaults` properties, their values, and the ability to delete properties. + +*EmailSenderTool* is used to let the user send emails with attachments from the app with ease. + ## Contributing We believe that the community can help us improve and build better a product. @@ -159,10 +204,10 @@ limitations under the License. Maintained and sponsored by [Infinum](https://infinum.com). \ No newline at end of file + + + + + + + From 0a73539121445ff3f4bd0f1635ce881ae11b36c4 Mon Sep 17 00:00:00 2001 From: Zvonimir Medak Date: Thu, 14 Nov 2024 08:00:19 +0100 Subject: [PATCH 6/6] reamde stlying --- README.md | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 4b0a49c..9904577 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@ **Sentinel** is a simple library that gives developers the possibility to configure one entry point for every debug tool. The idea of **Sentinel** is to give the ability to developers to configure a screen with multiple debug tools which are available via some event (e.g. shake, notification). -**Sentinel** has a tab bar that contains five screens. Three of those aren't configurable, and two of them are. The first screen is the **Device** screen which allows the user to look into some of the device-specific information. The second screen is the **Application** screen which allows the user to look into some of the application-specific information from the info.plist. The third, the first configurable screen, is the **Tools** screen. **Tools** screen allows you to add as much `Tool` object as your heart desires which can be used by the user to find out some specific information. The fourth, last configurable screen, is the **Preferences** screen. **Preferences** screen allows you to add options that allow or deny some activity inside the app. **Preferences** tab can also be used as a feature control entry point, the user will be able to enable or disable the features by pressing on the option button. The last, but not the least, is the **Performance** screen which contains performance-specific information. Later on, we'll explain how you can configure those screens. +**Sentinel** has a tab bar that contains five screens. Three of those aren't configurable, and two of them are. The first screen is the **Device** screen which allows the user to look into some of the device-specific information. The second screen is the **Application** screen which allows the user to look into some of the application-specific information from the info.plist. The third, the first configurable screen, is the **Tools** screen. **Tools** screen allows you to add as many `Tool` objects as your heart desires which can be used by the user to find out some specific information. The fourth, last configurable screen, is the **Preferences** screen. **Preferences** screen allows you to add options that allow or deny some activity inside the app. **Preferences** tab can also be used as a feature control entry point, the user will be able to enable or disable the features by pressing the option button. Last, but not the least, is the **Performance** screen which contains performance-specific information. Later on, we'll explain how you can configure those screens. -**Sentinel** contains a few custom tools which can be used. You can find out more in the [Usage](#usage) part. +**Sentinel** contains a few custom tools which can be used, some of which are in their own subspecs. You can find out more about it in the [Usage](#usage) section. This library supports both **Swift** and **Objective-C**. @@ -46,7 +46,7 @@ it, simply add the following line to your Podfile: pod 'Sentinel' ``` -*Sentinel* is made of multiple subspects: +*Sentinel* is made of multiple subspecs: - `Core` which will install only the core features for the *Sentinel* to be usable - `UserDefaults` which will add the `UserDefaultsTool` - `EmailSendel` which will add the `EmailSenderTool` @@ -68,9 +68,7 @@ dependencies: [ ## Usage -### Basics - -`Sentinel` is the main class used to setup the *Sentinel* which will be used in the application. The `Sentinel` object can configured via `setup:` method by `Configuration` object. The `setup:` can be called in the `AppDelegate` method `application(_:didFinishLaunchingWithOptions:)`. +`Sentinel` is the main class used to set up the *Sentinel* which will be used in the application. The `Sentinel` object can configured via `setup:` method by `Configuration` object. The `setup:` can be called in the `AppDelegate` method `application(_:didFinishLaunchingWithOptions:)`. ```swift let configuration = Sentinel.Configuration( @@ -87,11 +85,11 @@ dependencies: [ ### Configuration -To be able to configure the `Sentinel` object, the `Configuration` object is introduced. This object contains multiple objects which define general *Sentinel* behaviour. The inputs which this object needs are; `trigger`, `sourceScreenProvider`, `tools`, and `preferences`. +To configure the `Sentinel` object, the `Configuration` object is introduced. `Configuration` contains multiple objects which define general *Sentinel* behaviour. The inputs which this object needs are; `trigger`, `sourceScreenProvider`, `tools`, and `preferences`. -The `trigger` object is a type of `Trigger` which defines on which event the *Sentinel* will be triggered. Currently, three types of are supported; `ShakeTrigger`, `ScreenshotTrigger`, `NotificationTrigger`. New triggers can be added as well, just by conforming the `Trigger` protocol. Currently available triggers can be accessed from the `Triggers` class by using its designated static properties like `shake`, `screenshot` or `notification(forName:)`. +The `trigger` object is a type of `Trigger` which defines on which event the *Sentinel* will be triggered. Currently, three types are supported; `ShakeTrigger`, `ScreenshotTrigger`, `NotificationTrigger`. New triggers can be added as well, just by conforming to the `Trigger` protocol. Currently, available triggers can be accessed from the `Triggers` class by using its designated static properties like `shake`, `screenshot` or `notification(forName:)`. -In any case that there's a need for another `Trigger`, take a look at the currently implemented ones to gain some information on how it should be done. +In case there's a need for another `Trigger`, take a look at the currently implemented ones to gain some information on how it should be done. ```swift /// Defines interaction with trigger. @@ -106,11 +104,11 @@ public protocol Trigger: NSObjectProtocol { } ``` -The `sourceScreenProvider` object is a type of `SourceScreenProvider` which should provide a view controller from where will *Sentinel* be presented. Currently, one type is supported; `default`, and the initializer will default to it. The `SourceScreenProvider.default` uses the the current top ViewController to be the one providing the *Sentinel* screens. +The `sourceScreenProvider` object is a type of `SourceScreenProvider` which should provide a view controller from where will *Sentinel* be presented. Currently, one type is supported; `default`, and the initializer will default to it. The `SourceScreenProvider.default` uses the current top ViewController to be the one providing the *Sentinel* screens. The `tools` object is an array of `Tool` objects. `Tool` objects represent tools which will be available from *Sentinel*. There are multiple tools already supported by the library, but custom tools can be created and added to the *Sentinel*. -The last, but not the least, is the `preferences` object which is an array of `OptionSwitchItem` objects. `OptionSwitchItem` is used to allow the user to switch of some of the preferences which are contained in the `UserDefaults`. To allow the user the interaction, you will have to add a `getter`, and a `setter` for the property from the `UserDefaults` object. +Last, but not the least, is the `preferences` object which is an array of `OptionSwitchItem` objects. `OptionSwitchItem` is used to allow the user to switch of some of the preferences which are contained in the `UserDefaults`. To allow the user the interaction, you will have to add a `getter`, and a `setter` for the property from the `UserDefaults` object. e.g. The app supports Analitycs and you can add an `OptionSwitchTool` which will be shown on the `Preferences` screen and the user can turn it off if he doesn't want it. @@ -126,7 +124,7 @@ e.g. The app supports Analitycs and you can add an `OptionSwitchTool` which will ### Custom tools -To be able to create a custom tool that will be available through the *Sentinel*, a new class should be created which conforms the `Tool` protocol. This protocol is defined as: +To be able to create a custom tool that will be available through the *Sentinel*, a new class should be created which conforms to the `Tool` protocol. This protocol is defined as: ```swift /// Defines tool behaviour. @@ -145,7 +143,7 @@ public protocol Tool { The `name` property will be available in the `Tools` tab as one of the cells. The `presentPreview` method needs to instantiate the screen you want to show, and it will use the view controller from the `sourceScreenProvider` to show your custom tool. -At Infinum, we're using `Pulse` network logger. We only use it for internal builds, and it helps a lot if we can somehow access the logs from `Pulse`, as well as other debug tools. That's why we have a need to create the `PulseTool` which will be an example on how to create your own tool. +At Infinum, we're using `Pulse` as our network logger. We only use it for internal builds, and it helps a lot if we can somehow access the logs from `Pulse`, as well as other debug tools. That's why we have a need to create the `PulseTool` which will be an example on how to create your own tool. ```swift @@ -162,9 +160,9 @@ final class PulseTool: Tool { ### Available custom tools -*CustomInfoTool* is used on the `Device`, and `Application` tabs. It's primary use is to list out properties and their values. +*CustomInfoTool* is used on the `Device`, and `Application` tabs. Its primary use is to list out properties and their values. -*CustomLocationTool* is used to give the ability to change the current user location. After changing the location, the application will have to be restarted. +*CustomLocationTool* is used to change the current user's location. After changing the location, the application will have to be restarted. *TextEditingTool* is used to give the ability to edit a value. Where you have to provide a `getter`, and a `setter` for the property you want to change dynamically.