Quick-Dial Button/ActionSheet within ViewController

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
0
down vote

favorite












I'm creating a button that will dial a user quickly in to their conference calls should they have a default provider set. If they have no default provider an action sheet will appear that allows them to choose their provider for this call or set their default provider in the settings.
This works fine but I can't help but feel this is a MassiveViewController implementation as it appears subclassing a UIAlertController is not possible. I'm debating one of the following:



  • Creating a class that builds the quickDialActionSheet and either returns it or presents it.

  • Using a pre-existing Alerter class that has 600 lines of static functions for our existing alerts

  • Moving this extension to another file called QuickDialActionSheet

For the most part I'm looking for a way to move as much of this logic out of the ViewController although I'd be grateful for all input that can improve the quality of my code here.



QuickDialLogic Code



extension LandingPageViewController 
/// Quick dial in to a meeting as host when tapping the host button
@IBAction func hostClicked(_ sender: Any)
if let defaultConferenceProvider = Settings.defaultConferenceProvider
return placeCall(using: defaultConferenceProvider)


if ConferenceProvider.noQuickDialableProvidersExist
presentQuickDialSetupPrompt()
else
presentQuickDialProviderActionSheet()



private func presentQuickDialSetupPrompt()
// TODO: Create function


private func presentQuickDialProviderActionSheet()
refreshQuickDialProviderActionSheetActions()
self.present(quickDialActionSheet, animated: true)


// TODO: Swift 4.2 use enumeratable enum for Conference Provider types
private func refreshQuickDialProviderActionSheetActions()
quickDialActionSheet = UIAlertController(title: "Alerts.ActionSheet.Title".localized, message: nil, preferredStyle: .actionSheet)
addDialableProviderButtons()
addSetDefaultButton()
addCancelButton()


/**
Add ActionSheet buttons for Conference Providers that have both phonenumbers
& host codes assigned to them from the Settings.
*/
private func addDialableProviderButtons()
for provider in ConferenceProvider.allValues where provider != .custom
guard provider.isQuickDialableAsHost else continue
let quickDialAction = UIAlertAction(title: provider.rawValue, style: .default, handler: placeCall)
quickDialActionSheet.addAction(quickDialAction)

if ConferenceProvider.custom.isQuickDialableAsHost
addCustomProviderButton()



private func placeCall(action: UIAlertAction)
let providerName = String(action.title?.split(separator: ":").first ?? "")
let provider = ConferenceProvider(rawValue: providerName) ?? .unknown
placeCall(using: provider)


private func addCustomProviderButton()
let title = "("Settings.CustomProvider".localized): (Settings.CustomProvider.name ?? "")"
let customProviderAction = UIAlertAction(title: title, style: .default, handler: placeCall)
quickDialActionSheet.addAction(customProviderAction)


private func addSetDefaultButton()
let setDefaultAction = UIAlertAction(title: "Alerts.ActionSheet.SetDefaultActionTitle".localized, style: .default, handler: openDefaultProviderSettingsScreen)
quickDialActionSheet.addAction(setDefaultAction)


private func openDefaultProviderSettingsScreen(action: UIAlertAction)
// TODO: Create function


private func addCancelButton()
let cancelAction = UIAlertAction(title: "Alerts.Cancel".localized, style: .cancel)
quickDialActionSheet.addAction(cancelAction)


private func placeCall(using provider: ConferenceProvider)
do
try caller.placeQuickCallAsHost(with: provider)
catch
let callError = error as! CallerError
CallerErrorHandler.handleError(callError)
return





LandingPageTableViewController Properties (not showing all this class as all the code bar these properties is used for different things)



