导入GPX文件遇编码识别错误,修改文档选择器后文件不可选
iOS 导入GPX文件:编码错误与文档选择器文件变灰问题解决
一、解决读取GPX时的编码错误
你之前的代码里把文件内容转成String再转Data,这一步很容易触发编码检测失败的问题。GPX本质是XML格式,XMLParser可以直接处理原始Data,完全不需要经过String转换,直接跳过编码检测环节就能解决这个报错。
修改后的解析代码:
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { guard let fileURL = urls.first else { return } let coordinator = NSFileCoordinator() var error: NSError? coordinator.coordinate(readingItemAt: fileURL, options: [], error: &error) { tempURL in do { // 直接读取文件Data,不转String let data = try Data(contentsOf: tempURL) let parser = XMLParser(data: data) // 这里设置parser的delegate,开始解析逻辑 parser.delegate = self parser.parse() } catch { print("GPX读取/解析失败:\(error.localizedDescription)") } } dismiss(animated: true) }
二、解决文档选择器中GPX文件变灰的问题
文件变灰是因为UTI(Uniform Type Identifier)配置不完整,系统识别不到你的App支持GPX文件。需要在info.plist里添加自定义UTI声明,再配合正确的API初始化文档选择器。
1. 配置info.plist
添加以下两个配置项(可直接编辑XML,或在Xcode的Info标签页可视化添加):
<!-- 文档类型声明 --> <key>CFBundleDocumentTypes</key> <array> <dict> <key>CFBundleTypeName</key> <string>GPX File</string> <key>LSHandlerRank</key> <string>Alternate</string> <key>LSItemContentTypes</key> <array> <string>com.yourcompany.gpx</string> </array> </dict> </array> <!-- 导出自定义UTI --> <key>UTExportedTypeDeclarations</key> <array> <dict> <key>UTTypeIdentifier</key> <string>com.yourcompany.gpx</string> <key>UTTypeDescription</key> <string>GPX File</string> <key>UTTypeConformsTo</key> <array> <string>public.xml</string> </array> <key>UTTypeTagSpecification</key> <dict> <key>public.filename-extension</key> <array> <string>gpx</string> </array> <key>public.mime-type</key> <string>application/gpx+xml</string> </dict> </dict> </array>
注意:把com.yourcompany.gpx换成你自己的App专属UTI(一般用反向域名格式)。
2. 正确初始化文档选择器
iOS 14+推荐使用forOpeningContentTypes这个更现代的初始化方法,避免旧API的兼容问题:
// 获取自定义GPX UTI,找不到则回退到XML类型 let gpxUTI = UTType(exportedAs: "com.yourcompany.gpx") ?? UTType.xml let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: [gpxUTI]) documentPicker.allowsMultipleSelection = false documentPicker.delegate = self present(documentPicker, animated: true)
内容的提问来源于stack exchange,提问作者Kevvv
相关产品推荐
相关产品推荐

