في هذا الموضوع سوف اتطرق لافضل طريقة للحصول على التاريخ والوقت الحقيقي
في هذه الايام هناك عدة تطبيقات تعتمد على نظام الـ Credit بحيث يتم أعادة تعيينها بشكل يومي او اسبوعي
اغلب التطبيقات تعتمد على الوقت الحالي Current Date لكن هناك مشكله عند اعتماد التطبيقات عليها وهيا إمكانيه التلاعب بها بسهولة بتغيير وقت الجهاز في اعدادات النظام
وبما انه هذه التلاعب يضر المطور فهناك حل اخر وهو الاعتماد على السيرفر او خدمات World time API والتي اغلبها ليست مجانيه
لكن هناك طريقة افضل واسهل وهيا الاعتماد على بروتوكول NTP
فما هو NTP؟
NTP اختصار لـ Network Time Protocol، وهو بروتوكول ييستخدم لمزامنة الساعة (التاريخ والوقت) بين أجهزة الكمبيوتر والخوادم عبر الإنترنت
الهدف منه هو التأكد من أن كل الأجهزة في شبكة معينة تعمل بنفس الوقت الدقيق والفعلي
لماذا نحتاج إلى NTP؟
لأن الوقت الذي يظهر على الجهاز يمكن أن يكون غير دقيق، لعدة أسباب مثل:
-
تغيير المستخدم لإعدادات الوقت يدويًا
-
تعطل الساعة الداخلية للجهاز
-
الفروقات بين المناطق الزمنية
-
الحاجة لتوحيد الوقت بين عدة أنظمة أو خوادم (خاصة في التطبيقات الحساسة مثل البنوك، أو خدمات الاشتراكات)
كيف يعمل NTP؟
-
جهازك (أو تطبيقك) يرسل طلب إلى خادم وقت NTP على الإنترنت.
-
الخادم يرد بالتاريخ والوقت الدقيق
-
الجهاز يستخدم هذا الوقت لتصحيح أو مقارنة ساعته المحلية
الـ NTP يعتمد على خوادم موثوقة جدًا مثل:
-
خوادم خاصة بالشركات مثل ابل time.apple.com وجوجل time.google.com
دقة NTP
-
يمكن لـ NTP أن يصل دقته إلى ميلي ثانية واحدة عند استخدامه على شبكات جيدة
-
بالرغم من أن الإنترنت قد يسبب تأخيرًا بسيطًا إلا أن NTP يستخدم خوارزميات للتعويض عن هذا التأخير وتقديم وقت قريب جدًا من الحقيقي
متى تستخدم NTP في تطبيقك؟
-
إذا كان تطبيقك يقدم وظائف تعتمد على الوقت بدقة (مثل العد التنازلي، الاشتراكات، الأحداث اليومية)
-
إذا كنت تريد التأكد من أن المستخدم لم يغيّر التاريخ والوقت لتجاوز حدود معينة
-
إذا كنت لا تثق بالساعة المحلية وتريد التحقق من الوقت الحقيقي من مصدر خارجي
كيف أستخدمه في مشروعي ؟
هناك عدة مكتبات ومن احدثها مكتبة swift-ntp المطورة من شركة Apple
بإستخدام هذا الكود سوف يتم إرجاع الوقت الفعلي وايضا وقت النظام للمقارنة
import NTPClient
func getCurrentTime() async {
do {
let ntp = NTPClient(
config: NTPClient.Config(
version: .v4
),
server: "time.apple.com"
)
let response = try await ntp.query(timeout: .seconds(2))
let secondsComponent = Double(response.offset.components.seconds)
let attosecondsComponent = Double(response.offset.components.attoseconds) / 1_000_000_000_000_000_000
let offsetSeconds = secondsComponent + attosecondsComponent
let currentDate = Date().addingTimeInterval(offsetSeconds)
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS"
formatter.timeZone = TimeZone.current
print("System time: \(formatter.string(from: Date()))")
print("Accurate time: \(formatter.string(from: currentDate))")
} catch {
print("Failed to get NTP time: \(error)")
}
}
النتيجة
في هذه التجربة قمت بتقديم التاريخ الى يوم 20 مايو
واليوم الحقيقي هو يوم 15
كما تشاهد في المثال التاريخ تم ارجاعه بالتاريخ الحقيقي حتى رغم تغييره من اعدادات النظام
أمر اخر في حال خوفك من تعطل السيرفر تستطيع اضافة عدة سيرفرات وتكتب كود يتحقق منها جمعها بالاعتماد على الكود السابق وفقط تضيفهم في Array و تعمل Loop