问题
I'm trying to replicate how WhatsApp signals the callee's device about an incoming call when the caller starts a call to a user who has this WhatsApp closed. According to the lock screen, the call receiver's device seems to be repeatedly receiving push notification with an interval of approximately 1 second, saying "Call from UserName". But most notably, the notifications do not pile up. It appears that every notification about an incoming call is replaced by the next such notification. And when the caller drops the call, the last incoming-call notification on the callee end is replaced by "Missed call" notification.
How can I achieve push notification replacement/deletion in this way?
回答1:
You can use the "apns-collapse-id ". it will replace the Notification contents with the same id
https://developer.apple.com/documentation/usernotifications/unnotificationrequest/1649634-identifier
https://medium.com/the-guardian-mobile-innovation-lab/how-to-replace-the-content-of-an-ios-notification-2d8d93766446
回答2:
WhatsApp uses silent notifications to trigger the display of local notifications. Local notifications can be replaced by the app. This was the last time I reversed engineered their process. They probably use Push Kit messages now, as they are a VoIP app.
回答3:
Whatsapp, skype or any other VOIP related app uses push kit.
Use content-available = 1 in payload to make it silent push notification.
Silent push notification will invoke your app in background even if your app is in kill state ( Terminated state ), so it will allow you to schedule local notification.
Once you have payload for incoming call schedule local notification
Once you get payload for missed call, cancel incoming call local notification and schedule missed call local notification
Note - Incoming or missed call local notification object, always keeps in NSUserDefault to ensure its availability to cancel even if you restart your device.
Payload related details you can keep in localnotification.userInfo
Pushkit code
import UIKit
import PushKit
class AppDelegate: UIResponder, UIApplicationDelegate,PKPushRegistryDelegate{
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let types: UIRemoteNotificationType = [.Alert, .Badge, .Sound]
application.registerForRemoteNotificationTypes(types)
self. PushKitRegistration()
return true
}
//MARK: - PushKitRegistration
func PushKitRegistration()
{
let mainQueue = dispatch_get_main_queue()
// Create a push registry object
if #available(iOS 8.0, *) {
let voipRegistry: PKPushRegistry = PKPushRegistry(queue: mainQueue)
// Set the registry's delegate to self
voipRegistry.delegate = self
// Set the push type to VoIP
voipRegistry.desiredPushTypes = [PKPushTypeVoIP]
} else {
// Fallback on earlier versions
}
}
@available(iOS 8.0, *)
func pushRegistry(registry: PKPushRegistry!, didUpdatePushCredentials credentials: PKPushCredentials!, forType type: String!) {
// Register VoIP push token (a property of PKPushCredentials) with server
let hexString : String = UnsafeBufferPointer<UInt8>(start: UnsafePointer(credentials.token.bytes),
count: credentials.token.length).map { String(format: "%02x", $0) }.joinWithSeparator("")
print(hexString)
}
@available(iOS 8.0, *)
func pushRegistry(registry: PKPushRegistry!, didReceiveIncomingPushWithPayload payload: PKPushPayload!, forType type: String!) {
// Process the received push
// As per payload schedule local notification / cancel local notification
}
}
Kind of pushkit payload
{
"aps": {
"content-available": 1,
"screen": "IncomingCall",
"alertTitle": "Mr ...",
"alertBody": "Call from ...",
"category": "INCOMINGCALL_CATEGORY",
"data": "Any specific data you want to pass"
}
}
来源:https://stackoverflow.com/questions/38454913/how-do-you-replace-one-push-notification-with-another-on-the-receiving-device