Open acoutts opened 4 years ago
On closer look, I think it's working fine, and I have a bug elsewhere.
No, there is definitely an isssue.
} else {
latestText = url.absoluteString
if(setInitialData) {
initialText = latestText
}
eventSinkText?(latestText)
}
This will send any deep link back through and return true saying it's been handled. It should only handle it if it's relevant and from the share extension.
Here's one example. Wrap the inside of handleUrl
in SwiftReceiveSharingIntentPlugin.swift
with this:
if (url.absoluteString.contains("\(Bundle.main.infoDictionary!["CFBundleIdentifier"] as! String).ShareExtension")) {
This will only handle the url if it contains bundleIdentifier.ShareExtension
, and then in ShareViewController.swift
inside your own project, modify redirectToHostApp
to look like this:
let url = URL(string: "\(Bundle.main.infoDictionary!["CFBundleIdentifier"] as! String)://dataUrl=\(sharedKey)#\(type)")
Then make sure your project's Info.plist
has this scheme registered:
<dict>
<key>CFBundleURLName</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleURLSchemes</key>
<array>
<string>$(PRODUCT_BUNDLE_IDENTIFIER).ShareExtension</string>
</array>
</dict>
That should ensure only relevant links are handled from the plugin.
@KasemJaffer @acoutts Can we get a PR for this?
When I dug into this more, it's a much harder problem to solve to make it interoperate with unil_inks. In the end I removed unilinks and just use this lib to handle all of my deep linking and share intent now. It's tough because deep linking is so similar to this. It probably makes sense to just use this for everything if you intent to handle share intent and deep linking, and use uni_links if you don't need to handle share intent.
My concern is if I want to add firebase_dynamic_links in the future.
I'm not an IOS developer but based on this comment https://github.com/KasemJaffer/receive_sharing_intent/issues/36#issuecomment-595130324 it seems like different url schemes can be defined here? My app uses google_sign_in and part of the IOS integration requires defining a separate url scheme.
That's generally how the share extension communicates with the host app, via deep link. But the problem is, if you launch the app from an exited state by sharing a URL to it, then that also comes in on the didFinishLaunchingWithOptions
hook. And if someone else handles that link then the other libs won't see it. It is a race condition for who gets the didFinishLaunchingWithOptions
hook first.
In the end I think the best solution here is to make didFinishLaunchingWithOptions
always return true
, but just call handleUrl
like normal. This way we never make a decision about if the app can handle the URL or not because some other plugin in the app might handle it.
This is how I see it done in firebase_messaging and uni_links.
In the plugin, update it like this:
public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [AnyHashable : Any] = [:]) -> Bool {
if let url = launchOptions[UIApplication.LaunchOptionsKey.url] as? URL {
// Handle a single URL shared in
let _ = handleUrl(url: url, setInitialData: true)
} else if let activityDictionary = launchOptions[UIApplication.LaunchOptionsKey.userActivityDictionary] as? [AnyHashable: Any] {
// Handle multiple URLs shared in
for key in activityDictionary.keys {
if let userActivity = activityDictionary[key] as? NSUserActivity {
if let url = userActivity.webpageURL {
let _ = handleUrl(url: url, setInitialData: true)
}
}
}
}
return true
}
Made a PR that should resolve the issue of not propagating events to other modules. Not an iOS expert so feel free to offer suggestions.
@danReynolds still that fix of yours didn't work for me. I'm using receive_sharing_intent: ^1.4.3
and firebase_messaging: ^7.0.0
but firebase deep linking does not work for me. Any help on how to fix it?
Any updates on this @KasemJaffer @danReynolds ?
I understand the way this works is the share extension (a separate process) writes the shared files into a temporary location (the shared group), and then sends a deep link containing the path to the shared file (or just the url string if a url was shared) through a deep link to the plugin code, where it picks it up in these handlers: https://github.com/KasemJaffer/receive_sharing_intent/blob/master/ios/Classes/SwiftReceiveSharingIntentPlugin.swift#L53-L74
Then it sends a stream event so that the dart code can read the shared file path.
But the problem is, with the way it is currently implemented, it hijacks all deep links shared to the app, even if they weren't intended for this plugin. This is unexpected behavior and I just had to spend a lot of time tracing down why uni_links couldn't pickup anything. It's a race condition for which swift code runs first to get the
handleUrl
hook.What should be done is a check should be made to make sure the URL is relevant only to us in this context and allowing anything else to pass by to other intent / deep link listeners.