1 import ExpoModulesCore 2 3 struct SharingContext { 4 let pendingPromise: Promise 5 let delegate: SharingDelegate 6 } 7 8 public final class SharingModule: Module, OnDocumentInteractionResult { 9 private var documentInteractionController: UIDocumentInteractionController? 10 private var sharingContext: SharingContext? 11 12 public func definition() -> ModuleDefinition { 13 Name("ExpoSharing") 14 15 AsyncFunction("shareAsync") { (url: URL, options: SharingOptions, promise: Promise) in 16 guard sharingContext == nil else { 17 throw SharingInProgressException() 18 } 19 20 guard let filePermissions: EXFilePermissionModuleInterface = 21 appContext?.legacyModule(implementing: EXFilePermissionModuleInterface.self) 22 else { 23 throw FilePermissionModuleException() 24 } 25 26 let grantedPermissions = filePermissions.getPathPermissions(url.absoluteString) 27 guard grantedPermissions.rawValue >= EXFileSystemPermissionFlags.read.rawValue else { 28 throw FilePermissionException() 29 } 30 31 let sharingDelegate = SharingDelegate(resultHandler: self) 32 documentInteractionController = UIDocumentInteractionController(url: url) 33 documentInteractionController?.delegate = sharingDelegate 34 documentInteractionController?.uti = options.UTI 35 36 guard let currentViewcontroller = appContext?.utilities?.currentViewController(), 37 let rootView = currentViewcontroller.view, 38 let documentInteractionController = documentInteractionController 39 else { 40 throw MissingCurrentViewControllerException() 41 } 42 43 if documentInteractionController.presentOpenInMenu(from: .zero, in: rootView, animated: true) { 44 self.sharingContext = SharingContext(pendingPromise: promise, delegate: sharingDelegate) 45 } else { 46 self.documentInteractionController = nil 47 throw UnsupportedTypeException() 48 } 49 } 50 .runOnQueue(.main) 51 } 52 53 func didDismissOpenInMenu() { 54 guard let promise = self.sharingContext?.pendingPromise else { 55 log.error("SharingModule: sharing context has been lost") 56 return 57 } 58 59 promise.resolve(nil) 60 self.sharingContext = nil 61 self.documentInteractionController?.dismissMenu(animated: true) 62 self.documentInteractionController = nil 63 } 64 } 65