class RubyMotionQuery::App

Constants

ALERT_STYLES
ALL_FIELD_STYLES
TEMPLATE_FIELD_STYLES
VALID_STYLES

Public Class Methods

add_template_actions(template, &block) click to toggle source

When adding a new template do the following: 1 - Add it here 2 - Add the test 3 - Add symbol to the README.md list

# File lib/project/button_templates.rb, line 10
def self.add_template_actions(template, &block)
  yes    = "Yes" #NSLocalizedString("Yes", nil)
  no     = "No" #NSLocalizedString("No", nil)
  cancel = "Cancel" #NSLocalizedString("Cancel", nil)
  ok     = "OK" #NSLocalizedString("OK", nil)
  delete = "Delete" #NSLocalizedString("Delete", nil)

  case template
  when :yes_no
    [
      rmq.app.make_button(title: yes, tag: :yes, &block),
      rmq.app.make_button(title: no, tag: :no, &block)
    ]
  when :yes_no_cancel
    [
      rmq.app.make_button(title: yes, tag: :yes, &block),
      rmq.app.make_button(title: no, tag: :no, &block),
      rmq.app.make_button(title: cancel, tag: :cancel, style: :cancel, &block)
    ]
  when :ok_cancel
    [
      rmq.app.make_button(title: ok, &block),
      rmq.app.make_button(title: cancel, tag: :cancel, style: :cancel, &block)
    ]
  when :delete_cancel
    [
      rmq.app.make_button(title: delete, tag: :delete, style: :destructive, &block),
      rmq.app.make_button(title: cancel, tag: :cancel, style: :cancel, &block)
    ]
  else
    []
  end
end
add_template_fieldset(template, opts={}) click to toggle source

When adding a new template do the following: 1 - Add it here 2 - Add the test 3 - Add symbol to the README.md list

# File lib/project/field_templates.rb, line 9
def self.add_template_fieldset(template, opts={})

  login             = NSLocalizedString("Login", nil)
  password          = NSLocalizedString("Password", nil)
  current_password  = NSLocalizedString("Current Password", nil)
  new_password      = NSLocalizedString("New Password", nil)

  fieldset = {alert_view_style: UIAlertViewStyleDefault, fields: [] }
  case template
    when :input
      fieldset[:alert_view_style] = UIAlertViewStylePlainTextInput
      fieldset[:fields] =
      [
        rmq.app.make_field(:text, keyboard_type: :default, secure_text_entry: false, placeholder: opts.fetch(:placeholder,''))
      ]
    when :secure
      fieldset[:alert_view_style] = UIAlertViewStyleSecureTextInput
      fieldset[:fields] =
        [
          rmq.app.make_field(:text, keyboard_type: :default, secure_text_entry: true, placeholder: opts.fetch(:placeholder,''))
        ]
    when :login
      fieldset[:alert_view_style] = UIAlertViewStyleLoginAndPasswordInput
      fieldset[:fields] =
        [
          rmq.app.make_field(:login, keyboard_type: :email_address, secure_text_entry: false, placeholder: login),
          rmq.app.make_field(:password, keyboard_type: :default, secure_text_entry: true, placeholder: password)
        ]
    when :change_password
      fieldset[:alert_view_style] = UIAlertViewStyleLoginAndPasswordInput
      fieldset[:fields] =
        [
          rmq.app.make_field(:current_password, keyboard_type: :default, secure_text_entry: true, placeholder: current_password),
          rmq.app.make_field(:new_password, keyboard_type: :default, secure_text_entry: true, placeholder: new_password)
        ]
  end
  fieldset
end
alert(opts={}, &block) click to toggle source

Creates and shows the UIAlertController (iOS 8) or UIAlertView/UIActionSheet (iOS 7). Usage Example:

rmq.app.alert(message: "This is a test")
rmq.app.alert(title: "Hey there", message: "Are you happy?")

@return [UIAlertController]

