اللغة الصينية readme: 中文集成指南
يتيح لك حقن الكود تحديث تنفيذ الوظائف وأي طريقة لفئة أو بنية أو تعداد تدريجيًا في محاكاة iOS دون الحاجة إلى إعادة بناء أو إعادة تشغيل تطبيقك بالكامل. هذا يوفر للمطور قدرًا كبيرًا من الوقت لتبديل الوقت أو التكرار على التصميم. يغير بشكل فعال Xcode من كونه "محررًا للمصدر" إلى كونه "محرر برنامج" حيث لا يتم حفظ تغييرات المصدر فقط على القرص ولكن في برنامج التشغيل الخاص بك مباشرة.
أصبح إعداد مشاريعك لاستخدام الحقن أمرًا بسيطًا الآن مثل تنزيل أحد إصدارات GitHub للتطبيق أو من متجر تطبيقات MAC وإضافة الكود أدناه في مكان ما في تطبيقك ليتم تنفيذها عند بدء التشغيل (لم يعد من الضروري تشغيل التطبيق نفسه بالفعل).
#if DEBUG
Bundle ( path : " /Applications/InjectionIII.app/Contents/Resources/iOSInjection.bundle " ) ? . load ( )
//for tvOS:
Bundle ( path : " /Applications/InjectionIII.app/Contents/Resources/tvOSInjection.bundle " ) ? . load ( )
//Or for macOS:
Bundle ( path : " /Applications/InjectionIII.app/Contents/Resources/macOSInjection.bundle " ) ? . load ( )
#endif من المهم أيضًا إضافة الخيارات -Xlinker و -interposable (بدون علامات اقتباس مزدوجة وعلى خطوط منفصلة) إلى "أعلام الارتباط الأخرى" للأهداف في مشروعك (لتكوين Debug فقط) لتمكين "التوضيح" (انظر التفسير أدناه).

