دسترسی تقویم یک مکانیسم سیستمعامل موبایل است که از دادههای تقویم کاربر در برابر خواندن و تغییر غیرمجاز محافظت میکند. در iOS دسترسی به تقویم از طریق چارچوب EventKit با کلاسهای EKEventStore و EKCalendar و در Android از طریق دسترسیهای READ_CALENDAR و WRITE_CALENDAR همراه با CalendarContract API پیادهسازی میشود. بر اساس Apple Developer Documentation, 2025، برای دسترسی به تقویم در iOS 18+ یک درخواست صریح از طریق کاربر سیستم مورد نیاز است. EventKit یک رابط واحد برای خواندن و ایجاد رویدادها در تمامی تقویمهای متصل فراهم میکند.
نکات کلیدی
دسترسی به تقویم یک مکانیسم حفاظت از دادههای شخصی است که خواندن و نوشتن رویدادها را در برنامههای تقویم دستگاه کنترل میکند. تقویم حاوی اطلاعات محرمانه است: جلسات، مواعید، یادآوریها و برنامههای شخصی کاربر، بنابراین سیستمعاملهای موبایل دسترسی به آن را به عنوان حیاتی طبقهبندی میکنند.
در iOS، دسترسی به تقویم توسط چارچوب EventKit تنظیم میشود. برنامه میتواند دسترسی خواندن و نوشتن رویدادها را درخواست کند و کاربر میتواند از طریق کاربر سیستم درخواست را بپذیرد یا رد کند. در Android، حفاظت بر دو دسترسی رنتایم استوار دارد: READ_CALENDAR و WRITE_CALENDAR.
بر اساس تحقیقات Pew Research Center (2024)، حدود 45% از کاربران دستگاههای موبایل به طور منظم از تقویم استفاده میکنند و 62% آنها دسترسی را به برنامههایی که دلیل درخواست دادههای تقویم را توضیح نمیدهند، رد میکنند.
اصل کلیدی — برنامه باید تنها برای کارکردهایی درخواست دسترسی کند که مستقیماً با تقویم مرتبط هستند: ایجاد یادآوری، همگامسازی رویدادها، واردات برنامه.
در iOS، دسترسی به تقویم و یادآوریها توسط یک چارچوب واحد به نام EventKit ارائه میشود. کلاس مرکزی EKEventStore همه عملیات را مدیریت میکند: درخواست دسترسی، خواندن رویدادها، ایجاد و ویرایش نوشتههای تقویم. در اولین بار فراخوانی requestAccess(to:entityType:)، سیستم یک کاربر سیستم را با توضیح نمایش میدهد.
کلاس EKEventStore نقطه ورود به زیرسیستم تقویم iOS است. برای درخواست دسترسی، باید روش requestAccess(to: .event) را با ارسال نوع وجود (رویداد یا یادآوری) فراخوان کنید. پس از دریافت جواز، EKEventStore به همه تقویمهای متصل به حسابهای iCloud، Google، Exchange و سایر ارائهدهندگان دسترسی فراهم میکند.
ویژگی مهم: EKEventStore یک شئ سنگین است، ایجاد آن زمان میبرد و منابع مصرف میکند. توصیه میشود آن را یک بار مقداردهی کرده و در طول چرخه عمر برنامه مجدداً استفاده کنید. بر اساس WWDC Session 10117 (2024)، Apple برای بهینهسازی عملکرد، ذخیرهسازی نمونه EventStore را توصیه میکند.
iOS دسترسیهای خواندن و نوشتن تقویم را از هم جدا نمیکند — کاربر یا دسترسی کامل میدهد یا رد میکند. البته، برنامه میتواند عملیات را در سطح کد کنترل کند: خواندن رویدادها از طریق EKEventStore.event، ایجاد از طریق EKEventStore.save و حذف از طریق EKEventStore.remove. از iOS 18، امکان درخواست دسترسی فقط به یک نوع وجود مشخص — .event یا .reminder — فراهم شده است.
در iOS 17+ Apple یک مکانیسم دسترسی موقت را معرفی کرد: بعضی از برنامهها میتوانند پس از تأیید یکبار کاربر، به مدت 24 ساعت دسترسی داشته باشند. این ویژگی به ویژه برای برنامههایی که به تقویم فقط یکبار نیاز دارند — مانند واردات برنامه کنفرانس — مفید است.
در Android، دسترسی به تقویم توسط دو دسترسی جداگانه محافظت میشود: READ_CALENDAR و WRITE_CALENDAR. هر دو در طبقه خطرناک قرار دارند و نیازمند درخواست رنتایم هستند. جدایی خواندن از نوشتن به کاربر امکان میدهد سطح دسترسی برنامه را به طور ظریف تنظیم کند.
دسترسی READ_CALENDAR به برنامه امکان خواندن رویدادها از تمام تقویمهای کاربر را میدهد، از جمله نامها، زمان، شرکتکنندگان و توضیحات. دسترسی WRITE_CALENDAR امکان ایجاد، تغییر و حذف رویدادها را فراهم میکند. هر دو در مانیفست از طریق برچسب uses-permission مشخص میشوند و در زمان اجرا از طریق ActivityResultLauncher درخواست میشوند.
از Android 14 (API 34) به بعد، اگر برنامه هر دو دسترسی را به طور همزمان درخواست کند، سیستم به کاربر هشدار میدهد. توصیه میشود آنها را جداگانه درخواست کنید: ابتدا READ_CALENDAR برای خواندن، سپس WRITE_CALENDAR در اولین تلاش برای ایجاد رویداد. بر اساس Google I/O 2024، این رویکرد نرخ رد را 23% کاهش میدهد.
CalendarContract یک ContentProvider Android است که دادههای تقویم را در جداول رابطهای ساختاردهی میکند. جداول اصلی: Calendars (لیست تقویمها)، Events (رویدادها)، Attendees (شرکتکنندگان)، Reminders (یادآوریها). دسترسی به دادهها از طریق ContentResolver.query() با مشخص کردن URI و پروژکشن انجام میشود.
برای درج یک رویداد جدید، باید از ContentValues با مشخص کردن تقویم، زمان شروع و پایان، عنوان و توضیحات استفاده کنید. CalendarContract از مناطق زمانی، رویدادهای تکراری و یادآوریها با فاصله هشدار قابل تنظیم پشتیبانی میکند.
پیادهسازی درخواست دسترسی تقویم نیازمند در نظر گرفتن ویژگیهای سطح پلتفرم است. در زیر نمونههایی به Swift و Kotlin آورده شده است که کار صحیح با EventKit و CalendarContract را نشان میدهند.
درخواست دسترسی به تقویم iOS از طریق روش requestAccess کلاس EKEventStore انجام میشود. در نمونه زیر، ایجاد رویداد پس از دریافت جواز نشان داده شده است.
import EventKit
let eventStore = EKEventStore()
eventStore.requestAccess(to: .event) { granted, error in
guard granted else {
print("دسترسی تقویم رد شد")
return
}
let event = EKEvent(eventStore: eventStore)
event.title = "جلسه گروهی"
event.startDate = Date()
event.endDate = Date(timeIntervalSinceNow: 3600)
event.calendar = eventStore.defaultCalendarForNewEvents
do {
try eventStore.save(event, span: .thisEvent)
print("رویداد ایجاد شد: \(event.eventIdentifier)")
} catch {
print("خطای ذخیره: \(error.localizedDescription)")
}
}
در Android، درخواست دسترسیهای READ_CALENDAR و WRITE_CALENDAR از طریق ActivityResultLauncher انجام میشود. نمونه خواندن رویدادها از تقویم کاربر پس از دریافت دسترسی را نشان میدهد.
val calendarPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
if (permissions[Manifest.permission.READ_CALENDAR] == true) {
val uri = CalendarContract.Events.CONTENT_URI
val projection = arrayOf(
CalendarContract.Events.TITLE,
CalendarContract.Events.DTSTART,
CalendarContract.Events.DTEND
)
val cursor = contentResolver.query(uri, projection, null, null, null)
cursor?.use {
val titleIndex = it.getColumnIndex(CalendarContract.Events.TITLE)
while (it.moveToNext()) {
Log.d("Calendar", "رویداد: ${it.getString(titleIndex)}")
}
}
} else {
// توضیح را نشان بده و به تنظیمات برو
requestPermissionSettingsRedirect()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
calendarPermissionLauncher.launch(
arrayOf(Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR)
)
}
کار با دسترسیهای تقویم نیازمند یک راهبرد دقیق است که نیازهای هر دو پلتفرم و انتظارات کاربران را در نظر بگیرد. پیروی از توصیههای زیر به گذشتن از مدیریت و افزایش نرخ دادن دسترسی کمک میکند.
دسترسی به تقویم را تنها در زمانی درخواست کنید که کاربر اقدامی انجام میدهد که نیازمند دادههای تقویم است: «افزودن به تقویم»، «همگامسازی برنامه»، «واردات رویدادها». توضیح قبلی با استفاده از کاربر قبل از دسترسی (کاربر خود قبل از کاربر سیستم) نرخ موافقت را بر اساس Localytics (2024) تا 35% افزایش میدهد.
در iOS از کلید NSCalendarsUsageDescription در privacy manifest با متن مشخص استفاده کنید. به جای «برای ایجاد رویدادها»، بنویسید «برای افزودن ورزشهای شما به تقویمتان». عبارت مشخص نرخ تبدیل درخواست را 20–30% افزایش میدهد.
اگر کاربر درخواست را رد کرد، کاربر سیستم را مجدداً نشان ندهید — این منجر به فعال شدن neverAskAgain در Android یا غیرقابل دسترس شدن کاربر در iOS میشود. به جای آن، از طریق Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) در Android یا UIApplication.openSettingsURLString در iOS به تنظیمات بروید.
پس از ورود مجدد به صفحه، وضعیت دسترسی را بررسی کنید. در iOS، EKEventStore.authorizationStatus(for: .event) را فراخوانی کرده و UI را مطابق وضعیت فعلی بهروز کنید. در Android از ContextCompat.checkSelfPermission() برای بررسی وضعیت فعلی و تصمیمگیری درباره نشان دادن دکمه اعدام به تنظیمات استفاده کنید.
سوالات متداول
برنامهها برای ایجاد رویدادها، همگامسازی برنامه، واردات مواعید و یکپارچگی با یادآوریها به تقویم نیاز دارند. مثال: ریگهای تناسبانداز ورزش را اضافه میکنند، برنامهریزها وظایف ایجاد میکنند، و برنامههای مسافرتی پروازها را به تقویم کاربر وارد میکنند.
READ_CALENDAR دسترسی خواندن همه رویدادها و تقویمهای کاربر را فراهم میکند. WRITE_CALENDAR امکان ایجاد، تغییر و حذف رویدادها را فراهم میکند. کاربر میتواند یک دسترسی را بدون دیگری اعطا کند که کنترل انعطافپذیری بر سطح دسترسی برنامه به دادههای تقویم فراهم میکند.
تنظیمات — حریم خصوصی و امنیت — تقویمها را باز کنید. برنامه را انتخاب کرده و کلید دسترسی را خاموش کنید. برنامه تا درخواست صریح بعدی و تأیید کاربر، قادریت خواندن و ایجاد رویدادها را از دست خواهد داد.
برنامه نمیتواند رویدادها را بخواند یا بنویسد. روش requestAccess در iOS مقدار granted = false و یا checkSelfPermission در Android مقدار PERMISSION_DENIED را برمیگرداند. توسعهدهنده باید تنزل عزی مناسب را پیشبینی کند — برنامه بدون کارکردهای تقویم به کار خود ادامه میدهد، بدون کشتن یا نمایش خطا.
در iOS چنین امکانی وجود ندارد — EventKit برای هر گونه عملیات بر رویدادها به دسترسی کامل نیاز دارد. در Android میتوانید از Intent.ACTION_INSERT برای ایجاد رویداد از طریق برنامه تقویم سیستم استفاده کنید که نیازی به دسترسیهای رنتایم ندارد، اما امکان خواندن رویدادهای موجود را نیز ندارد.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید