Live Activity هي ويدجت ديناميكية على شاشة قفل iPhone وفي Dynamic Island، تعرض معلومات في الوقت الفعلي: حالة التوصيل، نتائج رياضية، مؤقتات وتشغيل الموسيقى. يتم تنفيذها عبر ActivityKit (Swift، iOS 16.1+) مع WidgetKit. يتم تحديث Live Activity محلياً أو عبر إشعارات الدفع، تدعم حالات متعددة وينهيها النظام بعد انتهاء الحدث. للمزيد — في ActivityKit Documentation.
أهم النقاط
Live Activity هي امتداد لـ WidgetKit تعرض محتوى ديناميكياً على شاشة قفل iPhone وفي Dynamic Island. على عكس الودجت الثابتة التي يتم تحديثها بواسطة مؤقت النظام، يتم تشغيل Live Activity بواسطة التطبيق وتعيش لوقت محدود — حتى 8 ساعات للنشاط النشط وحتى 4 ساعات بعد الانتهاء. يرى المستخدم بيانات محدثة دون فتح الجهاز: حالة طلب التوصيل، المسافة إلى الوجهة في سيارة أجرة، نتائج المباراة أو تقدم التمرين.
ActivityKit هو إطار عمل للتعامل مع Live Activities، تم تقديمه في iOS 16.1. يوفر API لطلب وتحديث وإنهاء Activities. النشاط هو كائن بمحتوى وحالة. المحتوى (ActivityContent) يحدد البيانات الثابتة، بينما الحالة (ActivityState) تحدد البيانات الديناميكية المتغيرة بمرور الوقت. النظام نفسه يقرر متى يعرض الحالة الجديدة — هذا يوفر البطارية ويضمن حركات سلسة.
كل Live Activity يتم تعريفها بشكل فريد بواسطة ActivityID ومرتبطة بعملية واحدة — التطبيق الذي أنشأها. قد ينهي النظام النشاط عند انخفاض الذاكرة أو شحن البطارية. يتلقى المطور إشعاراً بالإنهاء القسري عبر مفوض ActivityKit ويمكنه حفظ الحالة الأخيرة لاستعادتها.
هندسة Live Activity مبنية على إطارين: WidgetKit مسؤول عن عرض واجهات SwiftUI، وActivityKit مسؤول عن دورة حياة النشاط. ينشئ المطور WidgetBundle مع دعم LiveActivityConfiguration. كل تكوين يحدد نوع البيانات (Attributes وState) وواجهة SwiftUI التي يعرضها النظام على شاشة القفل وDynamic Island. يتم تمرير البيانات عبر ActivityAttributes — هيكل بحقول let للمحتوى وحقول var للحالة.
| المكون | الغرض | API |
|---|---|---|
| Attributes | بيانات ثابتة للنشاط بالكامل | let name: String, let icon: String |
| ContentState | حالة ديناميكية، تتغير عند التحديث | var progress: Double, var status: Status |
| Activity | كائن طلب وإدارة النشاط | Activity.request(attributes:content:) |
| PushToken | رمز لتحديثات الدفع من الخادم | activity.pushToken publisher |
| ActivityUI | واجهة SwiftUI لشاشة القفل وDynamic Island | LockScreenView, ExpandedView, CompactView |
دورة حياة النشاط تشمل ثلاث مراحل: نشط (يعرضه النظام ويحدثه)، نهائي (انتهى النشاط لكن الواجهة لا تزال مرئية لمدة 4 ساعات)، تمت الإزالة (يزيل النظام الواجهة). يمكن للتطبيق إنهاء النشاط في أي وقت. ينهي النظام أيضاً الأنشطة قسراً — على سبيل المثال، عند إعادة تشغيل الجهاز أو انتهاء حد 8 ساعات.
import ActivityKit
struct DeliveryAttributes: ActivityAttributes {
public struct ContentState: Codable & Hashable {
var status: DeliveryStatus
var estimatedMinutes: Int
}
var orderNumber: String
var restaurantName: String
}
WidgetBundle يسجل Live Activity عبر الماكرو @main: يعيد الودجت قائمة بالتكوينات بما فيها LiveActivityConfiguration. بناءً على هذا التكوين، يعرف النظام أنواع البيانات المتوقعة وكيفية عرض الواجهة في حالات مختلفة — مضغوط، أدنى وموسع لـ Dynamic Island.
إنشاء نشاط يبدأ بطلب إلى ActivityKit. يستدعي التطبيق Activity.request(attributes:content:pushType:) ببيانات أولية. يتحقق النظام مما إذا كان Dynamic Island متاحاً على الجهاز ويعيد كائن Activity. قد يفشل الطلب إذا تم تجاوز حد الأنشطة النشطة — عادةً لا يزيد عن 5 في وقت واحد. بعد طلب ناجح، يعرض النظام الودجت على شاشة القفل، وإذا كان متاحاً، في Dynamic Island.
let attributes = DeliveryAttributes(
orderNumber: "A-1234",
restaurantName: "Pizza House"
)
let initialState = DeliveryAttributes.ContentState(
status: DeliveryStatus.preparing,
estimatedMinutes: 30
)
do {
let activity = try await Activity<DeliveryAttributes>.request(
attributes: attributes,
content: ActivityContent(state: initialState, staleDate: nil),
pushType: .token
)
print("Activity started: \(activity.id)")
} catch {
print("Failed: \(error)")
}
واجهة SwiftUI لـ Live Activity تستخدم بنى LockScreenView وExpandedView وCompactView من WidgetKit. تتلقى الواجهة السياق (ActivityViewContext) مع السمات والحالة الحالية. يحدث تحديث الواجهة تلقائياً عند وصول حالة جديدة من النظام. تدعم Live Activity مجموعة محدودة فقط من مكونات SwiftUI — Text، Image، HStack، VStack وعدد قليل من المعدلات.
كل واجهة Live Activity يجب أن تكون خفيفة وسريعة — يرفض النظام عرض الواجهات الثقيلة. حد وقت العرض هو 30 مللي ثانية لكل إطار. تقتصر الحركات على انتقالات النظام بين الحالات — الحركات المخصصة غير متاحة في Live Activity. يتم العرض في عملية خلفية لـ WidgetKit بأولوية استجابة شاشة القفل.
تحديث محلي — يحدث التطبيق حالة النشاط باستدعاء activity.update(using:). تقبل الطريقة ContentState جديداً وAlertConfiguration اختيارياً لعرض إشعار عند التحديث. التحديثات المحلية سريعة — يعيد النظام رسم الواجهة في دورة العرض التالية، عادةً خلال 1–2 ثانية. للتحديثات المتكررة (مؤقت، ساعة إيقاف) استخدم الوضع المحلي — فهو أكثر موثوقية وأسرع من الدفع.
let updatedState = DeliveryAttributes.ContentState(
status: DeliveryStatus.outForDelivery,
estimatedMinutes: 10
)
await activity.update(
ActivityContent<DeliveryAttributes.ContentState>(
state: updatedState,
staleDate: Date().addingTimeInterval(60)
),
alertConfiguration: AlertConfiguration(
title: "Order out for delivery",
body: "Arriving in 10 min"
)
)
تحديثات الدفع — يرسل الخادم إشعار دفع ActivityKit بالحالة الجديدة بتنسيق JSON. لهذا، يتلقى التطبيق pushToken من ناشر activity.pushToken ويمرره إلى الخادم. يرسل الخادم طلب POST إلى APNs بحمولة تحتوي على ContentState الجديد. يتلقى النظام الدفع، يفك تشفير الحالة ويحدث Live Activity دون مشاركة التطبيق — وهذا يسمح بتحديث النشاط حتى عندما يكون التطبيق مغلقاً.
تحديثات الدفع أكثر كفاءة من التحديثات المحلية للتحديثات غير المتكررة (حالة التوصيل كل 5–10 دقائق) — لا يحتاج التطبيق إلى الحفاظ على اتصال شبكة. للتحديثات المتكررة كل 1–2 ثانية استخدم الطريقة المحلية. تتضمن حمولة الخادم فقط الحقول القابلة للتغيير لـ ContentState — يتم إرسال بيانات Attributes الثابتة فقط عند إنشاء النشاط.
Dynamic Island هي منطقة عتاد وبرنامج في iPhone 14 Pro و15 Pro والأحدث تتكيف مع محتوى Live Activity. يعرض النظام تلقائياً النشاط في ثلاثة أنماط: مضغوط (أيقونة + نص قصير يسار القطع)، أدنى (أيقونة فقط) وموسع (مستطيل 300pt بمعلومات). لا يتحكم المطور في هذه الأنماط مباشرة — يختار النظام النمط بناءً على الأولوية والمساحة المتاحة.
struct DeliveryLiveActivity: Widget {
var body: some WidgetConfiguration {
ActivityConfiguration(for: DeliveryAttributes.self) { context in
LockScreenView(context: context)
} dynamicIsland: { context in
DynamicIsland {
DynamicIslandExpandedContent {
ExpandedView(context: context)
}
} compactLeading: {
CompactLeadingView(context: context)
} compactTrailing: {
CompactTrailingView(context: context)
} minimal: {
MinimalView(context: context)
}
}
}
}
يدعم Dynamic Island التفاعلية — يلمس المستخدم المنطقة ويدخل التطبيق أو يفتح العرض الموسع. النقر على النمط المضغوط يحول إلى الموسع، والتمرير لليسار يقلص النشاط إلى النمط الأدنى. تتم معالجة الأزرار في النمط الموسع (إيقاف مؤقت/إلغاء) عبر Link من SwiftUI — يطلق النظام التطبيق بعنوان URL عميق، وتتم المعالجة في UIApplicationDelegate.
قيود Dynamic Island: عرض النمط الموسع يصل إلى 300pt، النص المضغوط حتى 30 حرفاً. تتطابق الألوان والخطوط مع سمة النظام — التخصيص محدود. حركات الانتقال بين الأنماط هي حركات نظامية ولا يمكن تخصيصها. إذا كانت هناك تطبيقات متعددة لديها أنشطة نشطة، يعرضها Dynamic Island بالأولوية حسب وقت التشغيل ونوع المحتوى.
الأسئلة الشائعة
الودجت العادية لـ WidgetKit تعرض معلومات ثابتة ويتم تحديثها بواسطة مؤقت النظام بفاصل زمني أدنى 15–30 دقيقة. Live Activity تعرض بيانات ديناميكية في الوقت الفعلي على شاشة القفل وDynamic Island. يتم تشغيل Live Activity بواسطة التطبيق، وتعيش حتى 8 ساعات وينهيها النظام بعد انتهاء الحدث، على عكس الودجت التي توجد بشكل دائم.
تدعم Live Activity وضعين للتحديث: محلي — يحدث التطبيق الحالة عبر API ActivityKit في أي لحظة، وتحديث دفع — يرسل الخادم إشعار دفع ActivityKit يحوله النظام إلى حالة جديدة للودجت. عند انخفاض شحن البطارية، قد يجمد النظام Live Activity حتى توصيل الشاحن.
Live Activities متاحة على iPhone بنظام iOS 16.1 والإصدارات الأحدث. على iPhone 14 Pro والأحدث، تظهر Live Activity أيضاً في Dynamic Island. على iPad، Live Activity مدعومة فقط على شاشة القفل — Dynamic Island غير متاح على iPad. لا تدعم Apple Watch Live Activities مباشرة، لكن يمكنها عرض إشعارات الانتهاء.
يحد النظام من عدد Live Activities النشطة — عادةً لا يزيد عن 5 في وقت واحد لجميع التطبيقات. محاولة تشغيل ما يتجاوز الحد يعيد خطأ من ActivityKit. يمكن أن تحتوي كل Live Activity على حالات متعددة — على سبيل المثال، قيد الانتظار، في الطريق، تم التوصيل لطلب طعام. بعد الانتهاء، يبقى النشاط في الواجهة لمدة 4 ساعات أخرى.
نعم، يجب على التطبيق طلب الإذن لإرسال الإشعارات — يستخدم Live Activity قناة الإشعارات النظامية. يمكن للمستخدم تعطيل Live Activity لتطبيق معين في الإعدادات. عند التشغيل الأول، يعرض ActivityKit حواراً يطلب الإذن. بدون الإذن، يفشل طلب النشاط.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.