I tried looking for a solution in posts such as this and this where people asked this very same question: How to share a url to Facebook using SwiftUI?
I even tried this post where somebody asked how to export a file using SwiftUI, but my problem is specifically with Facebook since I have no problem sharing urls to apps such as Whatsapp. However, I found no answers...
By reading Facebook's Developer documentation, I found a way to share a post using UIKit.
I created a very simple sample project to make sure I understood the topic. Here is the sample project in UIKit:
import UIKit
import FBSDKShareKit
class ProfileViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func share(_ sender: UIButton) {
shareLink(url: URL(string: "http://www.apple.com")!)
}
func shareLink(url: URL) {
let content = ShareLinkContent()
content.contentURL = url
let dialog = ShareDialog(
fromViewController: self,
content: content,
delegate: nil
)
dialog.show()
}
}
Luckily, this worked right away. By making this project work, I confirmed that I wasn't forgetting to link my AppBundleID to Facebook, or forgetting to add my FacebookAppID or any other needed files inside my info.plist.
I then tried to replicate the same project in SwiftUI to see if I could get it to work. I used ViewControllerRepresentable to be able to include UIActivityViewController into SwiftUI.
The reason for using UIActivityViewController is because I want the user to choose where they want to share the URL (Whatsapp, Twitter, Facebook, etc).
Here is the code:
struct ContentView: View {
@State var showSharingView = false
var body: some View {
Button("Share Link") {
showSharingView.toggle()
}
.sheet(isPresented: $showSharingView) {
ActivityViewController(activityItems: [URL(string: "https://www.apple.com/")!])
}
}
}
struct ActivityViewController: UIViewControllerRepresentable {
var activityItems: [URL]
var applicationActivities: [UIActivity]? = nil
func makeUIViewController(context: UIViewControllerRepresentableContext<ActivityViewController>) -> UIActivityViewController {
let controller = UIActivityViewController(activityItems: activityItems, applicationActivities: applicationActivities)
controller.completionWithItemsHandler = { (activityType, completed, returnedItems, error) in
if activityType == .postToFacebook {
shareLink(from: activityItems.first!)
}
}
return controller
}
func updateUIViewController(_ uiViewController: UIActivityViewController, context: UIViewControllerRepresentableContext<ActivityViewController>) {}
func shareLink(from url: URL) {
// controller was created so I would have a UIViewControllerType to put as a parameter for fromViewController in ShareDialog, even though I don't think it fits
let controller = UIActivityViewController(activityItems: activityItems, applicationActivities: applicationActivities)
let content = ShareLinkContent()
content.contentURL = url
let dialog = ShareDialog(fromViewController: controller, content: content, delegate: nil)
dialog.show()
}
}
This code doesn't work because of what I assume is the controller
variable used when initializing ShareDialog. (self doesn't work either because "XCode cannot convert value of type 'ActivityViewController' to expected argument type 'UIViewController?'")
Facebook Developer's documentation tells me that I need to write the following code in order to share a link:
guard let url = URL(string: "https://developers.facebook.com") else {
// handle and return
}
let content = ShareLinkContent()
content.contentURL = url
let dialog = ShareDialog(
viewController: self, //<--this has been changed to 'fromViewController'
content: content,
delegate: self
)
dialog.show()
However, SwiftUI doesn't work with ViewControllers. How can I create a ViewController to use as a parameter in fromViewController
in ShareDialog
in order to successfully share my URL to Facebook?
Use like this,
guard let url = URL(string: "https://developers.facebook.com") else {
// handle and return
}
let content = ShareLinkContent()
content.contentURL = url
let dialog = ShareDialog(
viewController: UIApplication.shared.windows.first!.rootViewController,
content: content,
delegate: UIApplication.shared.windows.first!.rootViewController
)
dialog.show()