I try to use the SwiftUI fileExporter modifier to save different kinds of documents from my app on macOS. Therefore, I store the document to save in an optional FileDocument? property.
import SwiftUI
import UniformTypeIdentifiers
struct PlaintextFile: FileDocument {
static var readableContentTypes = [UTType.plainText]
var text: String = ""
init(text: String) {
self.text = text
}
init(configuration: ReadConfiguration) throws {
if let data = configuration.file.regularFileContents {
text = String(decoding: data, as: UTF8.self)
}
}
func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
let data = Data(text.utf8)
return FileWrapper(regularFileWithContents: data)
}
}
struct ContentView: View {
@State private var showFileExporter = false
private let document: FileDocument? = PlaintextFile(text: "")
var body: some View {
Button("Save File: ") {
self.showFileExporter = true
}
.padding()
.fileExporter(isPresented: self.$showFileExporter, document: self.document, contentType: .plainText) { _ in }
}
}
However, this sample code above does not compile unless I initialize PlaintextFile directly in the fileExporter call. With the sample code the compiler shows the error
ContentView.swift:37:10: No exact matches in call to instance method 'fileExporter'
/SwiftUI.View:5:17: Candidate requires that 'FileDocument' conform to 'FileDocument' (requirement specified as 'D' == 'FileDocument')
Is there a way to not specify the document to save directly in the modifier but maintain it as optional property?
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
We use an AVPlayer for video playback with a custom video composition to render the video frames. Occasionally, we replace the item's composition with a new one to alter the rendering. Then, we acquire a new pixel buffer with hasNewPixelBuffer(forItemTime:) and copyPixelBuffer(forItemTime:, itemTimeForDisplay:) on the AVPlayerItemVideoOutput instance to display the changes. We get the item time with itemTime(forHostTime: CACurrentMediaTime()) on the output. However, when the player is paused there is no new pixel buffer and hasNewPixelBuffer(forItemTime:) returns false. How can we re-render the current frame?
https://developer.apple.com/library/archive/qa/qa1966/_index.html here it says that resetting the video composition should enable the re-rendering, which does not seem to work for us. When setting the composition a second time, the one set just before is applied instead, causing it to be always being one behind. Also the video "jumps" a little, meaning a slightly different frame is rendered.
We are using the PHPickerViewController to load photos and videos into our app. When an item was picked we load it using the loadFileRepresentation() method of NSItemProvider. In its callback we get the following error sometimes:
Error copying file type public.movie. Error: Error Domain=NSItemProviderErrorDomain Code=-1000 "Cannot load representation of type public.movie" UserInfo={NSLocalizedDescription=Cannot load representation of type public.movie, NSUnderlyingError=0x281a87a50 {Error Domain=NSCocoaErrorDomain Code=4101 "Couldn’t communicate with a helper application." UserInfo={NSUnderlyingError=0x281a85e30 {Error Domain=PHAssetExportRequestErrorDomain Code=0 "(null)" UserInfo={NSUnderlyingError=0x281a85620 {Error Domain=PFSharingRemakerErrorDomain Code=2 "Underlying operation encountered an error" UserInfo=0x280018500 (not displayed)}}}}}}
The error seems to occur randomly when picking arbitrary videos. What does the error mean and how do we make the item provider load more reliably here?