2022-05-03 02:20:19 -05:00
|
|
|
//
|
|
|
|
// NotificationService.swift
|
|
|
|
// SimpleX NSE
|
|
|
|
//
|
|
|
|
// Created by Evgeny on 26/04/2022.
|
|
|
|
// Copyright © 2022 SimpleX Chat. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
import UserNotifications
|
|
|
|
import OSLog
|
2022-05-31 01:55:13 -05:00
|
|
|
import SimpleXChat
|
2022-05-03 02:20:19 -05:00
|
|
|
|
|
|
|
let logger = Logger()
|
|
|
|
|
2022-06-02 07:16:22 -05:00
|
|
|
class NotificationService: UNNotificationServiceExtension {
|
2022-05-03 02:20:19 -05:00
|
|
|
var contentHandler: ((UNNotificationContent) -> Void)?
|
|
|
|
var bestAttemptContent: UNMutableNotificationContent?
|
|
|
|
|
|
|
|
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
|
|
|
|
logger.debug("NotificationService.didReceive")
|
2022-06-24 07:52:20 -05:00
|
|
|
let appState = appStateGroupDefault.get()
|
2022-06-19 13:49:39 -05:00
|
|
|
if appState.running {
|
2022-06-24 07:52:20 -05:00
|
|
|
print("userInfo", request.content.userInfo)
|
2022-05-03 02:20:19 -05:00
|
|
|
contentHandler(request.content)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
logger.debug("NotificationService: app is in the background")
|
|
|
|
self.contentHandler = contentHandler
|
|
|
|
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
|
2022-06-19 13:49:39 -05:00
|
|
|
let userInfo = request.content.userInfo
|
|
|
|
if let ntfData = userInfo["notificationData"] as? [AnyHashable : Any],
|
|
|
|
let nonce = ntfData["nonce"] as? String,
|
|
|
|
let encNtfInfo = ntfData["message"] as? String,
|
|
|
|
let _ = startChat() {
|
|
|
|
apiGetNtfMessage(nonce: nonce, encNtfInfo: encNtfInfo)
|
2022-06-24 07:52:20 -05:00
|
|
|
if let content = receiveMessages() {
|
|
|
|
contentHandler(content)
|
|
|
|
return
|
|
|
|
}
|
2022-05-03 02:20:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if let bestAttemptContent = bestAttemptContent {
|
|
|
|
// Modify the notification content here...
|
|
|
|
bestAttemptContent.title = "\(bestAttemptContent.title) [modified]"
|
|
|
|
|
|
|
|
contentHandler(bestAttemptContent)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override func serviceExtensionTimeWillExpire() {
|
|
|
|
logger.debug("NotificationService.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.
|
|
|
|
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
|
|
|
|
contentHandler(bestAttemptContent)
|
|
|
|
}
|
|
|
|
}
|
2022-06-02 07:16:22 -05:00
|
|
|
}
|
2022-05-03 02:20:19 -05:00
|
|
|
|
2022-06-02 07:16:22 -05:00
|
|
|
func receivedAppMachMessage(msgId: Int32, msg: String) -> String? {
|
|
|
|
logger.debug("MachMessenger: receivedAppMachMessage \"\(msg)\" from App, replying")
|
|
|
|
return "reply from NSE to: \(msg)"
|
2022-05-03 02:20:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func startChat() -> User? {
|
|
|
|
hs_init(0, nil)
|
|
|
|
if let user = apiGetActiveUser() {
|
|
|
|
logger.debug("active user \(String(describing: user))")
|
|
|
|
do {
|
|
|
|
try apiStartChat()
|
|
|
|
try apiSetFilesFolder(filesFolder: getAppFilesDirectory().path)
|
2022-06-24 07:52:20 -05:00
|
|
|
chatLastStartGroupDefault.set(Date.now)
|
2022-05-03 02:20:19 -05:00
|
|
|
return user
|
|
|
|
} catch {
|
2022-05-31 01:55:13 -05:00
|
|
|
logger.error("NotificationService startChat error: \(responseError(error), privacy: .public)")
|
2022-05-03 02:20:19 -05:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
logger.debug("no active user")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-06-24 07:52:20 -05:00
|
|
|
func receiveMessages() -> UNNotificationContent? {
|
2022-05-03 02:20:19 -05:00
|
|
|
logger.debug("NotificationService receiveMessages started")
|
|
|
|
while true {
|
2022-06-24 07:52:20 -05:00
|
|
|
if let res = recvSimpleXMsg() {
|
|
|
|
logger.debug("NotificationService receiveMessages: \(res.responseType)")
|
|
|
|
switch res {
|
|
|
|
// case let .newContactConnection(connection):
|
|
|
|
// case let .contactConnectionDeleted(connection):
|
|
|
|
case let .contactConnected(contact):
|
|
|
|
return createContactConnectedNtf(contact)
|
|
|
|
// case let .contactConnecting(contact):
|
|
|
|
// TODO profile update
|
|
|
|
case let .receivedContactRequest(contactRequest):
|
|
|
|
return createContactRequestNtf(contactRequest)
|
|
|
|
// case let .contactUpdated(toContact):
|
|
|
|
// TODO profile updated
|
|
|
|
case let .newChatItem(aChatItem):
|
|
|
|
let cInfo = aChatItem.chatInfo
|
|
|
|
let cItem = aChatItem.chatItem
|
|
|
|
return createMessageReceivedNtf(cInfo, cItem)
|
|
|
|
// case let .chatItemUpdated(aChatItem):
|
|
|
|
// TODO message updated
|
|
|
|
// let cInfo = aChatItem.chatInfo
|
|
|
|
// let cItem = aChatItem.chatItem
|
|
|
|
// NtfManager.shared.notifyMessageReceived(cInfo, cItem)
|
|
|
|
// case let .chatItemDeleted(_, toChatItem):
|
|
|
|
// TODO message updated
|
|
|
|
// case let .rcvFileComplete(aChatItem):
|
|
|
|
// TODO file received?
|
|
|
|
// let cInfo = aChatItem.chatInfo
|
|
|
|
// let cItem = aChatItem.chatItem
|
|
|
|
// NtfManager.shared.notifyMessageReceived(cInfo, cItem)
|
|
|
|
default:
|
|
|
|
logger.debug("NotificationService ignored event: \(res.responseType)")
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return nil
|
2022-05-03 02:20:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func apiGetActiveUser() -> User? {
|
|
|
|
let _ = getChatCtrl()
|
|
|
|
let r = sendSimpleXCmd(.showActiveUser)
|
|
|
|
logger.debug("apiGetActiveUser sendSimpleXCmd responce: \(String(describing: r))")
|
|
|
|
switch r {
|
|
|
|
case let .activeUser(user): return user
|
|
|
|
case .chatCmdError(.error(.noActiveUser)): return nil
|
|
|
|
default:
|
|
|
|
logger.error("NotificationService apiGetActiveUser unexpected response: \(String(describing: r))")
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func apiStartChat() throws {
|
|
|
|
let r = sendSimpleXCmd(.startChat)
|
2022-05-31 01:55:13 -05:00
|
|
|
switch r {
|
|
|
|
case .chatStarted: return
|
|
|
|
case .chatRunning: return
|
|
|
|
default: throw r
|
|
|
|
}
|
2022-05-03 02:20:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func apiSetFilesFolder(filesFolder: String) throws {
|
|
|
|
let r = sendSimpleXCmd(.setFilesFolder(filesFolder: filesFolder))
|
|
|
|
if case .cmdOk = r { return }
|
|
|
|
throw r
|
|
|
|
}
|
|
|
|
|
2022-06-19 13:49:39 -05:00
|
|
|
func apiGetNtfMessage(nonce: String, encNtfInfo: String) {
|
|
|
|
let r = sendSimpleXCmd(.apiGetNtfMessage(nonce: nonce, encNtfInfo: encNtfInfo))
|
|
|
|
if case let .ntfMessages(connEntity, msgTs, ntfMessages) = r {
|
2022-06-24 07:52:20 -05:00
|
|
|
if let connEntity = connEntity { print("connEntity", connEntity) }
|
|
|
|
if let msgTs = msgTs { print("msgTs", msgTs) }
|
|
|
|
print("ntfMessages", ntfMessages)
|
2022-06-19 13:49:39 -05:00
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|