1 import ExpoModulesCore
2 
3 public final class SharingModule: Module {
4 
definitionnull5   public func definition() -> ModuleDefinition {
6     Name("ExpoSharing")
7 
8     AsyncFunction("shareAsync") { (url: URL, options: SharingOptions, promise: Promise) in
9       guard let filePermissions: EXFilePermissionModuleInterface =
10         appContext?.legacyModule(implementing: EXFilePermissionModuleInterface.self)
11       else {
12         throw FilePermissionModuleException()
13       }
14 
15       let grantedPermissions = filePermissions.getPathPermissions(url.relativePath)
16       guard grantedPermissions.rawValue >= EXFileSystemPermissionFlags.read.rawValue else {
17         throw FilePermissionException()
18       }
19 
20       let activityController = UIActivityViewController(activityItems: [url], applicationActivities: nil)
21       activityController.title = options.dialogTitle
22 
23       activityController.completionWithItemsHandler = { type, completed, _, _ in
24         // user shared an item
25         if type != nil && completed {
26           promise.resolve(nil)
27         }
28 
29         // dismissed without action
30         if type == nil && !completed {
31           promise.resolve(nil)
32         }
33       }
34 
35       guard let currentViewcontroller = appContext?.utilities?.currentViewController() else {
36         throw MissingCurrentViewControllerException()
37       }
38 
39       // Apple docs state that `UIActivityViewController` must be presented in a
40       // popover on iPad https://developer.apple.com/documentation/uikit/uiactivityviewcontroller
41       if UIDevice.current.userInterfaceIdiom == .pad {
42         let viewFrame = currentViewcontroller.view.frame
43         activityController.popoverPresentationController?.sourceRect = CGRect(
44           x: viewFrame.midX,
45           y: viewFrame.maxY,
46           width: 0,
47           height: 0
48         )
49         activityController.popoverPresentationController?.sourceView = currentViewcontroller.view
50         activityController.modalPresentationStyle = .pageSheet
51       }
52 
53       currentViewcontroller.present(activityController, animated: true)
54     }
55     .runOnQueue(.main)
56   }
57 }
58