Register Signal to handle a wide variety of common document types.

// FREEBIE
This commit is contained in:
Matthew Chen 2017-04-24 22:30:46 -04:00
parent 54c1a38d50
commit 3c7574a908
6 changed files with 201 additions and 16 deletions

View File

@ -116,5 +116,153 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>Signal File</string>
<key>CFBundleTypeIconFiles</key>
<array>
<string>Icon</string>
<string>Icon@2x</string>
<string>Icon@3x</string>
</array>
<key>LSItemContentTypes</key>
<array>
<string>public.item</string>
<string>public.content</string>
<string>public.composite-content</string>
<string>public.message</string>
<string>public.contact</string>
<string>public.archive</string>
<string>public.disk-image</string>
<string>public.data</string>
<string>public.directory</string>
<string>com.apple.resolvable</string>
<string>public.symlink</string>
<string>public.executable</string>
<string>com.apple.mount-point</string>
<string>com.apple.alias-file</string>
<string>com.apple.alias-record</string>
<string>com.apple.bookmark</string>
<string>public.url</string>
<string>public.file-url</string>
<string>public.text</string>
<string>public.plain-text</string>
<string>public.utf8-plain-text</string>
<string>public.utf16-external-plain-text</string>
<string>public.utf16-plain-text</string>
<string>public.delimited-values-text</string>
<string>public.comma-separated-values-text</string>
<string>public.tab-separated-values-text</string>
<string>public.utf8-tab-separated-values-text</string>
<string>public.rtf</string>
<string>public.html</string>
<string>public.xml</string>
<string>public.source-code</string>
<string>public.assembly-source</string>
<string>public.c-source</string>
<string>public.objective-c-source</string>
<string>public.swift-source</string>
<string>public.c-plus-plus-source</string>
<string>public.objective-c-plus-plus-source</string>
<string>public.c-header</string>
<string>public.c-plus-plus-header</string>
<string>com.sun.java-source</string>
<string>public.script</string>
<string>com.apple.applescript.text</string>
<string>com.apple.applescript.script</string>
<string>com.apple.applescript.script-bundle</string>
<string>com.netscape.javascript-source</string>
<string>public.shell-script</string>
<string>public.perl-script</string>
<string>public.python-script</string>
<string>public.ruby-script</string>
<string>public.php-script</string>
<string>public.json</string>
<string>com.apple.property-list</string>
<string>com.apple.xml-property-list</string>
<string>com.apple.binary-property-list</string>
<string>com.adobe.pdf</string>
<string>com.apple.rtfd</string>
<string>com.apple.flat-rtfd</string>
<string>com.apple.txn.text-multimedia-data</string>
<string>com.apple.webarchive</string>
<string>public.image</string>
<string>public.jpeg</string>
<string>public.jpeg-2000</string>
<string>public.tiff</string>
<string>com.apple.pict</string>
<string>com.compuserve.gif</string>
<string>public.png</string>
<string>com.apple.quicktime-image</string>
<string>com.apple.icns</string>
<string>com.microsoft.bmp</string>
<string>com.microsoft.ico</string>
<string>public.camera-raw-image</string>
<string>public.svg-image</string>
<string>com.apple.live-photo</string>
<string>public.audiovisual-content</string>
<string>public.movie</string>
<string>public.video</string>
<string>public.audio</string>
<string>com.apple.quicktime-movie</string>
<string>public.mpeg</string>
<string>public.mpeg-2-video</string>
<string>public.mpeg-2-transport-stream</string>
<string>public.mp3</string>
<string>public.mpeg-4</string>
<string>public.mpeg-4-audio</string>
<string>com.apple.protected-mpeg-4-audio</string>
<string>com.apple.protected-mpeg-4-video</string>
<string>public.avi</string>
<string>public.aiff-audio</string>
<string>com.microsoft.waveform-audio</string>
<string>public.midi-audio</string>
<string>public.playlist</string>
<string>public.m3u-playlist</string>
<string>public.folder</string>
<string>public.volume</string>
<string>com.apple.package</string>
<string>com.apple.bundle</string>
<string>com.apple.plugin</string>
<string>com.apple.metadata-importer</string>
<string>com.apple.quicklook-generator</string>
<string>com.apple.xpc-service</string>
<string>com.apple.framework</string>
<string>com.apple.application</string>
<string>com.apple.application-bundle</string>
<string>com.apple.application-file</string>
<string>public.unix-executable</string>
<string>com.microsoft.windows-executable</string>
<string>com.sun.java-class</string>
<string>com.sun.java-archive</string>
<string>com.apple.systempreference.prefpane</string>
<string>org.gnu.gnu-zip-archive</string>
<string>public.bzip2-archive</string>
<string>public.zip-archive</string>
<string>public.spreadsheet</string>
<string>public.presentation</string>
<string>public.database</string>
<string>public.vcard</string>
<string>public.to-do-item</string>
<string>public.calendar-event</string>
<string>public.email-message</string>
<string>com.apple.internet-location</string>
<string>com.apple.ink.inktext</string>
<string>public.font</string>
<string>public.bookmark</string>
<string>public.3d-content</string>
<string>com.rsa.pkcs-12</string>
<string>public.x509-certificate</string>
<string>org.idpf.epub-container</string>
<string>public.log</string>
<string>com.adobe.pdf</string>
<string>public.pdf</string>
</array>
<key>LSHandlerRank</key>
<string>Alternate</string>
</dict>
</array>
</dict>
</plist>

