Comments (11)
thanks
from send-intent.
hi i dont have solution but i am not able to do successfully on ios can you please tell how you add and how you create group id or if you dont mind can you share code please
from send-intent.
Hello,
thankYou for your answer.
Im using your code from doc. See details below.
AppDelegate.swift
`import UIKit
import Capacitor
import SendIntent
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
let store = ShareStore.store
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
var success = true
if CAPBridge.handleOpenUrl(url, options) {
success = ApplicationDelegateProxy.shared.application(app, open: url, options: options)
}
guard let components = NSURLComponents(url: url, resolvingAgainstBaseURL: true),
let params = components.queryItems else {
return false
}
let titles = params.filter { $0.name == "title" }
let descriptions = params.filter { $0.name == "description" }
let types = params.filter { $0.name == "type" }
let urls = params.filter { $0.name == "url" }
store.shareItems.removeAll()
if(titles.count > 0){
for index in 0...titles.count-1 {
var shareItem: JSObject = JSObject()
shareItem["title"] = titles[index].value!
shareItem["description"] = descriptions[index].value!
shareItem["type"] = types[index].value!
shareItem["url"] = urls[index].value!
store.shareItems.append(shareItem)
}
}
dump(store.shareItems)
store.processed = false
let nc = NotificationCenter.default
nc.post(name: Notification.Name("triggerSendIntent"), object: nil )
return success
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
// Called when the app was launched with an activity, including Universal Links.
// Feel free to add additional processing here, but if you want the App API to support
// tracking app url opens, make sure to keep this call
return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
NotificationCenter.default.post(name: .capacitorDidRegisterForRemoteNotifications, object: deviceToken)
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
NotificationCenter.default.post(name: .capacitorDidFailToRegisterForRemoteNotifications, object: error)
}
}
`
ShareViewController.swift
`
import MobileCoreServices
import Social
import UIKit
class ShareItem {
public var title: String?
public var type: String?
public var url: String?
}
class ShareViewController: UIViewController {
private var shareItems: [ShareItem] = []
override public func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
}
private func sendData() {
let queryItems = shareItems.map {
[
URLQueryItem(
name: "title",
value: $0.title?.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? ""),
URLQueryItem(name: "description", value: ""),
URLQueryItem(
name: "type",
value: $0.type?.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? ""),
URLQueryItem(
name: "url",
value: $0.url?.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? ""),
]
}.flatMap({ $0 })
var urlComps = URLComponents(string: "vcpgo://")!
urlComps.queryItems = queryItems
openURL(urlComps.url!)
}
fileprivate func createSharedFileUrl(_ url: URL?) -> String {
let fileManager = FileManager.default
let copyFileUrl =
fileManager.containerURL(forSecurityApplicationGroupIdentifier: "group.vcpgo")!
.absoluteString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)! + "/" + url!
.lastPathComponent.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
try? Data(contentsOf: url!).write(to: URL(string: copyFileUrl)!)
return copyFileUrl
}
func saveScreenshot(_ image: UIImage) -> String {
let fileManager = FileManager.default
let copyFileUrl =
fileManager.containerURL(forSecurityApplicationGroupIdentifier: "group.vcpgo")!
.absoluteString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
+ "/screenshot.png"
do {
try image.pngData()?.write(to: URL(string: copyFileUrl)!)
return copyFileUrl
} catch {
print(error.localizedDescription)
return ""
}
}
fileprivate func handleTypeUrl(_ attachment: NSItemProvider)
async throws -> ShareItem
{
let results = try await attachment.loadItem(forTypeIdentifier: kUTTypeURL as String, options: nil)
let url = results as! URL?
let shareItem: ShareItem = ShareItem()
if url!.isFileURL {
shareItem.title = url!.lastPathComponent
shareItem.type = "application/" + url!.pathExtension.lowercased()
shareItem.url = createSharedFileUrl(url)
} else {
shareItem.title = url!.absoluteString
shareItem.url = url!.absoluteString
shareItem.type = "text/plain"
}
return shareItem
}
fileprivate func handleTypeText(_ attachment: NSItemProvider)
async throws -> ShareItem
{
let results = try await attachment.loadItem(forTypeIdentifier: kUTTypeText as String, options: nil)
let shareItem: ShareItem = ShareItem()
let text = results as! String
shareItem.title = text
shareItem.type = "text/plain"
return shareItem
}
fileprivate func handleTypeMovie(_ attachment: NSItemProvider)
async throws -> ShareItem
{
let results = try await attachment.loadItem(forTypeIdentifier: kUTTypeMovie as String, options: nil)
let shareItem: ShareItem = ShareItem()
let url = results as! URL?
shareItem.title = url!.lastPathComponent
shareItem.type = "video/" + url!.pathExtension.lowercased()
shareItem.url = createSharedFileUrl(url)
return shareItem
}
fileprivate func handleTypeImage(_ attachment: NSItemProvider)
async throws -> ShareItem
{
let data = try await attachment.loadItem(forTypeIdentifier: kUTTypeImage as String, options: nil)
let shareItem: ShareItem = ShareItem()
switch data {
case let image as UIImage:
shareItem.title = "screenshot"
shareItem.type = "image/png"
shareItem.url = self.saveScreenshot(image)
case let url as URL:
shareItem.title = url.lastPathComponent
shareItem.type = "image/" + url.pathExtension.lowercased()
shareItem.url = self.createSharedFileUrl(url)
default:
print("Unexpected image data:", type(of: data))
}
return shareItem
}
override public func viewDidLoad() {
super.viewDidLoad()
shareItems.removeAll()
let extensionItem = extensionContext?.inputItems[0] as! NSExtensionItem
Task {
try await withThrowingTaskGroup(
of: ShareItem.self,
body: { taskGroup in
for attachment in extensionItem.attachments! {
if attachment.hasItemConformingToTypeIdentifier(kUTTypeURL as String) {
taskGroup.addTask {
return try await self.handleTypeUrl(attachment)
}
} else if attachment.hasItemConformingToTypeIdentifier(kUTTypeText as String) {
taskGroup.addTask {
return try await self.handleTypeText(attachment)
}
} else if attachment.hasItemConformingToTypeIdentifier(kUTTypeMovie as String) {
taskGroup.addTask {
return try await self.handleTypeMovie(attachment)
}
} else if attachment.hasItemConformingToTypeIdentifier(kUTTypeImage as String) {
taskGroup.addTask {
return try await self.handleTypeImage(attachment)
}
}
}
for try await item in taskGroup {
self.shareItems.append(item)
}
})
self.sendData()
}
}
@objc func openURL(_ url: URL) -> Bool {
var responder: UIResponder? = self
while responder != nil {
if let application = responder as? UIApplication {
return application.perform(#selector(openURL(_:)), with: url) != nil
}
responder = responder?.next
}
return false
}
}
`
Dump from AppDelegate.swift shows following data. Even if Im sharing 5 different files, in the dump you can see one exact file 5 times instead of 5 different files.
5 elements ▿ 4 key/value pairs ▿ (2 elements) - key: "title" - value: "PHOTO-2023-03-24-09-49-39.jpg" ▿ (2 elements) - key: "description" - value: "" ▿ (2 elements) - key: "type" - value: "application%2Fjpg" ▿ (2 elements) - key: "url" - value: "file%3A%2F%2F%2Fprivate%2Fvar%2Fmobile%2FContainers%2FShared%2FAppGroup%2FAF4D217D-A918-4245-9C60-ACDF619D2EBC%2F%2FPHOTO-2023-03-24-09-49-39.jpg" ▿ 4 key/value pairs ▿ (2 elements) - key: "url" - value: "file%3A%2F%2F%2Fprivate%2Fvar%2Fmobile%2FContainers%2FShared%2FAppGroup%2FAF4D217D-A918-4245-9C60-ACDF619D2EBC%2F%2FPHOTO-2023-03-24-09-49-39.jpg" ▿ (2 elements) - key: "type" - value: "application%2Fjpg" ▿ (2 elements) - key: "description" - value: "" ▿ (2 elements) - key: "title" - value: "PHOTO-2023-03-24-09-49-39.jpg" ▿ 4 key/value pairs ▿ (2 elements) - key: "title" - value: "PHOTO-2023-03-24-09-49-39.jpg" ▿ (2 elements) - key: "url" - value: "file%3A%2F%2F%2Fprivate%2Fvar%2Fmobile%2FContainers%2FShared%2FAppGroup%2FAF4D217D-A918-4245-9C60-ACDF619D2EBC%2F%2FPHOTO-2023-03-24-09-49-39.jpg" ▿ (2 elements) - key: "type" - value: "application%2Fjpg" ▿ (2 elements) - key: "description" - value: "" ▿ 4 key/value pairs ▿ (2 elements) - key: "description" - value: "" ▿ (2 elements) - key: "type" - value: "application%2Fjpg" ▿ (2 elements) - key: "title" - value: "PHOTO-2023-03-24-09-49-39.jpg" ▿ (2 elements) - key: "url" - value: "file%3A%2F%2F%2Fprivate%2Fvar%2Fmobile%2FContainers%2FShared%2FAppGroup%2FAF4D217D-A918-4245-9C60-ACDF619D2EBC%2F%2FPHOTO-2023-03-24-09-49-39.jpg" ▿ 4 key/value pairs ▿ (2 elements) - key: "title" - value: "PHOTO-2023-03-24-09-49-39.jpg" ▿ (2 elements) - key: "url" - value: "file%3A%2F%2F%2Fprivate%2Fvar%2Fmobile%2FContainers%2FShared%2FAppGroup%2FAF4D217D-A918-4245-9C60-ACDF619D2EBC%2F%2FPHOTO-2023-03-24-09-49-39.jpg" ▿ (2 elements) - key: "type" - value: "application%2Fjpg" ▿ (2 elements) - key: "description" - value: ""
from send-intent.
Hello! Is this only on Whatsapp? Have you tried debugging ShareViewController.swift to see if the data arrives correctly at the plugin? (If not, I will test it later but I will have to set up a case first)
Best regards
from send-intent.
@carsten-klaffke Hi, it only happens when I share from WhatsApp, sharing multiple files from gallery works great. I tried to debug ShareViewController but I was not able to come to anything. ThankYou very much.
from send-intent.
@tarangshah19 @carsten-klaffke Guys, any update on this issue please?
from send-intent.
I created an Example (uploaded it to this repository) to test multiple file share. But I only have an iPad (no iPhone) and Whatsapp is not available for that. If you'd find another app where this happens, I could test it. Otherwise I have to wait to get an iPhone borrowed.
from send-intent.
@carsten-klaffke same thing happens when you share from Telegram or Signal messaging app, can you please test it in one of those apps, they might be available for iPad, ThankYou!
from send-intent.
Hey @StepZEROsk, I was now able to reproduce the bug (with Signal). There was an error in ShareViewController.swift, which put the same name for all images if they come as type image and not URL. I fixed it in the Code of SendIntentExample and also updated the Readme accordingly. Please let me know if this solves it for you!
from send-intent.
@carsten-klaffke it works with Signal and Telegram, but still doesn't work with WhatsApp. Im not sure what the different is, but when I share from WhatsApp i'm getting the actual file name, not the name generated with the index, like Im getting from Signal and Telegram.
from send-intent.
@carsten-klaffke From WhatsApp they comes like URL
from send-intent.
Related Issues (20)
- App crash after SendIntent.finish() HOT 14
- Multi Files HOT 1
- Android app reload when sharing HOT 1
- IOS ,Universal link
- multiple file when app working on background not get catch HOT 4
- Changelog? What changed in v3? HOT 2
- Android: Class referenced in the manifest, SendIntentActivity, was not found HOT 3
- Compatibility with Capacitor 5 HOT 3
- Video upload not working android HOT 1
- ShareViewController transfers too many '/' in file url HOT 2
- [solved] Manual signing HOT 3
- Named export not found. The request module is a CommonJS module
- [Android] Receive multiple intent data until app hangs and App Crash after calling finish HOT 2
- Invalid Info.plist value for NSExtensionActivationRule HOT 4
- My Capacitor app does not show up in the "Open With" list of GMAIL HOT 1
- App crashes upon changing device orientation HOT 2
- View intent on Android HOT 1
- Plugin working fine in android but not working in ios HOT 13
- App crashes when switching between Sliding Tabs by clicking the tabs (not swiping) HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from send-intent.