Instagram icon not showing in UIActivityViewController - ios

I have an application which uses UIActivityViewController to share a link with NSExtensionActivationSupportsWebURLWithMaxCount like so:
NSURL *shareUrl = [NSURL URLWithString:[[sarray valueForKey:#"url"] description]];
NSString* someText = #"";
NSArray* dataToShare = #[shareUrl,someText]; // ...or whatever pieces of data you want to share.
NSArray *appActivities = [NSArray arrayWithObjects:[[UIActivity alloc] init], nil];
UIActivityViewController* activityViewController = [[UIActivityViewController alloc] initWithActivityItems:dataToShare applicationActivities:appActivities];
activityViewController.excludedActivityTypes=#[UIActivityTypeAddToReadingList,UIActivityTypeAirDrop,UIActivityTypePrint,UIActivityTypeAssignToContact];
[self.navigationController presentViewController:activityViewController animated:YES completion:nil];
[activityViewController setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
if (!completed) return;
}];
Except for Instagram, all options are coming up in the UIActivityViewController.
Can anyone help me discover where I am going wrong or is this by default?

By default iOS doesn't have support for instagram. U might need to use 3rd party libraries.
For iOS 6 and above, you can use this UIActivity to upload images to Instagram which has the same workflow using iOS hooks but simplifies development.
Try this library
DMActivityInstagram

Swift 4.0+
To get the instagram app to show in the icon list, you must share an UIImage object in your dataToShare array.
I ran into a problem where my shared items contained a URL and an UIImage, and when sharing to iMessages I only wanted the URL to be shared and not the UIImage.
To solve this I made the presenting UIViewController conform to UIActivityItemSource protocol like so:
extension PresentingViewController: UIActivityItemSource {
public func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
UIImage() // This allows instagram app to show as a choice
}
public func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
guard let items = self.items else { return nil } // items to present
switch activityType! {
case .message, .postToTwitter, .copyToPasteboard, .mail:
return items.first(where: { $0 is URL })
default: // this catches the case where IG is tapped
return items.first(where: { $0 is UIImage }) as? UIImage
}
}
}
and instead of passing in an array of Activity Items that contain the object you want to share, you pass in the PresentingViewController like so:
// set up activity view controller
activityVC = UIActivityViewController(
activityItems: [PresentingViewController.self],
applicationActivities: [instaGramActivity]
)
self.present(activityVC, animated: true, completion: nil)

Instagram option will not be available with only text. For displaying instagram option in activity controller, you need to pass url object with text, or only url object else you can pass only image to share items which will enable instagram option for you.

Related

UIActivityViewController not Sharing both Text and Image on Facebook [duplicate]

