Merge pull request #235 from RyanRory/notifications

Fix Push Notification Bugs
pull/233/head
Niels Andriesse 4 years ago committed by GitHub
commit ddd908ee2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -15,31 +15,36 @@ final class NotificationServiceExtension : UNNotificationServiceExtension {
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
notificationContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
DispatchQueue.main.async {
self.setUpIfNecessary() {
if let notificationContent = self.notificationContent {
// Modify the notification content here...
let base64EncodedData = notificationContent.userInfo["ENCRYPTED_DATA"] as! String
let data = Data(base64Encoded: base64EncodedData)!
let decrypter = SSKEnvironment.shared.messageDecrypter
if let envelope = try? MessageWrapper.unwrap(data: data), let data = try? envelope.serializedData() {
decrypter.decryptEnvelope(envelope,
envelopeData: data,
successBlock: { result, transaction in
if (try? SSKProtoEnvelope.parseData(result.envelopeData)) != nil {
self.handleDecryptionResult(result: result, notificationContent: notificationContent, transaction: transaction)
} else {
self.completeWithFailure(content: notificationContent)
}
},
failureBlock: {
// The code using DispatchQueue.main.async { self.setUpIfNecessary(){ Modify the notification content } } will somehow cause a freezing when the second PN comes
DispatchQueue.main.sync { self.setUpIfNecessary(){} }
AppReadiness.runNowOrWhenAppDidBecomeReady {
if let notificationContent = self.notificationContent {
// Modify the notification content here...
let base64EncodedData = notificationContent.userInfo["ENCRYPTED_DATA"] as! String
let data = Data(base64Encoded: base64EncodedData)!
let decrypter = SSKEnvironment.shared.messageDecrypter
let messageManager = SSKEnvironment.shared.messageManager
if let envelope = try? MessageWrapper.unwrap(data: data), let data = try? envelope.serializedData() {
let wasReceivedByUD = self.wasReceivedByUD(envelope: envelope)
decrypter.decryptEnvelope(envelope,
envelopeData: data,
successBlock: { result, transaction in
if let envelope = try? SSKProtoEnvelope.parseData(result.envelopeData) {
messageManager.throws_processEnvelope(envelope, plaintextData: result.plaintextData, wasReceivedByUD: wasReceivedByUD, transaction: transaction, serverID: 0)
self.handleDecryptionResult(result: result, notificationContent: notificationContent, transaction: transaction)
} else {
self.completeWithFailure(content: notificationContent)
}
)
} else {
self.completeWithFailure(content: notificationContent)
}
},
failureBlock: {
self.completeWithFailure(content: notificationContent)
}
)
} else {
self.completeWithFailure(content: notificationContent)
}
}
}

@ -212,12 +212,16 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, UIScrol
isObservingDatabase = isViewVisible && CurrentAppContext().isAppForegroundAndActive()
}
private func reload() {
AssertIsOnMainThread()
private func updateThreadMapping() {
uiDatabaseConnection.beginLongLivedReadTransaction()
uiDatabaseConnection.read { transaction in
self.threads.update(with: transaction)
}
}
private func reload() {
AssertIsOnMainThread()
updateThreadMapping()
threadViewModelCache.removeAll()
tableView.reloadData()
emptyStateView.isHidden = (threadCount != 0)
@ -235,6 +239,21 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, UIScrol
}
return
}
// Guard for changes made in Notification Service Extension
// Crashes may happen if there is some modification in NSE
// The YapDBModificationNotification cannot cross process
// So the thread mapping won't update itself if DB modification happened in other process like NSE
// With these code we can sync the mapping before asking for changes from YapDB
if (notifications.count > 0) {
if let firstChangeset = notifications[0].userInfo {
let firstSnapshot = firstChangeset[YapDatabaseSnapshotKey] as! UInt64
if (self.threads.snapshotOfLastUpdate != firstSnapshot - 1) {
reload()
return
}
}
}
var sectionChanges = NSArray()
var rowChanges = NSArray()
ext.getSectionChanges(&sectionChanges, rowChanges: &rowChanges, for: notifications, with: threads)
@ -261,6 +280,7 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, UIScrol
@objc private func handleApplicationDidBecomeActiveNotification(_ notification: Notification) {
updateIsObservingDatabase()
updateThreadMapping()
}
@objc private func handleApplicationWillResignActiveNotification(_ notification: Notification) {

@ -1613,10 +1613,10 @@ NS_ASSUME_NONNULL_BEGIN
// Update thread preview in inbox
[masterThread touchWithTransaction:transaction];
[SSKEnvironment.shared.notificationsManager notifyUserForIncomingMessage:incomingMessage
inThread:masterThread
transaction:transaction];
if (CurrentAppContext().isMainAppAndActive) {
[SSKEnvironment.shared.notificationsManager notifyUserForIncomingMessage:incomingMessage inThread:masterThread transaction:transaction];
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.typingIndicators didReceiveIncomingMessageInThread:masterThread

@ -88,8 +88,6 @@ NSString *const kSessionStoreDBConnectionKey = @"kSessionStoreDBConnectionKey";
OWSAssertDebug(contactIdentifier.length > 0);
OWSAssertDebug(deviceId >= 0);
OWSAssertDebug([protocolContext isKindOfClass:[YapDatabaseReadWriteTransaction class]]);
// FIXME: This needs a comment from Ryan explaining why it's necessary (it has to do with push notifications)
if (!CurrentAppContext().isMainApp) { return; }
YapDatabaseReadWriteTransaction *transaction = protocolContext;

Loading…
Cancel
Save