Skip to content

tokopedia/ios-tptweak

Repository files navigation

TPTweak

TPTweak is a debugging tool to help adjust your iOS app on the fly without recompile. inspired by facebook's Tweak, TPTweak is fully written in swift, and with simpler API.

Example of TPTweak Selecting options of string Selecting options of number Search
Simulator Screenshot - iPhone 14 Pro - 2023-08-29 at 16 57 39
Set Favourite by swipe Set Favourite by long press Favourite Page
Simulator Screenshot - iPhone 14 Pro - 2023-08-29 at 19 07 10 Simulator Screenshot - iPhone 14 Pro - 2023-08-29 at 19 16 06 Simulator Screenshot - iPhone 14 Pro - 2023-08-29 at 19 07 04

✨ NEW

On version 3.0, you will have the options to use flatten home design.

Flatten Home Setting Page
Flatten Home Setting Page

Installation

Swift Package Manager

With xcode, add this URL

https://github.com/tokopedia/ios-tptweak

or manually add to your Package.swift

.package(url: "https://github.com/tokopedia/ios-tptweak", from: "3.0.0"),

Cocoapods

add this to your Podfile

pod 'TPTweak', '~> 3.0.0'

Development

TPTweak is written in Swift, so you need to have Xcode 14+ to build it.

run this command to open the project with the example project.

xed TPTweak.xcworkspace

Nomenclature

TPTweakEntry = Representation of option on TPTweak

TPTweakStore = Brain of TPTweak, all logic of storing, reading and mutating value of TPTweak.

TPTweakEntry

TPTweakEntry will represent a option on TPTweak.

TPTweakEntry(
    category: "Tracking",
    section: "Tracking",
    cell: "Enable Tracking",
    footer: "Turn this on to enable tracking",
    type: .switch(defaultValue: true)
)
  • category: will be a cell on the first page
  • section: will be a group of section on the second page
  • cell: will be the name of the cell inside the section
  • footer: add footer on the end of the section.(if multiply detected, will use the last one)
  • type: the type of cell you want to use

TPTweakEntry type

Switch

Using this type, you can create a cell with a UISwitch to enable/disable an option.You could also supply default value, if no value detected.

.switch(defaultValue: true)

You could also add closure: ((Bool) -> Void)? that will run after the value is changed.

.switch(defaultValue: true, closure: { isToggledOn in
    UserDefaults.standard.set(isToggledOn, forKey: "myvalue_is_on")
})

Strings

Using this type, you can create a selection of strings.When user tap the options, it will automatically open the selection.

.strings(item: ["US", "UK", "SG"], selected: "SG")

Numbers

Using this type, you can create a selectio of numbers.When user tap the options, it will automatically open the selection.

.numbers(item: [10, 15, 20], selected: 10)

Action

Using this type, it gives you the flexibility to do everything. with given closure, you can for example, open custom page you create, or executing a UserDefaults, or more.

.action({
    UserDefaults.standard.set(true, forKey: "clear_cache")
    Cache.clear()
})

How to Use

Creating your TPTweakEntry

first you need to create your entry, we recommend to create an extension and put every entry definition as a static.

import TPTweak

extension TPTweakEntry {
    static let enableTracking = TPTweakEntry(
        category: "Tracking",
        section: "Tracking",
        cell: "Enable Tracking",
        footer: "Turn this on to enable tracking",
        type: .switch(defaultValue: true)
    )
}

Registering your TPTweakEntry

once you create your entry, you need to register it to TPTweak so it will show up on TPTweak page. This can be achieved by calling register() on each entry.

You can call it whenever you want, but we suggest to put it on your AppDelegate's internal func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?)

internal func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // register TPTweak Entry
        TPTweakEntry.enableTracking.register()
    }

Openning TPTweak page

openning TPTweak is achievable by openning TPTweakViewController. but the easier way is to replace your UIWindow with TPTweakShakeWindow.

Manual

// without nav
let viewController = TPTweakViewController()
self.navigationController?.pushViewController(viewController, animated: true)

// with nav
let tptweakWithNav = TPTweakWithNavigatationViewController()
self.present(tptweakWithNav)

Shake (Recommended)

@UIApplicationMain
internal final class AppDelegate: UIResponder, UIApplicationDelegate {
    internal var window: UIWindow?

    internal func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // register TPTweakShakeWindow to enable openning TPTweak from shaking the device
        window = TPTweakShakeWindow(frame: UIScreen.main.bounds)
        ...
    }
}

Use TPTweak Value

Once your TPTweakEntry is set, you can get and set a value from it.

Read value

// will return true or false based on latest value changed on TPTweak
let isTrackingEnable = TPTweakEntry.enableTracking.getValue(Bool.self) 

Set value

if you want to set the value manually programmatically

TPTweakEntry.enableTracking.setValue(true)

Use custom UserDefaults provider

you can change the UserDefaults with modifying the TPTweakStore environment

TPTweakStore.environment.provider = {
    UserDefaults(suiteName: "group.com.example")!
}

Use custom isDebugMode logic

you can configure when to enable TPTweak value by adjusting TPTweakStore environment

TPTweakStore.environment.isDebugMode = {
    #if DEBUG || IN_HOUSE 
        return true
    #else
        return false
    #endif
}

License

 Copyright 2022-2025 Tokopedia. All rights reserved.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.

About

Debugging tool to help adjust your iOS app on the fly without recompiling

Topics

Resources

License

Stars

Watchers

Forks

Contributors 4

  •  
  •  
  •  
  •