Changeset View
Standalone View
native/ios/Comm/AppDelegate.mm
Show First 20 Lines • Show All 312 Lines • ▼ Show 20 Lines | TemporaryMessageStorage *temporaryStorage = | ||||
[[TemporaryMessageStorage alloc] init]; | [[TemporaryMessageStorage alloc] init]; | ||||
NSArray<NSString *> *messages = [temporaryStorage readAndClearMessages]; | NSArray<NSString *> *messages = [temporaryStorage readAndClearMessages]; | ||||
for (NSString *message in messages) { | for (NSString *message in messages) { | ||||
std::string messageInfos = std::string([message UTF8String]); | std::string messageInfos = std::string([message UTF8String]); | ||||
comm::GlobalDBSingleton::instance.scheduleOrRun([messageInfos]() mutable { | comm::GlobalDBSingleton::instance.scheduleOrRun([messageInfos]() mutable { | ||||
comm::MessageOperationsUtilities::storeMessageInfos(messageInfos); | comm::MessageOperationsUtilities::storeMessageInfos(messageInfos); | ||||
}); | }); | ||||
} | } | ||||
TemporaryMessageStorage *temporaryRescindsStorage = | |||||
[[TemporaryMessageStorage alloc] initForRescinds]; | |||||
NSArray<NSString *> *rescindMessages = | |||||
[temporaryRescindsStorage readAndClearMessages]; | |||||
for (NSString *rescindMessage in rescindMessages) { | |||||
NSData *binaryRescindMessage = | |||||
[rescindMessage dataUsingEncoding:NSUTF8StringEncoding]; | |||||
NSError *jsonError = nil; | |||||
NSDictionary *rescindPayload = | |||||
[NSJSONSerialization JSONObjectWithData:binaryRescindMessage | |||||
options:0 | |||||
error:&jsonError]; | |||||
atul: (I think this could probably be simpler (and maybe less error-prone) if we were to use the… | |||||
marcinAuthorUnsubmitted Done Inline ActionsAfter a quick research I found that using Codable API in OBJ-C requires some bridges with Swift: https://stackoverflow.com/questions/50617542/how-to-use-codable-protocol-in-objective-c-data-model-class. Additionally I am not sure how stable is the current structure of the rescind payload - how likely are we to be changing it in future. Using Codable would require us to declare class with fixed attributes, so each change in rescind payload on the JS side would require a change in this class. This increases the coupling in the codebase. However, once we reach a point where notifications payload structures are unlikely to change we might consider representing them in native languages as more rigid and restrictive types rather than just dictionaries mapping String -> Object. marcin: After a quick research I found that using Codable API in OBJ-C requires some bridges with… | |||||
if (jsonError) { | |||||
comm::Logger::log( | |||||
atulUnsubmitted Not Done Inline ActionsShould we react in a more "severe" way than logging + continueing if there's a failure here? atul: Should we react in a more "severe" way than logging + `continue`ing if there's a failure here? | |||||
marcinAuthorUnsubmitted Done Inline ActionsIn this particular case, if we ignore the error we will eventually pull the correct state of thread unread status from keyserver. Currently updating SQLite in response to notifications is a kind of redundancy that can be helpful when user opens the app in weak network environment but they still got the correct state because of received notifications. From the user perspective, killing the app here would be a poor experience (in worst case they would still get the correct state but just later). But from the dev perspective it might be useful since having an error here means that some error occurred on the NSE side since it failed to correctly persist rescind payload (it could be time out for example). This would make us investigate what had happened on the NSE side. marcin: In this particular case, if we ignore the error we will eventually pull the correct state of… | |||||
"Failed to deserialize persisted rescind payload. Details: " + | |||||
std::string([jsonError.localizedDescription UTF8String])); | |||||
atulUnsubmitted Not Done Inline ActionsDid you test initializing a std::string like this? I'm not super familiar with Objective C++ atul: Did you test initializing a `std::string` like this? I'm not super familiar with Objective C++ | |||||
marcinAuthorUnsubmitted Done Inline ActionsEvery where in our codebase where we create std::string from NSString* we call UTF8String method before passing it to std::string constructor. Apple docs suggest to do it this way: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Strings/Articles/CreatingStrings.html marcin: Every where in our codebase where we create `std::string` from `NSString*` we call `UTF8String`… | |||||
continue; | |||||
} | |||||
if (!(rescindPayload[setUnreadStatusKey] && rescindPayload[@"threadID"])) { | |||||
tomekUnsubmitted Not Done Inline ActionsShould we also extract a const for threadID? tomek: Should we also extract a const for `threadID`? | |||||
marcinAuthorUnsubmitted Done Inline ActionsIt would be a good measure. marcin: It would be a good measure. | |||||
continue; | |||||
} | |||||
std::string threadID = | |||||
std::string([rescindPayload[@"threadID"] UTF8String]); | |||||
comm::GlobalDBSingleton::instance.scheduleOrRun([threadID]() mutable { | |||||
atulUnsubmitted Not Done Inline ActionsHm, why does this lambda need to be mutable? atul: Hm, why does this lambda need to be mutable? | |||||
marcinAuthorUnsubmitted Done Inline ActionsThis answer: https://stackoverflow.com/a/5503357 nicely explains how capturing and mutability works in C++ lambdas. This lambda has to be mutable since the inner function: comm::ThreadOperations::updateSQLiteUnreadStatus(threadID, false) takes threadID be reference. marcin: This answer: https://stackoverflow.com/a/5503357 nicely explains how capturing and mutability… | |||||
comm::ThreadOperations::updateSQLiteUnreadStatus(threadID, false); | |||||
}); | |||||
} | |||||
} | } | ||||
// Copied from | // Copied from | ||||
// ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/OnLoad.cpp | // ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/OnLoad.cpp | ||||
static ::hermes::vm::RuntimeConfig | static ::hermes::vm::RuntimeConfig | ||||
makeRuntimeConfig(::hermes::vm::gcheapsize_t heapSizeMB) { | makeRuntimeConfig(::hermes::vm::gcheapsize_t heapSizeMB) { | ||||
namespace vm = ::hermes::vm; | namespace vm = ::hermes::vm; | ||||
auto gcConfigBuilder = | auto gcConfigBuilder = | ||||
Show All 18 Lines |
(I think this could probably be simpler (and maybe less error-prone) if we were to use the Foundation Codable API instead of NSJSONSerialization... but it looks like NSJSONSerialization is simpler if we're using Objective-C(++).
Nothing actionable, just a thought.)