There are two types of notifications in iOS: local notification and remote notification.
Local notifications
Using the step
- The import
UserNotifications
The module. - Apply for permission.
- Creating notification content
UNMutableNotificationContent
, can be set:
(1) Title: indicates the title of notification. (2) Subtitle: notification subtitle. (3) The body of the notification. A. sound B. sound C. sound D. sound (5) Badge: Horn. (6) userInfo: Additional information. (7) categoryIdentifier: Category unique identifier. (8) Attachments, which can be pictures, audio and video, displayed in the drop-down notification. 3. Specify the local notify the trigger condition, there are three kinds of trigger mode: (1) UNTimeIntervalNotificationTrigger: after a period of time. (2) UNCalendarNotificationTrigger: specify the date/time trigger. (3) UNLocationNotificationTrigger: according to the position trigger. 4. Create an UNNotificationRequest based on the notification content and triggering conditions. 5. Add UNNotificationRequest to UNUserNotificationCenter.
case
- Request authorization (asynchronous operation).
import UserNotifications
func application(_ application: UIApplication.didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Request notification permission
UNUserNotificationCenter.current()
.requestAuthorization(options: [.alert, .sound, .badge]) { // Banners, sounds, markers
(accepted, error) in
if !accepted {
print("User does not allow notifications")}}return true
}
Copy the code
- Send notifications.
import CoreLocation
import UIKit
import UserNotifications
class ViewController: UIViewController {
override func viewDidLoad(a) {
super.viewDidLoad()
}
// Trigger after a period of time
@IBAction func timeInterval(_ sender: Any) {
// Set the content to be pushed
let content = UNMutableNotificationContent()
content.title = "Hello"
content.subtitle = "Hi"
content.body = "This is an interval based test notification."
content.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: "feiji.wav"))
content.badge = 1
content.userInfo = ["username": "YungFan"."career": "Teacher"]
content.categoryIdentifier = "testUserNotifications1"
setupAttachment(content: content)
// Set the notification trigger
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
// Set the request identifier
let requestIdentifier = "com.abc.testUserNotifications2"
// Set a notification request
let request = UNNotificationRequest(identifier: requestIdentifier, content: content, trigger: trigger)
// Add the notification request to the sending center
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)}// Specify a date and time trigger
@IBAction func dateInterval(_ sender: Any) {
// Set the content to be pushed
let content = UNMutableNotificationContent()
content.title = "Hello"
content.body = "This is a date-based test notification."
/ / time
var components = DateComponents()
components.year = 2021
components.month = 5
components.day = 20
// Every Monday at 8 a.m
// var components = DateComponents()
// Weekday = 2 // Monday
Hour = 8 // 8 a.m
// components. Minute = 30 // 30 minutes
// Set the notification trigger
let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: false)
// Set the request identifier
let requestIdentifier = "com.abc.testUserNotifications3"
// Set a notification request
let request = UNNotificationRequest(identifier: requestIdentifier, content: content, trigger: trigger)
// Add the notification request to the sending center
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)}// Triggers by location
@IBAction func locationInterval(_ sender: Any) {
// Set the content to be pushed
let content = UNMutableNotificationContent()
content.title = "Hello"
content.body = "This is a location-based test notification."
/ / position
let coordinate = CLLocationCoordinate2D(latitude: 31.29065118, longitude: 118.3623587)
let region = CLCircularRegion(center: coordinate, radius: 500, identifier: "center")
region.notifyOnEntry = true // Triggers when entering this range
region.notifyOnExit = false // Leaving the range does not trigger
// Set the trigger
let trigger = UNLocationNotificationTrigger(region: region, repeats: true)
// Set the request identifier
let requestIdentifier = "com.abc.testUserNotifications"
// Set a notification request
let request = UNNotificationRequest(identifier: requestIdentifier, content: content, trigger: trigger)
// Add the notification request to the sending center
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)}}extension ViewController {
func setupAttachment(content: UNMutableNotificationContent) {
let imageURL = Bundle.main.url(forResource: "img", withExtension: ".png")!
do {
let imageAttachment = try UNNotificationAttachment(identifier: "iamgeAttachment", url: imageURL, options: nil)
content.attachments = [imageAttachment]
} catch {
print(error.localizedDescription)
}
}
}
Copy the code
Remote Notification (Notification Push)
Remote Notification, also known as Apple Push Notification Services (APNs), refers to the Notification that is pushed by the remote server to the client when the network is connected. When connected to the Internet, all devices have a persistent connection to An Apple server, so they can receive remote notifications pushed by the server regardless of whether the app is open or closed.
Realize the principle of
- When the App is opened, it first sends the UDID and BundleID to APNs for registration and returns deviceToken (steps 1,2,3 in the figure).
- After an App obtains the deviceToken, the App sends the relevant information and deviceToken to the application server through API, and the server records the information. (Step 4 in the figure)
- When a notification is to be pushed, the application server finds the stored deviceToken based on App information and sends the notification and deviceToken to APNs. (Step 5 in the figure)
- APNs uses deviceToken to find the specified App of the specified device and push the notification out. (Step 6 in the figure)
Implementation steps
Certificate of way
- Add App IDs to the Identifiers on your developer site and open Push Notifications in Capabilities.
- Create an APNs certificate for Apple Push Notification Service SSL (Sandbox & Production) in Certificates and associate it with the App IDs in step 1. Then download the certificate to a local PC and install it. After the installation, you can export the P12 certificate.
- Select Capability in the project, then enable Push Notifications, and then select Remote Notifications in Background Modes.
- Apply for permission.
- through
UIApplication.shared.registerForRemoteNotifications()
Request deviceToken from APNs. - through
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
Obtain deviceToken. If the deviceToken is obtained normally, the registration is successful and the remote notification can be pushed. Finally, the remote notification needs to be sent to the application server. Note:- DeviceToken does not change after App restarts.
- After the App is uninstalled and reinstalled, deviceToken changes.
- Notify tests.
Token way
- Find the Team ID in the Membership of the developer’s website and record it.
- Register a Key in Keys of Certificates, Identifiers & Profiles and check Apple Push Notifications Service (APNs), Finally, the generated Key ID is recorded and the AuthKey of P8 is downloaded locally (only once).
- Select Capability in the project, then enable Push Notifications, and then select Remote Notifications in Background Modes.
- Apply for permission.
- through
UIApplication.shared.registerForRemoteNotifications()
Request deviceToken from APNs. - through
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
Obtain deviceToken. If the deviceToken is obtained normally, the registration is successful and the remote notification can be pushed. Finally, the remote notification needs to be sent to the application server. - Notify tests.
Token Authentication is a new push Authentication mode launched by APNs. It has the following advantages:
(1) All apps under the same developer account, whether the test version or the official version, can be sent using the same Key instead of generating certificates for each App. (2) The generation of Key process is relatively simple, do not need the cumbersome certificate operation process, and it no longer has an expiration time, do not need to be like a certificate to periodically regenerate.
AppDelegate
import UserNotifications
class AppDelegate: UIResponder.UIApplicationDelegate {
func application(_ application: UIApplication.didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Request notification permission
UNUserNotificationCenter.current()
.requestAuthorization(options: [.alert, .sound, .badge]) {
accepted, _ in
if !accepted {
print("Users do not allow notifications.")}}// Request deviceToken from APNs
UIApplication.shared.registerForRemoteNotifications()
return true
}
// deviceToken request success callback
func application(_ application: UIApplication.didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
var deviceTokenString = String(a)let bytes = [UInt8](deviceToken)
for item in bytes {
deviceTokenString + = String(format: "%02x", item & 0x000000FF)}// Print the obtained token string
print(deviceTokenString)
// Send the token to the server over the network
}
// deviceToken request failed callback
func application(_ application: UIApplication.didFailToRegisterForRemoteNotificationsWithError error: Error) {
print(error.localizedDescription)
}
}
Copy the code
Note: Remote notifications do not support emulators (direct access to deviceToken request failure callbacks) and must be tested on real machines.
test
Real machine test
- Install the App on the real machine.
- Test through software (such as APNs) or a third party, but the relevant content needs to be set up.
(1) Certificate mode: P12 certificate + Bundle Identifier + deviceToken. (2) Token: P8 AuthKey + Team ID + Key ID + Bundle Identifier + deviceToken.
Emulator tests – Using JSON files
- JSON file.
{
"aps": {"alert": {"title":"Test"."subtitle":"Remote Push"."body":"This is a message from far away."
},
"sound":"default"."badge":1}}Copy the code
- Command.
xcrun simctl push booted developer.yf.TestUIKit /Users/yangfan/Desktop/playload.json
Copy the code
Simulator tests – using APNS files
Another way is to drag the APNs file directly into the iOS emulator. Prepare a file with the.apns suffix, similar to the JSON file above, but with a Simulator Target Bundle that describes the App’s Bundle Identifier.
- APNs file.
{
"Simulator Target Bundle": "developer.yf.TestUIKit"."aps": {"alert": {"title":"Test"."subtitle":"Remote Push"."body":"This is a message from far away."
},
"sound":"default"."badge":1}}Copy the code
The front desk to deal with
By default, the App can only receive notifications in the background, but not in the foreground. If the foreground also needs reminders, you can perform the following operations.
- Create UNUserNotificationCenterDelegate.
class NotificationHandler: NSObject.UNUserNotificationCenterDelegate {
// Display notifications in front
func userNotificationCenter(_ center: UNUserNotificationCenter.willPresent notification: UNNotification.withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) - >Void) {
// The front desk notification does not set badge generally
completionHandler([.list, .banner, .sound])
// If you don't want to display a notification, you can use []
// completionHandler([])}}Copy the code
- Set up the proxy.
class AppDelegate: UIResponder.UIApplicationDelegate {
// Custom notification callback class to implement notification proxy
let notificationHandler = NotificationHandler(a)func application(_ application: UIApplication.didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Set the proxy
UNUserNotificationCenter.current().delegate = notificationHandler
return true}}Copy the code
Angle of the set
- Whether it is local or remote notification, foreground notification generally does not set the logo reminder, so only need to process the logo for background notification.
- You do not need to manually set the notification icon. It is automatically set according to the notification.
// Add the marker manually
UIApplication.shared.applicationIconBadgeNumber = 10
// Clean up the corner marker
UIApplication.shared.applicationIconBadgeNumber = 0
Copy the code