JustTweak - это флаг -фреймворки для приложений для iOS. Он обеспечивает простой интерфейс фасада, взаимодействующий с несколькими поставщиками настройки, которые запрашиваются в отношении данного приоритета. Настройки представляют флаги, используемые для управления решениями в клиентском коде.
С JustTweak вы можете достичь следующего:
JustTweak доступен через кокопод. Чтобы установить его, просто добавьте следующую строку в свой Podfile:
pod "JustTweak"
JustTweak также доступен через SPM. Скопируйте URL для этого репо и добавьте пакет в настройки проекта.
LocalTweakProvider
JSON, включая ваши функции. См. LocalTweaks_example.json
для отправной точки.Чтобы настроить стек, у вас есть два варианта:
static let tweakManager : TweakManager = {
var tweakProviders : [ TweakProvider ] = [ ]
// Mutable TweakProvider (to override tweaks from other TweakProviders)
let userDefaultsTweakProvider = UserDefaultsTweakProvider ( userDefaults : UserDefaults . standard )
tweakProviders . append ( userDefaultsTweakProvider )
// Optimizely (remote TweakProvider)
let optimizelyTweakProvider = OptimizelyTweakProvider ( )
optimizelyTweakProvider . userId = UUID ( ) . uuidString
tweakProviders . append ( optimizelyTweakProvider )
// Firebase Remote Config (remote TweakProvider)
let firebaseTweakProvider = FirebaseTweakProvider ( )
tweakProviders . append ( firebaseTweakProvider )
// Local JSON-based TweakProvider (default TweakProvider)
let jsonFileURL = Bundle . main . url ( forResource : " LocalTweaks_example " , withExtension : " json " ) !
let localTweakProvider = LocalTweakProvider ( jsonURL : jsonFileURL )
tweakProviders . append ( localTweakProvider )
return TweakManager ( tweakProviders : tweakProviders )
} ( )
LocalTweakProvider
. Обратитесь к TweakAccessor.swift
для отправной точки. config.json
в следующем формате: {
"accessorName" : " GeneratedTweakAccessor "
}
Единственным поддерживаемым в настоящее время значением является accessorName
, которое определяет имя сгенерированного класса.
Podfile
script_phase :name = > ' TweakAccessorGenerator ' ,
:script = > ' $SRCROOT/../TweakAccessorGenerator
-l $SRCROOT/<path_to_the_local_tweaks_json_file>
-o $SRCROOT/<path_to_the_output_folder_for_the_generated_code>
-c $SRCROOT/<path_to_the_folder_containing_config.json> ' ,
:execution_position = > :before_compile
Каждый раз, когда целевая цель будет построена, инструмент генератора кодов будет регенерировать код для стека. Он будет включать все свойства, поддерживающие функции, определенные в LocalTweakProvider
.
Если вы использовали инструмент генератора кода, сгенерированный стек включает в себя все флаги функций. Просто выделите объект Accessont (какое имя вы определили в конфигурации .json
, и используйте его для доступа к флагам функций.
let accessor = GeneratedTweakAccessor ( with : < #tweak_manager_instance# > )
if accessor . meaningOfLife == 42 {
...
}
См. GeneratedTweakAccessor.swift
и GeneratedTweakAccessor+Constants.swift
для примера сгенерированного кода.
Если вы решили самостоятельно реализовать код стека, вам придется реализовать код для доступа к функциям через TweakManager
.
Три основных функции JustWeak можно получить из экземпляра TweakManager
чтобы принять решения о пути кода.
// check for a feature to be enabled
let enabled = tweakManager . isFeatureEnabled ( " some_feature " )
if enabled {
// enable the feature
} else {
// default behaviour
}
TweakManager
вернет значение от поставщика Tweak с наивысшим приоритетом и автоматически отступает к другим, если не найдено установленного значения. Он бросает выполнение, когда обнаруживается настройка нуля, которую можно поймать и обработать по мере необходимости. Используйте либо tweakWith(feature:variable:)
или предоставленные обертки свойств.
// check for a tweak value
let tweak = try ? tweakManager . tweakWith ( feature : " some_feature " , variable : " some_flag " )
if let tweak = tweak {
// tweak was found in some tweak provider, use tweak.value
} else {
// tweak was not found in any tweak provider
}
Или с Do-Catch
// check for a tweak value
do {
let tweak = try tweakManager . tweakWith ( feature : " some_feature " , variable : " some_flag " )
// tweak was found in some tweak provider, use tweak.value
return tweak
} catch let error as TweakError {
switch error {
case . notFound : ( ) // "Feature or variable is not found"
case . notSupported : ( ) // "Variable type is not supported"
case . decryptionClosureNotProvided : ( ) // "Value is encrypted but there's no decryption closure provided"
}
} catch let error { // add a default catch to satisfy the compiler
print ( error . localizedDescription )
}
@TweakProperty
, @OptionalTweakProperty
и @FallbackTweakProperty
Обертки доступны, чтобы отметить свойства, представляющие флаги функций. Имейте в виду, что для того, чтобы использовать эти обертки свойств, необходим статический экземпляр TweakManager
.
@ TweakProperty ( feature : < #feature_key# > ,
variable : < # var iable_key# > ,
tweakManager : < #TweakManager# > )
var labelText : String
@ OptionalTweakProperty ( fallbackValue : < #nillable_fallback_value# > ,
feature : < #feature_key# > ,
variable : < # var iable_key# > ,
tweakManager : < #TweakManager# > )
var meaningOfLife : Int ?
@ FallbackTweakProperty ( fallbackValue : < #nillable_fallback_value# > ,
feature : < #feature_key# > ,
variable : < # var iable_key# > ,
tweakManager : < #TweakManager# > )
var shouldShowFeatureX : Bool
Порядок объектов в массиве tweakProviders
определяет приоритет поставщиков Tweak.
MutableTweakProvider
с наивысшим приоритетом, таким как UserDefaultsTweakProvider
в примере выше, будет использоваться для отражения изменений, внесенных в пользовательском интерфейсе ( TweakViewController
). LocalTweakProvider
должен иметь самый низкий приоритет, поскольку он предоставляет значения по умолчанию от локального поставщика Tweak, и это тот, который используется TweakViewController
для заполнения пользовательского интерфейса.
Чтобы перейти из руководства в сгенерированную реализацию кода, необходимо обновить новый формат .json
. Чтобы помочь в этом процессе, мы добавили свойство GeneratedPropertyName
в объект Tweak. Установите это значение, чтобы соответствовать вашим текущим именам свойств в коде, чтобы сгенерированные свойства доступа соответствовали вашей существующей реализации.
TweakManager
предоставляет возможность кэшировать значения tweak для повышения производительности. Кэширование отключено по умолчанию, но может быть включено через свойство useCache
. При включении есть два способа сбросить кэш:
resetCache
на TweakManager
TweakProviderDidChangeNotification
JustTweak поставляется с ViewController, который позволяет пользователю редактировать MutableTweakProvider
с самым высоким приоритетом.
func presentTweakViewController ( ) {
let tweakViewController = TweakViewController ( style : . grouped , tweakManager : < #TweakManager# > )
// either present it modally
let tweaksNavigationController = UINavigationController ( rootViewController : tweakViewController )
tweaksNavigationController . navigationBar . prefersLargeTitles = true
present ( tweaksNavigationController , animated : true , completion : nil )
// or push it on an existing UINavigationController
navigationController ? . pushViewController ( tweakViewController , animated : true )
}
Когда значение изменяется в любой MutableTweakProvider
, уведомление запускается, чтобы дать клиентам возможность реагировать и отражать изменения в пользовательском интерфейсе.
override func viewDidLoad ( ) {
super . viewDidLoad ( )
NotificationCenter . defaultCenter ( ) . addObserver ( self ,
selector : #selector ( updateUI ) ,
name : TweakProviderDidChangeNotification ,
object : nil )
}
@ objc func updateUI ( ) {
// update the UI accordingly
}
JustTweak поставляется с тремя поставщиками твиков из коробки:
UserDefaultsTweakProvider
, который является изменчивым и использует UserDefaults
в качестве клавиш/хранилищеLocalTweakProvider
, который только для чтения и использует файл JSON, который предназначен для удержания установки функции по умолчанию.EphemeralTweakProvider
, который является просто экземпляром NSMutableDictionary
Кроме того, JustWeak определяет протоколы TweakProvider
и MutableTweakProvider
которые вы можете реализовать для создания собственного поставщика Tweak для удовлетворения ваших потребностей. В примере проекта вы можете найти несколько примеров, которые вы можете использовать в качестве отправной точки.
JustTweak предлагает возможность добавить decryptionClosure
в TweakProvider
. Это закрытие принимает Tweak
в качестве ввода и возвращает TweakValue
в качестве вывода. Закрытие позволяет вам сделать некоторую предварительную обработку при настройке, которая может быть использована для расшифровки значений. Это можно использовать, если у вас есть зашифрованное значение в вашем файле json, как можно увидеть ниже:
"encrypted_answer_to_the_universe" : {
"Title" : " Encrypted definitive answer " ,
"Description" : " Encrypted answer to the Ultimate Question of Life, the Universe, and Everything " ,
"Group" : " General " ,
"Value" : " 24 ton yletinifeD " ,
"GeneratedPropertyName" : " definitiveAnswerEncrypted " ,
"Encrypted" : true
}
Обратите внимание, что вы должны указать, зашифровано ли значение в вашем файле JSON (с Encrypted
свойством) для закрытия дешифрования для обработки значения. Закрытие дешифрования для JSON выше может быть указано следующим образом:
tweakProvider . decryptionClosure = { tweak in
// decrypt `tweak.value` with your cypher of choice and return the decrypted value
}
Таким образом, настройка, извлеченная из поставщика Tweak, будет иметь расшифрованное значение.
JustTweak доступен по лицензии Apache 2.0. Смотрите файл лицензии для получения дополнительной информации.