157 lines
6.1 KiB
Swift
157 lines
6.1 KiB
Swift
//
|
|
// NotificationService.swift
|
|
// notificationServiceAppExtension
|
|
//
|
|
// Created by QuentinArguillere on 26/07/2021.
|
|
//
|
|
|
|
import UserNotifications
|
|
import linphonesw
|
|
|
|
var APP_GROUP_ID = "group.org.linphone.tutorials.notification"
|
|
var LINPHONE_DUMMY_SUBJECT = "dummy subject"
|
|
|
|
struct MsgData: Codable {
|
|
var from: String?
|
|
var body: String?
|
|
var subtitle: String?
|
|
var callId: String?
|
|
var localAddr: String?
|
|
var peerAddr: String?
|
|
}
|
|
|
|
class NotificationService: UNNotificationServiceExtension {
|
|
|
|
var contentHandler: ((UNNotificationContent) -> Void)?
|
|
var bestAttemptContent: UNMutableNotificationContent?
|
|
|
|
var lc: Core?
|
|
static var logDelegate: LinphoneLoggingServiceManager!
|
|
static var log: LoggingService!
|
|
|
|
func stopCore() {
|
|
NotificationService.log.message(message: "stop core")
|
|
if let lc = lc {
|
|
lc.stop()
|
|
}
|
|
}
|
|
|
|
|
|
// This function will be called when the app received a notification while in background // closed
|
|
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
|
|
self.contentHandler = contentHandler
|
|
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
|
|
NSLog("[notificationServiceAppExtension] start notificationServiceAppExtension")
|
|
|
|
if let bestAttemptContent = bestAttemptContent {
|
|
|
|
NSLog("[notificationServiceAppExtension] create core")
|
|
let config = Config.newForSharedCore(appGroupId: APP_GROUP_ID, configFilename: "linphonerc", factoryConfigFilename: "")
|
|
if (NotificationService.log == nil) {
|
|
NotificationService.log = LoggingService.Instance /*enable liblinphone logs.*/
|
|
NotificationService.logDelegate = try! LinphoneLoggingServiceManager(config: config!, log: NotificationService.log, domain: "notificationServiceAppExtension")
|
|
}
|
|
// We are creating a shared core, which will use the configuration file form the main app thanks to the App Group
|
|
lc = try! Factory.Instance.createSharedCoreWithConfig(config: config!, systemContext: nil, appGroupId: APP_GROUP_ID, mainCore: false)
|
|
NotificationService.log.message(message: "received push payload : \(bestAttemptContent.userInfo.debugDescription)")
|
|
|
|
|
|
// Flexisip sends 2 types of remote push : invitation to a group chatroom, or receiving a chat message
|
|
if let chatRoomInviteAddr = bestAttemptContent.userInfo["chat-room-addr"] as? String, !chatRoomInviteAddr.isEmpty {
|
|
NotificationService.log.message(message: "fetch chat room for invite, addr: \(chatRoomInviteAddr)")
|
|
|
|
// create a chatroom with the address we received
|
|
let chatRoom = lc!.getNewChatRoomFromConfAddr(chatRoomAddr: chatRoomInviteAddr)
|
|
|
|
if let chatRoom = chatRoom {
|
|
stopCore()
|
|
NotificationService.log.message(message: "chat room invite received")
|
|
|
|
// Update notification body to display custom information
|
|
bestAttemptContent.title = "You have been invited to a chatroom"
|
|
if (chatRoom.hasCapability(mask:ChatRoomCapabilities.OneToOne.rawValue)) {
|
|
if (chatRoom.peerAddress?.displayName.isEmpty != true) {
|
|
bestAttemptContent.body = chatRoom.peerAddress!.displayName
|
|
} else {
|
|
bestAttemptContent.body = chatRoom.peerAddress!.username
|
|
}
|
|
} else {
|
|
bestAttemptContent.body = chatRoom.subject
|
|
}
|
|
|
|
contentHandler(bestAttemptContent)
|
|
return
|
|
}
|
|
} else if let callId = bestAttemptContent.userInfo["call-id"] as? String {
|
|
NotificationService.log.message(message: "fetch msg for callid ["+callId+"]")
|
|
// Get message content from the call id we received
|
|
let message = lc!.getNewMessageFromCallid(callId: callId)
|
|
|
|
if let message = message {
|
|
|
|
func parseMessage(message: PushNotificationMessage) -> MsgData? {
|
|
let content = message.isText ? message.textContent : "🗻"
|
|
let fromAddr = message.fromAddr?.username
|
|
let callId = message.callId
|
|
let localUri = message.localAddr?.asStringUriOnly()
|
|
let peerUri = message.peerAddr?.asStringUriOnly()
|
|
var msgData = MsgData(from: fromAddr, body: "", subtitle: "", callId:callId, localAddr: localUri, peerAddr:peerUri)
|
|
|
|
if let subject = message.subject as String?, subject != "" {
|
|
msgData.subtitle = subject
|
|
msgData.body = fromAddr! + " : " + content
|
|
} else {
|
|
msgData.subtitle = fromAddr
|
|
msgData.body = content
|
|
}
|
|
|
|
NotificationService.log.message(message: "received msg size : \(content.count) \n")
|
|
return msgData;
|
|
}
|
|
let msgData = parseMessage(message: message)
|
|
|
|
stopCore()
|
|
|
|
// Fill notification body with custom informations
|
|
bestAttemptContent.title = "Message received"
|
|
if let subtitle = msgData?.subtitle {
|
|
bestAttemptContent.subtitle = subtitle
|
|
}
|
|
if let body = msgData?.body {
|
|
bestAttemptContent.body = body
|
|
}
|
|
|
|
bestAttemptContent.userInfo.updateValue(msgData?.callId as Any, forKey: "CallId")
|
|
bestAttemptContent.userInfo.updateValue(msgData?.from as Any, forKey: "from")
|
|
bestAttemptContent.userInfo.updateValue(msgData?.peerAddr as Any, forKey: "peer_addr")
|
|
bestAttemptContent.userInfo.updateValue(msgData?.localAddr as Any, forKey: "local_addr")
|
|
|
|
contentHandler(bestAttemptContent)
|
|
return
|
|
} else {
|
|
NotificationService.log.message(message: "Message not found for callid ["+callId+"]")
|
|
}
|
|
}
|
|
serviceExtensionTimeWillExpire()
|
|
}
|
|
}
|
|
|
|
override func serviceExtensionTimeWillExpire() {
|
|
// Called just before the extension will be terminated by the system.
|
|
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
|
|
NotificationService.log.warning(message: "serviceExtensionTimeWillExpire")
|
|
stopCore()
|
|
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
|
|
NSLog("[notificationServiceAppExtension] serviceExtensionTimeWillExpire")
|
|
|
|
if let chatRoomInviteAddr = bestAttemptContent.userInfo["chat-room-addr"] as? String, !chatRoomInviteAddr.isEmpty {
|
|
bestAttemptContent.title = "You have been invited to a chatroom"
|
|
} else {
|
|
bestAttemptContent.title = "You have received a message"
|
|
}
|
|
contentHandler(bestAttemptContent)
|
|
}
|
|
}
|
|
|
|
}
|