我正在使用如何在 swift 中将图标添加到共享表中的代码?为我的应用程序创建的 KMZ 文件创建自定义图标。每当我运行代码时,我的 iPad 不再正确识别可以打开 KMZ(Google 地球和 ForeFlight)的应用程序。它似乎与将元数据添加到文件的 URL 有关。
共享表的外观: 不正确的共享表
共享表应该是什么样子: 正确的共享表
以下是未将文件正确共享为“存档”的代码:
/// Share button to send a KML file using the
/// Apple share screen for iPhone and iPad.
struct ShareButton: View {
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
@EnvironmentObject var overlayViewModel: OverlayViewModel
var body: some View {
ZStack {
Button(action: {
// unrelated code removed
if overlayViewModel.isShared {
showAppShareSheet(fileName: newOverlay.fileName, fileExtension: newOverlay.fileExtension/*fileUrl: fileUrl*/)
}
}, label: {
Label(overlayViewModel.isShared ? "Share Overlay" : "Save Overlay", systemImage: overlayViewModel.isShared ? "square.and.arrow.up" : "doc.badge.plus")
.font(horizontalSizeClass == .compact ? .title3 : .title2)
.symbolRenderingMode(.multicolor)
})
.padding()
}
}
}
/// Transform url to metadata to populate to user.
final class LinkMetadataManager: NSObject, UIActivityItemSource {
var linkMetadata: LPLinkMetadata
var fileName: String
var fileExtension: String
let iconImage = "shareIcon" // The name of the image file in your directory
let png = "png" // The extension of the image
init(linkMetadata: LPLinkMetadata = LPLinkMetadata(), fileName: String, fileExtension: String) {
self.linkMetadata = linkMetadata
self.fileName = fileName
self.fileExtension = fileExtension
}
}
// MARK: - LinkMetadataManager Setup
extension LinkMetadataManager {
/// Creating metadata to be populated in the share sheet.
func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? {
let fileUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! // appending the filename to the url
.appendingPathComponent(fileName)
.appendingPathExtension(fileExtension)
linkMetadata.originalURL = fileUrl
linkMetadata.url = linkMedata.originalURL
linkMetadata.title = fileName
linkMetadata.iconProvider = NSItemProvider(
contentsOf: Bundle.main.url(forResource: iconImage, withExtension: png))
return linkMetadata
}
/// Showing an empty string returns a share sheet with the minimum requirement.
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
return String()
}
/// Sharing the application url.
func activityViewController(_ activityViewController: UIActivityViewController,
itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
return linkMetadata.url
}
}
// MARK: View+ShareSheet
extension View {
/// Populate Apple share sheet to enable the user to share Apple Store link.
func showAppShareSheet(fileName: String, fileExtension: String) {
guard let source = UIApplication.shared.windows.first?.rootViewController else {
return
}
let activityItemMetadata = LinkMetadataManager(fileName: fileName, fileExtension: fileExtension)
let activityVC = UIActivityViewController(
activityItems: [activityItemMetadata],
applicationActivities: nil)
let excludedActivities = [UIActivity.ActivityType.addToReadingList,
UIActivity.ActivityType.assignToContact,
UIActivity.ActivityType.copyToPasteboard,
UIActivity.ActivityType.mail,
UIActivity.ActivityType.markupAsPDF,
UIActivity.ActivityType.message,
UIActivity.ActivityType.openInIBooks,
UIActivity.ActivityType.postToFacebook,
UIActivity.ActivityType.postToFlickr,
UIActivity.ActivityType.postToTencentWeibo,
UIActivity.ActivityType.postToTwitter,
UIActivity.ActivityType.postToVimeo,
UIActivity.ActivityType.postToWeibo,
UIActivity.ActivityType.print,
UIActivity.ActivityType.saveToCameraRoll]
activityVC.excludedActivityTypes = excludedActivities
if let popoverController = activityVC.popoverPresentationController {
popoverController.sourceView = source.view
popoverController.permittedArrowDirections = []
popoverController.sourceRect = CGRect(x: source.view.bounds.midX,
y: source.view.bounds.midY,
width: .zero, height: .zero)
}
source.present(activityVC, animated: true)
}
}
如果我let activityItemMetadata = LinkMetadataManager(fileName: fileName, fileExtension: fileExtension)
用 中的以下代码替换LinkMetadataManager
,那么一切都按预期工作(系统将 KMZ 文件识别为“存档”并且正确的应用程序显示在共享表上)。
let activityItemMetadata = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! // appending the filename to the url
.appendingPathComponent(fileName)
.appendingPathExtension(fileExtension)
据我所知,我已经在 Info 中正确设置了所有内容以导出文件:
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>com.pkware.zip-archive</string>
</array>
<key>UTTypeDescription</key>
<string>Archive</string>
<key>UTTypeIconFiles</key>
<array/>
<key>UTTypeIdentifier</key>
<string>com.google.kmz</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>kmz</string>
</array>
<key>public.mime-type</key>
<array>
<string>application/vnd.google-earth.kmz+xml</string>
</array>
</dict>
<key>com.apple.ostype</key>
<string>GKmz</string>
<key>public.filename-extension</key>
<array>
<string>kmz</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.google-earth.kmz+xml</string>
</dict>
</array>
那么......我在自定义元数据中做错了什么?我真的很想有一个自定义图标与共享表一起使用。谢谢!