SwiftUIでZIPをシェアすると大量にワーニングが出ます。
シェアが動かないわけではないけどとても不満。
Failed to request default share mode for fileURL:file:///
Only support loading options for CKShare and SWY types.
error fetching item for URL:file:///
error fetching file provider domain for URL:file:///
Collaboration: error loading metadata for documentURL:file:///
問題のコード
コードはよくあるSheetにフラグを立ててモーダル起動してダウンロードするパターン。
ボタンを押す方法だとiOS16からShareLink
もあるけど、他の機能からフラグ立てたり汎用的なのはこのパターン。
ContentView.swift
import SwiftUI
struct ContentView: View {
@State var isPresented = false
let zipFile = Bundle.main.url(forResource: "tmp", withExtension: "zip")!
var body: some View {
VStack {
Button(action: { isPresented = true } , label: {
Text("Download Zip")
})
}
.padding()
.sheet(isPresented: $isPresented, content: {
ZipDownloadView(zipFile: zipFile)
})
}
}
struct ZipDownloadView: UIViewControllerRepresentable {
let zipFile: URL
func makeUIViewController(context: Context) -> UIActivityViewController {
let activity = UIActivityViewController(activityItems: [zipFile], applicationActivities: nil)
return activity
}
func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {}
}
解決方法
META情報を付与してやれば解決。
ContentView.swift
import SwiftUI
import LinkPresentation
struct ContentView: View {
@State var isPresented = false
let zipFile = Bundle.main.url(forResource: "tmp", withExtension: "zip")!
var body: some View {
VStack {
Button(action: { isPresented = true } , label: {
Text("Download Zip")
})
}
.padding()
.sheet(isPresented: $isPresented, content: {
ZipDownloadView(zipFile: zipFile)
})
}
}
struct ZipDownloadView: UIViewControllerRepresentable {
let zipFile: URL
func makeUIViewController(context: Context) -> UIActivityViewController {
let metaData = getMetadataForSharingManually(title: "zipFile Sharering", url: zipFile, fileName: zipFile.lastPathComponent, fileType: "zip")
let metadataItemSource = LinkPresentationItemSource(metaData: metaData)
let activity = UIActivityViewController(activityItems: [metadataItemSource], applicationActivities: nil)
return activity
}
func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {}
func getMetadataForSharingManually(title: String, url: URL, fileName: String, fileType: String) -> LPLinkMetadata {
let linkMetaData = LPLinkMetadata()
let path = Bundle.main.path(forResource: fileName, ofType: fileType)
linkMetaData.iconProvider = NSItemProvider(contentsOf: URL(fileURLWithPath: path ?? ""))
linkMetaData.originalURL = url
linkMetaData.title = title
return linkMetaData
}
}
// Reference: https://medium.com/better-programming/whats-new-in-sharing-for-ios-13-3216999ff942
class LinkPresentationItemSource: NSObject, UIActivityItemSource {
var linkMetaData = LPLinkMetadata()
func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? {
return linkMetaData
}
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
return "Placeholder"
}
func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
return linkMetaData.originalURL
}
init(metaData: LPLinkMetadata) {
self.linkMetaData = metaData
}
}
このエラーは消えなかった
シュミレータでは表示するが、実機では出ないのでまぁいいかな…
Error acquiring assertion: <Error Domain=RBSServiceErrorDomain Code=1 "(originator doesn't have entitlement com.apple.runningboard.primitiveattribute AND originator doesn't have entitlement com.apple.runningboard.assertions.frontboard AND target is not running or doesn't have entitlement com.apple.runningboard.trustedtarget AND Target not hosted by originator)" UserInfo={NSLocalizedFailureReason=(originator doesn't have entitlement com.apple.runningboard.primitiveattribute AND originator doesn't have entitlement com.apple.runningboard.assertions.frontboard AND target is not running or doesn't have entitlement com.apple.runningboard.trustedtarget AND Target not hosted by originator)}>