5

I am using a share sheet in my iOS app. I am trying to figure out how I can add an icon to the top left corner of it when it opened. I added a photo example of what I mean.

[Example photo of what I mean][1]

    @IBAction func shareButtonClicked(_ sender: Any) {

        //Set the default sharing message.
        let message = "Check out Num8r, Its so much fun!"
        let link = NSURL(string: "https://apps.apple.com/us/app/num8r/id1497392799")

        // Screenshot:
        UIGraphicsBeginImageContextWithOptions(self.view.frame.size, true, 0.0)
        self.view.drawHierarchy(in: self.view.frame, afterScreenUpdates: false)
        let img = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        //Set the link, message, image to share.
        if let link = link, let img = img {
            let objectsToShare = [message,link,img] as [Any]
            let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
            activityVC.excludedActivityTypes = [UIActivity.ActivityType.airDrop, UIActivity.ActivityType.addToReadingList]
            self.present(activityVC, animated: true, completion: nil)
    }
}
ketaki Damale
  • 634
  • 7
  • 25
Chris
  • 59
  • 1
  • 3

3 Answers3

2

I tried the above code sample for getting the image in the UIActivityViewController. Whenever we try to share the message along with the url and the image, image does not appear. If we add only the url to the activityItems, then image present in the url appears.

I checked couple of applications which have share option, in which if there is a text while sharing the app, image does not appear. If there is only url, then the image present in the url appears.

UIActivityViewController with only url

  • I noticed it also, is there any way to do both text message and app image icon ? I tested also some quite famous apps where only one of the thing works – LDropl Apr 19 '22 at 21:11
2

This code is only available for iOS 13 as a minimum target. I added a code example to add a realated share button in a SwiftUI view in case other people need it. This code also work for iPad.

You can use this class LinkMetadataManager and add the image of your choice. The very important part, is that you must have your image in your project directory, not in the Assets.xcassets folder. Otherwise, it won't work.

When everything will be setup, you will use the button this way in your SwiftUI view.

struct ContentView: View {
    
  var body: some View {
    VStack {
      ShareButton()
    }
  }
}

This is the class that will be sharing your application with the Apple Store link. You can share whatever you want from that. You can see how the image is added using LPLinkMetadata, as it is the part that interests you.

import LinkPresentation

/// Transform url to metadata to populate to user.
final class LinkMetadataManager: NSObject,  UIActivityItemSource {

  var linkMetadata: LPLinkMetadata

  let appTitle = "Your application name"
  let appleStoreProductURL = "https://apps.apple.com/us/app/num8r/id1497392799" // The url of your app in Apple Store
  let iconImage = "appIcon" // The name of the image file in your directory
  let png = "png" // The extension of the image

  init(linkMetadata: LPLinkMetadata = LPLinkMetadata()) {
    self.linkMetadata = linkMetadata
  }
}

// MARK: - LinkMetadataManager Setup
extension LinkMetadataManager {
  /// Creating metadata to be populated in the share sheet.
  func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? {

    guard let url = URL(string: appleStoreProductURL) else { return linkMetadata }

    linkMetadata.originalURL = url
    linkMetadata.url = linkMetadata.originalURL
    linkMetadata.title = appTitle
    linkMetadata.iconProvider = NSItemProvider(
      contentsOf: Bundle.main.url(forResource: iconImage, withExtension: png))

    return linkMetadata
  }

  /// Showing an empty string returns a share sheet with the minimum requirement.
  func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
    return String()
  }

  /// Sharing the application url.
  func activityViewController(_ activityViewController: UIActivityViewController,
                              itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
    return linkMetadata.url
  }
}

Use this extension of View to trigger the share sheet on a SwiftUI view.

import SwiftUI

//  MARK: View+ShareSheet
extension View {

  /// Populate Apple share sheet to enable the user to share Apple Store link.
  func showAppShareSheet() {
    guard let source = UIApplication.shared.windows.first?.rootViewController else {
      return
    }

    let activityItemMetadata = LinkMetadataManager()

    let activityVC = UIActivityViewController(
      activityItems: [activityItemMetadata],
      applicationActivities: nil)

    if let popoverController = activityVC.popoverPresentationController {
      popoverController.sourceView = source.view
      popoverController.permittedArrowDirections = []
      popoverController.sourceRect = CGRect(x: source.view.bounds.midX,
                                            y: source.view.bounds.midY,
                                            width: .zero, height: .zero)
    }
    source.present(activityVC, animated: true)
  }
}

Then, create a ShareButton as a component to use it in any of your SwiftUI view. This is what is used in the ContentView.

import SwiftUI

/// Share button to send app store link using the 
/// Apple classic share screen for iPhone and iPad.
struct ShareButton: View {

  @Environment(\.horizontalSizeClass) private var horizontalSizeClass

  var body: some View {
    ZStack {
      Button(action: { showAppShareSheet() }) {
        Image(systemName: "square.and.arrow.up")
          .font(horizontalSizeClass == .compact ? .title2 : .title)
          .foregroundColor(.accentColor)
      }
      .padding()
    }
  }
}
Roland Lariotte
  • 2,606
  • 1
  • 16
  • 40
0

Icon is fetching from link which you adding in content , so if you will add link of any app than it will automatically capture icon from that link and you will see icon there , but as you mentioned if you will add any message and image together or any message and link together than it will only show first item which you append in array of objectToShare

matt
  • 515,959
  • 87
  • 875
  • 1,141