JustTweak adalah kerangka kerja penandaan fitur untuk aplikasi iOS. Ini menyediakan antarmuka fasad sederhana yang berinteraksi dengan beberapa penyedia tweak yang ditanyai menghormati prioritas yang diberikan. Tweak mewakili bendera yang digunakan untuk mengarahkan keputusan dalam kode klien.
Dengan JustTweak Anda dapat mencapai yang berikut:
Justtweak tersedia melalui cocoapods. Untuk menginstalnya, cukup tambahkan baris berikut ke podfile Anda:
pod "JustTweak"
JustTweak juga tersedia melalui SPM. Salin URL untuk repo ini, dan tambahkan paket di pengaturan proyek Anda.
LocalTweakProvider
termasuk fitur Anda. Lihat LocalTweaks_example.json
untuk titik awal.Untuk mengonfigurasi tumpukan, Anda memiliki dua opsi:
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
. Lihat TweakAccessor.swift
untuk titik awal. config.json
dalam format berikut: {
"accessorName" : " GeneratedTweakAccessor "
}
Satu -satunya nilai yang saat ini didukung adalah accessorName
yang mendefinisikan nama kelas yang dihasilkan.
Podfile
Anda 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
Setiap kali target dibangun, alat generator kode akan meregenerasi kode untuk tumpukan. Ini akan mencakup semua properti yang mendukung fitur yang ditentukan dalam LocalTweakProvider
.
Jika Anda telah menggunakan alat generator kode, tumpukan yang dihasilkan mencakup semua bendera fitur. Cukup alokasikan objek Accessor (nama mana yang telah Anda tentukan dalam konfigurasi .json
dan menggunakannya untuk mengakses bendera fitur.
let accessor = GeneratedTweakAccessor ( with : < #tweak_manager_instance# > )
if accessor . meaningOfLife == 42 {
...
}
Lihat GeneratedTweakAccessor.swift
dan GeneratedTweakAccessor+Constants.swift
Untuk contoh kode yang dihasilkan.
Jika Anda memutuskan untuk mengimplementasikan kode tumpukan sendiri, Anda harus menerapkan kode untuk mengakses fitur melalui TweakManager
.
Tiga fitur utama dari JustTweak dapat diakses dari instance TweakManager
untuk menggerakkan keputusan jalur kode.
// check for a feature to be enabled
let enabled = tweakManager . isFeatureEnabled ( " some_feature " )
if enabled {
// enable the feature
} else {
// default behaviour
}
TweakManager
akan mengembalikan nilai dari penyedia tweak dengan prioritas tertinggi dan secara otomatis mundur ke yang lain jika tidak ada nilai yang ditetapkan. Ini melempar eksekusi ketika tweak nil ditemukan yang dapat ditangkap dan ditangani sesuai kebutuhan. Gunakan salah satu tweakWith(feature:variable:)
atau pembungkus properti yang disediakan.
// 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
}
Atau dengan 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
dan @FallbackTweakProperty
Properti pembungkus tersedia untuk menandai properti yang mewakili bendera fitur. Pikiran bahwa untuk menggunakan pembungkus properti ini, contoh statis TweakManager
diperlukan.
@ 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
Urutan objek dalam array tweakProviders
mendefinisikan prioritas penyedia tweak.
MutableTweakProvider
dengan prioritas tertinggi, seperti UserDefaultsTweakProvider
dalam contoh di atas, akan digunakan untuk mencerminkan perubahan yang dibuat di UI ( TweakViewController
). LocalTweakProvider
harus memiliki prioritas terendah karena memberikan nilai default dari penyedia tweak lokal dan itu yang digunakan oleh TweakViewController
untuk mengisi UI.
Untuk bermigrasi dari manual ke implementasi yang dihasilkan kode, perlu untuk memperbarui ke format .json
baru. Untuk membantu proses ini, kami telah menambahkan properti GeneratedPropertyName
ke objek tweak. Atur nilai ini untuk selaras dengan nama properti Anda saat ini dalam kode, sehingga properti Accessor yang dihasilkan cocok dengan implementasi Anda yang ada.
TweakManager
menyediakan opsi untuk menyimpan nilai tweak untuk meningkatkan kinerja. Caching dinonaktifkan secara default tetapi dapat diaktifkan melalui properti useCache
. Saat diaktifkan, ada dua cara untuk mengatur ulang cache:
resetCache
di TweakManager
TweakProviderDidChangeNotification
JustTweak hadir dengan ViewController yang memungkinkan pengguna untuk mengedit MutableTweakProvider
dengan prioritas tertinggi.
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 )
}
Ketika suatu nilai dimodifikasi dalam setiap MutableTweakProvider
, pemberitahuan dipecat untuk memberi klien kesempatan untuk bereaksi dan mencerminkan perubahan dalam UI.
override func viewDidLoad ( ) {
super . viewDidLoad ( )
NotificationCenter . defaultCenter ( ) . addObserver ( self ,
selector : #selector ( updateUI ) ,
name : TweakProviderDidChangeNotification ,
object : nil )
}
@ objc func updateUI ( ) {
// update the UI accordingly
}
JustTweak hadir dengan tiga penyedia tweak di luar kotak:
UserDefaultsTweakProvider
yang dapat berubah dan menggunakan UserDefaults
sebagai Key/Value StoreLocalTweakProvider
yang hanya baca dan menggunakan file json yang dimaksudkan untuk menahan pengaturan penandaan fitur defaultEphemeralTweakProvider
yang merupakan contoh dari NSMutableDictionary
Selain itu, JustTweak mendefinisikan protokol TweakProvider
dan MutableTweakProvider
yang dapat Anda terapkan untuk membuat penyedia tweak Anda sendiri agar sesuai dengan kebutuhan Anda. Dalam contoh proyek Anda dapat menemukan beberapa contoh yang dapat Anda gunakan sebagai titik awal.
JustTweak menawarkan kemampuan untuk menambahkan decryptionClosure
ke TweakProvider
. Penutupan ini mengambil Tweak
sebagai input dan mengembalikan TweakValue
sebagai output. Penutupan memungkinkan Anda melakukan beberapa preprocessing pada tweak Anda yang dapat digunakan untuk digunakan untuk mendekripsi nilai. Ini dapat digunakan jika Anda memiliki nilai terenkripsi dalam file tweak JSON Anda seperti yang dapat dilihat di bawah:
"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
}
Perhatikan bahwa Anda harus menentukan apakah nilainya dienkripsi dalam file JSON Anda (dengan properti Encrypted
) untuk penutupan dekripsi untuk memproses nilai. Penutupan dekripsi untuk JSON di atas dapat ditentukan sebagai berikut:
tweakProvider . decryptionClosure = { tweak in
// decrypt `tweak.value` with your cypher of choice and return the decrypted value
}
Dengan cara ini, tweak yang diambil dari penyedia tweak akan memiliki nilai yang didekripsi.
JustTweak tersedia di bawah lisensi Apache 2.0. Lihat file lisensi untuk info lebih lanjut.