57 lines
2.2 KiB
Swift
57 lines
2.2 KiB
Swift
import Flutter
|
|
import UIKit
|
|
import receive_sharing_intent
|
|
|
|
// FlutterSceneDelegate has a fallback that forwards URL events to plugins
|
|
// registered via addApplicationDelegate, but the fallback is best-effort and
|
|
// has not always fired in our setup. This subclass forwards URLs explicitly
|
|
// to receive_sharing_intent so cold-start and warm shares both reach Dart.
|
|
class SceneDelegate: FlutterSceneDelegate {
|
|
override func scene(
|
|
_ scene: UIScene,
|
|
willConnectTo session: UISceneSession,
|
|
options connectionOptions: UIScene.ConnectionOptions
|
|
) {
|
|
super.scene(scene, willConnectTo: session, options: connectionOptions)
|
|
var handledShare = false
|
|
for context in connectionOptions.urlContexts where isShareUrl(context.url) {
|
|
_ = ReceiveSharingIntentPlugin.instance.application(
|
|
UIApplication.shared,
|
|
didFinishLaunchingWithOptions: [UIApplication.LaunchOptionsKey.url: context.url]
|
|
)
|
|
handledShare = true
|
|
}
|
|
if handledShare { clearSharedPayload() }
|
|
}
|
|
|
|
override func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
|
|
let shares = URLContexts.filter { isShareUrl($0.url) }
|
|
for context in shares {
|
|
_ = ReceiveSharingIntentPlugin.instance.application(
|
|
UIApplication.shared,
|
|
open: context.url,
|
|
options: [:]
|
|
)
|
|
}
|
|
if !shares.isEmpty { clearSharedPayload() }
|
|
let others = URLContexts.subtracting(shares)
|
|
if !others.isEmpty { super.scene(scene, openURLContexts: others) }
|
|
}
|
|
|
|
private func isShareUrl(_ url: URL) -> Bool {
|
|
ReceiveSharingIntentPlugin.instance.hasMatchingSchemePrefix(url: url)
|
|
}
|
|
|
|
// The plugin keeps the payload in memory once read but never removes it
|
|
// from the App Group defaults. The Share Extension opens the app twice per
|
|
// share and a scene reconnect replays the URL, so every later delivery
|
|
// would publish the finished share again.
|
|
private func clearSharedPayload() {
|
|
let groupId = Bundle.main.object(forInfoDictionaryKey: "AppGroupId") as? String
|
|
let defaults = UserDefaults(
|
|
suiteName: groupId ?? "group.\(Bundle.main.bundleIdentifier ?? "")")
|
|
defaults?.removeObject(forKey: "ShareKey")
|
|
defaults?.removeObject(forKey: "ShareMessageKey")
|
|
}
|
|
}
|