diff --git a/Signal/Signal-Info.plist b/Signal/Signal-Info.plist
index 88a652edb..bc3f5cdac 100644
--- a/Signal/Signal-Info.plist
+++ b/Signal/Signal-Info.plist
@@ -38,7 +38,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 2.18.0
+ 2.18.1
CFBundleSignature
????
CFBundleURLTypes
@@ -55,7 +55,7 @@
CFBundleVersion
- 2.18.0.9
+ 2.18.1.0
ITSAppUsesNonExemptEncryption
LOGS_EMAIL
diff --git a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncGroupsMessage.h b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncGroupsMessage.h
index 530997f53..212d3051b 100644
--- a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncGroupsMessage.h
+++ b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncGroupsMessage.h
@@ -1,12 +1,16 @@
-// Copyright © 2016 Open Whisper Systems. All rights reserved.
+//
+// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
+//
#import "OWSOutgoingSyncMessage.h"
NS_ASSUME_NONNULL_BEGIN
+@class YapDatabaseReadTransaction;
+
@interface OWSSyncGroupsMessage : OWSOutgoingSyncMessage
-- (NSData *)buildPlainTextAttachmentData;
+- (NSData *)buildPlainTextAttachmentDataWithTransaction:(YapDatabaseReadTransaction *)transaction;
@end
diff --git a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncGroupsMessage.m b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncGroupsMessage.m
index 575f3d9eb..651a7edb7 100644
--- a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncGroupsMessage.m
+++ b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncGroupsMessage.m
@@ -40,7 +40,7 @@ NS_ASSUME_NONNULL_BEGIN
return syncMessageBuilder;
}
-- (NSData *)buildPlainTextAttachmentData
+- (NSData *)buildPlainTextAttachmentDataWithTransaction:(YapDatabaseReadTransaction *)transaction
{
// TODO use temp file stream to avoid loading everything into memory at once
// First though, we need to re-engineer our attachment process to accept streams (encrypting with stream,
@@ -49,14 +49,16 @@ NS_ASSUME_NONNULL_BEGIN
[dataOutputStream open];
OWSGroupsOutputStream *groupsOutputStream = [OWSGroupsOutputStream streamWithOutputStream:dataOutputStream];
- [TSGroupThread enumerateCollectionObjectsUsingBlock:^(id obj, BOOL *stop) {
- if (![obj isKindOfClass:[TSGroupThread class]]) {
- DDLogVerbose(@"Ignoring non group thread in thread collection: %@", obj);
- return;
- }
- TSGroupModel *group = ((TSGroupThread *)obj).groupModel;
- [groupsOutputStream writeGroup:group];
- }];
+ [TSGroupThread
+ enumerateCollectionObjectsWithTransaction:transaction
+ usingBlock:^(id obj, BOOL *stop) {
+ if (![obj isKindOfClass:[TSGroupThread class]]) {
+ DDLogVerbose(@"Ignoring non group thread in thread collection: %@", obj);
+ return;
+ }
+ TSGroupModel *group = ((TSGroupThread *)obj).groupModel;
+ [groupsOutputStream writeGroup:group];
+ }];
[groupsOutputStream flush];
[dataOutputStream close];
diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.m b/SignalServiceKit/src/Messages/OWSMessageManager.m
index 4b146b86b..5eb9e024b 100644
--- a/SignalServiceKit/src/Messages/OWSMessageManager.m
+++ b/SignalServiceKit/src/Messages/OWSMessageManager.m
@@ -615,8 +615,8 @@ NS_ASSUME_NONNULL_BEGIN
}];
} else if (syncMessage.request.type == OWSSignalServiceProtosSyncMessageRequestTypeGroups) {
OWSSyncGroupsMessage *syncGroupsMessage = [[OWSSyncGroupsMessage alloc] init];
- DataSource *dataSource =
- [DataSourceValue dataSourceWithSyncMessage:[syncGroupsMessage buildPlainTextAttachmentData]];
+ DataSource *dataSource = [DataSourceValue
+ dataSourceWithSyncMessage:[syncGroupsMessage buildPlainTextAttachmentDataWithTransaction:transaction]];
[self.messageSender sendTemporaryAttachmentData:dataSource
contentType:OWSMimeTypeApplicationOctetStream
inMessage:syncGroupsMessage
diff --git a/SignalServiceKit/src/Network/API/OWSUploadingService.m b/SignalServiceKit/src/Network/API/OWSUploadingService.m
index 97127bdb2..3cc067802 100644
--- a/SignalServiceKit/src/Network/API/OWSUploadingService.m
+++ b/SignalServiceKit/src/Network/API/OWSUploadingService.m
@@ -107,9 +107,7 @@ static const CGFloat kAttachmentUploadProgressTheta = 0.001f;
DDLogInfo(@"%@ Uploaded attachment: %p.", self.tag, attachmentStream);
attachmentStream.serverId = serverId;
attachmentStream.isUploaded = YES;
- [attachmentStream save];
-
- successHandlerWrapper();
+ [attachmentStream saveAsyncWithCompletionBlock:successHandlerWrapper];
}
failure:failureHandlerWrapper];
diff --git a/SignalServiceKit/src/Storage/TSYapDatabaseObject.h b/SignalServiceKit/src/Storage/TSYapDatabaseObject.h
index 07dbcc6f8..cb68f9496 100644
--- a/SignalServiceKit/src/Storage/TSYapDatabaseObject.h
+++ b/SignalServiceKit/src/Storage/TSYapDatabaseObject.h
@@ -81,10 +81,22 @@
+ (instancetype)fetchObjectWithUniqueID:(NSString *)uniqueID NS_SWIFT_NAME(fetch(uniqueId:));
/**
- * Saves the object with a new YapDatabaseConnection
+ * Saves the object with the shared readWrite connection.
+ *
+ * This method will block if another readWrite transaction is open.
*/
- (void)save;
+/**
+ * Saves the object with the shared readWrite connection - does not block.
+ *
+ * Be mindful that this method may clobber other changes persisted
+ * while waiting to open the readWrite transaction.
+ *
+ * @param completionBlock is called on the main thread
+ */
+- (void)saveAsyncWithCompletionBlock:(void (^_Nullable)(void))completionBlock;
+
/**
* Saves the object with the provided transaction
*
diff --git a/SignalServiceKit/src/Storage/TSYapDatabaseObject.m b/SignalServiceKit/src/Storage/TSYapDatabaseObject.m
index 032d55b48..ec392ccde 100644
--- a/SignalServiceKit/src/Storage/TSYapDatabaseObject.m
+++ b/SignalServiceKit/src/Storage/TSYapDatabaseObject.m
@@ -37,6 +37,14 @@
}];
}
+- (void)saveAsyncWithCompletionBlock:(void (^_Nullable)(void))completionBlock
+{
+ [[self dbReadWriteConnection] asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
+ [self saveWithTransaction:transaction];
+ }
+ completionBlock:completionBlock];
+}
+
- (void)touchWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
[transaction touchObjectForKey:self.uniqueId inCollection:[self.class collection]];