user4806509
user4806509

Reputation: 3011

Sharing to Instagram does not work using the `UIActivityItemSource` protocol

I share text and an image using the UIActivityViewController. The image is from activityImage which is an UIImage(). The custom text is from activityText() which is returned from an UIActivityItemSource protocol.

The trouble is, Instagram is only visible in the UIActivityViewController under certain conditions.

To summerize the tests below:

The issue is that the UIActivityItemSource protocol needs to be called so that different sharing platforms can be managed separately.


Questions:

  • How can I share to Instagram when calling the UIActivityItemSource protocol?

  • What are the alternatives to "", nil and NSNull() that I could try when calling the UIActivityItemSource protocol?


Code:

class activityText: NSObject, UIActivityItemSource {
    @objc func activityViewControllerPlaceholderItem(activityViewController: UIActivityViewController) -> AnyObject {
        return ""
    }
    @objc func activityViewController(activityViewController: UIActivityViewController, itemForActivityType activityType: String) -> AnyObject? {
        switch activityType {
        case UIActivityTypeMessage:
            return "Special text when sharing to Messages."
        default:
            return ""
        }
    }
}

func shareEverwhere() {
      var activityImage: UIImage() 
      let activity = UIActivityViewController(activityItems: [activityImage, activityText()], applicationActivities: nil)
      self.presentViewController(activity, animated: true, completion: nil)
}

Tests:

Instagram is visible in the UIActivityViewController

let activity = UIActivityViewController(activityItems: [activityImage], applicationActivities: nil)

or

let activity = UIActivityViewController(activityItems: [activityImage, NSNull()], applicationActivities: nil)

Instagram is hidden in the UIActivityViewController

let activity = UIActivityViewController(activityItems: [activityImage, ""], applicationActivities: nil)

or

let activity = UIActivityViewController(activityItems: [activityImage, activityText()], applicationActivities: nil)

or

let activity = UIActivityViewController(activityItems: [activityImage, activityText()], applicationActivities: nil)
class activityText: NSObject, UIActivityItemSource {
    @objc func activityViewControllerPlaceholderItem(activityViewController: UIActivityViewController) -> AnyObject {
        return ""
    }
    @objc func activityViewController(activityViewController: UIActivityViewController, itemForActivityType activityType: String) -> AnyObject? {
        return NSNull()
    }
}

or

let activity = UIActivityViewController(activityItems: [activityImage, activityText()], applicationActivities: nil)
class activityText: NSObject, UIActivityItemSource {
    @objc func activityViewControllerPlaceholderItem(activityViewController: UIActivityViewController) -> AnyObject {
        return ""
    }
    @objc func activityViewController(activityViewController: UIActivityViewController, itemForActivityType activityType: String) -> AnyObject? {
            return nil
    }
}

or

let activity = UIActivityViewController(activityItems: [activityImage, activityText()], applicationActivities: nil)
class activityText: NSObject, UIActivityItemSource {
    @objc func activityViewControllerPlaceholderItem(activityViewController: UIActivityViewController) -> AnyObject {
        return ""
    }
    @objc func activityViewController(activityViewController: UIActivityViewController, itemForActivityType activityType: String) -> AnyObject? {
            return ""
    }
}

Upvotes: 2

Views: 4269

Answers (2)

buxik
buxik

Reputation: 2625

After testing only you have to do is add your image to activityViewControllerPlaceholderItem

final class MyImageItemSource: NSObject, UIActivityItemSource {

    final let image: UIImage

    init(image: UIImage) {
        self.image = image
    }

    func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
        image
    }

    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
        image
    }

}

Upvotes: 0

Olivier Brand
Olivier Brand

Reputation: 121

The question was asked and answered at: Share image with hashtag via UIActivityViewController (Twitter, Facebook, Instagram)

        UIActivityViewController *activityViewController =
 [[UIActivityViewController alloc] initWithActivityItems:@[vm.image, [[ActivityStringItemSource alloc] initWithString:attributedString]] applicationActivities:nil];

And the class that implements the return of the string (or not) is:

@interface ActivityStringItemSource()<UIActivityItemSource>

@property(strong, nonatomic) NSMutableAttributedString *stringContent;
@end

@implementation ActivityStringItemSource

- (instancetype)initWithString:(NSMutableAttributedString *) placeholder
{
    self = [super init];
    if (self) {
        _stringContent = placeholder;
    }
    return self;
}

- (id)activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController {
    return [NSObject new];
}

- (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(UIActivityType)activityType {
    if([activityType containsString:@"instagram"]) {
        return nil;
    } else {
        return _stringContent;
    }
}

@end

The key, as pointed by the original answer is to return an NSObject (the class extends NSObject). Then in the item selection, just test instagram to return nil and otherwise return your string.

Upvotes: 4

Related Questions