# File lib/project/red_alert.rb, line 15
def alert(opts={}, &block)

  # ------------------------------------
  # -- Setup sane defaults -------------
  # ------------------------------------
  opts           = {message: opts} if opts.is_a? String
  opts           = {style: :alert, animated: true, show_now: true}.merge(opts)
          # Ability to make no message
  opts[:message] = if opts.has_key?(:message)
    opts[:message].nil? ? nil : opts[:message].to_s
  else
    NSLocalizedString("Alert!", nil)
  end


  opts[:style]   = VALID_STYLES.include?(opts[:style]) ? opts[:style] : :alert
  if opts[:style] == :sheet and rmq.device.ipad? and opts[:source].nil?
    raise ArgumentError.new "Please provide a :source view to use :sheet on iPad"
  end
  opts[:fields]  = opts[:style] == :custom && opts[:fields] ? opts[:fields] : {text: {placeholder: ''}}
  api            = rmq.device.ios_at_least?(8) ? :modern : :deprecated
  api            = :deprecated if rmq.device.ios_at_least?(8) && opts[:api] == :deprecated
  opts[:api]     = api


  # -----------------------------------------
  # -- Who provides the alerts? -------------
  # -----------------------------------------

  if opts[:api] == :modern
    provider = AlertControllerProvider.new
  else
    if ALERT_STYLES.include?(opts[:style])
      provider = AlertViewProvider.new
    else
      provider = ActionSheetProvider.new
    end
  end

  # -------------------------------------------------
  # -- Configure the input fields --------------
  # -------------------------------------------------

  fieldset = {alert_view_style: UIAlertViewStyleDefault, fields: []}

  if TEMPLATE_FIELD_STYLES.include?(opts[:style])
    fieldset = add_template_fieldset(opts[:style], opts)
  elsif opts[:style] == :custom
    fieldset = custom_fieldset(opts[:api], opts[:fields])
  end

  opts[:style] = :alert if ALL_FIELD_STYLES.include?(opts[:style])

  # -------------------------------------------------
  # -- Configure the actions (choices) --------------
  # -------------------------------------------------
  actions = []
  if opts[:actions] && opts[:actions].is_a?(Array) && opts[:actions].length > 0
    # caller has pre-defined actions
    actions << map_action_buttons(opts[:actions], &block)
  elsif opts[:actions] && opts[:actions].is_a?(Symbol)
    # caller wants a template
    actions << add_template_actions(opts[:actions], &block)
  elsif block_given?
    # convert our block into the one & only action
    button_text = NSLocalizedString("OK", nil) # Localized string failing
    button_text = "OK"
    actions << AlertAction.new(button_text, &block)
  else
    # NSLocalizedString causes crash if passed to AlertAction
    actions << [AlertAction.new]
  end
  provider.build(actions.flatten.compact, fieldset, opts)

  # --------------------------------------------
  # -- Show the modal right away? --------------
  # --------------------------------------------
  provider.show if opts[:show_now]

  # TODO: find a better way to do this ugly housekeeping... right now, this never gets cleaned, so this is leaky.
  if opts[:api] == :deprecated
    @rmq_red_alert_providers ||= []
    @rmq_red_alert_providers << provider
  end

  provider
end
custom_fieldset(api_version = :modern, fields) click to toggle source
# File lib/project/red_alert.rb, line 103
def custom_fieldset(api_version = :modern, fields)
  raise ArgumentError.new "At least one field must be provided for a custom style" unless fields && fields.count > 0
  fieldset = {alert_view_style: UIAlertViewStyleDefault, fields: [] }
  if api_version == :deprecated
    case fields.count
      when 1
        fieldset[:alert_view_style] = UIAlertViewStylePlainTextInput
      when 2
        fieldset[:alert_view_style] = UIAlertViewStyleLoginAndPasswordInput
      else
        raise ArgumentError.new "When running iOS < 8, up to two fields can be provided for a custom style"
    end
  end
  alert_fields = []
  fields.each do |k, v|
    alert_fields << AlertField.new(k, v)
  end
  fieldset[:fields] = alert_fields
  fieldset
end
make_button(opts={}, &block) click to toggle source

Returns an AlertAction from given parameters Usage Example:

yes = rmq.make_button("Yes")
cancel = rmq.make_button(title: "Cancel", style: :cancel) {
   puts "Cancel pressed"
}

@return [AlertAction]

# File lib/project/red_alert.rb, line 141
def make_button(opts={}, &block)
  AlertAction.new(opts, &block)
end
make_field(name, opts={}) click to toggle source

Returns an AlertField from given parameters Usage Example:

login = rmq.make_field("Login")
password = rmq.make_field(:password, secure: true, placeholder: 'Password')

@return [AlertField]

# File lib/project/red_alert.rb, line 130
def make_field(name, opts={})
  AlertField.new(name, opts)
end
map_action_buttons(buttons, &block) click to toggle source

Returns an array of action buttons based on the symbols you pass in. Usage Example:

rmq.app.alert title: "Hey!", actions: [ "Go ahead", :cancel, :delete ] do |button_tag|
  puts "#{button_text} pressed"
end
# File lib/project/red_alert.rb, line 150
def map_action_buttons(buttons, &block)
  yes    = NSLocalizedString("Yes", nil)
  no     = NSLocalizedString("No", nil)
  cancel = NSLocalizedString("Cancel", nil)
  ok     = NSLocalizedString("OK", nil)
  delete = NSLocalizedString("Delete", nil)

  buttons.map do |button|
    case button
    when :cancel  then make_button(title: cancel, tag: :cancel, style: :cancel, &block)
    when :yes     then make_button(title: yes, tag: :yes, &block)
    when :no      then make_button(title: no, tag: :no, &block)
    when :ok      then make_button(title: ok, tag: :ok, &block)
    when :delete  then make_button(title: delete, tag: :delete, style: :destructive, &block)
    when String   then make_button(title: button, tag: button, &block)
    else button
    end
  end
end