2020 System Services
WWDC20 · 12 min · System Services
The Push Notifications primer
Help people get the most out of your app with push notifications for important events and updates — and by delivering up-to-date data in the background, so that it is ready when they open your app. Discover how you can use notifications and alert people to timely and relevant information. Learn the differences between alert and background notifications, how to adopt them in your apps, and avoid mistakes by using the right APIs for the job.
Watch at developer.apple.com ↗Code shown on screen · 9 snippets
Registering for notifications
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
UIApplication.shared.registerForRemoteNotifications()
UNUserNotificationCenter.current().delegate = self
return true
} UIApplicationDelegate callbacks
func application(_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error) {
// The token is not currently available.
print("Remote notification is unavailable: \(error.localizedDescription)")
}
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
// Forward the token to your provider, using a custom method.
self.forwardTokenToServer(token: deviceToken)
} Forward token to server
func forwardTokenToServer(token: Data) {
let tokenComponents = token.map { data in String(format: "%02.2hhx", data) }
let deviceTokenString = tokenComponents.joined()
let queryItems = [URLQueryItem(name: "deviceToken", value: deviceTokenString)]
var urlComps = URLComponents(string: "www.example.com/register")!
urlComps.queryItems = queryItems
guard let url = urlComps.url else {
return
}
let task = URLSession.shared.dataTask(with: url) { data, response, error in
// Handle data
}
task.resume()
} Request authorization
@IBAction func subscribeToNotifications(_ sender: Any) {
let userNotificationCenter = UNUserNotificationCenter.current()
userNotificationCenter.requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
print("Permission granted: \(granted)")
}
} Payload JSON
{
"aps" : {
"alert" : {
"title" : "Check out our new special!",
"body" : "Avocado Bacon Burger on sale"
},
"sound" : "default",
"badge" : 1,
},
"special" : "avocado_bacon_burger",
"price" : "9.99"
} didReceive response
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
guard let specialName = userInfo["special"] as? String,
let specialPriceString = userInfo["price"] as? String,
let specialPrice = Float(specialPriceString) else {
// Always call the completion handler when done.
completionHandler()
return
}
let item = Item(name: specialName, price: specialPrice)
addItemToCart(item)
showCartViewController()
completionHandler()
} Register for remote notifications (Background)
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
UIApplication.shared.registerForRemoteNotifications()
return true
} Background Notification Payload
{
"aps" : {
"content-available" : 1
},
"myCustomKey" : "myCustomData"
} didReceiveRemoteNotification
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler:
@escaping (UIBackgroundFetchResult) -> Void) {
guard let url = URL(string: "www.example.com/todays-menu") else {
completionHandler(.failed)
return
}
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data else {
completionHandler(.noData)
return
}
updateMenu(withData: data)
completionHandler(.newData)
}
} Resources
Related sessions
-
12 min -
39 min