diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 7d6cefe54..970535553 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -366,8 +366,8 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; } id _Nullable dataSource = [DataSourcePath dataSourceWithURL:url]; - SignalAttachment *attachment = - [SignalAttachment attachmentWithDataSource:dataSource dataUTI:utiType filename:filename]; + [dataSource setSourceFilename:filename]; + SignalAttachment *attachment = [SignalAttachment attachmentWithDataSource:dataSource dataUTI:utiType]; if (!attachment) { DDLogError(@"Application opened with URL with invalid content: %@", url); [OWSAlerts showAlertWithTitle: diff --git a/Signal/src/Models/SignalAttachment.swift b/Signal/src/Models/SignalAttachment.swift index aa0c97bf3..4725781a5 100644 --- a/Signal/src/Models/SignalAttachment.swift +++ b/Signal/src/Models/SignalAttachment.swift @@ -71,17 +71,15 @@ class SignalAttachment: NSObject { public var dataUrl: URL? { return dataSource.dataUrl() } + public var sourceFilename: String? { + return dataSource.sourceFilename() + } // Attachment types are identified using UTIs. // // See: https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html let dataUTI: String - // An optional field that indicates the filename, if known, for this attachment. - // - // TODO: Try to eliminate this property. - let filename: String? - var error: SignalAttachmentError? { didSet { AssertIsOnMainThread() @@ -115,10 +113,9 @@ class SignalAttachment: NSObject { // This method should not be called directly; use the factory // methods instead. - internal required init(dataSource: DataSource, dataUTI: String, filename: String?) { + internal required init(dataSource: DataSource, dataUTI: String) { self.dataSource = dataSource self.dataUTI = dataUTI - self.filename = filename super.init() } @@ -165,7 +162,7 @@ class SignalAttachment: NSObject { return "audio/aac" } - if let filename = filename { + if let filename = sourceFilename { let fileExtension = (filename as NSString).pathExtension if fileExtension.characters.count > 0 { if let mimeType = MIMETypeUtil.mimeType(forFileExtension:fileExtension) { @@ -192,7 +189,7 @@ class SignalAttachment: NSObject { // Use the filename if known. If not, e.g. if the attachment was copy/pasted, we'll generate a filename // like: "signal-2017-04-24-095918.zip" var filenameOrDefault: String { - if let filename = filename { + if let filename = sourceFilename { return filename } else { let kDefaultAttachmentName = "signal" @@ -213,7 +210,7 @@ class SignalAttachment: NSObject { // Returns the file extension for this attachment or nil if no file extension // can be identified. var fileExtension: String? { - if let filename = filename { + if let filename = sourceFilename { let fileExtension = (filename as NSString).pathExtension if fileExtension.characters.count > 0 { return fileExtension @@ -378,7 +375,7 @@ class SignalAttachment: NSObject { return nil } let dataSource = DataSourceValue.dataSource(with:data, utiType: dataUTI) - return imageAttachment(dataSource : dataSource, dataUTI : dataUTI, filename: nil) + return imageAttachment(dataSource : dataSource, dataUTI : dataUTI) } } for dataUTI in videoUTISet { @@ -388,7 +385,7 @@ class SignalAttachment: NSObject { return nil } let dataSource = DataSourceValue.dataSource(with:data, utiType: dataUTI) - return videoAttachment(dataSource : dataSource, dataUTI : dataUTI, filename: nil) + return videoAttachment(dataSource : dataSource, dataUTI : dataUTI) } } for dataUTI in audioUTISet { @@ -398,7 +395,7 @@ class SignalAttachment: NSObject { return nil } let dataSource = DataSourceValue.dataSource(with:data, utiType: dataUTI) - return audioAttachment(dataSource : dataSource, dataUTI : dataUTI, filename: nil) + return audioAttachment(dataSource : dataSource, dataUTI : dataUTI) } } @@ -408,7 +405,7 @@ class SignalAttachment: NSObject { return nil } let dataSource = DataSourceValue.dataSource(with:data, utiType: dataUTI) - return genericAttachment(dataSource : dataSource, dataUTI : dataUTI, filename: nil) + return genericAttachment(dataSource : dataSource, dataUTI : dataUTI) } // This method should only be called for dataUTIs that @@ -436,17 +433,17 @@ class SignalAttachment: NSObject { // // NOTE: The attachment returned by this method may not be valid. // Check the attachment's error property. - private class func imageAttachment(dataSource: DataSource?, dataUTI: String, filename: String?) -> SignalAttachment { + private class func imageAttachment(dataSource: DataSource?, dataUTI: String) -> SignalAttachment { assert(dataUTI.characters.count > 0) assert(dataSource != nil) guard let dataSource = dataSource else { - let attachment = SignalAttachment(dataSource : DataSourceValue.emptyDataSource(), dataUTI: dataUTI, filename: filename) + let attachment = SignalAttachment(dataSource : DataSourceValue.emptyDataSource(), dataUTI: dataUTI) attachment.error = .missingData return attachment } - let attachment = SignalAttachment(dataSource : dataSource, dataUTI: dataUTI, filename: filename) + let attachment = SignalAttachment(dataSource : dataSource, dataUTI: dataUTI) guard inputImageUTISet.contains(dataUTI) else { attachment.error = .invalidFileFormat @@ -480,7 +477,7 @@ class SignalAttachment: NSObject { } Logger.verbose("\(TAG) Compressing attachment as image/jpeg") - return compressImageAsJPEG(image : image, attachment : attachment, filename:filename) + return compressImageAsJPEG(image : image, attachment : attachment, filename:dataSource.sourceFilename()) } } @@ -520,13 +517,17 @@ class SignalAttachment: NSObject { assert(dataUTI.characters.count > 0) guard let image = image else { - let attachment = SignalAttachment(dataSource : DataSourceValue.emptyDataSource(), dataUTI: dataUTI, filename: filename) + let dataSource = DataSourceValue.emptyDataSource() + dataSource.setSourceFilename(filename) + let attachment = SignalAttachment(dataSource:dataSource, dataUTI: dataUTI) attachment.error = .missingData return attachment } // Make a placeholder attachment on which to hang errors if necessary. - let attachment = SignalAttachment(dataSource : DataSourceValue.emptyDataSource(), dataUTI: dataUTI, filename: filename) + let dataSource = DataSourceValue.emptyDataSource() + dataSource.setSourceFilename(filename) + let attachment = SignalAttachment(dataSource : dataSource, dataUTI: dataUTI) attachment.image = image Logger.verbose("\(TAG) Writing \(attachment.mimeType) as image/jpeg") @@ -555,9 +556,10 @@ class SignalAttachment: NSObject { attachment.error = .couldNotConvertToJpeg return attachment } + dataSource.setSourceFilename(filename) if UInt(jpgImageData.count) <= kMaxFileSizeImage { - let recompressedAttachment = SignalAttachment(dataSource : dataSource, dataUTI: kUTTypeJPEG as String, filename: filename) + let recompressedAttachment = SignalAttachment(dataSource : dataSource, dataUTI: kUTTypeJPEG as String) recompressedAttachment.image = dstImage return recompressedAttachment } @@ -627,12 +629,11 @@ class SignalAttachment: NSObject { // // NOTE: The attachment returned by this method may not be valid. // Check the attachment's error property. - private class func videoAttachment(dataSource: DataSource?, dataUTI: String, filename: String?) -> SignalAttachment { + private class func videoAttachment(dataSource: DataSource?, dataUTI: String) -> SignalAttachment { return newAttachment(dataSource : dataSource, dataUTI : dataUTI, validUTISet : videoUTISet, - maxFileSize : kMaxFileSizeVideo, - filename : filename) + maxFileSize : kMaxFileSizeVideo) } // MARK: Audio Attachments @@ -641,12 +642,11 @@ class SignalAttachment: NSObject { // // NOTE: The attachment returned by this method may not be valid. // Check the attachment's error property. - private class func audioAttachment(dataSource: DataSource?, dataUTI: String, filename: String?) -> SignalAttachment { + private class func audioAttachment(dataSource: DataSource?, dataUTI: String) -> SignalAttachment { return newAttachment(dataSource : dataSource, dataUTI : dataUTI, validUTISet : audioUTISet, - maxFileSize : kMaxFileSizeAudio, - filename : filename) + maxFileSize : kMaxFileSizeAudio) } // MARK: Oversize Text Attachments @@ -660,8 +660,7 @@ class SignalAttachment: NSObject { return newAttachment(dataSource : dataSource, dataUTI : kOversizeTextAttachmentUTI, validUTISet : nil, - maxFileSize : kMaxFileSizeGeneric, - filename : nil) + maxFileSize : kMaxFileSizeGeneric) } // MARK: Generic Attachments @@ -670,18 +669,17 @@ class SignalAttachment: NSObject { // // NOTE: The attachment returned by this method may not be valid. // Check the attachment's error property. - private class func genericAttachment(dataSource: DataSource?, dataUTI: String, filename: String?) -> SignalAttachment { + private class func genericAttachment(dataSource: DataSource?, dataUTI: String) -> SignalAttachment { return newAttachment(dataSource : dataSource, dataUTI : dataUTI, validUTISet : nil, - maxFileSize : kMaxFileSizeGeneric, - filename : filename) + maxFileSize : kMaxFileSizeGeneric) } // MARK: Voice Messages - public class func voiceMessageAttachment(dataSource: DataSource?, dataUTI: String, filename: String?) -> SignalAttachment { - let attachment = audioAttachment(dataSource : dataSource, dataUTI : dataUTI, filename: filename) + public class func voiceMessageAttachment(dataSource: DataSource?, dataUTI: String) -> SignalAttachment { + let attachment = audioAttachment(dataSource : dataSource, dataUTI : dataUTI) attachment.isVoiceMessage = true return attachment } @@ -692,22 +690,21 @@ class SignalAttachment: NSObject { // // NOTE: The attachment returned by this method may not be valid. // Check the attachment's error property. - public class func attachment(dataSource: DataSource?, dataUTI: String, filename: String?) -> SignalAttachment { + public class func attachment(dataSource: DataSource?, dataUTI: String) -> SignalAttachment { if inputImageUTISet.contains(dataUTI) { - return imageAttachment(dataSource : dataSource, dataUTI : dataUTI, filename: filename) + return imageAttachment(dataSource : dataSource, dataUTI : dataUTI) } else if videoUTISet.contains(dataUTI) { - return videoAttachment(dataSource : dataSource, dataUTI : dataUTI, filename: filename) + return videoAttachment(dataSource : dataSource, dataUTI : dataUTI) } else if audioUTISet.contains(dataUTI) { - return audioAttachment(dataSource : dataSource, dataUTI : dataUTI, filename: filename) + return audioAttachment(dataSource : dataSource, dataUTI : dataUTI) } else { - return genericAttachment(dataSource : dataSource, dataUTI : dataUTI, filename: filename) + return genericAttachment(dataSource : dataSource, dataUTI : dataUTI) } } public class func empty() -> SignalAttachment { return SignalAttachment.attachment(dataSource : DataSourceValue.emptyDataSource(), - dataUTI: kUTTypeContent as String, - filename:nil) + dataUTI: kUTTypeContent as String) } // MARK: Helper Methods @@ -715,18 +712,17 @@ class SignalAttachment: NSObject { private class func newAttachment(dataSource: DataSource?, dataUTI: String, validUTISet: Set?, - maxFileSize: UInt, - filename: String?) -> SignalAttachment { + maxFileSize: UInt) -> SignalAttachment { assert(dataUTI.characters.count > 0) assert(dataSource != nil) guard let dataSource = dataSource else { - let attachment = SignalAttachment(dataSource : DataSourceValue.emptyDataSource(), dataUTI: dataUTI, filename: filename) + let attachment = SignalAttachment(dataSource : DataSourceValue.emptyDataSource(), dataUTI: dataUTI) attachment.error = .missingData return attachment } - let attachment = SignalAttachment(dataSource : dataSource, dataUTI: dataUTI, filename: filename) + let attachment = SignalAttachment(dataSource : dataSource, dataUTI: dataUTI) if let validUTISet = validUTISet { guard validUTISet.contains(dataUTI) else { diff --git a/Signal/src/ViewControllers/AttachmentApprovalViewController.swift b/Signal/src/ViewControllers/AttachmentApprovalViewController.swift index cc30c846f..b98b7d8cd 100644 --- a/Signal/src/ViewControllers/AttachmentApprovalViewController.swift +++ b/Signal/src/ViewControllers/AttachmentApprovalViewController.swift @@ -283,10 +283,10 @@ class AttachmentApprovalViewController: OWSViewController, OWSAudioAttachmentPla } private func formattedFileName() -> String? { - guard let rawFilename = attachment.filename else { + guard let sourceFilename = attachment.sourceFilename else { return nil } - let filename = rawFilename.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) + let filename = sourceFilename.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) guard filename.characters.count > 0 else { return nil } diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m index fa58c0bf4..43c751e8a 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController.m @@ -1675,7 +1675,7 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) { if ([text lengthOfBytesUsingEncoding:NSUTF8StringEncoding] >= kOversizeTextMessageSizeThreshold) { id _Nullable dataSource = [DataSourceValue dataSourceWithOversizeText:text]; SignalAttachment *attachment = - [SignalAttachment attachmentWithDataSource:dataSource dataUTI:kOversizeTextAttachmentUTI filename:nil]; + [SignalAttachment attachmentWithDataSource:dataSource dataUTI:kOversizeTextAttachmentUTI]; message = [ThreadUtil sendMessageWithAttachment:attachment inThread:self.thread messageSender:self.messageSender]; } else { @@ -3207,8 +3207,8 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) { OWSAssert(type); OWSAssert(filename); id _Nullable dataSource = [DataSourcePath dataSourceWithURL:url]; - SignalAttachment *attachment = - [SignalAttachment attachmentWithDataSource:dataSource dataUTI:type filename:filename]; + [dataSource setSourceFilename:filename]; + SignalAttachment *attachment = [SignalAttachment attachmentWithDataSource:dataSource dataUTI:type]; [self tryToSendAttachmentIfApproved:attachment]; } @@ -3226,13 +3226,17 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) { picker.mediaTypes = @[ (__bridge NSString *)kUTTypeImage, (__bridge NSString *)kUTTypeMovie ]; picker.allowsEditing = NO; picker.delegate = self; + dispatch_async(dispatch_get_main_queue(), ^{ [self presentViewController:picker animated:YES completion:[UIUtil modalCompletionBlock]]; }); }]; } + - (void)chooseFromLibrary { + OWSAssert([NSThread isMainThread]); + if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) { DDLogError(@"PhotoLibrary ImagePicker source not available"); return; @@ -3242,9 +3246,8 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) { picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; picker.delegate = self; picker.mediaTypes = @[ (__bridge NSString *)kUTTypeImage, (__bridge NSString *)kUTTypeMovie ]; - dispatch_async(dispatch_get_main_queue(), ^{ - [self presentViewController:picker animated:YES completion:[UIUtil modalCompletionBlock]]; - }); + + [self presentViewController:picker animated:YES completion:[UIUtil modalCompletionBlock]]; } /* @@ -3376,8 +3379,9 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) { id _Nullable dataSource = [DataSourceValue dataSourceWithData:imageData utiType:dataUTI]; + [dataSource setSourceFilename:filename]; SignalAttachment *attachment = - [SignalAttachment attachmentWithDataSource:dataSource dataUTI:dataUTI filename:filename]; + [SignalAttachment attachmentWithDataSource:dataSource dataUTI:dataUTI]; [self dismissViewControllerAnimated:YES completion:^{ OWSAssert([NSThread isMainThread]); @@ -3424,8 +3428,6 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) { - (NSURL *)videoTempFolder { NSString *temporaryDirectory = NSTemporaryDirectory(); - // NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); - // NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil; NSString *videoDirPath = [temporaryDirectory stringByAppendingPathComponent:@"videos"]; if (![[NSFileManager defaultManager] fileExistsAtPath:videoDirPath]) { [[NSFileManager defaultManager] createDirectoryAtPath:videoDirPath @@ -3436,10 +3438,24 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) { return [NSURL fileURLWithPath:videoDirPath]; } +- (NSUInteger)sizeOfFileURL:(NSURL *)movieURL +{ + NSError *error; + NSDictionary *_Nullable attributes = + [[NSFileManager defaultManager] attributesOfItemAtPath:movieURL.path error:&error]; + OWSAssert(attributes); + OWSAssert(!error); + uint64_t fileSize = [attributes fileSize]; + return (NSUInteger)fileSize; +} + - (void)sendQualityAdjustedAttachmentForVideo:(NSURL *)movieURL filename:(NSString *)filename skipApprovalDialog:(BOOL)skipApprovalDialog { + OWSAssert([NSThread isMainThread]); + + DDLogError(@"movieURL: %@ %zd", movieURL, [self sizeOfFileURL:movieURL]); AVAsset *video = [AVAsset assetWithURL:movieURL]; AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:video presetName:AVAssetExportPresetMediumQuality]; @@ -3449,11 +3465,12 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) { URLByAppendingPathComponent:[[[NSUUID UUID] UUIDString] stringByAppendingPathExtension:@"mp4"]]; exportSession.outputURL = compressedVideoUrl; [exportSession exportAsynchronouslyWithCompletionHandler:^{ + DDLogError(@"compressedVideoUrl: %@ %zd", compressedVideoUrl, [self sizeOfFileURL:compressedVideoUrl]); dispatch_async(dispatch_get_main_queue(), ^{ id _Nullable dataSource = [DataSourcePath dataSourceWithURL:compressedVideoUrl]; - SignalAttachment *attachment = [SignalAttachment attachmentWithDataSource:dataSource - dataUTI:(NSString *)kUTTypeMPEG4 - filename:filename]; + [dataSource setSourceFilename:filename]; + SignalAttachment *attachment = + [SignalAttachment attachmentWithDataSource:dataSource dataUTI:(NSString *)kUTTypeMPEG4]; if (!attachment || [attachment hasError]) { DDLogError(@"%@ %s Invalid attachment: %@.", self.tag, @@ -3832,10 +3849,9 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) { NSString *filename = [NSLocalizedString(@"VOICE_MESSAGE_FILE_NAME", @"Filename for voice messages.") stringByAppendingPathExtension:@"m4a"]; - - SignalAttachment *attachment = [SignalAttachment voiceMessageAttachmentWithDataSource:dataSource - dataUTI:(NSString *)kUTTypeMPEG4Audio - filename:filename]; + [dataSource setSourceFilename:filename]; + SignalAttachment *attachment = + [SignalAttachment voiceMessageAttachmentWithDataSource:dataSource dataUTI:(NSString *)kUTTypeMPEG4Audio]; if (!attachment || [attachment hasError]) { DDLogWarn(@"%@ %s Invalid attachment: %@.", self.tag, diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m index 2f6ba4b91..ae0bd36ee 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m @@ -328,11 +328,11 @@ NS_ASSUME_NONNULL_BEGIN NSString *filename = [filePath lastPathComponent]; NSString *utiType = [MIMETypeUtil utiTypeForFileExtension:filename.pathExtension]; id _Nullable dataSource = [DataSourcePath dataSourceWithFilePath:filePath]; - SignalAttachment *attachment = - [SignalAttachment attachmentWithDataSource:dataSource dataUTI:utiType filename:filename]; + [dataSource setSourceFilename:filename]; + SignalAttachment *attachment = [SignalAttachment attachmentWithDataSource:dataSource dataUTI:utiType]; OWSAssert(attachment); if ([attachment hasError]) { - DDLogError(@"attachment[%@]: %@", [attachment filename], [attachment errorName]); + DDLogError(@"attachment[%@]: %@", [attachment sourceFilename], [attachment errorName]); [DDLog flushLog]; } OWSAssert(![attachment hasError]); @@ -589,7 +589,7 @@ NS_ASSUME_NONNULL_BEGIN id _Nullable dataSource = [DataSourceValue dataSourceWithOversizeText:message]; SignalAttachment *attachment = - [SignalAttachment attachmentWithDataSource:dataSource dataUTI:kOversizeTextAttachmentUTI filename:nil]; + [SignalAttachment attachmentWithDataSource:dataSource dataUTI:kOversizeTextAttachmentUTI]; [ThreadUtil sendMessageWithAttachment:attachment inThread:thread messageSender:messageSender]; } @@ -615,7 +615,7 @@ NS_ASSUME_NONNULL_BEGIN OWSMessageSender *messageSender = [Environment getCurrent].messageSender; id _Nullable dataSource = [DataSourceValue dataSourceWithData:[self createRandomNSDataOfSize:length] utiType:uti]; - SignalAttachment *attachment = [SignalAttachment attachmentWithDataSource:dataSource dataUTI:uti filename:nil]; + SignalAttachment *attachment = [SignalAttachment attachmentWithDataSource:dataSource dataUTI:uti]; [ThreadUtil sendMessageWithAttachment:attachment inThread:thread messageSender:messageSender ignoreErrors:YES]; } + (OWSSignalServiceProtosEnvelope *)createEnvelopeForThread:(TSThread *)thread diff --git a/Signal/src/ViewControllers/SendExternalFileViewController.m b/Signal/src/ViewControllers/SendExternalFileViewController.m index 393adb455..b4dbcd4b3 100644 --- a/Signal/src/ViewControllers/SendExternalFileViewController.m +++ b/Signal/src/ViewControllers/SendExternalFileViewController.m @@ -141,8 +141,9 @@ NS_ASSUME_NONNULL_BEGIN // // TODO: If we reuse this VC, for example to offer a "forward attachment to other thread", // feature, this assumption would no longer apply. - OWSAssert(self.attachment) NSString *filename = - [self.attachment.filename stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + OWSAssert(self.attachment); + NSString *filename = + [self.attachment.sourceFilename stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; OWSAssert(filename.length > 0); const NSUInteger kMaxFilenameLength = 20; if (filename.length > kMaxFilenameLength) { diff --git a/SignalServiceKit/src/Util/DataSource.h b/SignalServiceKit/src/Util/DataSource.h index fca39c480..f79899edb 100755 --- a/SignalServiceKit/src/Util/DataSource.h +++ b/SignalServiceKit/src/Util/DataSource.h @@ -45,6 +45,9 @@ NS_ASSUME_NONNULL_BEGIN // Returns YES on success. - (BOOL)writeToPath:(NSString *)dstFilePath; +- (nullable NSString *)sourceFilename; +- (void)setSourceFilename:(NSString *_Nullable)sourceFilename; + @end #pragma mark - diff --git a/SignalServiceKit/src/Util/DataSource.m b/SignalServiceKit/src/Util/DataSource.m index bda0dfc1e..9ae66528a 100755 --- a/SignalServiceKit/src/Util/DataSource.m +++ b/SignalServiceKit/src/Util/DataSource.m @@ -16,6 +16,8 @@ NS_ASSUME_NONNULL_BEGIN // This property is lazy-populated. @property (nonatomic) NSString *cachedFilePath; +@property (nonatomic, nullable) NSString *sourceFilename; + @end #pragma mark - @@ -153,6 +155,8 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic) NSData *cachedData; @property (nonatomic) NSNumber *cachedDataLength; +@property (nonatomic, nullable) NSString *sourceFilename; + @end #pragma mark -