پوش نوتیفیکیشن (Push Notification) در iOS با استفاده از Swift – به زبان ساده


در این مقاله به پیادهسازی پوش نوتیفیکیشن در iOS به کمک Swift میپردازیم. در واقع این فرایند اینک نسبت به گذشته بسیار سادهتر شده و شامل تنها چند گام زیر است:
- فعالسازی پوش نوتیفیکیشن در پروژه iOS
- درخواست مجوز برای نوتیفیکیشنهای کاربر
- ثبت نام در سرویس Apple Push Notifications
- ارسال نوتیفیکیشن تست
- مدیریت نوتیفیکیشنها در اپلیکیشن
باز کردن اشتراک دولوپر اپل
قبل از هر چیز باید یک حساب یا اشتراک دولوپر اپل داشته باشید تا بتوانید به سرویس Apple Push Notifications دسترسی پیدا کنید.
فعالسازی پوش نوتیفیکیشنها در پروژه iOS
به این منظور باید مراحل زیر را طی کنید:
- بخش project properties پروژه خود را که در آیکون ریشه پروژه قرار دارد باز کنید.
- در بخش General یک نام یکتا برای «Application Bundle» تعریف کنید. برای نمونه میتوانید از نام me.developer.ios.notifications استفاده کنید.
- در بخش Capabilities، به فعالسازی Push Notifications اقدام کنید. در نتیجه App ID شما به طور خودکار در اپاستور ثبت میشود.
ثبت شدن اپلیکیشن خود را میتوانید در وبسایت دولوپر اپل (+) در بخش Identifiers -> App Ids مشاهده کنید:
درخواست مجوز برای نوتیفیکیشنهای کاربر
جهت درخواست مجوز برای نوتیفیکیشنهای کاربر در اپلیکیشن باید برخی متدهای دیگر را به ViewController خود اضافه کنید.
شما میتوانید آن را به صورت یک افزونه مجزا به پروژه خود اضافه کنید تا در پروژههای دیگر نیز قابل استفاده باشد:
import UIKit import UserNotifications extension UIViewController { func getNotificationSettings() { UNUserNotificationCenter.current().getNotificationSettings { settings in //print("User Notification settings: \(settings)") guard settings.authorizationStatus == .authorized else { return } DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() } } } func requestNotificationAuthorization(){ // Request for permissions UNUserNotificationCenter.current() .requestAuthorization( options: [.alert, .sound, .badge]) { [weak self] granted, error in //print("Notification granted: \(granted)") guard granted else { return } self?.getNotificationSettings() } } }
متد اول ()getNotificationSettings جهت اطمینان یافتن از این است که تنظیمات نوتیفیکیشن کاربر در صورتی که کاربر اطلاعات احراز هویت را ابطال کند قابل بازیابی است و این که کاربر میتواند مجدداً مجوز را فعال کند. ضمناً پس از بررسی مجوز به فراخوانی ()registerForRemoteNotifications میپردازد تا نوتیفیکیشنهای ریموت را نیز فعال کند.
متد دوم requestNotificationAuthorization جهت درخواست مجوز از کاربر برای ارسال نوتیفیکیشن است. بخش Options یا UNAuthorizationOptions برای انتخاب نمایش نوع نوتیفیکیشنها است. یک کادر تأیید ظاهر میشود که به کاربر اجازه میدهد، نوتیفیکیشنهای کاربر را در اپلیکیشن شما فعال یا غیر فعال کند.
احراز هویت درخواست در اپلیکیشن
سپس در مقداردهی اولیه ویوی اپلیکیشن، برای نمونه در ()viewDidLoad میتوانید درخواستی برای احراز هویت ارائه دهید. اینک این متد بخشی از کنترلر ویو خواهد بود.
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() requestNotificationAuthorization() } }
دریافت توکن دسترسی برای تست کردن
شما میتوانید کدهای اضافی در AppDelegate اضافه کنید تا یک «توکن دستگاه» (Device Token) خاص جهت تست دستی پوش نوتیفیکیشن در گوشی خود داشته باشید. در این مورد نیز این کار از طریق افزودن افزونه به AppDelegate ممکن است:
import UIKit extension AppDelegate { func application( _ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data ) { let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) } let token = tokenParts.joined() print("My Device Token: \(token)") } func application( _ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { print("Error registering notifications: \(error)") } }
این کد در کنسول یک «توکن دستگاه» به شما نشان میدهد که برای تست پوش نوتیفیکیشن استفاده میشود. نخستین باری که اپلیکیشن را اجرا میکنید به این کد دقت کنید. ضمناً متد دوم هر خطایی که هنگام ثبت پوش نوتیفیکیشن دریافت کنید را نمایش خواهد داد. این حالت در مواردی که با برخی مشکلات یا خطاها مانند زیر مواجه میشوید و نوتیفیکیشن کار نمیکند، مفید خواهد بود:
Error registering notifications: Error Domain=NSCocoaErrorDomain Code=3010 "remote notifications are not supported in the simulator" UserInfo={NSLocalizedDescription=remote notifications are not supported in the simulator}
در این حالت، شما نمیتوانید نوتیفیکیشنهای پوش را در یک شبیهساز تست کنید و باید اپلیکیشن خود را روی یک دستگاه گوشی تلفن همراه واقعی اجرا کنید. زمانی که این اپلیکیشن را برای نخستین بار اجرا میکنید؛ درخواست مجوز نوتیفیکیشن کاربر را در آغاز اجرا مشاهده میکنید:
پس از آن یک خروجی در کنسول نیز در مورد این فرایند خواهید داشت:
Notification granted: true User Notification settings: <UNNotificationSettings: 0x282834380; authorizationStatus: Authorized, notificationCenterSetting: Enabled, soundSetting: Enabled, badgeSetting: Enabled, lockScreenSetting: Enabled, carPlaySetting: NotSupported, criticalAlertSetting: NotSupported, alertSetting: Enabled, alertStyle: Banner, providesAppNotificationSettings: No> My Device Token: 930976dfb191c5085b72aa347ad91c561a6fcdaab639c173a015f0745ee11401
ثبت سرویس پوش نوتیفیکیشن Apple
به این منظور باید یک «کلید احراز هویت» (Authentication Key) ایجاد کنید.
قبل از هر چیز باید به پورتال حساب دولوپر اپل (+) بروید و یک کلید احراز هویت برای اپلیکیشن خود بسازید. مراحل آن به صورت زیر است:
- در بخش Keys -> All میتوانید یک کلید جدید را با کلیک روی دکمه (+) ایجاد کنید.
- نام کلید اپلیکیشن خود را وارد کنید. برای نمونه PushNotificationsKey.
- کلید خود را ذخیره و تأیید کنید.
- فایل پشتیبان را روی رایانه خود دانلود کنید.
تست پوش نوتیفیکیشن
شما میتوانید پوش نوتیفیکیشن ریموت خود را با ابزار بسیار مفیدی به نام «Push Notifications» تست کنید. این ابزار را برای MacOS (+) دانلود کنید و آن را روی تست پوش نوتیفیکیشن روی دستگاه خود اجرا کنید. مراحل کار به صورت زیر است:
- PushNotifications را دانلود کنید.
- اپلیکیشن را از حالت فشرده خارج کرده و اجرا کنید.
- اطمینان حاصل کنید که در اولین اجرای اپلیکیشن این کار را با راست کلیک روی آیکون برنامه و انتخاب Open از منو انجام میدهید.
- اگر اپلیکیشن را به طور معمول اجرا کنید، احتمالاً یک هشدار دریافت میکنید که اپلیکیشن امضا نشده است و نمیتواند باز شود.
- در بخش Authentication گزینه Token را انتخاب کنید.
- روی دکمه Select P8 کلیک کرده و فایل p8. را که قبلاً دانلود کردهایم انتخاب کنید.
- «شناسه کلید» (Key ID) و «شناسه تیم» (Team ID) را در فیلدهای مربوطه وارد کنید.
- شناسه کلید همان ID کلید احراز هویت است که در گام قبلی ایجاد کرده بودیم و میتوانید کد را از این آدرس (+) دریافت کنید.
- شناسه تیم همان ID حساب دولوپر اپل شما است که میتوانید کدش را از این آدرس (+) دریافت کنید.
- شناسه App Bundle و توکن دستگاه خود را وارد کنید.
- شناسه App Bundle همان ID اپلیکیشن است که در بخش نخست وارد کردید.
- توکن دستگاه زمانی که اپلیکیشن را در گوشی خود از پروژه Xcode اجرا کردید در کنسول نمایش یافته است.
- متن درخواست را به صورت مثال زیر تنظیم کنید:
{ “aps”: { “alert”: “New Notification”, “sound”: “default”, “link_url”: “https://developerhowto.com" } } - دکمه صورتی را برای ارسال بزنید تا نوتیفیکیشن را در گوشی خود به همراه اطلاعاتی که در متن درخواست ایجاد کردید مشاهده کنید.
قالببندی پوش نوتیفیکیشن
یک پوش نوتیفیکیشن میتواند شامل هفت خصوصیت متفاوت باشد:
- Alert – پیام اصلی را شامل میشود. این پیام میتواند یک رشته داده یا یک پیام بومیسازی شده (یعنی به چند زبان) باشد که از فهرستی از کلید/مقدار (دیکشنری) استفاده میکند.
- Badge – عددی است که در گوشه آیکون اپلیکیشن نمایش مییابد. عدد 0 به معنی غیر فعال شدن است.
- Sound – نام فایل هشدار صورتی کوتاهی است که در اپلیکیشن قرار دارد.
- thread-id – در نوتیفیکیشنهای گروهی استفاده میشود.
- Category – این مقداری دستهبندی برای نوتیفیکیشن تعریف میکند. از آن میتوان برای شخصیسازی اقدامهای مختلف هنگام دریافت نوتیفیکیشن استفاده کرد.
- content-available – باعث میشود پوش نوتیفیکیشن بیصدا شود (1 = بیصدا).
- mutable-content – امکان اصلاح نوتیفیکیشن پیش از نمایش آن را میدهد (1 = تغییرپذیر).
مدیریت پوش نوتیفیکیشن در اپلیکیشن
در این بخش به بررسی پوش نوتیفیکیشن در مراحل مختلف درون اپلیکیشن میپردازیم.
مدیریت نوتیفیکیشن در طی مقداردهی اولیه
شما میتوانید نوتیفیکیشنهای دریافتی را در طی بارگذاری اپلیکیشن مدیریت کنید. به این منظور باید کد اضافی به AppDelegate خود و درون متد ()application با کمک didFinishLaunchingWithOptions اضافه کنید.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. // Check remote notification let notificationOption = launchOptions?[.remoteNotification] if let notification = notificationOption as? [String: AnyObject], let aps = notification["aps"] as? [String: AnyObject] { // Process remote notification in the view let main = window?.rootViewController as! ViewController main.initialNotification = aps } return true }
کد فوق دادههای نوتیفیکیشن را دریافت میکند و این دادهها را در ViewController اصلی پردازش میکند. ViewController اصلی یک خصوصیت initialNotification برای دریافت نوتیفیکیشنهای ابتدایی دارد. در این حالت، درون ViewController میتوانیم یک نوتیفیکیشن ریموت را با کد بهروزرسانی شده زیر پردازش کنیم:
import UIKit class ViewController: UIViewController { var initialNotification : [String : AnyObject]? override func viewDidLoad() { super.viewDidLoad() requestNotificationAuthorization() } override func viewDidAppear(_ animated: Bool) { if let app = initialNotification { let alert = UIAlertController(title: app["category"] as? String, message: app["alert"] as? String, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil)) self.present(alert, animated: true, completion: nil) } } }
زمانی که اپلیکیشن روی صفحه ظاهر شود، این کد یک هشدار به همراه دستهبندی و پیام آخرین نوتیفیکیشن دریافت شده، نمایش میدهد.
برای تست کردن این کد شما باید اپلیکیشن خود را با طرحبندی (Scheme) متفاوت آغاز کنید. به عبارت دیگر این کد تنها زمانی اجرا میشود که اپلیکیشن راهاندازی میشود. از این رو باید شِمای اجرایی را به صورت «Wait» تنظیم کنید. مراحل کار به صورت زیر است:
- در Xcode به مسیر Product -> Scheme -> Edit Scheme… بروید.
- مقدار Run Scheme را به صورت «Wait for executable to be launched» تنظیم کنید.
- ترجیحات را ذخیره کرده و دوباره روی Run کلیک کنید.
- این بار اپلیکیشن تنها کامپایل میشود و منتظر فعالسازی میماند.
- در این مرحله یک نوتیفیکیشن جدید را با استفاده از اپلیکیشن PushNotifications و با کد زیر ارسال کنید:
{{ “aps”: { “alert”: “4 New Notifications!”, “sound”: “default”, “link_url”: “https://developerhowto.com/", “category”: “Notify”, “badge”: 4 } - روی نوتیفیکیشن در گوشی خود بزنید تا اپلیکیشن پیام مربوطه را نمایش دهد.
مدیریت نوتیفیکیشن در طی اجرای اپلیکیشن
بخش قبلی توضیحات ما صرفاً زمانی اجرا میشود که اپلیکیشن قبلاً متوقف شده باشد. با این وجود اگر اپلیکیشن در حال اجرا باشد، باید از کد دیگری استفاده کنیم تا بتواند نوتیفیکیشنهای که ارسال میشوند را دریافت کند. کد ViewController را به صورت زیر تغییر دهید تا هر دو حالت فوق را شامل شود:
override func viewDidAppear(_ animated: Bool) { if let aps = initialNotification { processNotification(aps: aps) } } func processNotification(aps: [String : AnyObject]){ let alert = UIAlertController(title: aps["category"] as? String, message: aps["alert"] as? String, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil)) self.present(alert, animated: true, completion: nil) }
یک متد جدید به افزونه AppDelegate برای didReceiveRemoteNotification اضافه میکنیم تا نوتیفیکیشنها را در حال اجرای اپلیکیشن نیز دریافت کنیم:
func application( _ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void ) { guard let aps = userInfo["aps"] as? [String: AnyObject] else { completionHandler(.failed) return } let main = window?.rootViewController as! ViewController main.processNotification(aps: aps) }
ایجاد نوتیفیکیشنهای محلی
شما میتوانید نوتیفیکیشنهای محلی را نیز با استفاده از فریمورک UserNotification ارسال کنید. ابتدا باید متدهای اضافی برای ایجاد و مدیریت آسان نوتیفیکیشنهای محلی بنویسیم:
extension UIViewController { func userNotification(message: String, title: String, count: Int){ //creating the notification content let content = UNMutableNotificationContent() content.title = title content.subtitle = "" content.body = message content.badge = count as NSNumber //getting the notification trigger let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false) //getting the notification request let request = UNNotificationRequest(identifier: "SimplifiedIOSNotification", content: content, trigger: trigger) //adding the notification to notification center UNUserNotificationCenter.current().add(request, withCompletionHandler: nil) } func clearNotification(){ UIApplication.shared.applicationIconBadgeNumber = 0 let notifications = UNUserNotificationCenter.current() notifications.removeAllPendingNotificationRequests() notitications.removeAllDeliveredNotifications() } }
متد اول برای ایجاد یک نوتیفیکیشن جدید محلی با یک فراخوانی ساده به صورت زیر در ویو است:
userNotification(message: "You have 2 new messages", title: "Messages", count: 2)
متد دوم به نام ()clearNotification عدد نوتیفیکیشن را از کنار آیکون اپلیکیشن پاک کرده و نوتیفیکیشنهای قبلی را نیز وقتی کاربر اپلیکیشن را باز کند حذف میکند.
سخن پایانی
بدین ترتیب به پایان این راهنمای ارسال پوش نوتیفیکیشن در iOS میرسیم. شما میتوانید کد کامل اپلیکیشنی را که در این راهنما معرفی کردیم، از این ریپوی گیتهاب (+) دریافت کنید.
اگر این مطلب برایتان مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزش های پروژه محور برنامه نویسی
- آموزش برنامه نویسی Swift (سوئیفت) برای برنامه نویسی iOS
- مجموعه آموزشهای برنامهنویسی
- آموزش آرایه در برنامه نویسی Swift (سوئیفت)
- آموزش مقدماتی فریمورک React Native برای طراحی نرم افزارهای اندروید و iOS با زبان جاوا اسکریپت
==
سلام خسته نباشید
من سرویس پوش نوتیفیکیشن فایربیس را روی اندروید(زامارین)فعال کردم وبدرستی کار کرد ولی روی آی او اس (زامارین) کار نمیکنه. در ابتدا که توکن بهم نمیداد که متوجه شدم دلیلش اینه که ایران تحریمه و از فیلترشکن استفاده کردم و توکن را بهم داد ولی نوتیفیکیشنی نتونستم ارسال کنم خواستم ببینم آیا دلیل اینکه نوتیفیکیشن ارسال نمیشه هم تحریم بودن ایرانه؟