JustTweak هو إطار عمل لعلامة ميزة لتطبيقات iOS. يوفر واجهة واجهة بسيطة تتفاعل مع مقدمي تعديل متعددة والتي يتم الاستعلام عنها فيما يتعلق بأولوية معينة. تمثل التعديلات الأعلام المستخدمة لدفع القرارات في رمز العميل.
مع JustTweak يمكنك تحقيق ما يلي:
JustTweak متاح من خلال cocoapods. لتثبيته ، ما عليك سوى إضافة السطر التالي إلى podfile الخاص بك:
pod "JustTweak"
JustTweak متاح أيضا من خلال SPM. انسخ عنوان URL لهذا الريبو ، وأضف الحزمة في إعدادات مشروعك.
LocalTweakProvider
بما في ذلك الميزات الخاصة بك. الرجوع إلى 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
.
إذا كنت قد استخدمت أداة مولد الرمز ، فإن المكدس الذي تم إنشاؤه يتضمن جميع أعلام الميزات. ما عليك سوى تخصيص كائن الملحقات (أي الاسم الذي حددته في تكوين .json
واستخدمه للوصول إلى أعلام الميزة.
let accessor = GeneratedTweakAccessor ( with : < #tweak_manager_instance# > )
if accessor . meaningOfLife == 42 {
...
}
انظر GeneratedTweakAccessor.swift
و GeneratedTweakAccessor+Constants.swift
للحصول على مثال على التعليمات البرمجية التي تم إنشاؤها.
إذا قررت تنفيذ رمز المكدس بنفسك ، فسيتعين عليك تنفيذ التعليمات البرمجية للوصول إلى الميزات عبر TweakManager
.
يمكن الوصول إلى الميزات الرئيسية الثلاثة لـ JustTweak من مثيل TweakManager
لقيادة قرارات مسار الرمز.
// check for a feature to be enabled
let enabled = tweakManager . isFeatureEnabled ( " some_feature " )
if enabled {
// enable the feature
} else {
// default behaviour
}
TweakManager
بإرجاع القيمة من مزود التعديل بأعلى أولوية وتراجع تلقائيًا إلى الآخرين إذا لم يتم العثور على قيمة محددة. إنه يلقي التنفيذ عند العثور على قرص لا يمكن اللحاق به والتعامل معه حسب الحاجة. استخدم إما 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
أولوية مقدمي الخدمات.
سيتم استخدام MutableTweakProvider
مع أعلى الأولوية ، مثل UserDefaultsTweakProvider
في المثال أعلاه ، لتعكس التغييرات التي تم إجراؤها في واجهة المستخدم ( TweakViewController
). يجب أن يكون لـ LocalTweakProvider
أقل أولوية لأنه يوفر القيم الافتراضية من مزود تعديل محلي وهو الذي يستخدمه TweakViewController
لإلغاء واجهة المستخدم.
من أجل الترحيل من اليدوي إلى التنفيذ الذي تم إنشاؤه في الكود ، من الضروري التحديث إلى تنسيق .json
الجديد. للمساعدة في هذه العملية ، أضفنا خاصية GeneratedPropertyName
إلى كائن التعديل. قم بتعيين هذه القيمة للتوافق مع أسماء الخصائص الحالية الخاصة بك في الكود ، بحيث تتطابق خصائص الملحقات التي تم إنشاؤها إلى تطبيقك الحالي.
يوفر TweakManager
خيار تخزين قيم القرص من أجل تحسين الأداء. يتم تعطيل التخزين المؤقت افتراضيًا ولكن يمكن تمكينه عبر خاصية 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
بالإضافة إلى ذلك ، يحدد JustTweak بروتوكولات TweakProvider
و MutableTweakProvider
التي يمكنك تنفيذها لإنشاء موفر التعديل الخاص بك لتناسب احتياجاتك. في مشروع المثال ، يمكنك العثور على بعض الأمثلة التي يمكنك استخدامها كنقطة انطلاق.
يوفر JustTweak القدرة على إضافة decryptionClosure
إلى TweakProvider
. يأخذ هذا الإغلاق Tweak
كمدخلات ويعيد TweakValue
كمخرج. يتيح لك الإغلاق القيام ببعض المعالجة المسبقة على القرص الذي يمكن استخدامه على سبيل المثال لفك تشفير القيم. يمكن استخدام هذا إذا كان لديك قيمة مشفرة في ملف JSON TDEAKS كما هو موضح أدناه:
"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
}
وبهذه الطريقة ، سيكون للقرص الذي تم جلبه من مزود القرص القيمة التي تم فك تشفيرها.
JustTweak متاح بموجب ترخيص Apache 2.0. انظر ملف الترخيص لمزيد من المعلومات.