بعد ذلك ، عندما تقوم بتشغيل تطبيقك في جهاز المحاكاة ، يجب أن ترى رسالة تقول أن مراقب الملفات قد بدأ في الدليل الرئيسي الخاص بك ، وكلما قمت بحفظ ملف مصدر في المشروع الحالي ، يجب أن يبلغ عن حقنه. هذا يعني أن جميع الأماكن التي تسمى سابقًا للتنفيذ القديم سيتم تحديثها للاتصال بأحدث إصدار من الرمز الخاص بك.
الأمر ليس بسيطًا تمامًا مثل رؤية النتائج على الشاشة على الفور ، يجب أن يتم استدعاء الكود الجديد بالفعل. على سبيل المثال ، إذا قمت بحقن وحدة التحكم في العرض ، فيجب أن فرض إعادة اللعب. لحل هذه المشكلة ، يمكن للفئات تنفيذ طريقة @objc func injected() والتي سيتم استدعاؤها بعد حقن الفصل لإجراء أي تحديث على الشاشة. إحدى التقنيات التي يمكنك استخدامها هي تضمين الكود التالي في مكان ما في برنامجك:
#if DEBUG
extension UIViewController {
@ objc func injected ( ) {
viewDidLoad ( )
}
}
#endifحل آخر لهذه المشكلة هو "استضافة" باستخدام حزمة حقن SWIFT التي أدخلتها منشور المدونة هذا.
لا يمكنك حقن التغييرات على كيفية وضع البيانات في الذاكرة ، أي أنه لا يمكنك إضافة خصائص أو إزالة أو إعادة ترتيب الخواص مع التخزين. بالنسبة للفئات غير النهائية ، ينطبق هذا أيضًا على إضافة أو إزالة الأساليب لأن vtable المستخدمة للإرسال هو في حد ذاته بنية بيانات لا يجب أن تتغير عن الحقن. لا يمكن للحقن أيضًا تحديد أجزاء التعليمات البرمجية التي يجب إعادة تنفيذها لتحديث الشاشة كما هو موضح أعلاه. أيضا ، لا تنفذ مع التحكم في الوصول. لا يمكن حقن الخصائص والأساليب private مباشرة ، خاصة في الامتدادات لأنها ليست رمزًا global قابلاً للتشويش. يتم حقنهم بشكل عام بشكل غير مباشر لأنه لا يمكن أن يتم تنسيقهم إلا داخل الملف الذي يتم حقنه ولكن هذا يمكن أن يسبب الارتباك. أخيرًا ، لا يتعامل الحقن بشكل جيد مع ملفات المصدر التي يتم إضافتها/إعادة تسميتها/حذفها أثناء الحقن. قد تحتاج إلى إنشاء تطبيقك وإعادة تشغيله أو حتى إغلاق مشروعك وإعادة فتحه لمسح سجلات إنشاء Xcode القديمة.
Swiftui ، إذا كان أي شيء ، أكثر ملاءمة للحقن من Uikit لأنه يحتوي على آليات محددة لتحديث العرض ولكن تحتاج إلى إجراء تغييرات زوجين على كل بنية View تريد حقنها. لإجبار إعادة الرحم على أن أبسط طريقة هي إضافة خاصية تلاحظ عند حدوث حقن:
@ ObserveInjection var forceRedraw يتوفر غلاف الخاصية هذا إما في حزمة Hotswiftui أو حقن Swift. أنه يحتوي بشكل أساسي على عدد @Published لاحظ آرائك أن الزيادات مع كل حقن. يمكنك استخدام واحدة مما يلي لإتاحة إحدى هذه الحزم خلال مشروعك:
@ _exported import HotSwiftUI
or
@ _exported import Inject التغيير الثاني الذي تحتاجه لجعل حقن Swiftui الموثوق به هو "محو نوع الإرجاع" من خاصية الجسم عن طريق لفها في AnyView باستخدام طريقة .enableInjection() تمديد View في هذه الحزم. هذا لأنه ، أثناء إضافة أو إزالة عناصر Swiftui ، يمكن أن يغير نوع الإرجاع الخرساني من خاصية الجسم التي تصل إلى تغيير تخطيط الذاكرة الذي قد يتعطل. باختصار ، يجب أن تبدو نهاية الذيل لكل جسم دائمًا مثل هذا:
var body : some View {
VStack or whatever {
// Your SwiftUI code...
}
. enableInjection ( )
}
@ ObserveInjection var redraw يمكنك ترك هذه التعديلات في رمز الإنتاج الخاص بك ، حيث يقوم ببناء Release بتحسينه إلى عدم وجود OP.
الجديد في XCode 16 هو إعداد بناء بناء SWIFT_ENABLE_OPAQUE_TYPE_ERASURE . يتم تشغيل هذا الإعداد افتراضيًا ولا تحتاج إلى مسح الجسم بشكل صريح. ستظل بحاجة إلى @ObserveInjection لإجبار إعادة الرسم.
لمزيد من المعلومات ، راجع Xcode 16.2 ملاحظات الإصدار.
يمكن أن يعمل هذا ولكن ستحتاج فعليًا إلى تشغيل أحد إصدارات Github 4.8.0+ من injectioniii.app ، وتعيين المستخدم الافتراضي للاضطراب وإعادة تشغيل التطبيق.
$ defaults write com.johnholdsworth.InjectionIII deviceUnlock any
بعد ذلك ، بدلاً من تحميل حزم الحقن ، قم بتشغيل هذا البرنامج النصي في "مرحلة الإنشاء": (ستحتاج أيضًا إلى إيقاف تشغيل إعداد بناء المشروع "Sandboxing order")
RESOURCES=/Applications/InjectionIII.app/Contents/Resources
if [ -f "$RESOURCES/copy_bundle.sh" ]; then
"$RESOURCES/copy_bundle.sh"
fi
وفي التطبيق الخاص بك ، قم بتنفيذ الكود التالي عند بدء التشغيل:
#if DEBUG
if let path = Bundle . main . path ( forResource :
" iOSInjection " , ofType : " bundle " ) ??
Bundle . main . path ( forResource :
" macOSInjection " , ofType : " bundle " ) {
Bundle ( path : path ) ! . load ( )
}
#endifبمجرد التبديل إلى هذا التكوين ، ستعمل أيضًا عند استخدام المحاكاة. راجع The ReadMe of Hotreloading Project للحصول على تفاصيل حول كيفية تصحيح تصحيح برنامجك الاتصال بـ injectioniii.app عبر Wi-Fi. ستحتاج أيضًا إلى تحديد دليل المشروع لمراقبة الملف يدويًا من القائمة البوب.
إنه يعمل ولكنك تحتاج إلى إيقاف تشغيل "صندوق الرمل" و "التحقق من المكتبة" مؤقتًا ضمن "وقت التشغيل الصلب" أثناء التطوير حتى يتمكن من تحميل رمز ديناميكي. لتجنب مشكلات التصميم ، استخدم البرنامج النصي الجديد copy_bundle.sh كما هو مفصل في التعليمات الخاصة بالحقن على الأجهزة الحقيقية أعلاه.
لقد عمل الحقن على طرق مختلفة على مر السنين ، وبدأت في استخدام واجهات برمجة تطبيقات "Swizzling" لـ Objective-C ولكنها الآن مبنية إلى حد كبير حول ميزة رابط Apple تسمى "Enterposing" والتي توفر حلًا لأي طريقة سريعة أو خاصية محسوبة من أي نوع.
عندما يستدعي الكود وظيفة في Swift ، يتم "إرساله بشكل ثابت" بشكل عام ، أي مرتبط باستخدام "الرمز المشوش" للوظيفة التي يتم استدعاؤها. كلما قمت بربط التطبيق الخاص بك بخيار "-interposable" ، ومع ذلك ، تتم إضافة مستوى إضافي من عدم التوجيه حيث يجد عنوان جميع الوظائف التي يتم استدعاؤها من خلال قسم من الذاكرة القابلة للكتابة. باستخدام قدرة نظام التشغيل على تحميل التعليمات البرمجية القابلة للتنفيذ ومكتبة Fishhook "لإعادة" الدعوة ، من الممكن "التداخل" للتطبيقات الجديدة لأي وظيفة وتجنبها بفعالية في بقية البرنامج في وقت التشغيل. من هذه النقطة ، سيؤدي ذلك كما لو أن الكود الجديد قد تم إنشاؤه في البرنامج.
يستخدم الحقن واجهة برمجة تطبيقات FSEventSteam لمراقبة متى يتم تغيير ملف مصدر ومسح سجل إنشاء Xcode الأخير لكيفية إعادة ترجمةه وربط مكتبة ديناميكية يمكن تحميلها في البرنامج. يقوم دعم وقت التشغيل بالحقن بعد ذلك بتحميل المكتبة الديناميكية ومسحها لتعريفات الوظيفة التي تحتوي عليها ثم "الوخابض" في بقية البرنامج. ليست هذه هي القصة الكاملة حيث يستخدم إرسال أساليب الطبقة غير النهائية "VTABLE" (Think C ++ طرق افتراضية) والتي يجب أيضًا تحديثها ولكن المشروع يعتني به إلى جانب أي "Swizzling" القديم.
إذا كنت مهتمًا بمعرفة المزيد حول كيفية عمل الحقن ، فإن أفضل مصدر هو إما كتابي الأسرار السريعة أو التنفيذ المرجعي الجديد للبدء في حزمة InjectionLite Swift. لمزيد من المعلومات حول "التدخل" ، استشر منشور المدونة هذا أو ReadMe of the Fishhook Project. لمزيد من المعلومات حول تنظيم التطبيق نفسه ، استشر ROATMAP.MD.
الحصول على الحقن للعمل لديه ثلاثة مكونات. filewatcher ، الكود لإعادة ترجمة أي ملفات تم تغييرها وإنشاء مكتبة ديناميكية يمكن تحميلها ورمز الحقن نفسه الذي يثبت الإصدارات الجديدة من الكود الخاص بك في التطبيق أثناء تشغيله. كيف يتم الجمع بين هذه المكونات الثلاثة تؤدي إلى عدد الطرق التي يمكن استخدام بها حقن.
"Injection Classic" هو المكان الذي تقوم فيه بتنزيل أحد الإصدارات الثنائية من GitHub وتشغيل injectioniii.app. تقوم بعد ذلك بتحميل إحدى الحزم داخل هذا التطبيق في البرنامج كما هو موضح أعلاه في جهاز المحاكاة. في هذا التكوين ، تتم مراقبة الملفات وإعادة تجميع المصدر داخل التطبيق وتتصل الحزمة بالتطبيق باستخدام مقبس لمعرفة متى تكون مكتبة ديناميكية جديدة جاهزة للتحميل.
"حقن App Store" هذا الإصدار من التطبيق هو Sandboxed ، وبينما لا يزال مراقب الملف يعمل داخل التطبيق ، يتم تفويض التحميل والتحميل ليتم تنفيذها داخل المحاكاة. يمكن أن يؤدي ذلك إلى إنشاء مشاكل مع ملفات رأس C حيث يستخدم Simulator نظام ملفات حساس للحالة ليكون محاكاة مخلصة لجهاز حقيقي.
كان "Hotreloading Injection" هو المكان الذي تقوم فيه بتشغيل تطبيقك على جهاز ، ولأنك لا تستطيع تحميل حزمة من نظام ملفات Mac على هاتف حقيقي ، فإنك تضيف حزمة سريعة التحميل إلى مشروعك (أثناء التطوير فقط!) والتي تتضمن جميع التعليمات البرمجية التي عادة ما تكون في الحزمة لأداء التحميل الديناميكي. هذا يتطلب أن تستخدم واحدة من الإصدارات الثنائية un-sandboxed. كما تم استبداله بواسطة البرنامج النصي copy_bundle.sh الموضح أعلاه.
"الحقن المستقل". كان هذا هو أحدث تطور للمشروع حيث لم تعد تقوم بتشغيل التطبيق نفسه ، ولكن ببساطة يتم تحميل إحدى حزم الحقن ويتم إجراء مراقب الملف وإعادة التثبيت والحقن داخل المحاكاة. افتراضيًا ، هذه الساعات للتغييرات على أي ملف سريع داخل الدليل الرئيسي الخاص بك على الرغم من أنه يمكنك تغيير هذا باستخدام البيئة المتغير INJECTION_DIRECTORIES .
InjectionLite هو الحد الأدنى من التنفيذ للحقن المستقل للرجوع إليه. فقط أضف هذه الحزمة السريعة ويجب أن تكون قادرًا على الحقن في جهاز المحاكاة.
InjectionNext هو نسخة تجريبية حاليًا من الحقن يجب أن تكون أسرع وأكثر موثوقية للمشاريع الكبيرة. يدمج في علامة تصحيح الأخطاء من Xcode لمعرفة كيفية إعادة ترجمة الملفات لتجنب تحليل سجلات البناء وإعادة استخدام تنفيذ العميل للحقن من InjectionLite . لاستخدامها مع المحررين الخارجيين مثل Cursor ، يمكن لـ InjectionNext أيضًا استخدام مراقب الملفات لاكتشاف التعديلات والتراجع لبناء رمز تحليل السجل.
كل هذه الاختلافات تتطلب منك إضافة أعلام الارتباط "-xlinker -Interposble" لبناء تصحيح الأخطاء أو ستكون قادرًا فقط على حقن طرق الفئات غير النهائية ويمكن استخدامها جميعًا بالاقتران مع أي من المحقونة العليا أو Hotswiftui.
راجع ReadMe القديم الذي إذا كان أي شيء يحتوي ببساطة "الكثير من المعلومات" بما في ذلك متغيرات البيئة المختلفة التي يمكنك استخدامها للتخصيص. أمثلة قليلة:
| البيئة var. | غاية |
|---|---|
| Injection_detail | الإخراج المطول لجميع الإجراءات التي تم تنفيذها |
| Injection_trace | مكالمات السجل إلى الوظائف المحقونة (v4.6.6+) |
| حقن | عنوان IP الخاص بـ MAC لحقن الجهاز |
مع متغير بيئة Injection_trace ، فإن حقن أي ملف سيضيف تسجيل كل المكالمات إلى الوظائف والأساليب في الملف إلى جانب قيم الوسيطة الخاصة بهم كمساعد للتصحيح.
تتمثل ميزة Injectioniii المعروفة التي شريطة أن تقوم بإجراء اختبارات لتطبيقك في مرحلة ما ، يمكنك ضخ فئة XCTEST فردية وإطاراتها على الفور - الإبلاغ إذا كان قد فشلت في كل مرة تقوم فيها بتعديلها.
يتضمن هذا المشروع رمزًا من Rentzsch/Mach_inject و erwanb/machinjectsample و davedelong/ddhotkey و acj/timelapsebuilder-swift بموجب تراخيص كل منهما.
تستخدم وظيفة تتبع التطبيق تطبيق OliverleTterer/IMP_ImplementationForwardingToSelector Trampoline عبر مشروع SwiftTrace تحت رخصة معهد ماساتشوستس للتكنولوجيا.
يستخدم SwiftTrace https://github.com/facebook/fishhook. راجع مصدر المشروع وملف الرأس المضمّن في حزمة التطبيق للاطلاع على تفاصيل الترخيص.
يتضمن هذا الإصدار نسخة معدلة قليلاً من مكتبة Canviz الممتازة لتقديم ملفات "DOT" في قماش HTML الذي يخضع لترخيص MIT. تتمثل التغييرات في المرور عبر معرف العقدة إلى علامة تسمية العقدة (السطر 212) ، لعكس عرض العقد والخطوط التي تربطها (السطر 406) وتخزين مسارات الحافة حتى يمكن تلوينها (السطر 66 و 303) في "Canviz-0.1/canviz.js".
ويشمل أيضًا محرر Codemirror JavaScript لتقييم الكود باستخدام الحقن بموجب ترخيص معهد ماساتشوستس للتكنولوجيا.
أيقونة التطبيق الرائعة بفضل Katya of Pixel-Mixer.com.