class LandingPageViewController: UIViewController {

private let caller: Caller = Caller()
var quickDialActionSheet = UIAlertController(title: "Alerts.ActionSheet.Title".localized, message: nil, preferredStyle: .actionSheet)


ConferenceProvider enum



///Defines the type of conference call service the meeting uses if any.
enum ConferenceProvider :String
case airtel = "Airtel"
case att = "AT&T"
case custom = "Custom"
case ibmMeetings = "IBM Meetings"
case unknown = ""
case webex = "WebEx"
case zoom = "Zoom"

// TODO: Remove in favor of enumeratable enum Swift 4.2
static let allValues = [airtel, att, custom, ibmMeetings, webex, zoom]


// MARK: Settings properties
extension ConferenceProvider

/**
Providers that can be dialed in to without a meeting with user provided Settings information
instead of a meeting invite
*/
static var quickDialableProviders: [ConferenceProvider]
return allValues.filter $0.isQuickDialableAsHost

///No conference providers currently have the necessary information to dial in without a meeting.
static var noQuickDialableProvidersExist: Bool return quickDialableProviders.isEmpty

///Persistently saved user phoneNumber for provider
var phoneNumber: String?
switch self
case .airtel:
return Settings.airtelNumber
case .att:
return Settings.attNumber
case .custom:
return Settings.CustomProvider.number
case .ibmMeetings:
return Settings.ibmMeetingsNumber
case .unknown:
return nil
case .webex:
return Settings.webexNumber
case .zoom:
return Settings.zoomNumber



///Persistently saved user participant code for provider. If there's more than one the first is returned.
var participantCode: String?
switch self
case .airtel:
return Settings.airtelParticipantCode
case .att:
return Settings.attParticipantCodes.first
case .custom:
return Settings.CustomProvider.participantCode
case .ibmMeetings:
return Settings.ibmMeetingsModeratorCode
case .unknown:
return nil
case .webex:
return Settings.webexAccessCode
case .zoom:
return Settings.zoomMeetingId



///Persistently saved user participant code for provider. If there's more than one the first is returned.
var hostCode: String?
switch self
case .airtel:
return Settings.airtelHostCode
case .att:
return Settings.attHostCodes.first
case.custom:
return Settings.CustomProvider.hostCode
case .ibmMeetings:
return Settings.ibmMeetingsModeratorCode
case .unknown:
return nil
case .webex:
return Settings.webexHostPin
case .zoom:
return nil



/**
Schema from which to construct a dialcode for iOS phonecalls as a host.

## Key
* n = PhoneNumber
* h = HostCode
* p = ParticipantCode
* , = Pause (1 second)
* # = Submit current input
* ; = Wait for user input
*/
var hostDialCodeSchema: String
switch self
case .airtel, .att, .ibmMeetings, .unknown, .zoom:
return "n,,h#"
case .custom:
return Settings.CustomProvider.hostDialFormat ?? "n,,h#"
case .webex:
return "n,,p#,,#,,h#"



/**
Schema from which to construct a dialcode for iOS phonecalls as a participant.

## Key
* n = PhoneNumber
* h = HostCode
* p = ParticipantCode
* , = Pause (1 second)
* # = Submit current input
* ; = Wait for user input
*/
var participantDialCodeSchema: String
switch self
case .airtel, .att, .ibmMeetings, .unknown:
return "n,,p#"
case .custom:
return Settings.CustomProvider.participantDialFormat ?? "n,,p#"
case .webex:
return "n,,p#,,#,,#"
case .zoom:
return "n,,p#,,,,#"



/**
User can call in to this provider as the host without a meeting invite.

- Remark:
Zoom calls cannot be hosted via telephone/dial-in.
*/
var isQuickDialableAsHost: Bool
switch self
case .airtel:
return Settings.airtelHostCode != nil && Settings.airtelNumber != nil
case .att:
return Settings.attHostCodes.first != nil && Settings.attNumber != nil
case .custom:
return Settings.CustomProvider.hostCode != nil && Settings.CustomProvider.number != nil
case .ibmMeetings:
return Settings.ibmMeetingsModeratorCode != nil && Settings.ibmMeetingsNumber != nil
case .unknown:
return false
case .webex:
return Settings.webexHostPin != nil && Settings.webexNumber != nil
case .zoom:
return false









share|improve this question

























    up vote
    0
    down vote

    favorite












    I'm creating a button that will dial a user quickly in to their conference calls should they have a default provider set. If they have no default provider an action sheet will appear that allows them to choose their provider for this call or set their default provider in the settings.
    This works fine but I can't help but feel this is a MassiveViewController implementation as it appears subclassing a UIAlertController is not possible. I'm debating one of the following:



    • Creating a class that builds the quickDialActionSheet and either returns it or presents it.

    • Using a pre-existing Alerter class that has 600 lines of static functions for our existing alerts

    • Moving this extension to another file called QuickDialActionSheet

    For the most part I'm looking for a way to move as much of this logic out of the ViewController although I'd be grateful for all input that can improve the quality of my code here.



    QuickDialLogic Code



    extension LandingPageViewController 
    /// Quick dial in to a meeting as host when tapping the host button
    @IBAction func hostClicked(_ sender: Any)
    if let defaultConferenceProvider = Settings.defaultConferenceProvider
    return placeCall(using: defaultConferenceProvider)


    if ConferenceProvider.noQuickDialableProvidersExist
    presentQuickDialSetupPrompt()
    else
    presentQuickDialProviderActionSheet()



    private func presentQuickDialSetupPrompt()
    // TODO: Create function


    private func presentQuickDialProviderActionSheet()
    refreshQuickDialProviderActionSheetActions()
    self.present(quickDialActionSheet, animated: true)


    // TODO: Swift 4.2 use enumeratable enum for Conference Provider types
    private func refreshQuickDialProviderActionSheetActions()
    quickDialActionSheet = UIAlertController(title: "Alerts.ActionSheet.Title".localized, message: nil, preferredStyle: .actionSheet)
    addDialableProviderButtons()
    addSetDefaultButton()
    addCancelButton()


    /**
    Add ActionSheet buttons for Conference Providers that have both phonenumbers
    & host codes assigned to them from the Settings.
    */
    private func addDialableProviderButtons()
    for provider in ConferenceProvider.allValues where provider != .custom
    guard provider.isQuickDialableAsHost else continue
    let quickDialAction = UIAlertAction(title: provider.rawValue, style: .default, handler: placeCall)
    quickDialActionSheet.addAction(quickDialAction)

    if ConferenceProvider.custom.isQuickDialableAsHost
    addCustomProviderButton()



    private func placeCall(action: UIAlertAction)
    let providerName = String(action.title?.split(separator: ":").first ?? "")
    let provider = ConferenceProvider(rawValue: providerName) ?? .unknown
    placeCall(using: provider)


    private func addCustomProviderButton()
    let title = "("Settings.CustomProvider".localized): (Settings.CustomProvider.name ?? "")"
    let customProviderAction = UIAlertAction(title: title, style: .default, handler: placeCall)
    quickDialActionSheet.addAction(customProviderAction)


    private func addSetDefaultButton()
    let setDefaultAction = UIAlertAction(title: "Alerts.ActionSheet.SetDefaultActionTitle".localized, style: .default, handler: openDefaultProviderSettingsScreen)
    quickDialActionSheet.addAction(setDefaultAction)


    private func openDefaultProviderSettingsScreen(action: UIAlertAction)
    // TODO: Create function


    private func addCancelButton()
    let cancelAction = UIAlertAction(title: "Alerts.Cancel".localized, style: .cancel)
    quickDialActionSheet.addAction(cancelAction)


    private func placeCall(using provider: ConferenceProvider)
    do
    try caller.placeQuickCallAsHost(with: provider)
    catch
    let callError = error as! CallerError
    CallerErrorHandler.handleError(callError)
    return





    LandingPageTableViewController Properties (not showing all this class as all the code bar these properties is used for different things)



    class LandingPageViewController: UIViewController {

    private let caller: Caller = Caller()
    var quickDialActionSheet = UIAlertController(title: "Alerts.ActionSheet.Title".localized, message: nil, preferredStyle: .actionSheet)


    ConferenceProvider enum



    ///Defines the type of conference call service the meeting uses if any.
    enum ConferenceProvider :String
    case airtel = "Airtel"
    case att = "AT&T"
    case custom = "Custom"
    case ibmMeetings = "IBM Meetings"
    case unknown = ""
    case webex = "WebEx"
    case zoom = "Zoom"

    // TODO: Remove in favor of enumeratable enum Swift 4.2
    static let allValues = [airtel, att, custom, ibmMeetings, webex, zoom]


    // MARK: Settings properties
    extension ConferenceProvider

    /**
    Providers that can be dialed in to without a meeting with user provided Settings information
    instead of a meeting invite
    */
    static var quickDialableProviders: [ConferenceProvider]
    return allValues.filter $0.isQuickDialableAsHost

    ///No conference providers currently have the necessary information to dial in without a meeting.
    static var noQuickDialableProvidersExist: Bool return quickDialableProviders.isEmpty

    ///Persistently saved user phoneNumber for provider
    var phoneNumber: String?
    switch self
    case .airtel:
    return Settings.airtelNumber
    case .att:
    return Settings.attNumber
    case .custom:
    return Settings.CustomProvider.number
    case .ibmMeetings:
    return Settings.ibmMeetingsNumber
    case .unknown:
    return nil
    case .webex:
    return Settings.webexNumber
    case .zoom:
    return Settings.zoomNumber



    ///Persistently saved user participant code for provider. If there's more than one the first is returned.
    var participantCode: String?
    switch self
    case .airtel:
    return Settings.airtelParticipantCode
    case .att:
    return Settings.attParticipantCodes.first
    case .custom:
    return Settings.CustomProvider.participantCode
    case .ibmMeetings:
    return Settings.ibmMeetingsModeratorCode
    case .unknown:
    return nil
    case .webex:
    return Settings.webexAccessCode
    case .zoom:
    return Settings.zoomMeetingId



    ///Persistently saved user participant code for provider. If there's more than one the first is returned.
    var hostCode: String?
    switch self
    case .airtel:
    return Settings.airtelHostCode
    case .att:
    return Settings.attHostCodes.first
    case.custom:
    return Settings.CustomProvider.hostCode
    case .ibmMeetings:
    return Settings.ibmMeetingsModeratorCode
    case .unknown:
    return nil
    case .webex:
    return Settings.webexHostPin
    case .zoom:
    return nil



    /**
    Schema from which to construct a dialcode for iOS phonecalls as a host.

    ## Key
    * n = PhoneNumber
    * h = HostCode
    * p = ParticipantCode
    * , = Pause (1 second)
    * # = Submit current input
    * ; = Wait for user input
    */
    var hostDialCodeSchema: String
    switch self
    case .airtel, .att, .ibmMeetings, .unknown, .zoom:
    return "n,,h#"
    case .custom:
    return Settings.CustomProvider.hostDialFormat ?? "n,,h#"
    case .webex:
    return "n,,p#,,#,,h#"



    /**
    Schema from which to construct a dialcode for iOS phonecalls as a participant.

    ## Key
    * n = PhoneNumber
    * h = HostCode
    * p = ParticipantCode
    * , = Pause (1 second)
    * # = Submit current input
    * ; = Wait for user input
    */
    var participantDialCodeSchema: String
    switch self
    case .airtel, .att, .ibmMeetings, .unknown:
    return "n,,p#"
    case .custom:
    return Settings.CustomProvider.participantDialFormat ?? "n,,p#"
    case .webex:
    return "n,,p#,,#,,#"
    case .zoom:
    return "n,,p#,,,,#"



    /**
    User can call in to this provider as the host without a meeting invite.

    - Remark:
    Zoom calls cannot be hosted via telephone/dial-in.
    */
    var isQuickDialableAsHost: Bool
    switch self
    case .airtel:
    return Settings.airtelHostCode != nil && Settings.airtelNumber != nil
    case .att:
    return Settings.attHostCodes.first != nil && Settings.attNumber != nil
    case .custom:
    return Settings.CustomProvider.hostCode != nil && Settings.CustomProvider.number != nil
    case .ibmMeetings:
    return Settings.ibmMeetingsModeratorCode != nil && Settings.ibmMeetingsNumber != nil
    case .unknown:
    return false
    case .webex:
    return Settings.webexHostPin != nil && Settings.webexNumber != nil
    case .zoom:
    return false









    share|improve this question





















      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I'm creating a button that will dial a user quickly in to their conference calls should they have a default provider set. If they have no default provider an action sheet will appear that allows them to choose their provider for this call or set their default provider in the settings.
      This works fine but I can't help but feel this is a MassiveViewController implementation as it appears subclassing a UIAlertController is not possible. I'm debating one of the following:



      • Creating a class that builds the quickDialActionSheet and either returns it or presents it.

      • Using a pre-existing Alerter class that has 600 lines of static functions for our existing alerts

      • Moving this extension to another file called QuickDialActionSheet

      For the most part I'm looking for a way to move as much of this logic out of the ViewController although I'd be grateful for all input that can improve the quality of my code here.



      QuickDialLogic Code



      extension LandingPageViewController 
      /// Quick dial in to a meeting as host when tapping the host button
      @IBAction func hostClicked(_ sender: Any)
      if let defaultConferenceProvider = Settings.defaultConferenceProvider
      return placeCall(using: defaultConferenceProvider)


      if ConferenceProvider.noQuickDialableProvidersExist
      presentQuickDialSetupPrompt()
      else
      presentQuickDialProviderActionSheet()



      private func presentQuickDialSetupPrompt()
      // TODO: Create function


      private func presentQuickDialProviderActionSheet()
      refreshQuickDialProviderActionSheetActions()
      self.present(quickDialActionSheet, animated: true)


      // TODO: Swift 4.2 use enumeratable enum for Conference Provider types
      private func refreshQuickDialProviderActionSheetActions()
      quickDialActionSheet = UIAlertController(title: "Alerts.ActionSheet.Title".localized, message: nil, preferredStyle: .actionSheet)
      addDialableProviderButtons()
      addSetDefaultButton()
      addCancelButton()


      /**
      Add ActionSheet buttons for Conference Providers that have both phonenumbers
      & host codes assigned to them from the Settings.
      */
      private func addDialableProviderButtons()
      for provider in ConferenceProvider.allValues where provider != .custom
      guard provider.isQuickDialableAsHost else continue
      let quickDialAction = UIAlertAction(title: provider.rawValue, style: .default, handler: placeCall)
      quickDialActionSheet.addAction(quickDialAction)

      if ConferenceProvider.custom.isQuickDialableAsHost
      addCustomProviderButton()



      private func placeCall(action: UIAlertAction)
      let providerName = String(action.title?.split(separator: ":").first ?? "")
      let provider = ConferenceProvider(rawValue: providerName) ?? .unknown
      placeCall(using: provider)


      private func addCustomProviderButton()
      let title = "("Settings.CustomProvider".localized): (Settings.CustomProvider.name ?? "")"
      let customProviderAction = UIAlertAction(title: title, style: .default, handler: placeCall)
      quickDialActionSheet.addAction(customProviderAction)


      private func addSetDefaultButton()
      let setDefaultAction = UIAlertAction(title: "Alerts.ActionSheet.SetDefaultActionTitle".localized, style: .default, handler: openDefaultProviderSettingsScreen)
      quickDialActionSheet.addAction(setDefaultAction)


      private func openDefaultProviderSettingsScreen(action: UIAlertAction)
      // TODO: Create function


      private func addCancelButton()
      let cancelAction = UIAlertAction(title: "Alerts.Cancel".localized, style: .cancel)
      quickDialActionSheet.addAction(cancelAction)


      private func placeCall(using provider: ConferenceProvider)
      do
      try caller.placeQuickCallAsHost(with: provider)
      catch
      let callError = error as! CallerError
      CallerErrorHandler.handleError(callError)
      return





      LandingPageTableViewController Properties (not showing all this class as all the code bar these properties is used for different things)



      class LandingPageViewController: UIViewController {

      private let caller: Caller = Caller()
      var quickDialActionSheet = UIAlertController(title: "Alerts.ActionSheet.Title".localized, message: nil, preferredStyle: .actionSheet)


      ConferenceProvider enum



      ///Defines the type of conference call service the meeting uses if any.
      enum ConferenceProvider :String
      case airtel = "Airtel"
      case att = "AT&T"
      case custom = "Custom"
      case ibmMeetings = "IBM Meetings"
      case unknown = ""
      case webex = "WebEx"
      case zoom = "Zoom"

      // TODO: Remove in favor of enumeratable enum Swift 4.2
      static let allValues = [airtel, att, custom, ibmMeetings, webex, zoom]


      // MARK: Settings properties
      extension ConferenceProvider

      /**
      Providers that can be dialed in to without a meeting with user provided Settings information
      instead of a meeting invite
      */
      static var quickDialableProviders: [ConferenceProvider]
      return allValues.filter $0.isQuickDialableAsHost

      ///No conference providers currently have the necessary information to dial in without a meeting.
      static var noQuickDialableProvidersExist: Bool return quickDialableProviders.isEmpty

      ///Persistently saved user phoneNumber for provider
      var phoneNumber: String?
      switch self
      case .airtel:
      return Settings.airtelNumber
      case .att:
      return Settings.attNumber
      case .custom:
      return Settings.CustomProvider.number
      case .ibmMeetings:
      return Settings.ibmMeetingsNumber
      case .unknown:
      return nil
      case .webex:
      return Settings.webexNumber
      case .zoom:
      return Settings.zoomNumber



      ///Persistently saved user participant code for provider. If there's more than one the first is returned.
      var participantCode: String?
      switch self
      case .airtel:
      return Settings.airtelParticipantCode
      case .att:
      return Settings.attParticipantCodes.first
      case .custom:
      return Settings.CustomProvider.participantCode
      case .ibmMeetings:
      return Settings.ibmMeetingsModeratorCode
      case .unknown:
      return nil
      case .webex:
      return Settings.webexAccessCode
      case .zoom:
      return Settings.zoomMeetingId



      ///Persistently saved user participant code for provider. If there's more than one the first is returned.
      var hostCode: String?
      switch self
      case .airtel:
      return Settings.airtelHostCode
      case .att:
      return Settings.attHostCodes.first
      case.custom:
      return Settings.CustomProvider.hostCode
      case .ibmMeetings:
      return Settings.ibmMeetingsModeratorCode
      case .unknown:
      return nil
      case .webex:
      return Settings.webexHostPin
      case .zoom:
      return nil



      /**
      Schema from which to construct a dialcode for iOS phonecalls as a host.

      ## Key
      * n = PhoneNumber
      * h = HostCode
      * p = ParticipantCode
      * , = Pause (1 second)
      * # = Submit current input
      * ; = Wait for user input
      */
      var hostDialCodeSchema: String
      switch self
      case .airtel, .att, .ibmMeetings, .unknown, .zoom:
      return "n,,h#"
      case .custom:
      return Settings.CustomProvider.hostDialFormat ?? "n,,h#"
      case .webex:
      return "n,,p#,,#,,h#"



      /**
      Schema from which to construct a dialcode for iOS phonecalls as a participant.

      ## Key
      * n = PhoneNumber
      * h = HostCode
      * p = ParticipantCode
      * , = Pause (1 second)
      * # = Submit current input
      * ; = Wait for user input
      */
      var participantDialCodeSchema: String
      switch self
      case .airtel, .att, .ibmMeetings, .unknown:
      return "n,,p#"
      case .custom:
      return Settings.CustomProvider.participantDialFormat ?? "n,,p#"
      case .webex:
      return "n,,p#,,#,,#"
      case .zoom:
      return "n,,p#,,,,#"



      /**
      User can call in to this provider as the host without a meeting invite.

      - Remark:
      Zoom calls cannot be hosted via telephone/dial-in.
      */
      var isQuickDialableAsHost: Bool
      switch self
      case .airtel:
      return Settings.airtelHostCode != nil && Settings.airtelNumber != nil
      case .att:
      return Settings.attHostCodes.first != nil && Settings.attNumber != nil
      case .custom:
      return Settings.CustomProvider.hostCode != nil && Settings.CustomProvider.number != nil
      case .ibmMeetings:
      return Settings.ibmMeetingsModeratorCode != nil && Settings.ibmMeetingsNumber != nil
      case .unknown:
      return false
      case .webex:
      return Settings.webexHostPin != nil && Settings.webexNumber != nil
      case .zoom:
      return false









      share|improve this question











      I'm creating a button that will dial a user quickly in to their conference calls should they have a default provider set. If they have no default provider an action sheet will appear that allows them to choose their provider for this call or set their default provider in the settings.
      This works fine but I can't help but feel this is a MassiveViewController implementation as it appears subclassing a UIAlertController is not possible. I'm debating one of the following:



      • Creating a class that builds the quickDialActionSheet and either returns it or presents it.

      • Using a pre-existing Alerter class that has 600 lines of static functions for our existing alerts

      • Moving this extension to another file called QuickDialActionSheet

      For the most part I'm looking for a way to move as much of this logic out of the ViewController although I'd be grateful for all input that can improve the quality of my code here.



      QuickDialLogic Code



      extension LandingPageViewController 
      /// Quick dial in to a meeting as host when tapping the host button
      @IBAction func hostClicked(_ sender: Any)
      if let defaultConferenceProvider = Settings.defaultConferenceProvider
      return placeCall(using: defaultConferenceProvider)


      if ConferenceProvider.noQuickDialableProvidersExist
      presentQuickDialSetupPrompt()
      else
      presentQuickDialProviderActionSheet()



      private func presentQuickDialSetupPrompt()
      // TODO: Create function


      private func presentQuickDialProviderActionSheet()
      refreshQuickDialProviderActionSheetActions()
      self.present(quickDialActionSheet, animated: true)


      // TODO: Swift 4.2 use enumeratable enum for Conference Provider types
      private func refreshQuickDialProviderActionSheetActions()
      quickDialActionSheet = UIAlertController(title: "Alerts.ActionSheet.Title".localized, message: nil, preferredStyle: .actionSheet)
      addDialableProviderButtons()
      addSetDefaultButton()
      addCancelButton()


      /**
      Add ActionSheet buttons for Conference Providers that have both phonenumbers
      & host codes assigned to them from the Settings.
      */
      private func addDialableProviderButtons()
      for provider in ConferenceProvider.allValues where provider != .custom
      guard provider.isQuickDialableAsHost else continue
      let quickDialAction = UIAlertAction(title: provider.rawValue, style: .default, handler: placeCall)
      quickDialActionSheet.addAction(quickDialAction)

      if ConferenceProvider.custom.isQuickDialableAsHost
      addCustomProviderButton()



      private func placeCall(action: UIAlertAction)
      let providerName = String(action.title?.split(separator: ":").first ?? "")
      let provider = ConferenceProvider(rawValue: providerName) ?? .unknown
      placeCall(using: provider)


      private func addCustomProviderButton()
      let title = "("Settings.CustomProvider".localized): (Settings.CustomProvider.name ?? "")"
      let customProviderAction = UIAlertAction(title: title, style: .default, handler: placeCall)
      quickDialActionSheet.addAction(customProviderAction)


      private func addSetDefaultButton()
      let setDefaultAction = UIAlertAction(title: "Alerts.ActionSheet.SetDefaultActionTitle".localized, style: .default, handler: openDefaultProviderSettingsScreen)
      quickDialActionSheet.addAction(setDefaultAction)


      private func openDefaultProviderSettingsScreen(action: UIAlertAction)
      // TODO: Create function


      private func addCancelButton()
      let cancelAction = UIAlertAction(title: "Alerts.Cancel".localized, style: .cancel)
      quickDialActionSheet.addAction(cancelAction)


      private func placeCall(using provider: ConferenceProvider)
      do
      try caller.placeQuickCallAsHost(with: provider)
      catch
      let callError = error as! CallerError
      CallerErrorHandler.handleError(callError)
      return





      LandingPageTableViewController Properties (not showing all this class as all the code bar these properties is used for different things)



      class LandingPageViewController: UIViewController {

      private let caller: Caller = Caller()
      var quickDialActionSheet = UIAlertController(title: "Alerts.ActionSheet.Title".localized, message: nil, preferredStyle: .actionSheet)


      ConferenceProvider enum



      ///Defines the type of conference call service the meeting uses if any.
      enum ConferenceProvider :String
      case airtel = "Airtel"
      case att = "AT&T"
      case custom = "Custom"
      case ibmMeetings = "IBM Meetings"
      case unknown = ""
      case webex = "WebEx"
      case zoom = "Zoom"

      // TODO: Remove in favor of enumeratable enum Swift 4.2
      static let allValues = [airtel, att, custom, ibmMeetings, webex, zoom]


      // MARK: Settings properties
      extension ConferenceProvider

      /**
      Providers that can be dialed in to without a meeting with user provided Settings information
      instead of a meeting invite
      */
      static var quickDialableProviders: [ConferenceProvider]
      return allValues.filter $0.isQuickDialableAsHost

      ///No conference providers currently have the necessary information to dial in without a meeting.
      static var noQuickDialableProvidersExist: Bool return quickDialableProviders.isEmpty

      ///Persistently saved user phoneNumber for provider
      var phoneNumber: String?
      switch self
      case .airtel:
      return Settings.airtelNumber
      case .att:
      return Settings.attNumber
      case .custom:
      return Settings.CustomProvider.number
      case .ibmMeetings:
      return Settings.ibmMeetingsNumber
      case .unknown:
      return nil
      case .webex:
      return Settings.webexNumber
      case .zoom:
      return Settings.zoomNumber



      ///Persistently saved user participant code for provider. If there's more than one the first is returned.
      var participantCode: String?
      switch self
      case .airtel:
      return Settings.airtelParticipantCode
      case .att:
      return Settings.attParticipantCodes.first
      case .custom:
      return Settings.CustomProvider.participantCode
      case .ibmMeetings:
      return Settings.ibmMeetingsModeratorCode
      case .unknown:
      return nil
      case .webex:
      return Settings.webexAccessCode
      case .zoom:
      return Settings.zoomMeetingId



      ///Persistently saved user participant code for provider. If there's more than one the first is returned.
      var hostCode: String?
      switch self
      case .airtel:
      return Settings.airtelHostCode
      case .att:
      return Settings.attHostCodes.first
      case.custom:
      return Settings.CustomProvider.hostCode
      case .ibmMeetings:
      return Settings.ibmMeetingsModeratorCode
      case .unknown:
      return nil
      case .webex:
      return Settings.webexHostPin
      case .zoom:
      return nil



      /**
      Schema from which to construct a dialcode for iOS phonecalls as a host.

      ## Key
      * n = PhoneNumber
      * h = HostCode
      * p = ParticipantCode
      * , = Pause (1 second)
      * # = Submit current input
      * ; = Wait for user input
      */
      var hostDialCodeSchema: String
      switch self
      case .airtel, .att, .ibmMeetings, .unknown, .zoom:
      return "n,,h#"
      case .custom:
      return Settings.CustomProvider.hostDialFormat ?? "n,,h#"
      case .webex:
      return "n,,p#,,#,,h#"



      /**
      Schema from which to construct a dialcode for iOS phonecalls as a participant.

      ## Key
      * n = PhoneNumber
      * h = HostCode
      * p = ParticipantCode
      * , = Pause (1 second)
      * # = Submit current input
      * ; = Wait for user input
      */
      var participantDialCodeSchema: String
      switch self
      case .airtel, .att, .ibmMeetings, .unknown:
      return "n,,p#"
      case .custom:
      return Settings.CustomProvider.participantDialFormat ?? "n,,p#"
      case .webex:
      return "n,,p#,,#,,#"
      case .zoom:
      return "n,,p#,,,,#"



      /**
      User can call in to this provider as the host without a meeting invite.

      - Remark:
      Zoom calls cannot be hosted via telephone/dial-in.
      */
      var isQuickDialableAsHost: Bool
      switch self
      case .airtel:
      return Settings.airtelHostCode != nil && Settings.airtelNumber != nil
      case .att:
      return Settings.attHostCodes.first != nil && Settings.attNumber != nil
      case .custom:
      return Settings.CustomProvider.hostCode != nil && Settings.CustomProvider.number != nil
      case .ibmMeetings:
      return Settings.ibmMeetingsModeratorCode != nil && Settings.ibmMeetingsNumber != nil
      case .unknown:
      return false
      case .webex:
      return Settings.webexHostPin != nil && Settings.webexNumber != nil
      case .zoom:
      return false











      share|improve this question










      share|improve this question




      share|improve this question









      asked Jul 30 at 19:07









      Deco

      11310




      11310

























          active

          oldest

          votes











          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f200614%2fquick-dial-button-actionsheet-within-viewcontroller%23new-answer', 'question_page');

          );

          Post as a guest



































          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes










           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f200614%2fquick-dial-button-actionsheet-within-viewcontroller%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Greedy Best First Search implementation in Rust

          Function to Return a JSON Like Objects Using VBA Collections and Arrays

          C++11 CLH Lock Implementation