UIActivityController to share URL file - ios

I want to share an URL file that has been created in the app and a text. But it seems it only can share text and not any data like URL or UIImage.
The code I am using:
let sharedVideo = Video(Title: _data[1], VideoID: _data[0], Duration: _data[3], ViewCount: _data[2])
let sharedURL = VideoManager.exportData(video: sharedVideo)
let shareItems:Array = [sharedURL,"check this out baby!"] as [Any]
let activityViewController = UIActivityViewController(activityItems: shareItems, applicationActivities: nil)
self.present(activityViewController, animated: true, completion: nil)
Also I use an UIImage object instead of sharedURL to see If it has problem with URL or not.
It doesn't work even with an image file. When I click on share button inside UIActivityViewController, It works just for text, no URL nor image.
I am using Swift 3 in Xcode 8.
Thanks.
PS: I am sure about sharedURL object that it isn't nil nor undefined.

Try this:
#IBAction func btnExport(sender: AnyObject)
{
let someText:String = "Hello want to share text also"
let objectsToShare:URL = URL(string: "http://www.google.com")!
let sharedObjects:[AnyObject] = [objectsToShare as AnyObject,someText as AnyObject]
let activityViewController = UIActivityViewController(activityItems : sharedObjects, applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view
activityViewController.excludedActivityTypes = [ UIActivityType.airDrop, UIActivityType.postToFacebook,UIActivityType.postToTwitter,UIActivityType.mail]
self.present(activityViewController, animated: true, completion: nil)
}

Simplified solution working with Swift 5+
let url = URL(string: shareUrlString)!
let text = "Some text that you want shared"
let activity = UIActivityViewController(activityItems: [url, text], applicationActivities: nil)
present(activity, animated: true)

Related

How to share image with embedded url in Swift

I've created a function that will allow the user to share content via message, email, etc. However, I've only been able to include an image and a URL as separate objects. I would like to include a small image that has the url embedded, so the user can just tap the image. Is there any way to do this?
func shareApp() {
let textToShare = "Checkout this app!"
let imageToShare = UIImage(named: “ProductIcon”)
if let myWebsite = URL(string: "http://www.productwebsite.ca")
{
let objectsToShare = [textToShare, imageToShare, myWebsite] as [Any]
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
activityVC.view.backgroundColor = UIColor.clear
//Excluded Activities Code
activityVC.excludedActivityTypes = [UIActivity.ActivityType.airDrop, UIActivity.ActivityType.addToReadingList]
self.present(activityVC, animated: true, completion: nil)
}
}

NSURL prints twice when sharing through UIActivityView

Here is my code
let myURL = URL(string: "http://www.dwz.cn/BabySmarter")
let shareActivity = UIActivityViewController(activityItems: [myURL!, "我的宝宝比\(String(describing: Int(finalScore!)))% 的宝宝更发展!你的呢?"], applicationActivities: nil)
shareActivity.popoverPresentationController?.sourceView = self.view
self.present(shareActivity, animated: true, completion: nil)
Here is the result:
This has to be a glitch. Or am I completely wrong here?
May be problem with URL , you can pass url as string.
let shareActivity = UIActivityViewController(activityItems: ["http://www.dwz.cn/BabySmarter 我的宝宝比\(String(describing: Int(finalScore!)))% 的宝宝更发展!你的呢?"], applicationActivities: nil)
shareActivity.popoverPresentationController?.sourceView = self.view
self.present(shareActivity, animated: true, completion: nil)

iOS : customize of activityViewController

hi I implemented activityViewController and my activityItems is text when I press button this will pop up and I choose mail IMPORTENT : when I choose it my text in the (activityItems) go to the message body but I want it to go in sender message textfield (To :)
how should I implement this???
#IBAction func activityView(_ sender: UIButton) {
let text = "Mahdi.m#email.com"
let img = UIImage(named: "Buliding")!
let activityViewController = UIActivityViewController(activityItems: [text, img], applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view
activityViewController.excludedActivityTypes = [ UIActivityType.airDrop]
self.present(activityViewController, animated: true, completion: nil)
}

Basic example for sharing text or image with UIActivityViewController in Swift

I started my search by wanting to know how I could share to other apps in iOS. I discovered that two important ways are
UIActivityViewController
UIDocumentInteractionController
These and other methods are compared in this SO answer.
Often when I am learning a new concept I like to see a basic example to get me started. Once I get something basic set up I can modify it how I like later.
There are many SO questions related to UIActivityViewController, but I couldn't find any that were just asking for a simple example. Since I just learned how to do this, I will provide my own answer below. Feel free to add a better one (or an Objective-C version).
UIActivityViewController Example Project
Set up your storyboard with two buttons and hook them up to your view controller (see code below).
Add an image to your Assets.xcassets. I called mine "lion".
Code
import UIKit
class ViewController: UIViewController {
// share text
#IBAction func shareTextButton(_ sender: UIButton) {
// text to share
let text = "This is some text that I want to share."
// set up activity view controller
let textToShare = [ text ]
let activityViewController = UIActivityViewController(activityItems: textToShare, applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view // so that iPads won't crash
// exclude some activity types from the list (optional)
activityViewController.excludedActivityTypes = [ UIActivity.ActivityType.airDrop, UIActivity.ActivityType.postToFacebook ]
// present the view controller
self.present(activityViewController, animated: true, completion: nil)
}
// share image
#IBAction func shareImageButton(_ sender: UIButton) {
// image to share
let image = UIImage(named: "Image")
// set up activity view controller
let imageToShare = [ image! ]
let activityViewController = UIActivityViewController(activityItems: imageToShare, applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view // so that iPads won't crash
// exclude some activity types from the list (optional)
activityViewController.excludedActivityTypes = [ UIActivity.ActivityType.airDrop, UIActivity.ActivityType.postToFacebook ]
// present the view controller
self.present(activityViewController, animated: true, completion: nil)
}
}
Result
Clicking "Share some text" gives result on the left and clicking "Share an image" gives the result on the right.
Notes
I retested this with iOS 11 and Swift 4. I had to run it a couple times in the simulator before it worked because it was timing out. This may be because my computer is slow.
If you wish to hide some of these choices, you can do that with excludedActivityTypes as shown in the code above.
Not including the popoverPresentationController?.sourceView line will cause your app to crash when run on an iPad.
This does not allow you to share text or images to other apps. You probably want UIDocumentInteractionController for that.
See also
Add sharing to your Swift app via UIActivityViewController
UIActivity​View​Controller from NSHipster
UIActivityViewController documentation
Share extension documentation
comparison with UIDocumentInteractionController
Share : Text
#IBAction func shareOnlyText(_ sender: UIButton) {
let text = "This is the text....."
let textShare = [ text ]
let activityViewController = UIActivityViewController(activityItems: textShare , applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view
self.present(activityViewController, animated: true, completion: nil)
}
}
Share : Image
#IBAction func shareOnlyImage(_ sender: UIButton) {
let image = UIImage(named: "Product")
let imageShare = [ image! ]
let activityViewController = UIActivityViewController(activityItems: imageShare , applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view
self.present(activityViewController, animated: true, completion: nil)
}
Share : Text - Image - URL
#IBAction func shareAll(_ sender: UIButton) {
let text = "This is the text...."
let image = UIImage(named: "Product")
let myWebsite = NSURL(string:"https://stackoverflow.com/users/4600136/mr-javed-multani?tab=profile")
let shareAll= [text , image! , myWebsite]
let activityViewController = UIActivityViewController(activityItems: shareAll, applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view
self.present(activityViewController, animated: true, completion: nil)
}
Just as a note you can also use this for iPads:
activityViewController.popoverPresentationController?.sourceView = sender
So the popover pops from the sender (the button in that case).
I found this to work flawlessly if you want to share whole screen.
#IBAction func shareButton(_ sender: Any) {
let bounds = UIScreen.main.bounds
UIGraphicsBeginImageContextWithOptions(bounds.size, true, 0.0)
self.view.drawHierarchy(in: bounds, afterScreenUpdates: false)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let activityViewController = UIActivityViewController(activityItems: [img!], applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view
self.present(activityViewController, animated: true, completion: nil)
}
I've used the implementation above and just now I came to know that it doesn't work on iPad running iOS 13.
I had to add these lines before present() call in order to make it work
//avoiding to crash on iPad
if let popoverController = activityViewController.popoverPresentationController {
popoverController.sourceRect = CGRect(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height / 2, width: 0, height: 0)
popoverController.sourceView = self.view
popoverController.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
}
That's how it works for me
func shareData(_ dataToShare: [Any]){
let activityViewController = UIActivityViewController(activityItems: dataToShare, applicationActivities: nil)
//exclude some activity types from the list (optional)
//activityViewController.excludedActivityTypes = [
//UIActivity.ActivityType.postToFacebook
//]
//avoiding to crash on iPad
if let popoverController = activityViewController.popoverPresentationController {
popoverController.sourceRect = CGRect(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height / 2, width: 0, height: 0)
popoverController.sourceView = self.view
popoverController.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)
}
self.present(activityViewController, animated: true, completion: nil)
}
You may use the following functions which I wrote in one of my helper class in a project.
just call
showShareActivity(msg:"message", image: nil, url: nil, sourceRect: nil)
and it will work for both iPhone and iPad. If you pass any view's CGRect value by sourceRect it will also shows a little arrow in iPad.
func topViewController()-> UIViewController{
var topViewController:UIViewController = UIApplication.shared.keyWindow!.rootViewController!
while ((topViewController.presentedViewController) != nil) {
topViewController = topViewController.presentedViewController!;
}
return topViewController
}
func showShareActivity(msg:String?, image:UIImage?, url:String?, sourceRect:CGRect?){
var objectsToShare = [AnyObject]()
if let url = url {
objectsToShare = [url as AnyObject]
}
if let image = image {
objectsToShare = [image as AnyObject]
}
if let msg = msg {
objectsToShare = [msg as AnyObject]
}
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
activityVC.modalPresentationStyle = .popover
activityVC.popoverPresentationController?.sourceView = topViewController().view
if let sourceRect = sourceRect {
activityVC.popoverPresentationController?.sourceRect = sourceRect
}
topViewController().present(activityVC, animated: true, completion: nil)
}
iOS share text or image
present UIActivityViewController
let controller = UIActivityViewController(activityItems: [someObject], applicationActivities: nil) //someObject can be UIImage, NSURL, String... iOS decide how to handle it properly
controller.popoverPresentationController?.sourceView = self.view
controller.completionWithItemsHandler = {
(
activityType: UIActivity.ActivityType?,
completed: Bool,
arrayReturnedItems: [Any]?,
error: Error?
) in
if let error = error {
//error occured
return
}
if completed {
if let activityType = activityType {
switch activityType {
case .saveToCameraRoll:
break
case .copyToPasteboard:
break
case .addToReadingList:
break
case .airDrop:
break
default:
//all others
break
}
}
} else {
//Cancel
}
}
self.present(controller, animated: true)
If you are going to save image into library add NSPhotoLibraryAddUsageDescription into app's .plist file or you get runtime error
This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryAddUsageDescription key with a string value explaining to the user how the app uses this data.
or just exclude this opportunity:
controller.excludedActivityTypes = [.saveToCameraRoll]
variant with completionWithItemsHandler which can helps to add post logic or handle errors.
For example I run into next error when saving UIImage into Photo library in a corresponding handler:
Error Domain=ALAssetsLibraryErrorDomain Code=-1 "Unknown error" UserInfo={NSLocalizedDescription=Unknown error, NSUnderlyingError=0x600003f85110 {Error Domain=PHPhotosErrorDomain Code=3303 "(null)"}}
As figured out I tried to save CIImage. As a variant you can convert it to CGImage
let context = CIContext()
guard let cgImage = context.createCGImage(output, from: output.extent) else { return nil }
return UIImage(cgImage: cgImage)

How to share an URL Scheme link to social app

I want to share an URL scheme link to social app so that when the user open social page on safari, when they click on the link, the URL scheme will call to the app I set. But when I share, it only share the text. How to share the link instead of the text.
Here is the code:
#IBAction func shareButtonAction(sender: AnyObject) {
print("share")
let myShare = "TestSafari://"
let shareVC: UIActivityViewController = UIActivityViewController(activityItems: [myShare], applicationActivities: nil)
self.presentViewController(shareVC, animated: true, completion: nil)
}
You probably need to put a text first then the url, in that particular order. Try this:
let string: String = ...
let URL: NSURL = ...
let shareVC = UIActivityViewController(activityItems: [string, URL])
let activityViewController = UIActivityViewController(
activityItems: [image],
applicationActivities: nil)
activityViewController.excludedActivityTypes = [UIActivityTypeMessage,UIActivityTypeMail,UIActivityTypeCopyToPasteboard,UIActivityTypeAirDrop];
presentViewController(activityViewController, animated: true, completion: nil)
use this code for Present ActivityViewController only change activityItems to your string.

Resources