Switch from deprecated UTI functions to UTType

This commit is contained in:
Adam Sharp 2024-07-03 18:13:05 -04:00
parent 96a2890d21
commit c2fd39a95c
No known key found for this signature in database
15 changed files with 92 additions and 85 deletions

View File

@ -7,6 +7,7 @@ import CoreServices
import Photos
import SignalServiceKit
import SignalUI
import UniformTypeIdentifiers
extension ConversationViewController: ConversationInputToolbarDelegate {
@ -729,19 +730,17 @@ extension ConversationViewController: UIDocumentPickerDelegate {
public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
Logger.debug("Picked document at url: \(url)")
let typeIdentifier: String = {
let contentType: UTType = {
do {
let resourceValues = try url.resourceValues(forKeys: Set([
.typeIdentifierKey
]))
guard let typeIdentifier = resourceValues.typeIdentifier else {
owsFailDebug("Missing typeIdentifier.")
return kUTTypeData as String
let resourceValues = try url.resourceValues(forKeys: [.contentTypeKey])
guard let contentType = resourceValues.contentType else {
owsFailDebug("Missing contentType.")
return .data
}
return typeIdentifier
return contentType
} catch {
owsFailDebug("Error: \(error)")
return kUTTypeData as String
return .data
}
}()
let isDirectory: Bool = {
@ -802,12 +801,12 @@ extension ConversationViewController: UIDocumentPickerDelegate {
// Although we want to be able to send higher quality attachments through the document picker
// it's more important that we ensure the sent format is one all clients can accept (e.g. *not* quicktime .mov)
if SignalAttachment.isVideoThatNeedsCompression(dataSource: dataSource,
dataUTI: typeIdentifier) {
dataUTI: contentType.identifier) {
self.showApprovalDialogAfterProcessingVideoURL(url, filename: filename)
return
}
let attachment = SignalAttachment.attachment(dataSource: dataSource, dataUTI: typeIdentifier)
let attachment = SignalAttachment.attachment(dataSource: dataSource, dataUTI: contentType.identifier)
showApprovalDialog(forAttachment: attachment)
}
@ -831,7 +830,7 @@ extension ConversationViewController: UIDocumentPickerDelegate {
dataSource.sourceFilename = filename
let promise = Promise.wrapAsync({
return try await SignalAttachment.compressVideoAsMp4(dataSource: dataSource,
dataUTI: kUTTypeMPEG4 as String)
dataUTI: UTType.mpeg4Movie.identifier)
})
promise.done(on: DispatchQueue.main) { (attachment: SignalAttachment) in
if modalActivityIndicator.wasCancelled {

View File

@ -6,6 +6,7 @@
import CoreServices
import Foundation
import SignalServiceKit
import UniformTypeIdentifiers
protocol VoiceMessageSendableDraft {
func prepareForSending() throws -> URL
@ -27,7 +28,7 @@ extension VoiceMessageSendableDraft {
let dataSource = try DataSourcePath.dataSource(with: attachmentUrl, shouldDeleteOnDeallocation: true)
dataSource.sourceFilename = userVisibleFilename(currentDate: Date())
let attachment = SignalAttachment.voiceMessageAttachment(dataSource: dataSource, dataUTI: kUTTypeMPEG4Audio as String)
let attachment = SignalAttachment.voiceMessageAttachment(dataSource: dataSource, dataUTI: UTType.mpeg4Audio.identifier)
guard !attachment.hasError else {
throw OWSAssertionError("Failed to create voice message attachment: \(attachment.errorName ?? "Unknown Error")")
}

View File

@ -6,6 +6,7 @@
import CoreServices
import SignalServiceKit
import SignalUI
import UniformTypeIdentifiers
class AvatarSettingsViewController: OWSTableViewController2 {
let context: AvatarContext
@ -334,7 +335,7 @@ class AvatarSettingsViewController: OWSTableViewController2 {
picker.delegate = self
picker.allowsEditing = false
picker.sourceType = .camera
picker.mediaTypes = [kUTTypeImage as String]
picker.mediaTypes = [UTType.image.identifier]
self.present(picker, animated: true)
}
}
@ -352,7 +353,7 @@ class AvatarSettingsViewController: OWSTableViewController2 {
let picker = OWSImagePickerController()
picker.delegate = self
picker.sourceType = .photoLibrary
picker.mediaTypes = [kUTTypeImage as String]
picker.mediaTypes = [UTType.image.identifier]
self.present(picker, animated: true)
}
}

View File

@ -7,6 +7,7 @@ import CoreServices
import LibSignalClient
import SignalServiceKit
import SignalUI
import UniformTypeIdentifiers
#if USE_DEBUG_UI
@ -101,7 +102,7 @@ class DebugUIMessages: DebugUIPage, Dependencies {
DebugUIMessages.sendRandomAttachmentInThread(thread, uti: MimeTypeUtil.unknownTestAttachmentUti)
}),
OWSTableItem(title: "Send pdf", actionBlock: {
DebugUIMessages.sendRandomAttachmentInThread(thread, uti: kUTTypePDF as String)
DebugUIMessages.sendRandomAttachmentInThread(thread, uti: UTType.pdf.identifier)
}),
OWSTableItem(title: "Create all system messages", actionBlock: {
DebugUIMessages.createSystemMessagesInThread(thread)
@ -1739,12 +1740,12 @@ class DebugUIMessages: DebugUIPage, Dependencies {
sendUnsafeFile = {
guard let filename = filenames.popLast() else { return }
let utiType = kUTTypeData as String
let type = UTType.data
let dataLength: UInt32 = 32
guard let dataSource = DataSourceValue.dataSource(with: createRandomDataOfSize(dataLength), utiType: utiType) else { return }
guard let dataSource = DataSourceValue.dataSource(with: createRandomDataOfSize(dataLength), utiType: type.identifier) else { return }
dataSource.sourceFilename = filename
let attachment = SignalAttachment.attachment(dataSource: dataSource, dataUTI: utiType)
let attachment = SignalAttachment.attachment(dataSource: dataSource, dataUTI: type.identifier)
guard attachment.hasError else {
Logger.error("attachment[\(String(describing: attachment.sourceFilename))]: \(String(describing: attachment.errorName))")

View File

@ -14,6 +14,7 @@ import CoreServices
import MapKit
import SignalServiceKit
import SignalUI
import UniformTypeIdentifiers
public protocol LocationPickerDelegate: AnyObject {
func didPickLocation(_ locationPicker: LocationPicker, location: Location)
@ -496,8 +497,8 @@ public class Location: NSObject {
throw LocationError.assertion
}
let dataSource = DataSourceValue.dataSource(with: jpegData, utiType: kUTTypeJPEG as String)
return SignalAttachment.attachment(dataSource: dataSource, dataUTI: kUTTypeJPEG as String)
let dataSource = DataSourceValue.dataSource(with: jpegData, utiType: UTType.jpeg.identifier)
return SignalAttachment.attachment(dataSource: dataSource, dataUTI: UTType.jpeg.identifier)
}
}

View File

@ -844,7 +844,7 @@ class CameraCaptureSession: NSObject {
return handleVideoCaptureError(PhotoCaptureError.captureFailed)
}
let attachment = SignalAttachment.attachment(dataSource: dataSource, dataUTI: kUTTypeMPEG4 as String)
let attachment = SignalAttachment.attachment(dataSource: dataSource, dataUTI: UTType.mpeg4Movie.identifier)
delegate.cameraCaptureSession(self, didFinishProcessing: attachment)
}
@ -1010,9 +1010,9 @@ extension CameraCaptureSession: PhotoCaptureDelegate {
case .failure(let error):
delegate.cameraCaptureSession(self, didFailWith: error)
case .success(let photoData):
let dataSource = DataSourceValue.dataSource(with: photoData, utiType: kUTTypeJPEG as String)
let dataSource = DataSourceValue.dataSource(with: photoData, utiType: UTType.jpeg.identifier)
let attachment = SignalAttachment.attachment(dataSource: dataSource, dataUTI: kUTTypeJPEG as String)
let attachment = SignalAttachment.attachment(dataSource: dataSource, dataUTI: UTType.jpeg.identifier)
delegate.cameraCaptureSession(self, didFinishProcessing: attachment)
}
}

View File

@ -193,7 +193,7 @@ class PhotoAlbumContents {
let baseFilename: String?
if let onDiskVideo = video as? AVURLAsset {
let url = onDiskVideo.url
dataUTI = MimeTypeUtil.utiTypeForFileExtension(url.pathExtension) ?? kUTTypeVideo as String
dataUTI = MimeTypeUtil.utiTypeForFileExtension(url.pathExtension) ?? UTType.video.identifier
if let dataSource = try? DataSourcePath.dataSource(with: url, shouldDeleteOnDeallocation: false) {
if !SignalAttachment.isVideoThatNeedsCompression(dataSource: dataSource, dataUTI: dataUTI) {
@ -204,7 +204,7 @@ class PhotoAlbumContents {
baseFilename = url.lastPathComponent
} else {
dataUTI = kUTTypeVideo as String
dataUTI = UTType.video.identifier
baseFilename = nil
}

View File

@ -6,6 +6,7 @@
import CoreServices
import SignalServiceKit
import SignalUI
import UniformTypeIdentifiers
class SetWallpaperViewController: OWSTableViewController2 {
lazy var collectionView = WallpaperCollectionView(container: self, shouldDimInDarkMode: shouldDimInDarkMode) { [weak self] wallpaper in
@ -84,7 +85,7 @@ class SetWallpaperViewController: OWSTableViewController2 {
let vc = UIImagePickerController()
vc.delegate = self
vc.sourceType = .photoLibrary
vc.mediaTypes = [kUTTypeImage as String]
vc.mediaTypes = [UTType.image.identifier]
self.presentFormSheet(vc, animated: true)
}
photosSection.add(choosePhotoItem)

View File

@ -6,6 +6,7 @@
import XCTest
import CoreServices
import SignalServiceKit
import UniformTypeIdentifiers
class SignalAttachmentTest: SignalBaseTest {
// MARK: - Utilities
@ -16,7 +17,7 @@ class SignalAttachmentTest: SignalBaseTest {
let dataSource = try DataSourcePath.dataSource(with: url, shouldDeleteOnDeallocation: false)
let attachment = SignalAttachment.attachment(
dataSource: dataSource,
dataUTI: kUTTypeJPEG as String
dataUTI: UTType.jpeg.identifier
)
let newSize = attachment.data.imageMetadata(withPath: nil, mimeType: "image/jpeg").pixelSize
@ -60,7 +61,7 @@ class SignalAttachmentTest: SignalBaseTest {
let attachment = SignalAttachment.attachment(
dataSource: dataSource,
dataUTI: kUTTypePNG as String
dataUTI: UTType.png.identifier
)
XCTAssertEqual(
@ -98,7 +99,7 @@ class SignalAttachmentTest: SignalBaseTest {
let attachment = SignalAttachment.attachment(
dataSource: dataSource,
dataUTI: kUTTypePNG as String
dataUTI: UTType.png.identifier
)
XCTAssert(

View File

@ -433,10 +433,7 @@ public class SignalAttachment: NSObject {
if dataUTI == MimeTypeUtil.unknownTestAttachmentUti {
return MimeType.unknownMimetype.rawValue
}
guard let mimeType = UTTypeCopyPreferredTagWithClass(dataUTI as CFString, kUTTagClassMIMEType) else {
return MimeType.applicationOctetStream.rawValue
}
return mimeType.takeRetainedValue() as String
return UTType(dataUTI)?.preferredMIMEType ?? MimeType.applicationOctetStream.rawValue
}
// Use the filename if known. If not, e.g. if the attachment was copy/pasted, we'll generate a filename
@ -502,7 +499,7 @@ public class SignalAttachment: NSObject {
}
private class var outputVideoUTISet: Set<String> {
return Set([kUTTypeMPEG4 as String])
[UTType.mpeg4Movie.identifier]
}
// Returns the set of UTIs that correspond to valid animated image formats
@ -557,11 +554,12 @@ public class SignalAttachment: NSObject {
}
public var isText: Bool {
return UTTypeConformsTo(dataUTI as CFString, kUTTypeText) || isOversizeText
let isText = UTType(dataUTI)?.conforms(to: .text) ?? false
return isText || isOversizeText
}
public var isUrl: Bool {
return UTTypeConformsTo(dataUTI as CFString, kUTTypeURL)
UTType(dataUTI)?.conforms(to: .url) ?? false
}
public class func pasteboardHasPossibleAttachment() -> Bool {
@ -608,13 +606,13 @@ public class SignalAttachment: NSObject {
var hasTextUTIType = false
var hasNonTextUTIType = false
for utiType in pasteboardUTISet {
if UTTypeConformsTo(utiType as CFString, kUTTypeText) {
if let type = UTType(utiType), type.conforms(to: .text) {
hasTextUTIType = true
} else if mediaUTISet.contains(utiType) {
hasNonTextUTIType = true
}
}
if pasteboardUTISet.contains(kUTTypeURL as String) {
if pasteboardUTISet.contains(UTType.url.identifier) {
// Treat URL as a textual UTI type.
hasTextUTIType = true
}
@ -659,8 +657,8 @@ public class SignalAttachment: NSObject {
// and png uti types when sending memoji stickers and
// `inputImageUTISet` is unordered, so without this check there
// is a 50/50 chance that we'd pick the jpg.
if pasteboardUTISet.isSuperset(of: [kUTTypeJPEG as String, kUTTypePNG as String]) {
pasteboardUTISet.remove(kUTTypeJPEG as String)
if pasteboardUTISet.isSuperset(of: [UTType.jpeg.identifier, UTType.png.identifier]) {
pasteboardUTISet.remove(UTType.jpeg.identifier)
}
for dataUTI in inputImageUTISet {
@ -762,7 +760,7 @@ public class SignalAttachment: NSObject {
}
// Never re-encode animated images (i.e. GIFs) as JPEGs.
if dataUTI == (kUTTypePNG as String) {
if dataUTI == UTType.png.identifier {
do {
return try attachment.removingImageMetadata()
} catch {
@ -777,7 +775,7 @@ public class SignalAttachment: NSObject {
if let sourceFilename = dataSource.sourceFilename,
let sourceFileExtension = sourceFilename.fileExtension,
["heic", "heif"].contains(sourceFileExtension.lowercased()),
dataUTI == kUTTypeJPEG as String {
dataUTI == UTType.jpeg.identifier as String {
// If a .heic file actually contains jpeg data, update the extension to match.
//
@ -822,7 +820,7 @@ public class SignalAttachment: NSObject {
// JPEGs and instead go through the recompresing step.
// This is an iOS bug (FB13285956) still present in iOS 17 and should
// be revisitied in the future to see if JPEG support can be reenabled.
guard dataUTI != (kUTTypeJPEG as String) else { return false }
guard dataUTI != UTType.jpeg.identifier else { return false }
guard SignalAttachment.outputImageUTISet.contains(dataUTI) else { return false }
guard dataSource.dataLength <= imageQuality.maxFileSize else { return false }
@ -909,7 +907,7 @@ public class SignalAttachment: NSObject {
// so we can keep the image out of memory.
let dataFileExtension: String
let dataUTI: CFString
let dataType: UTType
// We convert everything that's not sticker-like to jpg, because
// often images with alpha channels don't actually have any
@ -918,15 +916,15 @@ public class SignalAttachment: NSObject {
// are any transparent pixels in an image.
if dataSource.hasStickerLikeProperties {
dataFileExtension = "png"
dataUTI = kUTTypePNG
dataType = .png
} else {
dataFileExtension = "jpg"
dataUTI = kUTTypeJPEG
dataType = .jpeg
imageProperties[kCGImageDestinationLossyCompressionQuality] = compressionQuality(for: pixelSize)
}
let tempFileUrl = OWSFileSystem.temporaryFileUrl(fileExtension: dataFileExtension)
guard let destination = CGImageDestinationCreateWithURL(tempFileUrl as CFURL, dataUTI, 1, nil) else {
guard let destination = CGImageDestinationCreateWithURL(tempFileUrl as CFURL, dataType.identifier as CFString, 1, nil) else {
owsFailDebug("Failed to create CGImageDestination for attachment")
return .error(error: .couldNotConvertImage)
}
@ -950,7 +948,7 @@ public class SignalAttachment: NSObject {
outputDataSource.sourceFilename = newFilenameWithExtension
if outputDataSource.dataLength <= imageQuality.maxFileSize, outputDataSource.dataLength <= kMaxFileSizeImage {
let recompressedAttachment = attachment.replacingDataSource(with: outputDataSource, dataUTI: dataUTI as String)
let recompressedAttachment = attachment.replacingDataSource(with: outputDataSource, dataUTI: dataType.identifier)
return .signalAttachment(signalAttachment: recompressedAttachment)
}
@ -1065,7 +1063,7 @@ public class SignalAttachment: NSObject {
private func removingImageMetadata() throws -> SignalAttachment {
owsAssertDebug(isImage)
if dataUTI == (kUTTypePNG as String) {
if dataUTI == UTType.png.identifier {
let cleanedData = try Self.removeMetadata(fromPng: data)
guard let dataSource = DataSourceValue.dataSource(with: cleanedData, utiType: dataUTI) else {
throw SignalAttachmentError.couldNotRemoveMetadata
@ -1234,7 +1232,7 @@ public class SignalAttachment: NSObject {
shouldDeleteOnDeallocation: true)
dataSource.sourceFilename = mp4Filename
return SignalAttachment(dataSource: dataSource, dataUTI: kUTTypeMPEG4 as String)
return SignalAttachment(dataSource: dataSource, dataUTI: UTType.mpeg4Movie.identifier)
} catch {
owsFailDebug("Failed to build data source for exported video URL")
let attachment = SignalAttachment(dataSource: DataSourceValue.emptyDataSource(), dataUTI: dataUTI)
@ -1323,8 +1321,7 @@ public class SignalAttachment: NSObject {
}
public class func empty() -> SignalAttachment {
return SignalAttachment.attachment(dataSource: DataSourceValue.emptyDataSource(),
dataUTI: kUTTypeContent as String)
SignalAttachment.attachment(dataSource: DataSourceValue.emptyDataSource(), dataUTI: UTType.content.identifier)
}
// MARK: Helper Methods

View File

@ -4,7 +4,7 @@
//
import Foundation
import CoreServices
import UniformTypeIdentifiers
public class GiphyAsset: ProxiedContentAssetDescription {
let rendition: Rendition
@ -114,9 +114,9 @@ extension GiphyAsset {
public var utiType: String {
switch self {
case .jpg: return kUTTypeJPEG as String
case .gif: return kUTTypeGIF as String
case .mp4: return kUTTypeMPEG4 as String
case .jpg: return UTType.jpeg.identifier
case .gif: return UTType.gif.identifier
case .mp4: return UTType.mpeg4Movie.identifier
}
}
}

View File

@ -6,6 +6,7 @@
import CoreServices
import Foundation
import ImageIO
import UniformTypeIdentifiers
@objc
public class BadgeAssets: NSObject {
@ -148,7 +149,7 @@ public class BadgeAssets: NSObject {
guard !OWSFileSystem.fileOrFolderExists(url: destinationUrl) else { return }
guard let spriteImage = spriteParser.copySprite(variant: variant),
let imageDestination = CGImageDestinationCreateWithURL(destinationUrl as CFURL, kUTTypePNG, 1, nil) else {
let imageDestination = CGImageDestinationCreateWithURL(destinationUrl as CFURL, UTType.png.identifier as CFString, 1, nil) else {
throw OWSAssertionError("Couldn't load image")
}
CGImageDestinationAddImage(imageDestination, spriteImage, nil)

View File

@ -5,6 +5,7 @@
import CoreServices
import Foundation
import UniformTypeIdentifiers
public enum MimeType: String {
case applicationJson = "application/json"
@ -164,12 +165,14 @@ public class MimeTypeUtil: NSObject {
// MARK: - Conversion Functions for UTI Type / MIME Type / File Extension
public static func utiTypeForMimeType(_ mimeType: String) -> String? {
UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType as CFString, nil)?.takeRetainedValue() as String?
UTType(mimeType: mimeType)?.identifier
}
public static func utiTypeForFileExtension(_ fileExtension: String) -> String? {
owsAssertDebug(!fileExtension.isEmpty)
return UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension as CFString, nil)?.takeRetainedValue() as String?
return UTType(filenameExtension: fileExtension)?.identifier
}
@objc
public static func mimeTypeForFileExtension(_ fileExtension: String) -> String? {
owsAssertDebug(!fileExtension.isEmpty)
@ -183,7 +186,7 @@ public class MimeTypeUtil: NSObject {
if utiType == "public.aac-audio" {
return "m4a"
} else {
return UTTypeCopyPreferredTagWithClass(utiType as CFString, kUTTagClassFilenameExtension)?.takeRetainedValue() as String?
return UTType(utiType)?.preferredFilenameExtension
}
}
@objc

View File

@ -8,6 +8,7 @@ import Intents
import PureLayout
import SignalServiceKit
import SignalUI
import UniformTypeIdentifiers
public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailedViewDelegate {
@ -574,8 +575,8 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed
// Handle safari sharing images and PDFs as two separate items one with the object to share and the other as the URL of the data.
for extensionItem in extensionItems {
for attachment in extensionItem.attachments ?? [] {
if attachment.hasItemConformingToTypeIdentifier(kUTTypeData as String)
|| attachment.hasItemConformingToTypeIdentifier(kUTTypeFileURL as String)
if attachment.hasItemConformingToTypeIdentifier(UTType.data.identifier)
|| attachment.hasItemConformingToTypeIdentifier(UTType.fileURL.identifier)
|| attachment.hasItemConformingToTypeIdentifier("com.apple.pkpass") {
return extensionItem
}
@ -599,23 +600,23 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed
var typeIdentifier: String {
switch self {
case .movie:
return kUTTypeMovie as String
return UTType.movie.identifier
case .image:
return kUTTypeImage as String
return UTType.image.identifier
case .webUrl:
return kUTTypeURL as String
return UTType.url.identifier
case .fileUrl:
return kUTTypeFileURL as String
return UTType.fileURL.identifier
case .contact:
return kUTTypeVCard as String
return UTType.vCard.identifier
case .text:
return kUTTypeText as String
return UTType.text.identifier
case .pdf:
return kUTTypePDF as String
return UTType.pdf.identifier
case .pkPass:
return "com.apple.pkpass"
case .data:
return kUTTypeData as String
return UTType.data.identifier
}
}
}
@ -710,9 +711,9 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed
let url: NSURL = try await Self.loadObjectWithKeyedUnarchiverFallback(fromItemProvider: itemProvider, forTypeIdentifier: typedItemProvider.itemType.typeIdentifier, cannotLoadError: .cannotLoadURLObject, failedLoadError: .loadURLObjectFailed)
return try Self.createAttachment(withText: (url as URL).absoluteString)
case .contact:
let contactData = try await Self.loadDataRepresentation(fromItemProvider: itemProvider, forTypeIdentifier: kUTTypeContact as String)
let dataSource = DataSourceValue.dataSource(with: contactData, utiType: kUTTypeContact as String)
let attachment = SignalAttachment.attachment(dataSource: dataSource, dataUTI: kUTTypeContact as String)
let contactData = try await Self.loadDataRepresentation(fromItemProvider: itemProvider, forTypeIdentifier: UTType.contact.identifier)
let dataSource = DataSourceValue.dataSource(with: contactData, utiType: UTType.contact.identifier)
let attachment = SignalAttachment.attachment(dataSource: dataSource, dataUTI: UTType.contact.identifier)
attachment.isConvertibleToContactShare = true
if let attachmentError = attachment.error {
throw attachmentError
@ -733,7 +734,7 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed
}
}
nonisolated private static func copyAttachment(fromUrl url: URL, defaultTypeIdentifier: String = kUTTypeData as String) throws -> SignalAttachment {
nonisolated private static func copyAttachment(fromUrl url: URL, defaultTypeIdentifier: String = UTType.data.identifier) throws -> SignalAttachment {
guard let dataSource = try? DataSourcePath.dataSource(with: url, shouldDeleteOnDeallocation: false) else {
throw ShareViewControllerError.nonFileUrl
}
@ -843,7 +844,7 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed
nonisolated private static func createAttachment(withText text: String) throws -> SignalAttachment {
let dataSource = DataSourceValue.dataSource(withOversizeText: text)
let attachment = SignalAttachment.attachment(dataSource: dataSource, dataUTI: kUTTypeText as String)
let attachment = SignalAttachment.attachment(dataSource: dataSource, dataUTI: UTType.text.identifier)
if let attachmentError = attachment.error {
throw attachmentError
}
@ -855,9 +856,9 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed
guard let imagePng = image.pngData() else {
throw ShareViewControllerError.uiImageMissingOrCorruptImageData
}
let typeIdentifier = kUTTypePNG as String
let dataSource = DataSourceValue.dataSource(with: imagePng, utiType: typeIdentifier)
let attachment = SignalAttachment.attachment(dataSource: dataSource, dataUTI: typeIdentifier)
let type = UTType.png
let dataSource = DataSourceValue.dataSource(with: imagePng, utiType: type.identifier)
let attachment = SignalAttachment.attachment(dataSource: dataSource, dataUTI: type.identifier)
if let attachmentError = attachment.error {
throw attachmentError
}

View File

@ -684,21 +684,21 @@ public class AttachmentApprovalViewController: UIPageViewController, UIPageViewC
}
return dstImage
}.map(on: DispatchQueue.global()) { (dstImage: UIImage) -> SignalAttachment in
var dataUTI = kUTTypeImage as String
var dataType = UTType.image
guard let dstData: Data = {
let isLossy: Bool = attachmentApprovalItem.attachment.mimeType.caseInsensitiveCompare(MimeType.imageJpeg.rawValue) == .orderedSame
if isLossy {
dataUTI = kUTTypeJPEG as String
dataType = .jpeg
return dstImage.jpegData(compressionQuality: 0.9)
} else {
dataUTI = kUTTypePNG as String
dataType = .png
return dstImage.pngData()
}
}() else {
owsFailDebug("Could not export for output.")
return attachmentApprovalItem.attachment
}
guard let dataSource = DataSourceValue.dataSource(with: dstData, utiType: dataUTI) else {
guard let dataSource = DataSourceValue.dataSource(with: dstData, utiType: dataType.identifier) else {
owsFailDebug("Could not prepare data source for output.")
return attachmentApprovalItem.attachment
}
@ -706,13 +706,13 @@ public class AttachmentApprovalViewController: UIPageViewController, UIPageViewC
// Rewrite the filename's extension to reflect the output file format.
var filename: String? = attachmentApprovalItem.attachment.sourceFilename
if let sourceFilename = attachmentApprovalItem.attachment.sourceFilename {
if let fileExtension: String = MimeTypeUtil.fileExtensionForUtiType(dataUTI) {
if let fileExtension: String = MimeTypeUtil.fileExtensionForUtiType(dataType.identifier) {
filename = (sourceFilename as NSString).deletingPathExtension.appendingFileExtension(fileExtension)
}
}
dataSource.sourceFilename = filename
let dstAttachment = SignalAttachment.attachment(dataSource: dataSource, dataUTI: dataUTI)
let dstAttachment = SignalAttachment.attachment(dataSource: dataSource, dataUTI: dataType.identifier)
if let attachmentError = dstAttachment.error {
owsFailDebug("Could not prepare attachment for output: \(attachmentError).")
return attachmentApprovalItem.attachment