Please, can you tell me if I'm doing mistakes?
NSString *sharedMsg=[NSString stringWithFormat:#"Hello world"];
UIImage* sharedImg=[UIImage imageNamed:#"image"];
NSArray* sharedObjects=[NSArray arrayWithObjects:sharedMsg, sharedImg, nil];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc]
initWithActivityItems:sharedObjects applicationActivities:nil];
activityViewController.popoverPresentationController.sourceView = self.view;
[self presentViewController:activityViewController animated:YES completion:nil];
At runtime when I select the icon of Facebook the text is missing, the image is correctly displayed.
My xcode is 6.3.1, tested on iPad.
It seems that a recent update to the Facebook application has replaced the in-built Facebook share activity with one that ignores status text - If you remove the Facebook app from your device the text will be displayed using the code you have. If you have the Facebook app installed you get images, URLs but not the text
Facebook's policies don't allow you to pre-populate status messages and require all content to be user generated - while I understand the intention behind this, I personally think it is kind of stupid in many cases - For example in my game I want to pre-populate the user's score, but now I can't, so the user is presented with an empty dialog box. I will probably simply remove the Facebook sharing option as no-one will ever use it now.
This response from Facebook confirms that the behaviour is by design
Here is the answer in Swift. It may not help your problem, but it might be helpful with someone looking for this title. Just create a button and it's action. And install the button's action like this.
Note: You have to log in your facebook or twitter by going to setting. Then do like this.
#IBAction func onShareTouched(sender: AnyObject) {
print("share")
let myShare = "My beautiful photo! <3 <3"
let image: UIImage = UIImage(named: "yourImageNameHere")
let shareVC: UIActivityViewController = UIActivityViewController(activityItems: [(image), myShare], applicationActivities: nil)
self.presentViewController(shareVC, animated: true, completion: nil)
}
NSString* text=#"Hello world";
NSURL *myWebsite = [NSURL URLWithString:#"http://www.website.com/"];
// UIImage * myImage =[UIImage imageNamed:#"myImage.png"];
NSArray* sharedObjects=#[text,myWebsite];
UIActivityViewController * activityViewController=[[UIActivityViewController alloc]initWithActivityItems:sharedObjects applicationActivities:nil];
activityViewController.popoverPresentationController.sourceView = self.view;
[self presentViewController:activityViewController animated:YES completion:nil];

IMGLYMainEditorViewController completion block issue

I successfully implemented imglyKit in my Objective-C code, this library is made in swift language. Now i am opening a IMGLYMainEditorViewController from my viewcontroller.
My problem is that when the image is edited and when i press the done button i did not get the edited image. I checked the code and show that they set the completion block when they open IMGLYMainEditorViewController.
This is the code which is written in the library.
let editorViewController = IMGLYMainEditorViewController()
editorViewController.highResolutionImage = image
if let cameraController = cameraController {
editorViewController.initialFilterType = cameraController.effectFilter.filterType
editorViewController.initialFilterIntensity = cameraController.effectFilter.inputIntensity
}
editorViewController.completionBlock = editorCompletionBlock
private func editorCompletionBlock(result: IMGLYEditorResult, image: UIImage?) {
if let image = image where result == .Done {
UIImageWriteToSavedPhotosAlbum(image, self, "image:didFinishSavingWithError:contextInfo:", nil)
}
dismissViewControllerAnimated(true, completion: nil)
}
I wrote this code in my controller.
IMGLYMainEditorViewController *temp view = [[IMGLYMainEditorViewController alloc]init];
view.highResolutionImage = self.image_view.image;
[self.navigationController pushViewController:view animated:YES];
I want to set a block method here when i open a IMGLYMainEditorViewControlle so that i am able to get that edited image.
I did lots of try but not able to do that because i did not have a much knowledge about the block and how to deal with that. so please help me because i stuck here.
Remove the space between "temp view" instance name,
This is how you provide a completion block to an object:
IMGLYMainEditorViewController *tempView = [[IMGLYMainEditorViewController alloc] init];
tempView.completionBlock = ^(IMGLYEditorResult result, UIImage *image){
view.highResolutionImage = image;
};
[self.navigationController pushViewController:view animated:YES];

iOS: How to share text and image on social networks?

Please, can you tell me if I'm doing mistakes?
NSString *sharedMsg=[NSString stringWithFormat:#"Hello world"];
UIImage* sharedImg=[UIImage imageNamed:#"image"];
NSArray* sharedObjects=[NSArray arrayWithObjects:sharedMsg, sharedImg, nil];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc]
initWithActivityItems:sharedObjects applicationActivities:nil];
activityViewController.popoverPresentationController.sourceView = self.view;
[self presentViewController:activityViewController animated:YES completion:nil];
At runtime when I select the icon of Facebook the text is missing, the image is correctly displayed.
My xcode is 6.3.1, tested on iPad.
It seems that a recent update to the Facebook application has replaced the in-built Facebook share activity with one that ignores status text - If you remove the Facebook app from your device the text will be displayed using the code you have. If you have the Facebook app installed you get images, URLs but not the text
Facebook's policies don't allow you to pre-populate status messages and require all content to be user generated - while I understand the intention behind this, I personally think it is kind of stupid in many cases - For example in my game I want to pre-populate the user's score, but now I can't, so the user is presented with an empty dialog box. I will probably simply remove the Facebook sharing option as no-one will ever use it now.
This response from Facebook confirms that the behaviour is by design
Here is the answer in Swift. It may not help your problem, but it might be helpful with someone looking for this title. Just create a button and it's action. And install the button's action like this.
Note: You have to log in your facebook or twitter by going to setting. Then do like this.
#IBAction func onShareTouched(sender: AnyObject) {
print("share")
let myShare = "My beautiful photo! <3 <3"
let image: UIImage = UIImage(named: "yourImageNameHere")
let shareVC: UIActivityViewController = UIActivityViewController(activityItems: [(image), myShare], applicationActivities: nil)
self.presentViewController(shareVC, animated: true, completion: nil)
}
NSString* text=#"Hello world";
NSURL *myWebsite = [NSURL URLWithString:#"http://www.website.com/"];
// UIImage * myImage =[UIImage imageNamed:#"myImage.png"];
NSArray* sharedObjects=#[text,myWebsite];
UIActivityViewController * activityViewController=[[UIActivityViewController alloc]initWithActivityItems:sharedObjects applicationActivities:nil];
activityViewController.popoverPresentationController.sourceView = self.view;
[self presentViewController:activityViewController animated:YES completion:nil];

UIActivityViewController completion handler executes before the view controller disappears from the screen

I am using UIActivityViewController to present sharing options and I want to display another view controller when the UIActivityViewController is dismissed by the user or when the animation that follows "activityDidFinish:(bool)completed" gets over. When I try to present the other controller in the completion handler of the UIActivityViewController, I get the following warning and the second VC does not get displayed at all!
Attempt to present <_UIViewController: 0x1e16f020> on <###> while a presentation is in progress!
UIActivityViewController activityVC = [[UIActivityViewController alloc]initWithActivityItems:selectedAssetsURL applicationActivities:nil];
[activityVC setCompletionHandler:^(NSString *activityType, BOOL completed) {
NSLog(#"completed");
//Present another VC
}];
The question is, how to know when the UIActivityViewController disappears from the screen? Even the -ViewDidAppear method of the view controller which presents the UIActivityViewController does not get fired!
In this link there's good information about how the UIActivityViewController works:
http://www.apeth.com/iOSBook/ch26.html#_activity_view
Basically you can subclass the UIActivityViewController into another class and implement a method to know when it has been dissmissed.
UIActivityViewController* avc =
[[UIActivityViewController alloc]
initWithActivityItems:#[myCoolString]
applicationActivities:#[[MyCoolActivity new]]];
Here’s the preparatory part of the implementation of MyCoolActivity:
-(NSString *)activityType {
return #"com.neuburg.matt.coolActivity"; // make up your own unique string
}
-(NSString *)activityTitle {
return #"Be Cool";
}
-(UIImage *)activityImage {
return self.image; // prepared beforehand
}
-(BOOL)canPerformWithActivityItems:(NSArray *)activityItems {
for (id obj in activityItems) {
if ([obj isKindOfClass: [NSString class]])
return YES;
}
return NO;
}
-(void)prepareWithActivityItems:(NSArray *)activityItems {
self.items = activityItems;
}
To perform the activity, we implement one of two methods:
-(void)performActivity {
// ... do something with self.items here ...
[self activityDidFinish:YES];
}
-(UIViewController *)activityViewController {
MustacheViewController* mvc = [MustacheViewController new];
mvc.activity = self;
mvc.items = self.items;
return mvc;
}
And then MustacheViewController would have code like this:
- (IBAction)doCancel:(id)sender {
[self.activity activityDidFinish:NO];
}
- (IBAction)doDone:(id)sender {
[self.activity activityDidFinish:YES];
}

UIActivityViewController freezes when email or text but not fb or Twitter

I have a very standard implementation of UIActivityViewController. When I use Twitter or Facebook, the view controller is dismissed, and the app continues working. However, when I email or text the same content, the view controller is dismissed but the app freezes (not crashes). Everything is still on screen but frozen - no input etc.
Perhaps the Mail or Message apps have not released control back to my app? Is there a way using Instruments to analyze what's going on?
Thanks!
I am getting a leak from this part from NSArray as the offenders
- (void)postToFacebook:(UITapGestureRecognizer *)sender
{
NSString *postText = #"Testing";
UIImage *imageToPost = [self captureTheScreenImage];
NSArray *postItems = #[postText, imageToPost];
UIActivityViewController *activityPostVC = [[UIActivityViewController alloc]initWithActivityItems:postItems applicationActivities:nil];
NSArray *excludedItems = #[UIActivityTypePostToWeibo,UIActivityTypePrint,UIActivityTypeCopyToPasteboard,UIActivityTypeAssignToContact,UIActivityTypeSaveToCameraRoll, UIActivityTypeMail, UIActivityTypeMessage];
[activityPostVC setExcludedActivityTypes:excludedItems];
[self presentViewController:activityPostVC animated:YES completion:nil];
}
This issue happened to me too when using multiple UIWindow objects at the same time.
Upon dismissal of the UIActivityViewController, the presenting windows contents are not restored correctly. Specifically, the window's first subview (UILayoutContainerView) is missing its constraints to the superview. This causes the window the width of the UILayoutContainerView to be zero causing the window appear transparent and reveal the window underneath it but not allowing user interaction.
The fix can be to place an empty transparent window on top of the current window and present the UIActivityViewController from an empty view controller associated with that new window. When the UIActivityViewController is dismissed, we can dispose of the empty window that it was presented from.
import Foundation
private var previousWindow: UIWindow?
private var activityViewControllerWindow: UIWindow?
extension UIViewController {
fileprivate var isActivityViewControllerWindowPresented: Bool {
return activityViewControllerWindow?.isKeyWindow ?? false
}
func presentActivityViewController(_ activityViewController: UIActivityViewController, animated: Bool = true, completion: (() -> Void)? = nil) {
if isActivityViewControllerWindowPresented {
return
}
let window = UIWindow(frame: view.window!.frame)
previousWindow = UIApplication.shared.keyWindow
activityViewControllerWindow = window
window.rootViewController = UIViewController()
window.makeKeyAndVisible()
let activityCompletionClosure = activityViewController.completionWithItemsHandler
activityViewController.completionWithItemsHandler = { [weak self] (activityType, completed, returnedItems, activityError) in
self?.cleanUpActivityViewControllerWindow()
activityCompletionClosure?(activityType, completed, returnedItems, activityError)
}
window.rootViewController?.present(activityViewController, animated: animated, completion: completion)
}
fileprivate func cleanUpActivityViewControllerWindow() {
previousWindow?.makeKeyAndVisible()
activityViewControllerWindow?.rootViewController = nil
activityViewControllerWindow = nil
}
}
Yes, there is a way, like you mentioned, using Instruments. But If I were to foreshadow your results, I'd say you might want to do network calls on a non-UI thread, somewhere in the background so that your UI thread can do its thang while your app talks to Twitter or Facebook.

Resources