CocoaPods Plugin هي إضافة Gradle لـ Kotlin Multiplatform Mobile تدمج مدير التبعيات CocoaPods مباشرة في نظام بناء مشروع KMM. تسمح الإضافة بتعريف تبعيات iOS (pods) مباشرة في build.gradle.kts، وتوليد Podfile تلقائياً، وتثبيت pods، وربطها بكود Kotlin. بدلاً من إدارة .xcworkspace يدوياً، يدير المطور تبعيات iOS عبر Gradle، مما يجعل إعداد مشروع KMM قابلاً للتكرار بالكامل. وفقاً لـ JetBrains، 2025، تُستخدم الإضافة في 20% من مشاريع KMM لإدارة مكتبات iOS.
الخلاصة
CocoaPods Plugin (المعروف أيضاً باسم kotlin.cocoapods) هي إضافة رسمية من JetBrains لدمج CocoaPods مع Kotlin Multiplatform Mobile. الإضافة هي جزء من Kotlin Gradle DSL ويتم تكوينها مباشرة في build.gradle.kts لوحدة KMM. تقوم بأتمتة إنشاء وصيانة Podfile، وتوليد .xcworkspace، وإدارة تبعيات pods، مما يلغي الحاجة إلى التكوين اليدوي لمشروع Xcode.
قبل ظهور CocoaPods Plugin، كان مطورو KMM مضطرين لإنشاء Podfile يدوياً، وتشغيل pod install، وتكوين bridge headers، وتتبع إصدارات pods بشكل منفصل عن تبعيات Gradle. أدى ذلك إلى عدم تزامن الإصدارات وصعوبات في خطوط أنابيب CI/CD. حلّت الإضافة هذه المشاكل بجعل إدارة تبعيات iOS بنفس سهولة إدارة تبعيات Gradle في وحدات Android.
تدعم الإضافة كلاً من pods العامة من CocoaPods Trunk و pods المخصصة من المستودعات الخاصة. كما أن العمل مع Podspec المحلية والمستودعات القائمة على git مدعوم أيضاً. الإضافة متوافقة مع Kotlin 1.6.0 وما فوق، وتتطلب تثبيت CocoaPods (gem install cocoapods) على جهاز التطوير.
CocoaPods Plugin تعمل على مستوى task-graph في Gradle، مضيفة مهاماً متخصصة للعمل مع CocoaPods. تشمل المهام الرئيسية podInstall (تثبيت pods)، و podGenXcodeWorkspace (توليد .xcworkspace)، و podBuildDebugFramework (بناء إصدار Debug من الإطار). تقوم الإضافة بتحليل قسم cocoapods في build.gradle.kts، وإنشاء Podfile بناءً على التبعيات المعلنة، وتشغيل pod install بالمعلمات المطلوبة.
تتضمن بنية الإضافة ثلاثة مكونات: امتداد DSL لـ build.gradle.kts، و مولد Podfile لإنشاء Podfile، و طبقة تكامل Xcode لتكوين .xcworkspace. يوفر امتداد DSL كتلة cocoapods { } مع وظائف pod() المتداخلة لتعريف التبعيات، و specRepo() لتحديد المستودعات الخاصة، و framework { } لتكوين إطار المخرجات. يقوم مولد Podfile بترجمة هذه التعريفات إلى صيغة Ruby التي يفهمها CocoaPods.
kotlin {
cocoapods {
summary = "Shared module for iOS project"
homepage = "https://itsectr.com"
framework {
baseName = "Shared"
isStatic = true
export(project(":core"))
}
pod("Alamofire") {
version = "~> 5.9"
}
pod("Kingfisher") {
version = "7.12"
}
}
}
عند تنفيذ podInstall، تقوم الإضافة بالتسلسل التالي: توليد Podfile في جذر المشروع، تشغيل pod install عبر سطر الأوامر، توليد .xcworkspace، التحقق من تطابق إصدارات pods مع المعلنة، وتخزين Podfile.lock في الذاكرة المؤقتة. في التشغيلات اللاحقة دون تغييرات في التكوين، يتم تخطي podInstall إذا لم يتغير Podfile.lock. هذا يوفر الوقت في CI/CD، حيث يمكن أن يستغرق pod install حتى 2-3 دقائق للتثبيت النظيف.
يتطلب إعداد CocoaPods Plugin عدة خطوات. تثبيت CocoaPods على جهاز التطوير (gem install cocoapods) شرط أساسي. ثم، في build.gradle.kts للوحدة المشتركة، تتم إضافة كتلة cocoapods { } مع تكوين الإطار والتبعيات. بعد التكوين، يتم تنفيذ مهمة podInstall، والتي ستقوم بإنشاء Podfile وتثبيت pods. سيكون .xcworkspace المُولّد في جذر المشروع بجوار Podfile.
تتكامل الإضافة مع مراحل بناء Xcode. عند بناء تطبيق iOS، يقوم Xcode بتشغيل embedAndSignAppleFrameworkForXcode — وهي مهمة تنسخ إطار Kotlin/Native إلى حزمة التطبيق. تضيف CocoaPods Plugin مرحلة البناء هذه تلقائياً عند توليد .xcworkspace. إذا تم توليد .xcworkspace، يجب فتحه بدلاً من .xcodeproj للبناء الصحيح مع تبعيات pods.
| الخطوة | الوصف | الأمر / الإجراء |
|---|---|---|
| 1 | تثبيت CocoaPods | gem install cocoapods |
| 2 | إضافة الإضافة إلى build.gradle.kts | kotlin { cocoapods { ... } } |
| 3 | تعريف pods | pod("Alamofire") { version = "5.9.0" } |
| 4 | توليد Podfile | ./gradlew :shared:podInstall (تلقائياً) |
| 5 | فتح .xcworkspace | بدلاً من .xcodeproj |
| 6 | بناء تطبيق iOS | Xcode Build (⌘B) |
دعنا نستعرض سيناريوهات مختلفة لتعريف pods في CocoaPods Plugin. الحالة الأساسية هي توصيل pod عام من CocoaPods Trunk مع تحديد الإصدار. تتضمن السيناريوهات الأكثر تعقيداً استخدام podspec مخصص، و pods محلية، و pods من مستودعات git.
kotlin {
iosArm64()
iosSimulatorArm64()
cocoapods {
framework {
baseName = "Shared"
isStatic = false
}
// Pod عام من CocoaPods Trunk
pod("Alamofire") { version = "5.9.0" }
// إصدار مخصص مع عامل
pod("SnapKit") { version = "~> 5.6" }
// Pod من مستودع خاص
specRepo("https://git.itsectr.com/specs.git",
"internal-specs")
pod("InternalAnalyticsPod")
// Pod محلي مع مسار
pod(name = "CustomPod",
localPath = "./ios-pods/CustomPod")
// Pod من مستودع git
pod(name = "PrivateSDK",
git = "https://git.itsectr.com/ios/sdk.git",
tag = "2.1.0")
}
}
توصيل pods هو مجرد جزء من التكوين. تسمح الإضافة أيضاً بتصدير التبعيات من وحدات Kotlin الأخرى إلى إطار iOS. تحدد وظيفة export(project(":core")) أن جميع واجهات API العامة لوحدة :core يجب أن تكون قابلة للوصول من رأس Objective-C للإطار المُولّد. هذا ضروري عندما يستخدم كود Kotlin المشترك فئات من وحدة أخرى وتحتاج أن تكون قابلة للوصول من Swift.
cocoapods {
framework {
baseName = "Shared"
// تصدير الوحدات إلى إطار iOS
export(project(":network"))
export(project(":domain"))
// ربط ثابت أو ديناميكي
isStatic = true
}
// Pod مطلوب للوحدات المصدرة
pod("Moya") { version = "15.0" }
}
بعد التكوين، تحتاج إلى تنفيذ podInstall لتوليد Podfile وتثبيت التبعيات. ثم يتم فتح .xcworkspace المُولّد في Xcode، حيث يمكن بناء التطبيق بالطريقة القياسية. بالنسبة لـ CI/CD، تأكد من تثبيت CocoaPods و Ruby على جهاز البناء. تدعم الإضافة العلم --no-daemon للعمل في بيئة CI.
// تثبيت pods يولد Podfile + xcworkspace
./gradlew :shared:podInstall
// بناء إطار debug للاختبار
./gradlew :shared:podBuildDebugFramework
// بناء iOS كامل من سطر الأوامر
xcodebuild -workspace ios-app.xcworkspace \
-scheme ios-app -configuration Debug
Swift Package Manager (SPM) هو مدير تبعيات بديل من Apple يكتسب شعبية ويحل محل CocoaPods تدريجياً في مجتمع iOS. ومع ذلك، يظل CocoaPods Plugin ذا صلة لعدة أسباب: لا يدعم SPM الأطر الديناميكية في سياق KMM، ويتطلب تكامل إطار Kotlin/Native عبر SPM إعدادات إضافية. يوفر CocoaPods Plugin مسار تكامل أكثر نضجاً وتوثيقاً.
المقارنة بين CocoaPods Plugin والتكامل المباشر عبر SPM تظهر أن الأول يتفوق في الأتمتة، بينما الثاني يتفوق في الدعم الأصلي من Apple. يقوم CocoaPods Plugin تلقائياً بتوليد Podfile، وإدارة الإصدارات، وتكوين مراحل بناء Xcode. يتطلب SPM توصيل إطار Kotlin يدوياً عبر Package.swift، وهو أصعب في الصيانة لمشاريع KMM الكبيرة. تعمل JetBrains على دعم SPM لـ Kotlin/Native، ولكن في 2025 يبقى تكامل SPM تجريبياً.
| الخاصية | CocoaPods Plugin | Swift Package Manager |
|---|---|---|
| النضج | جاهز للإنتاج | تجريبي |
| توليد Podfile | تلقائي | غير قابل للتطبيق |
| الأطر الديناميكية | مدعومة | محدودة |
| إعداد CI/CD | بسيط (مهمة Gradle) | يتطلب خطوات يدوية |
| المستودعات الخاصة | مدعومة (specRepo) | مدعومة (URL) |
| الدعم الأصلي من Apple | عبر CocoaPods | أصلي |
عند استخدام CocoaPods Plugin، يواجه مطورو KMM العديد من المشاكل النموذجية. تضارب إصدارات pods هو المشكلة الأكثر شيوعاً، عندما يتطلب اثنان من pods إصدارات مختلفة من نفس التبعية. الحل هو تحديد إصدار التبعية المتعارضة بشكل صريح عبر pod("Dependency") { version = "x.x" }. الحالة الثانية الشائعة هي عدم توافق الإصدارات، عندما يتطلب pod إصدار iOS SDK أحدث من الإصدار الأدنى لمشروع KMM.
مشاكل مع .xcworkspace تنشأ إذا تم فتح .xcodeproj بدلاً من .xcworkspace بعد تكوين الإضافة. تحذر الإضافة من ذلك في سجلات podInstall. خطأ متكرر آخر هو عدم وجود CocoaPods على جهاز التطوير. تتحقق الإضافة من وجود أمر pod قبل تشغيل podInstall وتظهر رسالة خطأ واضحة. بالنسبة لـ CI/CD، قم بتثبيت CocoaPods: gem install cocoapods.
// حل تضارب الإصدارات
cocoapods {
pod("Alamofire") { version = "5.9.0" }
// حل التضارب بشكل صريح
pod("Alamofire") {
version = "5.9.0"
options[name] = mapOf("force" to true)
}
}
// التحقق من تثبيت CocoaPods عبر Gradle
tasks.register("checkCocoapods") {
doLast {
val result = "pod --version".runCommand()
println("إصدار CocoaPods: $result")
}
}
إذا فشل podInstall، استخدم العلم --info للحصول على مخرجات مفصلة: ./gradlew podInstall --info. تسجل الإضافة كل خطوة: توليد Podfile، تشغيل pod install، تحليل Podfile.lock. غالباً ما ترتبط الأخطاء بمشاكل الشبكة (عدم توفر CocoaPods Trunk) أو بناء جملة Podfile غير صحيح. في مثل هذه الحالات، حاول تشغيل pod install يدوياً في جذر المشروع للحصول على رسالة خطأ أكثر تفصيلاً من CocoaPods.
الأسئلة الشائعة
إذا كانت جميع تبعيات iOS تدار عبر SPM، فإن CocoaPods Plugin غير ضروري. الإضافة مطلوبة للتكامل مع CocoaPods. تعمل JetBrains على دعم SPM، ولكن في 2025 لا يزال تجريبياً.
وقت البناء يزداد فقط أثناء التشغيل الأول لـ podInstall (توليد Podfile + تثبيت pods). تستخدم عمليات البناء اللاحقة ذاكرة التخزين المؤقت Podfile.lock. بناء إطار Kotlin/Native نفسه لا يعتمد على pods.
نعم، تدعم الإضافة وظيفة specRepo لتوصيل المستودعات الخاصة. حدد عنوان URL واسم المستودع في specRepo، وبعد ذلك تصبح pods من هذا المستودع متاحة للتعريف.
قم بتشغيل pod install يدوياً في جذر المشروع للحصول على رسالة خطأ مفصلة. تحقق من الاتصال بـ CocoaPods Trunk، وصحة إصدارات pods، ووجود Ruby على الجهاز.
نعم، يجب إضافة Podfile.lock إلى git لضمان بنائات قابلة للتكرار. يقوم CocoaPods Plugin بتوليد Podfile، لكن Podfile.lock يثبت الإصدارات الدقيقة للـ pods المثبتة أثناء pod install.
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.