parent
f848bbf7c4
commit
b9bdd29986
|
@ -56,6 +56,7 @@ private let imageType = UTType.image.identifier
|
||||||
private let mp4Type = UTType.mpeg4Movie.identifier
|
private let mp4Type = UTType.mpeg4Movie.identifier
|
||||||
private let quickTimeType = UTType.quickTimeMovie.identifier
|
private let quickTimeType = UTType.quickTimeMovie.identifier
|
||||||
private let dataType = UTType.data.identifier
|
private let dataType = UTType.data.identifier
|
||||||
|
private let gifType = UTType.gif.identifier
|
||||||
|
|
||||||
extension CompositionAttachment: NSItemProviderWriting {
|
extension CompositionAttachment: NSItemProviderWriting {
|
||||||
static var writableTypeIdentifiersForItemProvider: [String] {
|
static var writableTypeIdentifiersForItemProvider: [String] {
|
||||||
|
@ -95,20 +96,22 @@ extension CompositionAttachment: NSItemProviderReading {
|
||||||
[typeIdentifier] + UIImage.readableTypeIdentifiersForItemProvider + [mp4Type, quickTimeType] + NSURL.readableTypeIdentifiersForItemProvider
|
[typeIdentifier] + UIImage.readableTypeIdentifiersForItemProvider + [mp4Type, quickTimeType] + NSURL.readableTypeIdentifiersForItemProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
static func object(withItemProviderData data: Data, typeIdentifier: String) throws -> Self {
|
static func object(withItemProviderData data: Data, typeIdentifier: String) throws -> CompositionAttachment {
|
||||||
if typeIdentifier == CompositionAttachment.typeIdentifier {
|
if typeIdentifier == CompositionAttachment.typeIdentifier {
|
||||||
return try PropertyListDecoder().decode(Self.self, from: data)
|
return try PropertyListDecoder().decode(CompositionAttachment.self, from: data)
|
||||||
|
} else if typeIdentifier == gifType {
|
||||||
|
return CompositionAttachment(data: .gif(data))
|
||||||
} else if UIImage.readableTypeIdentifiersForItemProvider.contains(typeIdentifier), let image = try? UIImage.object(withItemProviderData: data, typeIdentifier: typeIdentifier) {
|
} else if UIImage.readableTypeIdentifiersForItemProvider.contains(typeIdentifier), let image = try? UIImage.object(withItemProviderData: data, typeIdentifier: typeIdentifier) {
|
||||||
return CompositionAttachment(data: .image(image)) as! Self
|
return CompositionAttachment(data: .image(image))
|
||||||
} else if let type = UTType(typeIdentifier), type == .mpeg4Movie || type == .quickTimeMovie {
|
} else if let type = UTType(typeIdentifier), type == .mpeg4Movie || type == .quickTimeMovie {
|
||||||
let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
|
let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
|
||||||
let temporaryFileName = ProcessInfo().globallyUniqueString
|
let temporaryFileName = ProcessInfo().globallyUniqueString
|
||||||
let fileExt = type.preferredFilenameExtension!
|
let fileExt = type.preferredFilenameExtension!
|
||||||
let temporaryFileURL = temporaryDirectoryURL.appendingPathComponent(temporaryFileName).appendingPathExtension(fileExt)
|
let temporaryFileURL = temporaryDirectoryURL.appendingPathComponent(temporaryFileName).appendingPathExtension(fileExt)
|
||||||
try data.write(to: temporaryFileURL)
|
try data.write(to: temporaryFileURL)
|
||||||
return CompositionAttachment(data: .video(temporaryFileURL)) as! Self
|
return CompositionAttachment(data: .video(temporaryFileURL))
|
||||||
} else if NSURL.readableTypeIdentifiersForItemProvider.contains(typeIdentifier), let url = try? NSURL.object(withItemProviderData: data, typeIdentifier: typeIdentifier) as URL {
|
} else if NSURL.readableTypeIdentifiersForItemProvider.contains(typeIdentifier), let url = try? NSURL.object(withItemProviderData: data, typeIdentifier: typeIdentifier) as URL {
|
||||||
return CompositionAttachment(data: .video(url)) as! Self
|
return CompositionAttachment(data: .video(url))
|
||||||
} else {
|
} else {
|
||||||
throw ItemProviderError.incompatibleTypeIdentifier
|
throw ItemProviderError.incompatibleTypeIdentifier
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ enum CompositionAttachmentData {
|
||||||
case image(UIImage)
|
case image(UIImage)
|
||||||
case video(URL)
|
case video(URL)
|
||||||
case drawing(PKDrawing)
|
case drawing(PKDrawing)
|
||||||
|
case gif(Data)
|
||||||
|
|
||||||
var type: AttachmentType {
|
var type: AttachmentType {
|
||||||
switch self {
|
switch self {
|
||||||
|
@ -27,6 +28,8 @@ enum CompositionAttachmentData {
|
||||||
return .video
|
return .video
|
||||||
case .drawing(_):
|
case .drawing(_):
|
||||||
return .image
|
return .image
|
||||||
|
case .gif(_):
|
||||||
|
return .image
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +122,8 @@ enum CompositionAttachmentData {
|
||||||
case let .drawing(drawing):
|
case let .drawing(drawing):
|
||||||
let image = drawing.imageInLightMode(from: drawing.bounds, scale: 1)
|
let image = drawing.imageInLightMode(from: drawing.bounds, scale: 1)
|
||||||
completion(.success((image.pngData()!, .png)))
|
completion(.success((image.pngData()!, .png)))
|
||||||
|
case let .gif(data):
|
||||||
|
completion(.success((data, .gif)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,6 +196,8 @@ extension CompositionAttachmentData: Codable {
|
||||||
try container.encode("drawing", forKey: .type)
|
try container.encode("drawing", forKey: .type)
|
||||||
let drawingData = drawing.dataRepresentation()
|
let drawingData = drawing.dataRepresentation()
|
||||||
try container.encode(drawingData, forKey: .drawing)
|
try container.encode(drawingData, forKey: .drawing)
|
||||||
|
case .gif(_):
|
||||||
|
throw EncodingError.invalidValue(self, EncodingError.Context(codingPath: [], debugDescription: "gif CompositionAttachments cannot be encoded"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +221,7 @@ extension CompositionAttachmentData: Codable {
|
||||||
let drawing = try PKDrawing(data: drawingData)
|
let drawing = try PKDrawing(data: drawingData)
|
||||||
self = .drawing(drawing)
|
self = .drawing(drawing)
|
||||||
default:
|
default:
|
||||||
throw DecodingError.dataCorruptedError(forKey: .type, in: container, debugDescription: "CompositionAttachment type must be one of 'image' or 'asset'")
|
throw DecodingError.dataCorruptedError(forKey: .type, in: container, debugDescription: "CompositionAttachment type must be one of image, asset, or drawing")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,18 +13,14 @@ import AVKit
|
||||||
|
|
||||||
class AssetPreviewViewController: UIViewController {
|
class AssetPreviewViewController: UIViewController {
|
||||||
|
|
||||||
let attachment: CompositionAttachmentData
|
let asset: PHAsset
|
||||||
|
|
||||||
init(attachment: CompositionAttachmentData) {
|
init(asset: PHAsset) {
|
||||||
self.attachment = attachment
|
self.asset = asset
|
||||||
|
|
||||||
super.init(nibName: nil, bundle: nil)
|
super.init(nibName: nil, bundle: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
convenience init(asset: PHAsset) {
|
|
||||||
self.init(attachment: .asset(asset))
|
|
||||||
}
|
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
required init?(coder: NSCoder) {
|
||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
|
@ -34,27 +30,17 @@ class AssetPreviewViewController: UIViewController {
|
||||||
|
|
||||||
view.backgroundColor = .black
|
view.backgroundColor = .black
|
||||||
|
|
||||||
switch attachment {
|
switch asset.mediaType {
|
||||||
case let .image(image):
|
case .image:
|
||||||
showImage(image)
|
if asset.mediaSubtypes.contains(.photoLive) {
|
||||||
case let .video(url):
|
showLivePhoto(asset)
|
||||||
showVideo(asset: AVURLAsset(url: url))
|
} else {
|
||||||
case let .asset(asset):
|
showAssetImage(asset)
|
||||||
switch asset.mediaType {
|
|
||||||
case .image:
|
|
||||||
if asset.mediaSubtypes.contains(.photoLive) {
|
|
||||||
showLivePhoto(asset)
|
|
||||||
} else {
|
|
||||||
showAssetImage(asset)
|
|
||||||
}
|
|
||||||
case .video:
|
|
||||||
showAssetVideo(asset)
|
|
||||||
default:
|
|
||||||
fatalError("asset mediaType must be image or video")
|
|
||||||
}
|
}
|
||||||
case let .drawing(drawing):
|
case .video:
|
||||||
let image = drawing.imageInLightMode(from: drawing.bounds)
|
showAssetVideo(asset)
|
||||||
showImage(image)
|
default:
|
||||||
|
fatalError("asset mediaType must be image or video")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,10 @@ struct ComposeAttachmentImage: View {
|
||||||
image = drawing.imageInLightMode(from: drawing.bounds)
|
image = drawing.imageInLightMode(from: drawing.bounds)
|
||||||
imageContentMode = .fit
|
imageContentMode = .fit
|
||||||
imageBackgroundColor = .white
|
imageBackgroundColor = .white
|
||||||
|
case let .gif(data):
|
||||||
|
if let image = UIImage(data: data) {
|
||||||
|
self.image = image
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue