2

please barer with me that I am completely new to swift and iOS..

I'm trying to make a "team select" on my share extension. Ideally I want to be able to tap the "Team" footer and select multiple teams from a table view, and at last share/post to the selected teams.

enter image description here

I have been following a tutorial from 2016, but I think it is outdated by now unfortunately, and I haven't been able to find one similar that is up to date. (if you know one please link)

I have created a TeamTableViewController.swift (UITableViewController) with a hardcoded teamList which I hope to populate in the share extension.

my UITableViewController file looks like this:

import UIKit

protocol TeamViewProtocol {
  func sendingViewController(viewController: TeamTableViewController, sentItem: String)
}

class TeamTableViewController: UITableViewController {

  var teamList: [String] = ["Team 1", "Team 2", "Team 3", "Team 4", "Team 5"]
  var delegate: TeamViewProtocol?

    override func viewDidLoad() {
        super.viewDidLoad()

        self.clearsSelectionOnViewWillAppear = false
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
      return 1
    }

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

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

        cell.textLabel!.text = self.teamList[indexPath.item]

        return cell
    }

}

My ShareViewController filer looks like this:

import UIKit
import Social

class ShareViewController: SLComposeServiceViewController, TeamViewProtocol {

  var item: SLComposeSheetConfigurationItem!
  var teamPickerVC: TeamTableViewController!

    override func isContentValid() -> Bool {
        // Do validation of contentText and/or NSExtensionContext attachments here
        return true
    }

    override func didSelectPost() {
        // This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments.

        // Inform the host that we're done, so it un-blocks its UI. Note: Alternatively you could call super's -didSelectPost, which will similarly complete the extension context.
        self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
    }

  override func configurationItems() -> [Any]! {
    self.item = SLComposeSheetConfigurationItem()

    self.item.title = "Team"
    self.item.value = "None"

    self.item.tapHandler = {
      self.teamPickerVC = TeamTableViewController()
      self.pushConfigurationViewController(self.teamPickerVC)
    }

    return [self.item]
  }

  func sendingViewController(viewController: TeamTableViewController, sentItem: String) {
    self.item.value = sentItem
    self.popConfigurationViewController()
  }

}

When I tap the extension window footer "Team" the entire extension dismisses with no error message. If however, I set the hard coded teamList array to an empty array, then the extensions does not crash/dismiss but instead shows the table view with empty rows.

What am I missing in order for my hard coded teams to show as cell/lines/rows? in the table view?

Rasmus Puls
  • 3,009
  • 7
  • 21
  • 58
  • I don't understand what you want to achieve: Do you want to display a table view over the extension, select rows there, and then dismiss the table view and be back at your share extension so that you can post to the selected entries? If so, this is maybe not the best way to do it. [Apple's docs](https://developer.apple.com/design/human-interface-guidelines/ios/extensions/sharing-and-actions/) say _Avoid placing modal views above your extension. Extensions are displayed within a modal view by default. While an alert might make sense above an extension, avoid layering additional modal views._ – Reinhard Männer May 09 '19 at 12:56
  • As I read their "Apple way of doing things" docs, I feel quite confident that I follow that convention. I'm not trying to launch a new layer on top of the share extension, I'm trying to populate the `configurationItems` with a table view with options. hundreds of apps are doing this: example here: https://github.com/couchbaselabs/mini-hacks/tree/master/ios-share-extension Which were this initial tutorial i was following, however the code is not up to date with swift 4 – Rasmus Puls May 09 '19 at 13:32
  • Sorry, I was not aware of this. Thanks for the link to the tutorial! Maybe you could edit your question and refer to the link there? – Reinhard Männer May 10 '19 at 11:31

3 Answers3

1

You should return the proper number of sections or can remove that method, so it will take the default value of numerOfSections as 1

override func numberOfSections(in tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
  return 1
}

Hope it helps

Bhavin Kansagara
  • 2,866
  • 1
  • 16
  • 20
  • Ok thanks! At leats that confirms my gut feelings. So, the reason why the entire share extension dismisses when tapping on "Team" must be some kind of crash, because something else is wrong? – Rasmus Puls May 09 '19 at 11:37
  • 1
    Did help! and I found the solution to the rest of the issue :) – Rasmus Puls May 10 '19 at 11:38
0

After a lot of trial and error. I finally found a forum post about the correct implementation of the tableView function that calls with the argument cellForRowAt

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  var cell = tableView.dequeueReusableCell(withIdentifier: "TeamCell")

  if cell == nil {
    cell = UITableViewCell(style: .default, reuseIdentifier: "TeamCell")
  }

  cell!.textLabel!.text = self.teamList[indexPath.item]
  return cell!
}

This was not easy to debug, and there were no error or exceptions printed.

Rasmus Puls
  • 3,009
  • 7
  • 21
  • 58
0

You also have to implement the didSelectRowAt delegate for the tableView to be able to send the selected item back to the main view.

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let selectedItem = self.teamList[indexPath.item]
    delegate?.sendingViewController(viewController: self, sentItem: selectedItem)
    self.navigationController?.popViewController(animated: true)
}