0

我正在使用如何在 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>

那么......我在自定义元数据中做错了什么?我真的很想有一个自定义图标与共享表一起使用。谢谢!

4

0 回答 0