Add Instagram to Uiactivityviewcontroller

UIActivityViewController for Facebook, Twitter and Instagram ONLY

There are option available for Facebook and Twitter, You need to just add excludedActivityTypes. You have missing it.

Instagram option still not available in activity types

let image = UIImage(named: "TheImage")
let activityViewController = UIActivityViewController(activityItems: [shareText,image], applicationActivities: nil)

activityViewController.excludedActivityTypes = [.addToReadingList,
.airDrop,
.assignToContact,
.copyToPasteboard,
.mail,
.message,
.openInIBooks,
.print,
.saveToCameraRoll,
.postToWeibo,
.copyToPasteboard,
.saveToCameraRoll,
.postToFlickr,
.postToVimeo,
.postToTencentWeibo,
.markupAsPDF
]

present(activityViewController, animated: true, completion: {})

I hope this will help you.

There are following list of Activity types available.

extension UIActivityType {


@available(iOS 6.0, *)
public static let postToFacebook: UIActivityType

@available(iOS 6.0, *)
public static let postToTwitter: UIActivityType

@available(iOS 6.0, *)
public static let postToWeibo: UIActivityType // SinaWeibo

@available(iOS 6.0, *)
public static let message: UIActivityType

@available(iOS 6.0, *)
public static let mail: UIActivityType

@available(iOS 6.0, *)
public static let print: UIActivityType

@available(iOS 6.0, *)
public static let copyToPasteboard: UIActivityType

@available(iOS 6.0, *)
public static let assignToContact: UIActivityType

@available(iOS 6.0, *)
public static let saveToCameraRoll: UIActivityType

@available(iOS 7.0, *)
public static let addToReadingList: UIActivityType

@available(iOS 7.0, *)
public static let postToFlickr: UIActivityType

@available(iOS 7.0, *)
public static let postToVimeo: UIActivityType

@available(iOS 7.0, *)
public static let postToTencentWeibo: UIActivityType

@available(iOS 7.0, *)
public static let airDrop: UIActivityType

@available(iOS 9.0, *)
public static let openInIBooks: UIActivityType

@available(iOS 11.0, *)
public static let markupAsPDF: UIActivityType
}

Add Instagram to UIActivityViewController

I think it would be very easier to add other social shares to the code you wrote for Instagram. The ".igo" extension is exclusive for Instagram so other apps will not support it. Just change this extension from ".igo" to ".ig" and other apps will read it:

var savePath: String = NSHomeDirectory().stringByAppendingPathComponent("Documents/Test.ig")

But Instagram also have an exclusive UTI to avoiding other apps to appear in the same Document Interaction View. So you will also need to change it from "exclusivegram" to "photo":

docController.UTI = "com.instagram.photo"

I have an app with a similar functionality and this is my original code:

@IBAction func shareOnIntagram(sender: UIButton) {

let finalImage: UIImage = UIImage.imageWithView(photoView)
let instagramURL = NSURL(string: "instagram://app")
if (UIApplication.sharedApplication().canOpenURL(instagramURL!)) {

let imageData = UIImageJPEGRepresentation(finalImage, 1)
let captionString = "caption"
let writePath = (NSTemporaryDirectory() as NSString).stringByAppendingPathComponent("instagram.ig")
if imageData?.writeToFile(writePath, atomically: true) == false {

return

} else {

let fileURL = NSURL(fileURLWithPath: writePath)
self.documentController = UIDocumentInteractionController(URL: fileURL)
self.documentController.delegate = self
self.documentController.UTI = "com.instagram.photo"
self.documentController.annotation = NSDictionary(object: captionString, forKey: "InstagramCaption")
self.documentController.presentOpenInMenuFromRect(self.view.frame, inView: self.view, animated: true)
}

} else {
print(" Instagram is not installed ")
}
}

To make this code work, don't forget to add UIDocumentInteractionControllerDelegate in the UIViewController class.

Share image with hashtag via UIActivityViewController (Twitter, Facebook, Instagram)

Define two UIActivityItemSource classes, one for Image and one for Text.

In first one only return the image.
In second one return NSObject() for placeHolder, and return Text or nil depending on activity. By returning NSObject(), UIActivity will allow all services to be available.

UIActivityViewController(activityItems: [ImageProvider(), TextProvider()], applicationActivities: nil)

and providers:

class TextProvider: NSObject, UIActivityItemSource {
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
return NSObject()
}

func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivityType) -> Any? {
if activityType == .postToTwitter || activityType == .postToFacebook {
return "Tweet with #Hashtag"
}
return nil
}
}

class ImageProvider: NSObject, UIActivityItemSource {
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
return UIImage(named: ...)
}

func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivityType) -> Any? {
return UIImage(named: ...)
}
}

Explaination

First of all, Keys are not really sensitive, The only sensitive-key was "subject" for email and apps supporting it, which is implemented in UIActivityController's API and we can set it directly. It doesn't matter if you provide UIImage with key "image" or "1".

As it turns out, Twitter activity will not work if it's text is not returned directly in ...itemForActivity... method. So the solution is to separate item sources.

Twitter activity also will not work, if placeholder receives anything other than String, but by returning String Instagram activity will not work, So by returning NSObject() Type will be ignored and all services will be available.
if you want to limit some services use UIActivityViewController.excludedActivityTypes

Posting to correct Instagram Account with UIActivityViewController

This is only a workaround however might be your only choice at the moment as you see that even native Photos has the same issue so it is rather down to Apple to fix it.

In your application's Info.plist, add a boolean key UIApplicationExitsOnSuspend with the value YES. See the Information Property List Key Reference for more information.

This way the app is getting terminated when enters a background state and once you go back to it it will get reloaded. The user might not notice the difference.

Perhaps before killing the app you could add some interface state saving function in:

 optional func applicationWillTerminate(_ application: UIApplication)

I don't know how your app is laid out but you could create a singleton class which could be implementing Codable and keep tracking all the app state variables which would have a save and load function. Saving would be triggered upon termination and loading when app is launching.

I hope it will help in some way.

EDIT1: Should work in iOS 13
Below this code should work and terminate your app however it is not recommended and you might face an issue when uploading to AppStore. I guess you can challenge the rejection with the Apple review team by explaining that they have a bug in the SDK and point them to the problem.

DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
UIApplication.shared.perform(#selector(NSXPCConnection.suspend))
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
exit(0)
}
}

Share a video and text on Twitter, Instagram and other services using UIActivityViewController

I found the answer. The correct way to do this is to use the implementation of the UIActivityItemSource protocol. The reason for Instagram not showing up in the second solution where i am using the VideoActivityItemSource class is that i am returning an empty String in the activityViewControllerPlaceholderItem function.
Although Apple's documentation says that the type of the object returned in this function does not have to match the type that is used by the itemForActivityType function, it actually needs to be processable by the sharing service. In the case of Instagram it needs to be a video or an image, otherwise Instagram does not show up as a sharing option in the actionsheet.

So the solution is to return a UIImage in the activityViewControllerPlaceholderItem function instead of an empty String, then both Twitter and Instagram will show up as sharing options.

func activityViewControllerPlaceholderItem(activityViewController: UIActivityViewController) -> AnyObject {
// this needs to return some random image to make sure Twitter and Instagram show up in the sharing actionsheet
return UIImage(named: "someImage")!
}


Related Topics



Leave a reply



Submit