Search code examples
iosiphoneswift3uiactivityviewcontrolleruitableviewrowaction

ActivityViewController Won't show any options to share? Swift - 3


I am trying to share my saved events in core data from tableViewCell but whenever I press on share, it displays the activityViewController but won't give me any options to share it with. I tried running it on my iPhone as well and same issue appears.

class EventsTableViewController: UITableViewController {

@IBOutlet var table: UITableView!

var  eventsArray: [NSManagedObject] = []

// The Managed Object Context retrieved from the app delegate

let managedContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext



override func viewDidLoad() {
    super.viewDidLoad()

    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = false

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    //self.navigationItem.rightBarButtonItem = self.editButtonItem
}

override func viewWillAppear(_ animated: Bool) {
    gettAllRecords()
}

// MARK: - Table view data source

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return eventsArray.count
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomTableViewCell

    let event = eventsArray[indexPath.row]

    let eventTitle = event.value(forKeyPath: "eTitle") as? String
    let eventLocation = event.value(forKeyPath: "eLocation") as? String
    let eventDateTime = event.value(forKeyPath: "eDateTime") as? String

    cell.titleLable.text = eventTitle
    cell.locationLable.text = eventLocation
    cell.dateTimeLable.text = eventDateTime

    return cell
}


/***********************************************************************
 *
 * This function gets all records from the database and returns
 * an array of ManagedObject
 *
 **********************************************************************/

func gettAllRecords() {

    let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Event")

    do {
        eventsArray = try managedContext.fetch(fetchRequest)

        table.reloadData()

    } catch let error as NSError {

        print("Could not fetch. \(error), \(error.userInfo)")

    }
}


// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

}

override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {

    let shareActions = UITableViewRowAction(style: .normal, title: "Share") { (_ rowAction: UITableViewRowAction, _ indexPath: IndexPath) in

        let shareEvent = self.eventsArray[indexPath.row] //I feel like shareEvent is not being populated with self.eventsArray

        let activityViewController = UIActivityViewController(activityItems: [shareEvent], applicationActivities: nil)

        self.present(activityViewController, animated: true, completion: nil)

    }

    let deleteAction = UITableViewRowAction(style: .default, title: "Delete") { (_ rowAction: UITableViewRowAction, _ indexPath: IndexPath) in
        let event = self.eventsArray[indexPath.row]
        self.managedContext.delete(event)

        (UIApplication.shared.delegate as! AppDelegate).saveContext()

        self.gettAllRecords()
    }

    shareActions.backgroundColor = UIColor.gray

    return [deleteAction, shareActions]

}

This is what it shows when i try to save it

Any idea what's going on here? I tried running it on my iPhone as well and same problem appears.


Solution

  • The items you're offering to share are just your NSManagedObject instances. None of the sharing services know what to do with that, so none of them appear.

    You can share items as images, text, or various standard file types. What you need to do is implement something that translates your NSManagedObject data into some standard format.

    Create a class that adopts the UIActivityItemSource protocol. That class will take your data, turn it into some standard format to share (text, image, or whatever is appropriate for your app) and return that. Then, instead of passing your raw objects to UIActivityViewController, you pass the UIActivityItemSource object.

    For instance, say your items should be shared as text. You would implement a class that adopts the UIActivityItemSource protocol, and it would contain a function that takes your data and creates a nicely formatted string.

    class MyItemSource: UIActivityItemSource {
    
        func activityViewController(_ activityViewController: UIActivityViewController,
                                itemForActivityType activityType: UIActivityType) -> Any? {
    
            // Take your data and create a string
            var stringToShare = "Hello world!"
            ...
            return stringToShare
        }
    
        // other UIActivityItemSource methods
    }
    

    If you pass an instance of MyItemSource to UIActivityViewController, the sharing services will receive a string that says "Hello world!".