-
-
Save freemansion/b5b32178bdfef57c873fdce7a1bb1fdc to your computer and use it in GitHub Desktop.
UserNotifications iOS 10 Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UserNotifications | |
// 1. Request Permission | |
func requestAuthorization() { | |
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { (granted, error) in | |
if granted { | |
// Success | |
} else { | |
// Error | |
print(error?.localizedDescription) | |
} | |
} | |
} | |
// 2. Create Notification | |
func createNotification() { | |
let content = UNMutableNotificationContent() | |
content.title = "New cuddlePix!" | |
content.subtitle = "What a treat" | |
content.body = "Cheer yourself up with a hug 🤗" | |
let attachment = try! UNNotificationAttachment(identifier: randomImageName, url: imageURL, options: .none) | |
content.attachments = [attachment] | |
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: seconds, repeats: false) | |
let request = UNNotificationRequest(identifier: randomImageName, content: content, trigger: trigger) | |
UNUserNotificationCenter.current().add(request) { (error) in | |
if let error = error { | |
print(error) | |
completion(false) | |
} else { | |
completion(true) | |
} | |
} | |
} | |
// 3. Foreground Notification Support | |
// Auto show the notification with alert type, dont need to create custome one | |
extension AppDelegate: UNUserNotificationCenterDelegate { | |
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { | |
completionHandler(.alert) | |
} | |
} | |
// 4. Querying Notification | |
func queryNotification(callback: (() -> ())? = .none) { | |
// 4.0 Process in the background | |
let group = DispatchGroup() | |
let notificationCenter = UNUserNotificationCenter.current() | |
let dataSaveQueue = DispatchQueue(label: "com.xxx.yyy") | |
// 4.1 Get notification settings | |
group.enter() | |
notificationCenter.getNotificationSettings { (settings) in | |
dataSaveQueue.async(execute: { | |
// Do what you want | |
group.leave() | |
}) | |
} | |
// 4.2 Get pending notification request | |
group.enter() | |
notificationCenter.getPendingNotificationRequests { (request) in | |
dataSaveQueue.async(execute: { | |
// Do what you want | |
group.leave() | |
}) | |
} | |
// 4.4 Get Delivered Notification | |
group.enter() | |
notificationCenter.getDeliveredNotifications { (notifications) in | |
dataSaveQueue.async(execute: { | |
// Do what you want | |
group.leave() | |
}) | |
} | |
// 4.5 Notification for process | |
group.notify(queue: DispatchQueue.main) { | |
if let callback = callback { | |
callback() | |
} else { | |
// Do what you want | |
} | |
} | |
} | |
// 5. Remove pending notification request | |
func removePendingRequest(request: UNNotificationRequest) { | |
UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [request.identifier]) | |
} | |
// 6. Custom Notification view (NotificationExtension) | |
// 6.1 Create Notification Extension by File > New > Target > Notification Content Extension | |
// 6.2 Custom interface in .storyboard and .swift file | |
// 6.3 Input data to custom interface | |
func didReceive(_ notification: UNNotification) { | |
guard let attachment = notification.request.content.attachments.first else { | |
return | |
} | |
if attachment.url.startAccessingSecurityScopedResource() { | |
let imageData = try? Data.init(contentsOf: attachment.url) | |
// Do what you want with the image data | |
attachment.url.stopAccessingSecurityScopedResource() | |
} | |
} | |
// 6.4 Add NSExtension > NSExtensionAttributes > UNNotificationExtensionCategory = "<Unique string>" in Extension > Info.plist | |
// Update code in 2. function | |
content.categoryIdentifier = newCuddlePixCategoryName | |
// 7. Handle Action | |
// 7.1 AppDelegate > | |
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool { | |
configureUserNotification() | |
} | |
func configureUserNotification() { | |
let starAction = UNNotificationAction(identifier: "star", title: "🌟 star my cuddle 🌟", options: []) | |
let category = UNNotificationCategory(identifier: "<Unique string>", actions: [starAction], intentIdentifiers: [], options: []) | |
UNUserNotificationCenter.current().setNotificationCategories([category]) | |
} | |
// 7.2 Notification Extension > NotificationViewController | |
func didReceive(_ response: UNNotificationResponse, completionHandler completion: @escaping (UNNotificationContentExtensionResponseOption) -> Void) { | |
if response.actionIdentifier == "xxx" { | |
// Do what you do | |
let time = DispatchTime.now() + | |
DispatchTimeInterval.milliseconds(2000) | |
DispatchQueue.main.asyncAfter(deadline: time) { | |
completion(.dismissAndForwardAction) | |
} | |
} | |
} | |
// 7.3 Process in AppDelegate | |
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, | |
withCompletionHandler completionHandler: @escaping () -> Void) { | |
print("Response received for \(response.actionIdentifier)") | |
completionHandler() | |
} | |
// --- DOCUMENT --- | |
// 1. userNotificationCenter(_:willPresent:withCompletionHandler:) is called in the UNUserNotificationCenterDelegate (only in the foreground), and determines if the notification should present itself. | |
// 2. didReceive(_:) is called in the UNNotificationContentExtension and provides an opportunity to configure the custom notification's interface. | |
// 3. didReceive(_:completionHandler:) is called in the UNNotificationContentExtension after the user selects a response action. | |
// 4. userNotificationCenter(_:didReceive:withCompletionHandler:) is called in the UNUserNotificationCenterDelegate if the UNNotificationContentExtension passes it along via the dismissAndForwardAction response option. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment