Merge branch 'mkirk/long-text-nondurable'

This commit is contained in:
Michael Kirk 2019-02-26 10:06:59 -07:00
commit e6ad6c85bf
5 changed files with 195 additions and 167 deletions

View file

@ -660,14 +660,20 @@ class NotificationActionHandler {
} }
extension ThreadUtil { extension ThreadUtil {
static var dbReadConnection: YapDatabaseConnection {
return OWSPrimaryStorage.shared().dbReadConnection
}
class func sendMessageNonDurably(text: String, thread: TSThread, quotedReplyModel: OWSQuotedReplyModel?, messageSender: MessageSender) -> Promise<Void> { class func sendMessageNonDurably(text: String, thread: TSThread, quotedReplyModel: OWSQuotedReplyModel?, messageSender: MessageSender) -> Promise<Void> {
return Promise { resolver in return Promise { resolver in
self.sendMessageNonDurably(withText: text, self.dbReadConnection.read { transaction in
in: thread, _ = self.sendMessageNonDurably(withText: text,
quotedReplyModel: quotedReplyModel, in: thread,
messageSender: messageSender, quotedReplyModel: quotedReplyModel,
success: resolver.fulfill, transaction: transaction,
failure: resolver.reject) messageSender: messageSender,
completion: resolver.resolve)
}
} }
} }
} }

View file

@ -30,7 +30,6 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion);
@property (nonatomic) TSThread *thread; @property (nonatomic) TSThread *thread;
@property (nonatomic, readonly, weak) id<ShareViewDelegate> shareViewDelegate; @property (nonatomic, readonly, weak) id<ShareViewDelegate> shareViewDelegate;
@property (nonatomic, readonly) UIProgressView *progressView; @property (nonatomic, readonly) UIProgressView *progressView;
@property (nonatomic, readonly) YapDatabaseConnection *editingDBConnection;
@property (atomic, nullable) TSOutgoingMessage *outgoingMessage; @property (atomic, nullable) TSOutgoingMessage *outgoingMessage;
@end @end
@ -46,13 +45,26 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion);
return self; return self;
} }
_editingDBConnection = [OWSPrimaryStorage.sharedManager newDatabaseConnection];
_shareViewDelegate = shareViewDelegate; _shareViewDelegate = shareViewDelegate;
self.selectThreadViewDelegate = self; self.selectThreadViewDelegate = self;
return self; return self;
} }
#pragma mark - Dependencies
- (YapDatabaseConnection *)dbReadWriteConnection
{
return OWSPrimaryStorage.sharedManager.dbReadWriteConnection;
}
- (YapDatabaseConnection *)dbReadConnection
{
return OWSPrimaryStorage.sharedManager.dbReadConnection;
}
#pragma mark - UIViewController overrides
- (void)loadView - (void)loadView
{ {
[super loadView]; [super loadView];
@ -274,14 +286,18 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion);
// the sending operation. Alternatively, we could use a durable send, but do more to make sure the // the sending operation. Alternatively, we could use a durable send, but do more to make sure the
// SAE runs as long as it needs. // SAE runs as long as it needs.
// TODO ALBUMS - send album via SAE // TODO ALBUMS - send album via SAE
outgoingMessage = [ThreadUtil sendMessageNonDurablyWithAttachments:attachments
inThread:self.thread [self.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) {
messageBody:messageText outgoingMessage = [ThreadUtil sendMessageNonDurablyWithText:messageText
quotedReplyModel:nil mediaAttachments:attachments
messageSender:self.messageSender inThread:self.thread
completion:^(NSError *_Nullable error) { quotedReplyModel:nil
sendCompletion(error, outgoingMessage); transaction:transaction
}]; messageSender:self.messageSender
completion:^(NSError *_Nullable error) {
sendCompletion(error, outgoingMessage);
}];
}];
// This is necessary to show progress. // This is necessary to show progress.
self.outgoingMessage = outgoingMessage; self.outgoingMessage = outgoingMessage;
@ -310,19 +326,22 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion);
// DURABLE CLEANUP - SAE uses non-durable sending to make sure the app is running long enough to complete // DURABLE CLEANUP - SAE uses non-durable sending to make sure the app is running long enough to complete
// the sending operation. Alternatively, we could use a durable send, but do more to make sure the // the sending operation. Alternatively, we could use a durable send, but do more to make sure the
// SAE runs as long as it needs. // SAE runs as long as it needs.
outgoingMessage = [ThreadUtil sendMessageNonDurablyWithText:messageText [self.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) {
inThread:self.thread outgoingMessage = [ThreadUtil sendMessageNonDurablyWithText:messageText
quotedReplyModel:nil inThread:self.thread
messageSender:self.messageSender quotedReplyModel:nil
success:^{ transaction:transaction
sendCompletion(nil, outgoingMessage); messageSender:self.messageSender
} completion:^(NSError *_Nullable error) {
failure:^(NSError *_Nonnull error) { if (error) {
sendCompletion(error, outgoingMessage); sendCompletion(error, outgoingMessage);
}]; } else {
sendCompletion(nil, outgoingMessage);
// This is necessary to show progress. }
self.outgoingMessage = outgoingMessage; }];
// This is necessary to show progress.
self.outgoingMessage = outgoingMessage;
}];
} }
fromViewController:approvalViewController]; fromViewController:approvalViewController];
} }
@ -344,11 +363,12 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion);
OWSAssertIsOnMainThread(); OWSAssertIsOnMainThread();
// TODO - in line with QuotedReply and other message attachments, saving should happen as part of sending // TODO - in line with QuotedReply and other message attachments, saving should happen as part of sending
// preparation rather than duplicated here and in the SAE // preparation rather than duplicated here and in the SAE
[self.editingDBConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { [self.dbReadWriteConnection
if (contactShare.avatarImage) { asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
[contactShare.dbRecord saveAvatarImage:contactShare.avatarImage transaction:transaction]; if (contactShare.avatarImage) {
[contactShare.dbRecord saveAvatarImage:contactShare.avatarImage transaction:transaction];
}
} }
}
completionBlock:^{ completionBlock:^{
__block TSOutgoingMessage *outgoingMessage = nil; __block TSOutgoingMessage *outgoingMessage = nil;
outgoingMessage = [ThreadUtil sendMessageNonDurablyWithContactShare:contactShare.dbRecord outgoingMessage = [ThreadUtil sendMessageNonDurablyWithContactShare:contactShare.dbRecord
@ -521,8 +541,7 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion);
OWSLogDebug(@"Confirming identity for recipient: %@", recipientId); OWSLogDebug(@"Confirming identity for recipient: %@", recipientId);
[OWSPrimaryStorage.sharedManager.newDatabaseConnection asyncReadWriteWithBlock:^( [self.dbReadWriteConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
YapDatabaseReadWriteTransaction *transaction) {
OWSVerificationState verificationState = OWSVerificationState verificationState =
[[OWSIdentityManager sharedManager] verificationStateForRecipientId:recipientId transaction:transaction]; [[OWSIdentityManager sharedManager] verificationStateForRecipientId:recipientId transaction:transaction];
switch (verificationState) { switch (verificationState) {

View file

@ -63,26 +63,27 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Non-Durable Sending #pragma mark - Non-Durable Sending
// Used by SAE and "reply from lockscreen", otherwise we should use the durable `enqueue` counterpart // Used by SAE and "reply from lockscreen", otherwise we should use the durable `enqueue` counterpart
+ (TSOutgoingMessage *)sendMessageNonDurablyWithText:(NSString *)text + (TSOutgoingMessage *)sendMessageNonDurablyWithText:(NSString *)fullMessageText
inThread:(TSThread *)thread inThread:(TSThread *)thread
quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel
transaction:(YapDatabaseReadTransaction *)transaction
messageSender:(OWSMessageSender *)messageSender messageSender:(OWSMessageSender *)messageSender
success:(void (^)(void))successHandler completion:(void (^)(NSError *_Nullable error))completion;
failure:(void (^)(NSError *error))failureHandler;
// Used by SAE, otherwise we should use the durable `enqueue` counterpart // Used by SAE, otherwise we should use the durable `enqueue` counterpart
+ (TSOutgoingMessage *)sendMessageNonDurablyWithAttachments:(NSArray<SignalAttachment *> *)attachments + (TSOutgoingMessage *)sendMessageNonDurablyWithText:(NSString *)fullMessageText
inThread:(TSThread *)thread mediaAttachments:(NSArray<SignalAttachment *> *)attachments
messageBody:(nullable NSString *)messageBody inThread:(TSThread *)thread
quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel
messageSender:(OWSMessageSender *)messageSender transaction:(YapDatabaseReadTransaction *)transaction
completion:(void (^_Nullable)(NSError *_Nullable error))completion; messageSender:(OWSMessageSender *)messageSender
completion:(void (^)(NSError *_Nullable error))completion;
// Used by SAE, otherwise we should use the durable `enqueue` counterpart // Used by SAE, otherwise we should use the durable `enqueue` counterpart
+ (TSOutgoingMessage *)sendMessageNonDurablyWithContactShare:(OWSContact *)contactShare + (TSOutgoingMessage *)sendMessageNonDurablyWithContactShare:(OWSContact *)contactShare
inThread:(TSThread *)thread inThread:(TSThread *)thread
messageSender:(OWSMessageSender *)messageSender messageSender:(OWSMessageSender *)messageSender
completion:(void (^_Nullable)(NSError *_Nullable error))completion; completion:(void (^)(NSError *_Nullable error))completion;
#pragma mark - dynamic interactions #pragma mark - dynamic interactions

View file

@ -65,6 +65,10 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - #pragma mark -
typedef void (^BuildOutgoingMessageCompletionBlock)(TSOutgoingMessage *savedMessage,
NSMutableArray<OWSOutgoingAttachmentInfo *> *attachmentInfos,
YapDatabaseReadWriteTransaction *writeTransaction);
@implementation ThreadUtil @implementation ThreadUtil
#pragma mark - Dependencies #pragma mark - Dependencies
@ -95,26 +99,8 @@ NS_ASSUME_NONNULL_BEGIN
transaction:transaction]; transaction:transaction];
} }
+ (nullable OWSLinkPreview *)linkPreviewForLinkPreviewDraft:(nullable OWSLinkPreviewDraft *)linkPreviewDraft
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssertDebug(transaction);
if (!linkPreviewDraft) {
return nil;
}
NSError *linkPreviewError;
OWSLinkPreview *_Nullable linkPreview = [OWSLinkPreview buildValidatedLinkPreviewFromInfo:linkPreviewDraft
transaction:transaction
error:&linkPreviewError];
if (linkPreviewError && ![OWSLinkPreview isNoPreviewError:linkPreviewError]) {
OWSLogError(@"linkPreviewError: %@", linkPreviewError);
}
return linkPreview;
}
+ (TSOutgoingMessage *)enqueueMessageWithText:(nullable NSString *)fullMessageText + (TSOutgoingMessage *)enqueueMessageWithText:(nullable NSString *)fullMessageText
mediaAttachments:(NSArray<SignalAttachment *> *)attachmentsParam mediaAttachments:(NSArray<SignalAttachment *> *)mediaAttachments
inThread:(TSThread *)thread inThread:(TSThread *)thread
quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel
linkPreviewDraft:(nullable nullable OWSLinkPreviewDraft *)linkPreviewDraft linkPreviewDraft:(nullable nullable OWSLinkPreviewDraft *)linkPreviewDraft
@ -123,8 +109,36 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssertIsOnMainThread(); OWSAssertIsOnMainThread();
OWSAssertDebug(thread); OWSAssertDebug(thread);
return [self
buildOutgoingMessageWithText:fullMessageText
mediaAttachments:mediaAttachments
thread:thread
quotedReplyModel:quotedReplyModel
linkPreviewDraft:linkPreviewDraft
transaction:transaction
completion:^(TSOutgoingMessage *savedMessage,
NSMutableArray<OWSOutgoingAttachmentInfo *> *attachmentInfos,
YapDatabaseReadWriteTransaction *writeTransaction) {
if (attachmentInfos.count == 0) {
[self.messageSenderJobQueue addMessage:savedMessage transaction:writeTransaction];
} else {
[self.messageSenderJobQueue addMediaMessage:savedMessage
attachmentInfos:attachmentInfos
isTemporaryAttachment:NO];
}
}];
}
+ (TSOutgoingMessage *)buildOutgoingMessageWithText:(nullable NSString *)fullMessageText
mediaAttachments:(NSArray<SignalAttachment *> *)mediaAttachments
thread:(TSThread *)thread
quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel
linkPreviewDraft:(nullable OWSLinkPreviewDraft *)linkPreviewDraft
transaction:(YapDatabaseReadTransaction *)transaction
completion:(BuildOutgoingMessageCompletionBlock)completionBlock;
{
NSString *_Nullable truncatedText; NSString *_Nullable truncatedText;
NSArray<SignalAttachment *> *attachments = attachmentsParam; NSArray<SignalAttachment *> *attachments = mediaAttachments;
if ([fullMessageText lengthOfBytesUsingEncoding:NSUTF8StringEncoding] <= kOversizeTextMessageSizeThreshold) { if ([fullMessageText lengthOfBytesUsingEncoding:NSUTF8StringEncoding] <= kOversizeTextMessageSizeThreshold) {
truncatedText = fullMessageText; truncatedText = fullMessageText;
} else { } else {
@ -141,7 +155,7 @@ NS_ASSUME_NONNULL_BEGIN
if (dataSource) { if (dataSource) {
SignalAttachment *oversizeTextAttachment = SignalAttachment *oversizeTextAttachment =
[SignalAttachment attachmentWithDataSource:dataSource dataUTI:kOversizeTextAttachmentUTI]; [SignalAttachment attachmentWithDataSource:dataSource dataUTI:kOversizeTextAttachmentUTI];
attachments = [attachmentsParam arrayByAddingObject:oversizeTextAttachment]; attachments = [mediaAttachments arrayByAddingObject:oversizeTextAttachment];
} else { } else {
OWSFailDebug(@"dataSource was unexpectedly nil"); OWSFailDebug(@"dataSource was unexpectedly nil");
} }
@ -188,21 +202,13 @@ NS_ASSUME_NONNULL_BEGIN
[message updateWithLinkPreview:linkPreview transaction:writeTransaction]; [message updateWithLinkPreview:linkPreview transaction:writeTransaction];
} }
if (attachments.count == 0) { NSMutableArray<OWSOutgoingAttachmentInfo *> *attachmentInfos = [NSMutableArray new];
[self.messageSenderJobQueue addMessage:message transaction:writeTransaction]; for (SignalAttachment *attachment in attachments) {
} else { OWSOutgoingAttachmentInfo *attachmentInfo =
NSMutableArray<OWSOutgoingAttachmentInfo *> *attachmentInfos = [attachment buildOutgoingAttachmentInfoWithMessage:message];
[NSMutableArray new]; [attachmentInfos addObject:attachmentInfo];
for (SignalAttachment *attachment in attachments) {
OWSOutgoingAttachmentInfo *attachmentInfo =
[attachment buildOutgoingAttachmentInfoWithMessage:message];
[attachmentInfos addObject:attachmentInfo];
}
[self.messageSenderJobQueue addMediaMessage:message
attachmentInfos:attachmentInfos
isTemporaryAttachment:NO];
} }
completionBlock(message, attachmentInfos, writeTransaction);
} }
completionBlock:benchmarkCompletion]; completionBlock:benchmarkCompletion];
}]; }];
@ -257,104 +263,86 @@ NS_ASSUME_NONNULL_BEGIN
// MARK: Non-Durable Sending // MARK: Non-Durable Sending
// We might want to generate a link preview here. // We might want to generate a link preview here.
+ (TSOutgoingMessage *)sendMessageNonDurablyWithText:(NSString *)text + (TSOutgoingMessage *)sendMessageNonDurablyWithText:(NSString *)fullMessageText
inThread:(TSThread *)thread inThread:(TSThread *)thread
quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel
transaction:(YapDatabaseReadTransaction *)transaction
messageSender:(OWSMessageSender *)messageSender messageSender:(OWSMessageSender *)messageSender
success:(void (^)(void))successHandler completion:(void (^)(NSError *_Nullable error))completion
failure:(void (^)(NSError *error))failureHandler
{ {
OWSAssertIsOnMainThread(); OWSAssertDebug(completion);
OWSAssertDebug(text.length > 0);
OWSAssertDebug(thread);
OWSAssertDebug(messageSender);
OWSDisappearingMessagesConfiguration *configuration = return [self sendMessageNonDurablyWithText:fullMessageText
[OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:thread.uniqueId]; mediaAttachments:@[]
uint32_t expiresInSeconds = (configuration.isEnabled ? configuration.durationSeconds : 0); inThread:thread
TSOutgoingMessage *message = quotedReplyModel:quotedReplyModel
[TSOutgoingMessage outgoingMessageInThread:thread transaction:transaction
messageBody:text messageSender:messageSender
attachmentId:nil completion:completion];
expiresInSeconds:expiresInSeconds
quotedMessage:[quotedReplyModel buildQuotedMessageForSending]
linkPreview:nil];
[messageSender sendMessage:message success:successHandler failure:failureHandler];
return message;
} }
+ (TSOutgoingMessage *)sendMessageNonDurablyWithAttachments:(NSArray<SignalAttachment *> *)attachments + (TSOutgoingMessage *)sendMessageNonDurablyWithText:(NSString *)fullMessageText
inThread:(TSThread *)thread mediaAttachments:(NSArray<SignalAttachment *> *)mediaAttachments
messageBody:(nullable NSString *)messageBody inThread:(TSThread *)thread
quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel
messageSender:(OWSMessageSender *)messageSender transaction:(YapDatabaseReadTransaction *)transaction
completion:(void (^_Nullable)(NSError *_Nullable error))completion messageSender:(OWSMessageSender *)messageSender
completion:(void (^)(NSError *_Nullable error))completion
{ {
OWSAssertIsOnMainThread(); OWSAssertIsOnMainThread();
OWSAssertDebug(attachments.count > 0);
OWSAssertDebug(thread); OWSAssertDebug(thread);
OWSAssertDebug(messageSender); OWSAssertDebug(completion);
OWSDisappearingMessagesConfiguration *configuration = return
[OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:thread.uniqueId]; [self buildOutgoingMessageWithText:fullMessageText
mediaAttachments:mediaAttachments
uint32_t expiresInSeconds = (configuration.isEnabled ? configuration.durationSeconds : 0); thread:thread
BOOL isVoiceMessage = (attachments.count == 1 && attachments.firstObject.isVoiceMessage); quotedReplyModel:quotedReplyModel
// MJK TODO - remove senderTimestamp linkPreviewDraft:nil
TSOutgoingMessage *message = transaction:transaction
[[TSOutgoingMessage alloc] initOutgoingMessageWithTimestamp:[NSDate ows_millisecondTimeStamp] completion:^(TSOutgoingMessage *_Nonnull savedMessage,
inThread:thread NSMutableArray<OWSOutgoingAttachmentInfo *> *_Nonnull attachmentInfos,
messageBody:messageBody YapDatabaseReadWriteTransaction *_Nonnull writeTransaction) {
attachmentIds:[NSMutableArray new] if (attachmentInfos.count == 0) {
expiresInSeconds:expiresInSeconds [messageSender sendMessage:savedMessage
expireStartedAt:0 success:^{
isVoiceMessage:isVoiceMessage dispatch_async(dispatch_get_main_queue(), ^(void) {
groupMetaMessage:TSGroupMetaMessageUnspecified completion(nil);
quotedMessage:[quotedReplyModel buildQuotedMessageForSending] });
contactShare:nil }
linkPreview:nil]; failure:^(NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^(void) {
NSMutableArray<OWSOutgoingAttachmentInfo *> *attachmentInfos = [NSMutableArray new]; completion(error);
for (SignalAttachment *attachment in attachments) { });
OWSAssertDebug([attachment mimeType].length > 0); }];
} else {
[attachmentInfos addObject:[attachment buildOutgoingAttachmentInfoWithMessage:message]]; [messageSender sendAttachments:attachmentInfos
} inMessage:savedMessage
success:^{
[messageSender sendAttachments:attachmentInfos dispatch_async(dispatch_get_main_queue(), ^(void) {
inMessage:message completion(nil);
success:^{ });
OWSLogDebug(@"Successfully sent message attachment."); }
if (completion) { failure:^(NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^(void) { dispatch_async(dispatch_get_main_queue(), ^(void) {
completion(nil); completion(error);
}); });
} }];
} }
failure:^(NSError *error) { }];
OWSLogError(@"Failed to send message attachment with error: %@", error);
if (completion) {
dispatch_async(dispatch_get_main_queue(), ^(void) {
completion(error);
});
}
}];
return message;
} }
+ (TSOutgoingMessage *)sendMessageNonDurablyWithContactShare:(OWSContact *)contactShare + (TSOutgoingMessage *)sendMessageNonDurablyWithContactShare:(OWSContact *)contactShare
inThread:(TSThread *)thread inThread:(TSThread *)thread
messageSender:(OWSMessageSender *)messageSender messageSender:(OWSMessageSender *)messageSender
completion:(void (^_Nullable)(NSError *_Nullable error))completion completion:(void (^)(NSError *_Nullable error))completion
{ {
OWSAssertIsOnMainThread(); OWSAssertIsOnMainThread();
OWSAssertDebug(contactShare); OWSAssertDebug(contactShare);
OWSAssertDebug(contactShare.ows_isValid); OWSAssertDebug(contactShare.ows_isValid);
OWSAssertDebug(thread); OWSAssertDebug(thread);
OWSAssertDebug(messageSender); OWSAssertDebug(messageSender);
OWSAssertDebug(completion);
OWSDisappearingMessagesConfiguration *configuration = OWSDisappearingMessagesConfiguration *configuration =
[OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:thread.uniqueId]; [OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:thread.uniqueId];
@ -377,24 +365,38 @@ NS_ASSUME_NONNULL_BEGIN
[messageSender sendMessage:message [messageSender sendMessage:message
success:^{ success:^{
OWSLogDebug(@"Successfully sent contact share."); OWSLogDebug(@"Successfully sent contact share.");
if (completion) { dispatch_async(dispatch_get_main_queue(), ^(void) {
dispatch_async(dispatch_get_main_queue(), ^(void) { completion(nil);
completion(nil); });
});
}
} }
failure:^(NSError *error) { failure:^(NSError *error) {
OWSLogError(@"Failed to send contact share with error: %@", error); OWSLogError(@"Failed to send contact share with error: %@", error);
if (completion) { dispatch_async(dispatch_get_main_queue(), ^(void) {
dispatch_async(dispatch_get_main_queue(), ^(void) { completion(error);
completion(error); });
});
}
}]; }];
return message; return message;
} }
+ (nullable OWSLinkPreview *)linkPreviewForLinkPreviewDraft:(nullable OWSLinkPreviewDraft *)linkPreviewDraft
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssertDebug(transaction);
if (!linkPreviewDraft) {
return nil;
}
NSError *linkPreviewError;
OWSLinkPreview *_Nullable linkPreview = [OWSLinkPreview buildValidatedLinkPreviewFromInfo:linkPreviewDraft
transaction:transaction
error:&linkPreviewError];
if (linkPreviewError && ![OWSLinkPreview isNoPreviewError:linkPreviewError]) {
OWSLogError(@"linkPreviewError: %@", linkPreviewError);
}
return linkPreview;
}
#pragma mark - Dynamic Interactions #pragma mark - Dynamic Interactions
+ (ThreadDynamicInteractions *)ensureDynamicInteractionsForThread:(TSThread *)thread + (ThreadDynamicInteractions *)ensureDynamicInteractionsForThread:(TSThread *)thread

View file

@ -234,7 +234,7 @@ void AssertIsOnSendingQueue()
- (void)didFailWithError:(NSError *)error - (void)didFailWithError:(NSError *)error
{ {
OWSLogDebug(@"failed with error: %@", error); OWSLogError(@"failed with error: %@", error);
self.failureHandler(error); self.failureHandler(error);
} }