View File

@ -263,6 +263,38 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
} else {
DDLogWarn(@"Application opened with an unknown URL action: %@", url.host);
}
} else if ([url.scheme.lowercaseString isEqualToString:@"file"]) {
NSString *filename = url.lastPathComponent;
if ([filename stringByDeletingPathExtension].length < 1) {
DDLogError(@"Application opened with URL invalid filename: %@", url);
return NO;
}
NSString *fileExtension = [filename pathExtension];
if (fileExtension.length < 1) {
DDLogError(@"Application opened with URL missing file extension: %@", url);
return NO;
}
NSString *utiType = [MIMETypeUtil utiTypeForFileExtension:fileExtension];
if (utiType.length < 1) {
DDLogError(@"Application opened with URL of unknown UTI type: %@", url);
return NO;
}
NSData *data = [NSData dataWithContentsOfURL:url];
if (!data) {
DDLogError(@"Application opened with URL with unloadable content: %@", url);
return NO;
}
SignalAttachment *attachment = [SignalAttachment attachmentWithData:data dataUTI:utiType filename:filename];
if (!attachment) {
DDLogError(@"Application opened with URL with invalid content: %@", url);
return NO;
}
if ([attachment hasError]) {
DDLogError(@"Application opened with URL with content error: %@ %@", url, [attachment errorName]);
return NO;
}
DDLogInfo(@"Application opened with URL: %@", url);
return YES;
} else {
DDLogWarn(@"Application opened with an unknown URL scheme: %@", url.scheme);
}

View File

@ -26,9 +26,9 @@ class AttachmentApprovalViewController: UIViewController, OWSAudioAttachmentPlay
@available(*, unavailable, message:"use attachment: constructor instead.")
required init?(coder aDecoder: NSCoder) {
self.attachment = SignalAttachment.genericAttachment(data: nil,
dataUTI: kUTTypeContent as String,
filename:nil)
self.attachment = SignalAttachment.attachment(data: nil,
dataUTI: kUTTypeContent as String,
filename:nil)
super.init(coder: aDecoder)
assertionFailure()
}

View File

