Xcode 9.1与iOS11环境下WhatsApp图片分享功能失效
问题原因与解决办法
核心原因分析
你的代码在iOS11/Xcode9.1下失效,主要有两个关键问题:
- 沙盒路径获取方式过时:
NSHomeDirectory()直接拼接Documents目录的写法在iOS11之后的沙盒结构中存在兼容性问题,系统对文件目录的访问权限和路径规则有了更严格的限制,直接拼接可能导致文件写入的路径不正确。 - 临时文件扩展名不规范:你使用的
.wai不是标准图片扩展名,WhatsApp在iOS11版本中对文件类型的识别变得更严格,无法识别非标准扩展名的图片文件。
另外,虽然你已经声明了全局的documentInteractionController变量,但如果没有设置delegate,在某些场景下可能会因为控制器被提前释放导致分享界面无法正常弹出,这也是需要注意的点。
修复后的完整代码
import UIKit class ViewController: UIViewController, UIDocumentInteractionControllerDelegate { var documentInteractionController: UIDocumentInteractionController? override func viewDidLoad() { super.viewDidLoad() } @IBAction func ShareImages(_ sender: AnyObject) { let urlWhats = "whatsapp://app" guard let urlString = urlWhats.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), let whatsappURL = URL(string: urlString), UIApplication.shared.canOpenURL(whatsappURL) else { // 提示用户未安装WhatsApp print("Cannot open WhatsApp") return } guard let image = UIImage(named: "whatsappIcon"), let imageData = UIImageJPEGRepresentation(image, 1.0) else { print("Failed to get image data") return } // 正确获取Documents目录路径 guard let documentsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { print("Cannot access Documents directory") return } // 使用标准.jpg扩展名 let tempFile = documentsDir.appendingPathComponent("whatsAppTmp.jpg") do { try imageData.write(to: tempFile, options: .atomic) documentInteractionController = UIDocumentInteractionController(url: tempFile) documentInteractionController?.uti = "net.whatsapp.image" documentInteractionController?.delegate = self // 设置delegate避免提前释放 // 从sender的位置弹出菜单,体验更好 let senderFrame = sender.convert(sender.bounds, to: view) documentInteractionController?.presentOpenInMenu(from: senderFrame, in: view, animated: true) } catch { print("Error writing file: \(error.localizedDescription)") } } // 实现UIDocumentInteractionControllerDelegate的必要方法(可选,但建议添加) func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController { return self } }
额外说明
- 权限配置:你已经在
info.plist中添加的LSApplicationQueriesSchemes配置是正确的,无需修改。 - 临时文件清理:建议在分享完成后删除临时文件,避免占用设备存储空间,可以在
documentInteractionControllerDidEndOpenInMenu代理方法中执行删除操作。 - 图片格式:如果你需要分享PNG图片,可改用
UIImagePNGRepresentation,并将扩展名改为.png,同时UTI保持net.whatsapp.image即可。
内容的提问来源于stack exchange,提问作者MilkBottle
相关产品推荐
相关产品推荐

