diff --git a/.gitignore b/.gitignore
index 95c4320..f3c8e33 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@
/Packages
/*.xcodeproj
xcuserdata/
+.swiftpm/
diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
deleted file mode 100644
index 706eede..0000000
--- a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
diff --git a/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
deleted file mode 100644
index 18d9810..0000000
--- a/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
- IDEDidComputeMac32BitWarning
-
-
-
diff --git a/Package.swift b/Package.swift
index ca5cdcc..f9ba04e 100644
--- a/Package.swift
+++ b/Package.swift
@@ -6,23 +6,11 @@ import PackageDescription
let package = Package(
name: "Share",
products: [
- // Products define the executables and libraries produced by a package, and make them visible to other packages.
- .library(
- name: "Share",
- targets: ["Share"]),
- ],
- dependencies: [
- // Dependencies declare other packages that this package depends on.
- // .package(url: /* package url */, from: "1.0.0"),
+ .library(name: "Share", targets: ["Share"]),
],
+ dependencies: [ ],
targets: [
- // Targets are the basic building blocks of a package. A target can define a module or a test suite.
- // Targets can depend on other targets in this package, and on products in packages which this package depends on.
- .target(
- name: "Share",
- dependencies: []),
- .testTarget(
- name: "ShareTests",
- dependencies: ["Share"]),
+ .target(name: "Share", dependencies: []),
+ .testTarget(name: "ShareTests", dependencies: ["Share"]),
]
)
diff --git a/Sources/Share/Share.swift b/Sources/Share/Share.swift
index 6c3d50c..d6c563a 100644
--- a/Sources/Share/Share.swift
+++ b/Sources/Share/Share.swift
@@ -1,3 +1,51 @@
-struct Share {
- var text = "Hello, World!"
+#if os(macOS)
+import Cocoa
+#elseif os(iOS)
+import UIKit
+#endif
+
+public protocol Sharable {
+ var shareItems: [Any] { get }
+}
+
+public protocol ShareDelegate {
+ func didChange(status: Share.Service.Status)
+}
+
+public struct Share { }
+
+extension Share {
+ #if os(macOS)
+ public typealias Service = NSSharingService
+ #elseif os(iOS)
+ public typealias Service = UIActivity.ActivityType
+ #endif
+}
+
+extension Share.Service {
+ public enum Status {
+ case willShare([Any], via: Share.Service)
+ case didShare([Any], via: Share.Service)
+ case error(Share.Service.Status.Error, sharing:[Any])
+ }
+}
+
+extension Share.Service.Status {
+ public enum Error {
+ case cancelled(Share.Service?)
+ case other(Swift.Error, with: Share.Service?)
+
+ var service: Share.Service? {
+ switch self {
+ case .cancelled(let service): return service
+ case .other(_, with: let service): return service
+ }
+ }
+ }
+}
+
+extension Sharable {
+ public func shareSheet(delegate: ShareDelegate? = nil) -> Share.Sheet {
+ return Share.Sheet(for: self, delegate: delegate)
+ }
}
diff --git a/Sources/Share/Sheet.swift b/Sources/Share/Sheet.swift
new file mode 100644
index 0000000..b27b7fa
--- /dev/null
+++ b/Sources/Share/Sheet.swift
@@ -0,0 +1,85 @@
+#if os(macOS)
+import Cocoa
+
+extension Share {
+ public class Sheet: NSSharingServicePicker, NSSharingServicePickerDelegate, NSSharingServiceDelegate {
+ let sharable: Sharable
+ let serviceDelegate: ShareDelegate?
+
+ private override init(items: [Any]) { fatalError("This is private") }
+
+ public init(for sharable: Sharable, delegate: ShareDelegate? = nil) {
+ self.sharable = sharable
+ serviceDelegate = delegate
+ super.init(items: sharable.shareItems)
+ }
+
+ // MARK:- NSSharingServicePickerDelegate
+ public func sharingServicePicker(_ sharingServicePicker: NSSharingServicePicker, didChoose service: NSSharingService?) {
+ guard service == nil
+ else { return }
+
+ serviceDelegate?.didChange(status: .error(.cancelled(service), sharing: sharable.shareItems))
+ }
+
+ public func sharingServicePicker(_ sharingServicePicker: NSSharingServicePicker, delegateFor sharingService: NSSharingService) -> NSSharingServiceDelegate? {
+ return self
+ }
+
+ // MARK:- NSSharingServiceDelegate
+
+ public func sharingService(_ sharingService: NSSharingService, willShareItems items: [Any]) {
+ serviceDelegate?.didChange(status: .willShare(items, via: sharingService))
+ }
+
+ public func sharingService(_ sharingService: NSSharingService, didShareItems items: [Any]) {
+ serviceDelegate?.didChange(status: .didShare(items, via: sharingService))
+ }
+
+ public func sharingService(_ sharingService: NSSharingService, didFailToShareItems items: [Any], error: Error) {
+ serviceDelegate?.didChange(status: .error(.other(error, with: sharingService), sharing: items))
+ }
+ }
+}
+#endif
+
+#if os(iOS)
+import UIKit
+
+extension Share {
+ public class Sheet: UIActivityViewController {
+ let sharable: Sharable
+ let serviceDelegate: ShareDelegate?
+
+ public init(for sharable: Sharable, delegate: ShareDelegate? = nil) {
+ self.sharable = sharable
+ serviceDelegate = delegate
+
+ super.init(activityItems: sharable.shareItems, applicationActivities: nil)
+
+ completionWithItemsHandler = {(activityType: UIActivity.ActivityType?, completed: Bool, returnedItems:[Any]?, error: Error?) in
+ guard let service = activityType
+ else { self.report(error: .cancelled(activityType)); return }
+
+ if let error = error {
+ self.report(error: .other(error, with: service)); return
+ }
+
+ if !completed {
+ self.report(.willShare(sharable.shareItems, via: service))
+ } else {
+ self.report(.didShare(sharable.shareItems, via: service))
+ }
+ }
+ }
+
+ private func report(_ status: Share.Service.Status) {
+ serviceDelegate?.didChange(status: status)
+ }
+
+ private func report(error: Share.Service.Status.Error) {
+ serviceDelegate?.didChange(status: .error(error, sharing: sharable.shareItems))
+ }
+ }
+}
+#endif