@ -139,8 +139,10 @@ NS_ASSUME_NONNULL_BEGIN
for (int i=0; i < 32; i++) {
[message appendString:@"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse rutrum, nulla vitae pretium hendrerit, tellus turpis pharetra libero, vitae sodales tortor ante vel sem. Fusce sed nisl a lorem gravida tincidunt. Suspendisse efficitur non quam ac sodales. Aenean ut velit maximus, posuere sem a, accumsan nunc. Donec ullamcorper turpis lorem. Quisque dignissim purus eu placerat ultricies. Proin at urna eget mi semper congue. Aenean non elementum ex. Praesent pharetra quam at sem vestibulum, vestibulum ornare dolor elementum. Vestibulum massa tortor, scelerisque sit amet pulvinar a, rhoncus vitae nisl. Sed mi nunc, tempus at varius in, malesuada vitae dui. Vivamus efficitur pulvinar erat vitae congue. Proin vehicula turpis non felis congue facilisis. Nullam aliquet dapibus ligula ac mollis. Etiam sit amet posuere lorem, in rhoncus nisi."];
}
SignalAttachment *attachment = [SignalAttachment oversizeTextAttachmentWithText:message];
SignalAttachment *attachment = [SignalAttachment attachmentWithData:[message dataUsingEncoding:NSUTF8StringEncoding]
dataUTI:SignalAttachment.kOversizeTextAttachmentUTI
filename:nil];
[ThreadUtil sendMessageWithAttachment:attachment
inThread:thread
messageSender:messageSender];
@ -163,7 +165,7 @@ NS_ASSUME_NONNULL_BEGIN
uti:(NSString *)uti {
OWSMessageSender *messageSender = [Environment getCurrent].messageSender;
SignalAttachment *attachment =
[SignalAttachment genericAttachmentWithData:[self createRandomNSDataOfSize:256] dataUTI:uti filename:nil];
[SignalAttachment attachmentWithData:[self createRandomNSDataOfSize:256] dataUTI:uti filename:nil];
[ThreadUtil sendMessageWithAttachment:attachment
inThread:thread
messageSender:messageSender];

View File

@ -1168,7 +1168,10 @@ typedef enum : NSUInteger {
// which are presented as normal text messages.
const NSUInteger kOversizeTextMessageSizeThreshold = 16 * 1024;
if ([text lengthOfBytesUsingEncoding:NSUTF8StringEncoding] >= kOversizeTextMessageSizeThreshold) {
SignalAttachment *attachment = [SignalAttachment oversizeTextAttachmentWithText:text];
SignalAttachment *attachment =
[SignalAttachment attachmentWithData:[text dataUsingEncoding:NSUTF8StringEncoding]
dataUTI:SignalAttachment.kOversizeTextAttachmentUTI
filename:nil];
[ThreadUtil sendMessageWithAttachment:attachment inThread:self.thread messageSender:self.messageSender];
} else {
[ThreadUtil sendMessageWithText:text inThread:self.thread messageSender:self.messageSender];
@ -2423,7 +2426,7 @@ typedef enum : NSUInteger {
OWSAssert([NSThread isMainThread]);
SignalAttachment *attachment =
[SignalAttachment imageAttachmentWithData:imageData dataUTI:dataUTI filename:filename];
[SignalAttachment attachmentWithData:imageData dataUTI:dataUTI filename:filename];
[self dismissViewControllerAnimated:YES
completion:^{
OWSAssert([NSThread isMainThread]);
@ -2488,7 +2491,7 @@ typedef enum : NSUInteger {
NSData *videoData = [NSData dataWithContentsOfURL:compressedVideoUrl];
dispatch_async(dispatch_get_main_queue(), ^{
SignalAttachment *attachment =
[SignalAttachment videoAttachmentWithData:videoData dataUTI:(NSString *)kUTTypeMPEG4 filename:filename];
[SignalAttachment attachmentWithData:videoData dataUTI:(NSString *)kUTTypeMPEG4 filename:filename];
if (!attachment || [attachment hasError]) {
DDLogWarn(@"%@ %s Invalid attachment: %@.",
self.tag,
@ -2715,7 +2718,7 @@ typedef enum : NSUInteger {
if (flag) {
NSData *audioData = [NSData dataWithContentsOfURL:recorder.url];
SignalAttachment *attachment =
[SignalAttachment audioAttachmentWithData:audioData dataUTI:(NSString *)kUTTypeMPEG4Audio filename:nil];
[SignalAttachment attachmentWithData:audioData dataUTI:(NSString *)kUTTypeMPEG4Audio filename:nil];
if (!attachment ||
[attachment hasError]) {
DDLogWarn(@"%@ %s Invalid attachment: %@.",

View File

@ -353,7 +353,7 @@ class SignalAttachment: NSObject {
//
// NOTE: The attachment returned by this method may not be valid.
// Check the attachment's error property.
public class func imageAttachment(data imageData: Data?, dataUTI: String, filename: String?) -> SignalAttachment {
private class func imageAttachment(data imageData: Data?, dataUTI: String, filename: String?) -> SignalAttachment {
assert(dataUTI.characters.count > 0)
assert(imageData != nil)
@ -539,7 +539,7 @@ class SignalAttachment: NSObject {
//
// NOTE: The attachment returned by this method may not be valid.
// Check the attachment's error property.
public class func videoAttachment(data: Data?, dataUTI: String, filename: String?) -> SignalAttachment {
private class func videoAttachment(data: Data?, dataUTI: String, filename: String?) -> SignalAttachment {
return newAttachment(data : data,
dataUTI : dataUTI,
validUTISet : videoUTISet,
@ -553,7 +553,7 @@ class SignalAttachment: NSObject {
//
// NOTE: The attachment returned by this method may not be valid.
// Check the attachment's error property.
public class func audioAttachment(data: Data?, dataUTI: String, filename: String?) -> SignalAttachment {
private class func audioAttachment(data: Data?, dataUTI: String, filename: String?) -> SignalAttachment {
return newAttachment(data : data,
dataUTI : dataUTI,
validUTISet : audioUTISet,
@ -567,12 +567,12 @@ class SignalAttachment: NSObject {
//
// NOTE: The attachment returned by this method may not be valid.
// Check the attachment's error property.
public class func oversizeTextAttachment(text: String?) -> SignalAttachment {
private class func oversizeTextAttachment(text: String?) -> SignalAttachment {
return newAttachment(data : text?.data(using: .utf8),
dataUTI : kOversizeTextAttachmentUTI,
validUTISet : nil,
maxFileSize : kMaxFileSizeGeneric,
filename : nil)
filename : nil)
}
// MARK: Generic Attachments
@ -581,7 +581,7 @@ class SignalAttachment: NSObject {
//
// NOTE: The attachment returned by this method may not be valid.
// Check the attachment's error property.
public class func genericAttachment(data: Data?, dataUTI: String, filename: String?) -> SignalAttachment {
private class func genericAttachment(data: Data?, dataUTI: String, filename: String?) -> SignalAttachment {
return newAttachment(data : data,
dataUTI : dataUTI,
validUTISet : nil,